Android游戏开发之八:SurfaceView类的应用实例

大家可以把此工程导入到Eclipse,然后编译运行,试玩一下。最后对应着看代码,这样更容易理解。下面上代码:

专注于为中小企业提供网站设计制作、成都网站设计服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业祁连免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了数千家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。

 
 
  1. class LunarView extends SurfaceView implements SurfaceHolder.Callback {    
  2.     class LunarThread extends Thread {    
  3.         /*   
  4.          * Difficulty setting constants   
  5.          */   
  6.         public static final int DIFFICULTY_EASY = 0;    
  7.         public static final int DIFFICULTY_HARD = 1;    
  8.         public static final int DIFFICULTY_MEDIUM = 2;    
  9.         /*   
  10.          * Physics constants   
  11.          */   
  12.         public static final int PHYS_DOWN_ACCEL_SEC = 35;    
  13.         public static final int PHYS_FIRE_ACCEL_SEC = 80;    
  14.         public static final int PHYS_FUEL_INIT = 60;    
  15.         public static final int PHYS_FUEL_MAX = 100;    
  16.         public static final int PHYS_FUEL_SEC = 10;    
  17.         public static final int PHYS_SLEW_SEC = 120; // degrees/second rotate    
  18.         public static final int PHYS_SPEED_HYPERSPACE = 180;    
  19.         public static final int PHYS_SPEED_INIT = 30;    
  20.         public static final int PHYS_SPEED_MAX = 120;    
  21.         /*   
  22.          * State-tracking constants   
  23.          */   
  24.         public static final int STATE_LOSE = 1;    
  25.         public static final int STATE_PAUSE = 2;    
  26.         public static final int STATE_READY = 3;    
  27.         public static final int STATE_RUNNING = 4;    
  28.         public static final int STATE_WIN = 5;    
  29.    
  30.         /*   
  31.          * Goal condition constants   
  32.          */   
  33.         public static final int TARGET_ANGLE = 18; // > this angle means crash    
  34.         public static final int TARGET_BOTTOM_PADDING = 17; // px below gear    
  35.         public static final int TARGET_PAD_HEIGHT = 8; // how high above ground    
  36.         public static final int TARGET_SPEED = 28; // > this speed means crash    
  37.         public static final double TARGET_WIDTH = 1.6; // width of target    
  38.         /*   
  39.          * UI constants (i.e. the speed & fuel bars)   
  40.          */   
  41.         public static final int UI_BAR = 100; // width of the bar(s)    
  42.         public static final int UI_BAR_HEIGHT = 10; // height of the bar(s)    
  43.         private static final String KEY_DIFFICULTY = "mDifficulty";    
  44.         private static final String KEY_DX = "mDX";    
  45.    
  46.         private static final String KEY_DY = "mDY";    
  47.         private static final String KEY_FUEL = "mFuel";    
  48.         private static final String KEY_GOAL_ANGLE = "mGoalAngle";    
  49.         private static final String KEY_GOAL_SPEED = "mGoalSpeed";    
  50.         private static final String KEY_GOAL_WIDTH = "mGoalWidth";    
  51.    
  52.         private static final String KEY_GOAL_X = "mGoalX";    
  53.         private static final String KEY_HEADING = "mHeading";    
  54.         private static final String KEY_LANDER_HEIGHT = "mLanderHeight";    
  55.         private static final String KEY_LANDER_WIDTH = "mLanderWidth";    
  56.         private static final String KEY_WINS = "mWinsInARow";    
  57.    
  58.         private static final String KEY_X = "mX";    
  59.         private static final String KEY_Y = "mY";    
  60.    
  61.         /*   
  62.          * Member (state) fields   
  63.          */   
  64.         /** The drawable to use as the background of the animation canvas */   
  65.         private Bitmap mBackgroundImage;    
  66.    
  67.         /**   
  68.          * Current height of the surface/canvas.   
  69.          *    
  70.          * @see #setSurfaceSize   
  71.          */   
  72.         private int mCanvasHeight = 1;    
  73.    
  74.         /**   
  75.          * Current width of the surface/canvas.   
  76.          *    
  77.          * @see #setSurfaceSize   
  78.          */   
  79.         private int mCanvasWidth = 1;    
  80.    
  81.         /** What to draw for the Lander when it has crashed */   
  82.         private Drawable mCrashedImage;    
  83.    
  84.         /**   
  85.          * Current difficulty -- amount of fuel, allowed angle, etc. Default is   
  86.          * MEDIUM.   
  87.          */   
  88.         private int mDifficulty;    
  89.    
  90.         /** Velocity dx. */   
  91.         private double mDX;    
  92.    
  93.         /** Velocity dy. */   
  94.         private double mDY;    
  95.    
  96.         /** Is the engine burning? */   
  97.         private boolean mEngineFiring;    
  98.    
  99.         /** What to draw for the Lander when the engine is firing */   
  100.         private Drawable mFiringImage;    
  101.    
  102.         /** Fuel remaining */   
  103.         private double mFuel;    
  104.    
  105.         /** Allowed angle. */   
  106.         private int mGoalAngle;    
  107.    
  108.         /** Allowed speed. */   
  109.         private int mGoalSpeed;    
  110.    
  111.         /** Width of the landing pad. */   
  112.         private int mGoalWidth;    
  113.    
  114.         /** X of the landing pad. */   
  115.         private int mGoalX;    
  116.    
  117.         /** Message handler used by thread to interact with TextView */   
  118.         private Handler mHandler;    
  119.    
  120.         /**   
  121.          * Lander heading in degrees, with 0 up, 90 right. Kept in the range   
  122.          * 0..360.   
  123.          */   
  124.         private double mHeading;    
  125.    
  126.         /** Pixel height of lander image. */   
  127.         private int mLanderHeight;    
  128.    
  129.         /** What to draw for the Lander in its normal state */   
  130.         private Drawable mLanderImage;    
  131.    
  132.         /** Pixel width of lander image. */   
  133.         private int mLanderWidth;    
  134.    
  135.         /** Used to figure out elapsed time between frames */   
  136.         private long mLastTime;    
  137.    
  138.         /** Paint to draw the lines on screen. */   
  139.         private Paint mLinePaint;    
  140.    
  141.         /** "Bad" speed-too-high variant of the line color. */   
  142.         private Paint mLinePaintBad;    
  143.    
  144.         /** The state of the game. One of READY, RUNNING, PAUSE, LOSE, or WIN */   
  145.         private int mMode;    
  146.    
  147.         /** Currently rotating, -1 left, 0 none, 1 right. */   
  148.         private int mRotating;    
  149.    
  150.         /** Indicate whether the surface has been created & is ready to draw */   
  151.         private boolean mRun = false;    
  152.    
  153.         /** Scratch rect object. */   
  154.         private RectF mScratchRect;    
  155.    
  156.         /** Handle to the surface manager object we interact with */   
  157.         private SurfaceHolder mSurfaceHolder;    
  158.    
  159.         /** Number of wins in a row. */   
  160.         private int mWinsInARow;    
  161.    
  162.         /** X of lander center. */   
  163.         private double mX;    
  164.    
  165.         /** Y of lander center. */   
  166.         private double mY;    
  167.    
  168.         public LunarThread(SurfaceHolder surfaceHolder, Context context,    
  169.                 Handler handler) {    
  170.             // get handles to some important objects    
  171.             mSurfaceHolder = surfaceHolder;    
  172.             mHandler = handler;    
  173.             mContext = context;    
  174.    
  175.             Resources res = context.getResources();    
  176.             // cache handles to our key sprites & other drawables    
  177.             mLanderImage = context.getResources().getDrawable(    
  178.                     R.drawable.lander_plain);    
  179.             mFiringImage = context.getResources().getDrawable(    
  180.                     R.drawable.lander_firing);    
  181.             mCrashedImage = context.getResources().getDrawable(    
  182.                     R.drawable.lander_crashed);    
  183.    
  184.             // load background image as a Bitmap instead of a Drawable b/c    
  185.             // we don't need to transform it and it's faster to draw this way    
  186.             mBackgroundImage = BitmapFactory.decodeResource(res,    
  187.                     R.drawable.earthrise);    
  188.    
  189.             // Use the regular lander image as the model size for all sprites    
  190.             mLanderWidth = mLanderImage.getIntrinsicWidth();    
  191.             mLanderHeight = mLanderImage.getIntrinsicHeight();    
  192.    
  193.             // Initialize paints for speedometer    
  194.             mLinePaint = new Paint();    
  195.             mLinePaint.setAntiAlias(true);    
  196.             mLinePaint.setARGB(255, 0, 255, 0);    
  197.    
  198.             mLinePaintBad = new Paint();    
  199.             mLinePaintBad.setAntiAlias(true);    
  200.             mLinePaintBad.setARGB(255, 120, 180, 0);    
  201.    
  202.             mScratchRect = new RectF(0, 0, 0, 0);    
  203.    
  204.             mWinsInARow = 0;    
  205.             mDifficulty = DIFFICULTY_MEDIUM;    
  206.    
  207.             // initial show-up of lander (not yet playing)    
  208.             mX = mLanderWidth;    
  209.             mY = mLanderHeight * 2;    
  210.             mFuel = PHYS_FUEL_INIT;    
  211.             mDX = 0;    
  212.             mDY = 0;    
  213.             mHeading = 0;    
  214.             mEngineFiring = true;    
  215.         }    
  216.    
  217.         /**   
  218.          * Starts the game, setting parameters for the current difficulty.   
  219.          */   
  220.         public void doStart() {    
  221.             synchronized (mSurfaceHolder) {    
  222.                 // First set the game for Medium difficulty    
  223.                 mFuel = PHYS_FUEL_INIT;    
  224.                 mEngineFiring = false;    
  225.                 mGoalWidth = (int) (mLanderWidth * TARGET_WIDTH);    
  226.                 mGoalSpeed = TARGET_SPEED;    
  227.                 mGoalAngle = TARGET_ANGLE;    
  228.                 int speedInit = PHYS_SPEED_INIT;    
  229.    
  230.                 // Adjust difficulty params for EASY/HARD    
  231.                 if (mDifficulty == DIFFICULTY_EASY) {    
  232.                     mFuel = mFuel * 3 / 2;    
  233.                     mGoalWidth = mGoalWidth * 4 / 3;    
  234.                     mGoalSpeed = mGoalSpeed * 3 / 2;    
  235.                     mGoalAngle = mGoalAngle * 4 / 3;    
  236.                     speedInit = speedInit * 3 / 4;    
  237.                 } else if (mDifficulty == DIFFICULTY_HARD) {    
  238.                     mFuel = mFuel * 7 / 8;    
  239.                     mGoalWidth = mGoalWidth * 3 / 4;    
  240.                     mGoalSpeed = mGoalSpeed * 7 / 8;    
  241.                     speedInit = speedInit * 4 / 3;    
  242.                 }    
  243.    
  244.                 // pick a convenient initial location for the lander sprite    
  245.                 mX = mCanvasWidth / 2;    
  246.                 mY = mCanvasHeight - mLanderHeight / 2;    
  247.    
  248.                 // start with a little random motion    
  249.                 mDY = Math.random() * -speedInit;    
  250.                 mDX = Math.random() * 2 * speedInit - speedInit;    
  251.                 mHeading = 0;    
  252.    
  253.                 // Figure initial spot for landing, not too near center    
  254.                 while (true) {    
  255.                     mGoalX = (int) (Math.random() * (mCanvasWidth - mGoalWidth));    
  256.                     if (Math.abs(mGoalX - (mX - mLanderWidth / 2)) > mCanvasHeight / 6)    
  257.                         break;    
  258.                 }    
  259.    
  260.                 mLastTime = System.currentTimeMillis() + 100;    
  261.                 setState(STATE_RUNNING);    
  262.             }    
  263.         }    
  264.    
  265.         /**   
  266.          * Pauses the physics update & animation.   
  267.          */   
  268.         public void pause() {    
  269.             synchronized (mSurfaceHolder) {    
  270.                 if (mMode == STATE_RUNNING) setState(STATE_PAUSE);    
  271.             }    
  272.         }    
  273.    
  274.         /**   
  275.          * Restores game state from the indicated Bundle. Typically called when   
  276.          * the Activity is being restored after having been previously   
  277.          * destroyed.   
  278.          *    
  279.          * @param savedState Bundle containing the game state   
  280.          */   
  281.         public synchronized void restoreState(Bundle savedState) {    
  282.             synchronized (mSurfaceHolder) {    
  283.                 setState(STATE_PAUSE);    
  284.                 mRotating = 0;    
  285.                 mEngineFiring = false;    
  286.    
  287.                 mDifficulty = savedState.getInt(KEY_DIFFICULTY);    
  288.                 mX = savedState.getDouble(KEY_X);    
  289.                 mY = savedState.getDouble(KEY_Y);    
  290.                 mDX = savedState.getDouble(KEY_DX);    
  291.                 mDY = savedState.getDouble(KEY_DY);    
  292.                 mHeading = savedState.getDouble(KEY_HEADING);    
  293.    
  294.                 mLanderWidth = savedState.getInt(KEY_LANDER_WIDTH);    
  295.                 mLanderHeight = savedState.getInt(KEY_LANDER_HEIGHT);    
  296.                 mGoalX = savedState.getInt(KEY_GOAL_X);    
  297.                 mGoalSpeed = savedState.getInt(KEY_GOAL_SPEED);    
  298.                 mGoalAngle = savedState.getInt(KEY_GOAL_ANGLE);    
  299.                 mGoalWidth = savedState.getInt(KEY_GOAL_WIDTH);    
  300.                 mWinsInARow = savedState.getInt(KEY_WINS);    
  301.                 mFuel = savedState.getDouble(KEY_FUEL);    
  302.             }    
  303.         }    
  304.    
  305.         @Override   
  306.         public void run() {    
  307.             while (mRun) {    
  308.                 Canvas c = null;    
  309.                 try {    
  310.                     c = mSurfaceHolder.lockCanvas(null);    
  311.                     synchronized (mSurfaceHolder) {    
  312.                         if (mMode == STATE_RUNNING) updatePhysics();    
  313.                         doDraw(c);    
  314.                     }    
  315.                 } finally {    
  316.                     // do this in a finally so that if an exception is thrown    
  317.                     // during the above, we don't leave the Surface in an    
  318.                     // inconsistent state    
  319.                     if (c != null) {    
  320.                         mSurfaceHolder.unlockCanvasAndPost(c);    
  321.                     }    
  322.                 }    
  323.             }    
  324.         }    
  325.    
  326.         /**   
  327.          * Dump game state to the provided Bundle. Typically called when the   
  328.          * Activity is being suspended.   
  329.          *    
  330.          * @return Bundle with this view's state   
  331.          */   
  332.         public Bundle saveState(Bundle map) {    
  333.             synchronized (mSurfaceHolder) {    
  334.                 if (map != null) {    
  335.                     map.putInt(KEY_DIFFICULTY, Integer.valueOf(mDifficulty));    
  336.                     map.putDouble(KEY_X, Double.valueOf(mX));    
  337.                     map.putDouble(KEY_Y, Double.valueOf(mY));    
  338.                     map.putDouble(KEY_DX, Double.valueOf(mDX));    
  339.                     map.putDouble(KEY_DY, Double.valueOf(mDY));    
  340.                     map.putDouble(KEY_HEADING, Double.valueOf(mHeading));    
  341.                     map.putInt(KEY_LANDER_WIDTH, Integer.valueOf(mLanderWidth));    
  342.                     map.putInt(KEY_LANDER_HEIGHT, Integer    
  343.                             .valueOf(mLanderHeight));    
  344.                     map.putInt(KEY_GOAL_X, Integer.valueOf(mGoalX));    
  345.                     map.putInt(KEY_GOAL_SPEED, Integer.valueOf(mGoalSpeed));    
  346.                     map.putInt(KEY_GOAL_ANGLE, Integer.valueOf(mGoalAngle));    
  347.                     map.putInt(KEY_GOAL_WIDTH, Integer.valueOf(mGoalWidth));    
  348.                     map.putInt(KEY_WINS, Integer.valueOf(mWinsInARow));    
  349.                     map.putDouble(KEY_FUEL, Double.valueOf(mFuel));    
  350.                 }    
  351.             }    
  352.             return map;    
  353.         }    
  354.    
  355.         /**   
  356.          * Sets the current difficulty.   
  357.          *    
  358.          * @param difficulty   
  359.          */   
  360.         public void setDifficulty(int difficulty) {    
  361.             synchronized (mSurfaceHolder) {    
  362.                 mDifficulty = difficulty;    
  363. &nb

    文章标题:Android游戏开发之八:SurfaceView类的应用实例
    转载来源:http://www.hantingmc.com/qtweb/news15/400465.html

    网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联