📄 lunarview.java
字号:
mHeading = 0; // Figure initial spot for landing, not too near center while (true) { mGoalX = (int) (Math.random() * (mCanvasWidth - mGoalWidth)); if (Math.abs(mGoalX - (mX - mLanderWidth / 2)) > mCanvasHeight / 6) break; } mLastTime = System.currentTimeMillis() + 100; setState(STATE_RUNNING); } } /** * Pauses the physics update & animation. */ public void pause() { synchronized (mSurfaceHolder) { if (mMode == STATE_RUNNING) setState(STATE_PAUSE); } } /** * Restores game state from the indicated Bundle. Typically called when * the Activity is being restored after having been previously * destroyed. * * @param savedState Bundle containing the game state */ public synchronized void restoreState(Bundle savedState) { synchronized (mSurfaceHolder) { setState(STATE_PAUSE); mRotating = 0; mEngineFiring = false; mDifficulty = savedState.getInt(KEY_DIFFICULTY); mX = savedState.getDouble(KEY_X); mY = savedState.getDouble(KEY_Y); mDX = savedState.getDouble(KEY_DX); mDY = savedState.getDouble(KEY_DY); mHeading = savedState.getDouble(KEY_HEADING); mLanderWidth = savedState.getInt(KEY_LANDER_WIDTH); mLanderHeight = savedState.getInt(KEY_LANDER_HEIGHT); mGoalX = savedState.getInt(KEY_GOAL_X); mGoalSpeed = savedState.getInt(KEY_GOAL_SPEED); mGoalAngle = savedState.getInt(KEY_GOAL_ANGLE); mGoalWidth = savedState.getInt(KEY_GOAL_WIDTH); mWinsInARow = savedState.getInt(KEY_WINS); mFuel = savedState.getDouble(KEY_FUEL); } } @Override public void run() { while (mRun) { Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { if (mMode == STATE_RUNNING) updatePhysics(); doDraw(c); } } finally { // do this in a finally so that if an exception is thrown // during the above, we don't leave the Surface in an // inconsistent state if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } } /** * Dump game state to the provided Bundle. Typically called when the * Activity is being suspended. * * @return Bundle with this view's state */ public Bundle saveState(Bundle map) { synchronized (mSurfaceHolder) { if (map != null) { map.putInt(KEY_DIFFICULTY, Integer.valueOf(mDifficulty)); map.putDouble(KEY_X, Double.valueOf(mX)); map.putDouble(KEY_Y, Double.valueOf(mY)); map.putDouble(KEY_DX, Double.valueOf(mDX)); map.putDouble(KEY_DY, Double.valueOf(mDY)); map.putDouble(KEY_HEADING, Double.valueOf(mHeading)); map.putInt(KEY_LANDER_WIDTH, Integer.valueOf(mLanderWidth)); map.putInt(KEY_LANDER_HEIGHT, Integer .valueOf(mLanderHeight)); map.putInt(KEY_GOAL_X, Integer.valueOf(mGoalX)); map.putInt(KEY_GOAL_SPEED, Integer.valueOf(mGoalSpeed)); map.putInt(KEY_GOAL_ANGLE, Integer.valueOf(mGoalAngle)); map.putInt(KEY_GOAL_WIDTH, Integer.valueOf(mGoalWidth)); map.putInt(KEY_WINS, Integer.valueOf(mWinsInARow)); map.putDouble(KEY_FUEL, Double.valueOf(mFuel)); } } return map; } /** * Sets the current difficulty. * * @param difficulty */ public void setDifficulty(int difficulty) { synchronized (mSurfaceHolder) { mDifficulty = difficulty; } } /** * Sets if the engine is currently firing. */ public void setFiring(boolean firing) { synchronized (mSurfaceHolder) { mEngineFiring = firing; } } /** * Used to signal the thread whether it should be running or not. * Passing true allows the thread to run; passing false will shut it * down if it's already running. Calling start() after this was most * recently called with false will result in an immediate shutdown. * * @param b true to run, false to shut down */ public void setRunning(boolean b) { mRun = b; } /** * Sets the game mode. That is, whether we are running, paused, in the * failure state, in the victory state, etc. * * @see #setState(int, CharSequence) * @param mode one of the STATE_* constants */ public void setState(int mode) { synchronized (mSurfaceHolder) { setState(mode, null); } } /** * Sets the game mode. That is, whether we are running, paused, in the * failure state, in the victory state, etc. * * @param mode one of the STATE_* constants * @param message string to add to screen or null */ public void setState(int mode, CharSequence message) { /* * This method optionally can cause a text message to be displayed * to the user when the mode changes. Since the View that actually * renders that text is part of the main View hierarchy and not * owned by this thread, we can't touch the state of that View. * Instead we use a Message + Handler to relay commands to the main * thread, which updates the user-text View. */ synchronized (mSurfaceHolder) { mMode = mode; if (mMode == STATE_RUNNING) { Message msg = mHandler.obtainMessage(); Bundle b = new Bundle(); b.putString("text", ""); b.putInt("viz", View.INVISIBLE); msg.setData(b); mHandler.sendMessage(msg); } else { mRotating = 0; mEngineFiring = false; Resources res = mContext.getResources(); CharSequence str = ""; if (mMode == STATE_READY) str = res.getText(R.string.mode_ready); else if (mMode == STATE_PAUSE) str = res.getText(R.string.mode_pause); else if (mMode == STATE_LOSE) str = res.getText(R.string.mode_lose); else if (mMode == STATE_WIN) str = res.getString(R.string.mode_win_prefix) + mWinsInARow + " " + res.getString(R.string.mode_win_suffix); if (message != null) { str = message + "\n" + str; } if (mMode == STATE_LOSE) mWinsInARow = 0; Message msg = mHandler.obtainMessage(); Bundle b = new Bundle(); b.putString("text", str.toString()); b.putInt("viz", View.VISIBLE); msg.setData(b); mHandler.sendMessage(msg); } } } /* Callback invoked when the surface dimensions change. */ public void setSurfaceSize(int width, int height) { // synchronized to make sure these all change atomically synchronized (mSurfaceHolder) { mCanvasWidth = width; mCanvasHeight = height; // don't forget to resize the background image mBackgroundImage = mBackgroundImage.createScaledBitmap( mBackgroundImage, width, height, true); } } /** * Resumes from a pause. */ public void unpause() { // Move the real time clock up to now synchronized (mSurfaceHolder) { mLastTime = System.currentTimeMillis() + 100; } setState(STATE_RUNNING); } /** * Handles a key-down event. * * @param keyCode the key that was pressed * @param msg the original event object * @return true */ boolean doKeyDown(int keyCode, KeyEvent msg) { synchronized (mSurfaceHolder) { boolean okStart = false; if (keyCode == KeyEvent.KEYCODE_DPAD_UP) okStart = true; if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) okStart = true; if (keyCode == KeyEvent.KEYCODE_S) okStart = true; boolean center = (keyCode == KeyEvent.KEYCODE_DPAD_UP); if (okStart && (mMode == STATE_READY || mMode == STATE_LOSE || mMode == STATE_WIN)) { // ready-to-start -> start doStart(); return true; } else if (mMode == STATE_PAUSE && okStart) { // paused -> running unpause(); return true; } else if (mMode == STATE_RUNNING) { // center/space -> fire if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_SPACE) { setFiring(true); return true; // left/q -> left } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_Q) { mRotating = -1; return true; // right/w -> right } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_W) { mRotating = 1; return true; // up -> pause } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { pause(); return true; } } return false; } } /** * Handles a key-up event. * * @param keyCode the key that was pressed * @param msg the original event object * @return true if the key was handled and consumed, or else false */ boolean doKeyUp(int keyCode, KeyEvent msg) { boolean handled = false; synchronized (mSurfaceHolder) { if (mMode == STATE_RUNNING) { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -