📄 lunarview.java
字号:
/* * Copyright (C) 2007 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.google.android.lunarlander;import android.content.Context;import android.content.Resources;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.drawable.Drawable;import android.view.KeyEvent;import android.util.AttributeSet;import android.os.Bundle;import android.view.View;import android.widget.TextView;import java.util.Map;/** * View that draws, takes keystrokes, etc. for a simple LunarLander game. * * Has a mode which RUNNING, PAUSED, etc. Has a x, y, dx, dy, ... capturing the * current ship physics. All x/y etc. are measured with (0,0) at the lower left. * updatePhysics() advances the physics based on realtime. draw() renders the * ship, and does an invalidate() to prompt another draw() as soon as possible * by the system. */class LunarView extends View { public static final int READY = 0; public static final int RUNNING = 1; public static final int PAUSE = 2; public static final int LOSE = 3; public static final int WIN = 4; public static final int EASY = 0; public static final int MEDIUM = 1; public static final int HARD = 2; // Parameters for how the physics works. public static final int FIRE_ACCEL_SEC = 80; public static final int DOWN_ACCEL_SEC = 35; public static final int FUEL_SEC = 10; public static final int SLEW_SEC = 120; // degrees/second rotate public static final int FUEL_INIT = 60; public static final int FUEL_MAX = 100; public static final int SPEED_INIT = 30; public static final int SPEED_MAX = 120; public static final int SPEED_HYPERSPACE = 180; // Parameters for landing successfully (MEDIUM difficulty). public static final int TARGET_SPEED = 28; public static final double TARGET_WIDTH = 1.6; // how much wider than lander public static final int TARGET_ANGLE = 18; /** * Pixel height of the fuel/speed bar. */ public static final int BAR_HEIGHT = 10; /** * Pixel width of the fuel/speed bar. */ public static final int BAR = 100; /** * Height of the landing pad off the bottom. */ public static final int PAD_HEIGHT = 8; /** * Extra pixels below the landing gear in the images */ public static final int BOTTOM_PADDING = 17; /** * The state of the game. One of READY, RUNNING, PAUSE, LOSE, or WIN */ private int mMode; /** * Current difficulty -- amount of fuel, allowed angle, etc. * Default is MEDIUM. */ private int mDifficulty; /** * X of lander center. */ private double mX; /** * Y of lander center. */ private double mY; /** * Velocity dx. */ private double mDX; /** * Velocity dy. */ private double mDY; /** * Lander heading in degrees, with 0 up, 90 right. * Kept in the range 0..360. */ private double mHeading; /** * Pixel width of lander image. */ private int mLanderWidth; /** * Pixel height of lander image. */ private int mLanderHeight; /** * Currently rotating, -1 left, 0 none, 1 right. */ private int mRotating; /** * X of the landing pad. */ private int mGoalX; /** * Allowed speed. */ private int mGoalSpeed; /** * Allowed angle. */ private int mGoalAngle; /** * Width of the landing pad. */ private int mGoalWidth; /** * Number of wins in a row. */ private int mWinsInARow; /** * Fuel remaining */ private double mFuel; /** * Is the engine burning? */ private boolean mEngineFiring; /** * Used to figure out elapsed time between frames */ private long mLastTime; /** * Paint to draw the lines on screen. */ private Paint mLinePaint; /** * "Bad" speed-too-high variant of the line color. */ private Paint mLinePaintBad; /** * What to draw for the Lander in its normal state */ private Drawable mLanderImage; /** * What to draw for the Lander when the engine is firing */ private Drawable mFiringImage; /** * What to draw for the Lander when it has crashed */ private Drawable mCrashedImage; /** * Pointer to the text view to display "Paused.." etc. */ private TextView mStatusText; /** * Scratch rect object. */ private RectF mScratchRect; public LunarView(Context context, AttributeSet attrs, Map inflateParams) { super(context, attrs, inflateParams); mLanderImage = context.getResources().getDrawable( R.drawable.lander_plain); mFiringImage = context.getResources().getDrawable( R.drawable.lander_firing); mCrashedImage = context.getResources().getDrawable( R.drawable.lander_crashed); // Use the regular lander image as the model size // for all the images. mLanderWidth = mLanderImage.getIntrinsicWidth(); mLanderHeight = mLanderImage.getIntrinsicHeight(); setBackground(R.drawable.earthrise); // Make sure we get keys setFocusable(true); // Initialize paints for speedometer mLinePaint = new Paint(); mLinePaint.setAntiAlias(true); mLinePaint.setARGB(255, 0, 255, 0); mLinePaintBad = new Paint(); mLinePaintBad.setAntiAlias(true); mLinePaintBad.setARGB(255, 120, 180, 0); mScratchRect= new RectF(0,0,0,0); mWinsInARow = 0; mDifficulty = MEDIUM; // initial show-up of lander (not yet playing) mX = mLanderWidth; mY = mLanderHeight * 2; mFuel = FUEL_INIT; mDX = 0; mDY = 0; mHeading = 0; mEngineFiring = true; } /** * Save game state so that the user does not lose anything * if the game process is killed while we are in the * background. * * @return Map with this view's state */ public Bundle saveState() { Bundle map = new Bundle(); map.putInteger("mDifficulty", Integer.valueOf(mDifficulty)); map.putDouble("mX", Double.valueOf(mX)); map.putDouble("mY", Double.valueOf(mY)); map.putDouble("mDX", Double.valueOf(mDX)); map.putDouble("mDY", Double.valueOf(mDY)); map.putDouble("mHeading", Double.valueOf(mHeading)); map.putInteger("mLanderWidth", Integer.valueOf(mLanderWidth)); map.putInteger("mLanderHeight", Integer.valueOf(mLanderHeight)); map.putInteger("mGoalX", Integer.valueOf(mGoalX)); map.putInteger("mGoalSpeed", Integer.valueOf(mGoalSpeed)); map.putInteger("mGoalAngle", Integer.valueOf(mGoalAngle)); map.putInteger("mGoalWidth", Integer.valueOf(mGoalWidth)); map.putInteger("mWinsInARow", Integer.valueOf(mWinsInARow)); map.putDouble("mFuel", Double.valueOf(mFuel)); return map; } /** * Restore game state if our process is being relaunched * * @param icicle Map containing the game state */ public void restoreState(Bundle icicle) { setMode(PAUSE); mRotating = 0; mEngineFiring = false; mDifficulty = icicle.getInteger("mDifficulty"); mX = icicle.getDouble("mX"); mY = icicle.getDouble("mY"); mDX = icicle.getDouble("mDX"); mDY = icicle.getDouble("mDY"); mHeading = icicle.getDouble("mHeading"); mLanderWidth = icicle.getInteger("mLanderWidth"); mLanderHeight = icicle.getInteger("mLanderHeight"); mGoalX = icicle.getInteger("mGoalX"); mGoalSpeed = icicle.getInteger("mGoalSpeed"); mGoalAngle = icicle.getInteger("mGoalAngle"); mGoalWidth = icicle.getInteger("mGoalWidth"); mWinsInARow = icicle.getInteger("mWinsInARow"); mFuel = icicle.getDouble("mFuel"); } /** * Installs a pointer to the text view used * for messages. */ public void setTextView(TextView textView) { mStatusText = textView; } /** * Standard window-focus override. * Notice focus lost so we can pause on focus lost. * e.g. user switches to take a call. */ @Override public void windowFocusChanged(boolean hasWindowFocus) { if (!hasWindowFocus) doPause(); } /** * Standard override of View.draw. * Draws the ship and fuel/speed bars. */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mMode == RUNNING) updatePhysics(); int screenWidth = getWidth(); int screenHeight = getHeight(); int yTop = screenHeight - ((int)mY + mLanderHeight/2); int xLeft = (int)mX - mLanderWidth/2; // Draw fuel rect int fuelWidth = (int)(BAR * mFuel / FUEL_MAX); mScratchRect.set(4, 4, 4 + fuelWidth, 4 + BAR_HEIGHT); canvas.drawRect(mScratchRect, mLinePaint); double speed = Math.sqrt(mDX*mDX + mDY*mDY); int speedWidth = (int)(BAR * speed / SPEED_MAX);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -