1、Snake游戏分析Snake游戏分析Snake也是一个经典游戏了, Nokia蓝屏机的王牌游戏之一。 Android SDK 1.5就有了它的身影。我们这里就来详细解析一下 Android SDK Sample中的 Snake工程。本工程基于 SDK 2.3.3版本中的工程,路径为: %Android_SDK_HOME% /samples/android-10/Snake 一、 Eclipse 工程 通过 File-New Project-Android-Android Project,选择“ Create project from existing sample”创建自己的应用 SnakeA
2、ndroid,如下图: 运行效果如下图: 二、工程结构和类图 其实 Snake的工程蛮简单的,源文件就三个: Snake.java SnakeView.java TileView.java。 Snake类是这个游戏的入口点, TitleView类进行游戏的绘画, SnakeView类则是对游戏控制操作的处理。 Coordinate, RefreshHandler是 2个辅助类,也是 SnakeView类中的内部类。其中, Coordinate是一个点的坐标( x, y), RefreshHandler将 RefreshHandler对象绑定某个线程并给它发送消息。如下图: 任何游戏都需要有个引
3、擎来推动游戏的运行,最简化的游戏引擎就是:在一个线程中 While循环,检测用户操作,对用户的操作作出反应,更新游戏的界面,直到用户退出游戏。 在 Snake这个游戏中,辅助类 RefreshHandler继承自 Handler,用来把 RefreshHandler与当前线程进行绑定,从而可以直接给线程发送消息并处理消息。注意一点: Handle对消息的处理都是异步。 RefreshHandler在 Handler的基础上增加 sleep()接口,用来每隔一个时间段后给当前线程发送一个消息。 handleMessage()方法在接受消息后,根据当前的游戏状态重绘界面,运行机制如下: 运行机制
4、这比较类似定时器的概念,在特定的时刻发送消息,根据消息处理相应的事件。 update()与 sleep()间接的相互调用就构成了一个循环。这里要注意: mRedrawHandle绑定的是 Avtivity所在的线程,也就是程序的主线程;另外由于 sleep()是个异步函数,所以 update()与 sleep()之间的相互调用才没有构成死循环。 最后分析下游戏数据的保存机制,如下: 这里考虑了 Activity的生命周期:如果用户在游戏期间离开游戏界面,游戏暂停;或者由于内存比较紧张, Android关闭游戏释放内存,那么当用户返回游戏界面的时候恢复到上次离开时的界面。 三、源码解析 详细解析
5、下源代码,由于代码量不大,以注释的方式列出如下: 1、 Snake.java Java代码 1. /* 2. *Title:Snake 3. *Copyright:(C)2007TheAndroidOpenSourceProject.LicensedundertheApacheLicense,Version2.0(theLicense) 4. *authorGavin标注 5. */ 6. packagecom.deaboway.snake; 7. importandroid.app.Activity; 8. importandroid.os.Bundle; 9. importandroid.
6、widget.TextView; 10. /* 11. *Snake:asimplegamethateveryonecanenjoy. 12. * 13. *ThisisanimplementationoftheclassicGameSnake,inwhichyoucontrola 14. *serpentroamingaroundthegardenlookingforapples.Becareful,though, 15. *becausewhenyoucatchone,notonlywillyoubecomelonger,butyoullmove 16. *faster.Runningin
7、toyourselforthewallswillendthegame. 17. * 18. */ 19. /贪吃蛇:经典游戏,在一个花园中找苹果吃,吃了苹果会变长,速度变快。碰到自己和墙就挂掉。 20. publicclassSnakeextendsActivity 21. privateSnakeViewmSnakeView; 22. privatestaticStringICICLE_KEY=snake-view; 23. /* 24. *CalledwhenActivityisfirstcreated.Turnsoffthetitlebar,setsup 25. *thecontentv
8、iews,andfiresuptheSnakeView. 26. * 27. */ 28. /在activity第一次创建时被调用 29. Override 30. publicvoidonCreate(BundlesavedInstanceState) 31. super.onCreate(savedInstanceState); 32. setContentView(R.layout.snake_layout); 33. mSnakeView=(SnakeView)findViewById(R.id.snake); 34. mSnakeView.setTextView(TextView)f
9、indViewById(R.id.text); 35. /检查存贮状态以确定是重新开始还是恢复状态 36. if(savedInstanceState=null) 37. /存储状态为空,说明刚启动可以切换到准备状态 38. mSnakeView.setMode(SnakeView.READY); 39. else 40. /已经保存过,那么就去恢复原有状态 41. Bundlemap=savedInstanceState.getBundle(ICICLE_KEY); 42. if(map!=null) 43. /恢复状态 44. mSnakeView.restoreState(map); 4
10、5. else 46. /设置状态为暂停 47. mSnakeView.setMode(SnakeView.PAUSE); 48. 49. 50. 51. /暂停事件被触发时 52. Override 53. protectedvoidonPause() 54. super.onPause(); 55. /Pausethegamealongwiththeactivity 56. mSnakeView.setMode(SnakeView.PAUSE); 57. 58. /状态保存 59. Override 60. publicvoidonSaveInstanceState(BundleoutSt
11、ate) 61. /存储游戏状态到View里 62. outState.putBundle(ICICLE_KEY,mSnakeView.saveState(); 63. 64. /* * Title: Snake * Copyright: (C) 2007 The Android Open Source Project. Licensed under the Apache License, Version 2.0 (the License) * author Gavin 标注 */ package com.deaboway.snake; import android.app.Activity;
12、 import android.os.Bundle; import android.widget.TextView; /* * Snake: a simple game that everyone can enjoy. * * This is an implementation of the classic Game Snake, in which you control a * serpent roaming around the garden looking for apples. Be careful, though, * because when you catch one, not
13、only will you become longer, but youll move * faster. Running into yourself or the walls will end the game. * */ / 贪吃蛇: 经典游戏,在一个花园中找苹果吃,吃了苹果会变长,速度变快。碰到自己和墙就挂掉。 public class Snake extends Activity private SnakeView mSnakeView; private static String ICICLE_KEY = snake-view; /* * Called when Activity i
14、s first created. Turns off the title bar, sets up * the content views, and fires up the SnakeView. * */ / 在 activity 第一次创建时被调用 Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.snake_layout); mSnakeView = (SnakeView) findViewById(R.i
15、d.snake); mSnakeView.setTextView(TextView) findViewById(R.id.text); / 检查存贮状态以确定是重新开始还是恢复状态 if (savedInstanceState = null) / 存储状态为空,说明刚启动可以切换到准备状态 mSnakeView.setMode(SnakeView.READY); else / 已经保存过,那么就去恢复原有状态 Bundle map = savedInstanceState.getBundle(ICICLE_KEY); if (map != null) / 恢复状态 mSnakeView.res
16、toreState(map); else / 设置状态为暂停 mSnakeView.setMode(SnakeView.PAUSE); / 暂停事件被触发时 Override protected void onPause() super.onPause(); / Pause the game along with the activity mSnakeView.setMode(SnakeView.PAUSE); / 状态保存 Override public void onSaveInstanceState(Bundle outState) / 存储游戏状态到View里 outState.put
17、Bundle(ICICLE_KEY, mSnakeView.saveState(); 2、 SnakeView.java Java代码 1. /* 2. *Title:Snake 3. *Copyright:(C)2007TheAndroidOpenSourceProject.LicensedundertheApacheLicense,Version2.0(theLicense) 4. *authorGavin标注 5. */6. 7. packagecom.deaboway.snake; 8. 9. importjava.util.ArrayList; 10. importjava.util
18、.Random; 11. 12. importandroid.content.Context; 13. importandroid.content.res.Resources; 14. importandroid.os.Handler; 15. importandroid.os.Message; 16. importandroid.util.AttributeSet; 17. importandroid.os.Bundle; 18. importandroid.util.Log; 19. importandroid.view.KeyEvent; 20. importandroid.view.V
19、iew; 21. importandroid.widget.TextView; 22. 23. /* 24. *SnakeView:implementationofasimplegameofSnake 25. * 26. * 27. */28. publicclassSnakeViewextendsTileView 29. 30. privatestaticfinalStringTAG=Deaboway; 31. 32. /* 33. *Currentmodeofapplication:READYtorun,RUNNING,oryouhavealready 34. *lost.staticfi
20、nalintsareusedinsteadofanenumforperformance 35. *reasons. 36. */37. /游戏状态,默认值是准备状态 38. privateintmMode=READY; 39. 40. /游戏的四个状态暂停准备运行和失败 41. publicstaticfinalintPAUSE=0; 42. publicstaticfinalintREADY=1; 43. publicstaticfinalintRUNNING=2; 44. publicstaticfinalintLOSE=3; 45. 46. /游戏中蛇的前进方向,默认值北方 47. pr
21、ivateintmDirection=NORTH; 48. /下一步的移动方向,默认值北方 49. privateintmNextDirection=NORTH; 50. 51. /游戏方向设定北南东西 52. privatestaticfinalintNORTH=1; 53. privatestaticfinalintSOUTH=2; 54. privatestaticfinalintEAST=3; 55. privatestaticfinalintWEST=4; 56. 57. /* 58. *LabelsforthedrawablesthatwillbeloadedintotheTile
22、Viewclass 59. */60. /三种游戏元 61. privatestaticfinalintRED_STAR=1; 62. privatestaticfinalintYELLOW_STAR=2; 63. privatestaticfinalintGREEN_STAR=3; 64. 65. /* 66. *mScore:usedtotrackthenumberofapplescapturedmMoveDelay:numberof 67. *millisecondsbetweensnakemovements.Thiswilldecreaseasapplesare 68. *captur
23、ed. 69. */70. /游戏得分 71. privatelongmScore=0; 72. 73. /移动延迟 74. privatelongmMoveDelay=600; 75. 76. /* 77. *mLastMove:trackstheabsolutetimewhenthesnakelastmoved,andis 78. *usedtodetermineifamoveshouldbemadebasedonmMoveDelay. 79. */80. /最后一次移动时的毫秒时刻 81. privatelongmLastMove; 82. 83. /* 84. *mStatusText
24、:textshowstotheuserinsomerunstates 85. */86. /显示游戏状态的文本组件 87. privateTextViewmStatusText; 88. 89. /* 90. *mSnakeTrail:alistofCoordinatesthatmakeupthesnakesbody 91. *mAppleList:thesecretlocationofthejuicyapplesthesnakecraves. 92. */93. /蛇身数组(数组以坐标对象为元素) 94. privateArrayListmSnakeTrail=newArrayList();
25、 95. 96. /苹果数组(数组以坐标对象为元素) 97. privateArrayListmAppleList=newArrayList(); 98. 99. /* 100. *Everyoneneedsalittlerandomnessintheirlife 101. */102. /随机数 103. privatestaticfinalRandomRNG=newRandom(); 104. 105. /* 106. *Createasimplehandlerthatwecanusetocauseanimationtohappen.We 107. *setourselvesasatargetandwecanusethesleep()functiontocausean 108. *update/inv
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2