1、Android 游戏框架 楼主 发表于 2011-7-13 08:50:22 | 查看: 1849| 回复: 16 Android SDK中游戏示例代码的框架也剥出来共享给大家,自称为真正实用的游戏框架。已拿其开发过一款游戏,感觉还可以。 其主要“实用”之处在于: 1.框架整体很小,上手快,做大游戏的公司没多少,做小游戏的个人开发者铺天盖地,相比动则上升到引擎级的庞然大物,小型的框架更加实用,更加考虑大多数开发者的利益。 2.小不等于不完善,之所以剥SDK的游戏示例代码的框架出来,就是学习后发现它对于系统事件的处理比
2、较完善,另外我个人还修正了它对于来电处理等异常事件不完美之处,使其更加完善。
R.layout.main 布局文件
java代码:
1.
2.
3. 3、om.mstanford.gameframework.GameSurfaceView
12. android:id="@+id/gameview"
13. android:layout_width="match_parent"
14. android:layout_height="match_parent" />
15.
16. 4、oid:id="@+id/textview"
22. android:layout_width="wrap_content"
23. android:layout_height="wrap_content"
24. android:layout_centerInParent="true"
25. android:gravity="center_horizontal"
26. android:textColor="#88ffffff"
27. android:textSize="24sp" />
28.
29. 5、eLayout>
复制代码
Activity类
java代码:
1. package eoe.demo;
2.
3. import com.mstanford.gameframe.R;
4. import android.app.Activity;
5. import android.os.Bundle;
6. import android.util.Log;
7. import android.view.Menu;
8. import android.view.MenuItem;
9. import android.widget.TextView;
10 6、
11. public class GameActivity extends Activity {
12.
13. private GameSurfaceView gameSurfaceView;
14. private GameThread gameThread;
15.
16. @Override
17. public void onCreate(Bundle savedInstanceState) {
18. super.onCreate(savedInstanceState);
19. setContentView(R.layout.main);
20.
21. 7、 gameSurfaceView = (GameSurfaceView) this.findViewById(R.id.gameview);
22. gameThread = gameSurfaceView.getThread();
23. gameSurfaceView.setTextView((TextView) findViewById(R.id.textview));
24.
25. if (savedInstanceState == null) {
26. // 游戏第一次启动时,初始化游戏状态
27. gameThread.doStart();
28. Log.w(t 8、his.getClass().getName(), "SIS is null");
29. }else {
30. // 从其他应用界面切回游戏时,如果Activity重新创建,则恢复上次切出游戏时的各项数据
31. gameThread.restoreState(savedInstanceState);
32. Log.w(this.getClass().getName(), "SIS is nonnull");
33. }
34. }
35.
36. /**
37. * 当Activity被切换到后台时调用,存储Activity重新创建时需要恢复的游戏数据
38. */ 9、
39.
40. @Override
41. protected void onSaveInstanceState(Bundle outState) {
42. super.onSaveInstanceState(outState);
43. gameThread.saveState(outState);
44. Log.w(this.getClass().getName(), "SIS called");
45. }
46.
47. /**
48. * 当Activity被切换到后台时调用,在这里对游戏做"暂停"的处理
49. */
50.
51. @Overrid 10、e
52. protected void onPause() {
53. super.onPause();
54. // 暂停游戏
55. gameSurfaceView.getThread().pause();
56. }
57.
58. /**
59. * 当Activity切换到前台时调用
60. */
61.
62. @Override
63. protected void onResume() {
64. super.onResume();
65. // 游戏结束暂停状态,游戏正常进行
66. gameSurfaceView.getThread().un 11、pause();
67. }
68.
69. /**
70. * 创建游戏菜单
71. */
72.
73. @Override
74. public boolean onCreateOptionsMenu(Menu menu) {
75. // TODO Auto-generated method stub
76. return super.onCreateOptionsMenu(menu);
77. }
78.
79. /**
80. * 定义游戏菜单的点击事件处理
81. */
82.
83. @Override
84. public boolean 12、onOptionsItemSelected(MenuItem item) {
85. // TODO Auto-generated method stub
86. return super.onOptionsItemSelected(item);
87. }
88.
89. @Override
90. protected void onDestroy() {
91. super.onDestroy();
92. Log.v(this.getClass().getName(), "onDestroy");
93.
94. //停止游戏
95. gameThread.setR 13、unning(false);
96. boolean retry = true;
97. while (retry) {
98. try {
99. //阻塞Activity的主线程直到游戏线程执行完
100. gameThread.join();
101. retry = false;
102. } catch (InterruptedException e) {
103. }
104. }
105. }
106.
107. }
复制代码
SurfaceView类
java代码:
1. package eoe.demo;
2.
3. import an 14、droid.content.Context;
4. import android.os.Handler;
5. import android.os.Message;
6. import android.util.AttributeSet;
7. import android.util.Log;
8. import android.view.KeyEvent;
9. import android.view.SurfaceHolder;
10. import android.view.SurfaceView;
11. import android.view.SurfaceHolde 15、r.Callback;
12. import android.widget.TextView;
13.
14. public class GameSurfaceView extends SurfaceView implements Callback {
15. private GameThread gameThread;
16. private TextView textview;
17.
18. public GameSurfaceView(Context context, AttributeSet attrs) {
19. super(context, attrs);
2 16、0. SurfaceHolder holder = getHolder();
21. holder.addCallback(this);
22.
23. gameThread = new GameThread(holder, context, new Handler() {
24.
25. @Override
26. public void handleMessage(Message m) {
27. textview.setText(m.getData().getString("text"));
28. }
29. });
30.
31. // 设置可获得焦点,确保能捕 17、获到KeyEvent
32. setFocusable(true);
33. }
34.
35. /**
36. * 获取一个Activity传来的View协助SurfaceView显示游戏视图,View的具体类型可以根据游戏需要来定
37. */
38.
39. public void setTextView(TextView view) {
40. this.textview = view;
41. }
42.
43. public GameThread getThread() {
44. return gameThread;
45. }
46.
47. @ 18、Override
48. public boolean onKeyDown(int keyCode, KeyEvent event) {
49. return gameThread.doKeyDown(keyCode, event);
50. }
51.
52. @Override
53. public boolean onKeyUp(int keyCode, KeyEvent event) {
54. return gameThread.doKeyUp(keyCode, event);
55. }
56.
57. /**
58. * 当SurfaceView得到或失去焦 19、点时调用,使游戏暂停/恢复运行,
59. */
60.
61. @Override
62. public void onWindowFocusChanged(boolean hasWindowFocus) {
63. if (!hasWindowFocus) {
64. gameThread.pause();
65. }else {
66. gameThread.unpause();
67. }
68. }
69.
70. @Override
71. public void surfaceChanged(SurfaceHolder holder, int format 20、 int width,int height) {
72. Log.v(this.getClass().getName(), "surfaceChanged()");
73. gameThread.setSurfaceSize(width, height);
74. gameThread.setRunning(true);
75.
76. if (gameThread.isAlive()) {
77. Log.v(this.getClass().getName(), "unpause gameThread");
78. gameThread.unpause();
79. }el 21、se {
80. Log.v(this.getClass().getName(), "start gameThread");
81. gameThread.start();
82. }
83.
84. }
85.
86. @Override
87. public void surfaceCreated(SurfaceHolder holder) {
88. Log.v(this.getClass().getName(), "surfaceCreated()");
89. }
90.
91. /**
92. * 为防止surface还会被创建(比如来电)导致gameTh 22、read再次启动出现错误,且Activity的onPause方法中已做暂停处理,
93. * 这边不对gameThread做处理
94. * @param holder
95. */
96.
97. @Override
98. public void surfaceDestroyed(SurfaceHolder holder) {
99. Log.v(this.getClass().getName(), "surfaceDestroyed");
100. }
复制代码
游戏线程类
java代码:
1. package eoe.demo;
2.
3. impo 23、rt android.content.Context;
4. import android.graphics.Canvas;
5. import android.os.Bundle;
6. import android.os.Handler;
7. import android.util.Log;
8. import android.view.KeyEvent;
9. import android.view.SurfaceHolder;
10.
11. public class GameThread extends Thread {
12. // 游戏状态值:ready
1 24、3. public final static int GS_READY = 0;
14. //游戏线程每执行一次需要睡眠的时间
15. private final static int DELAY_TIME = 100;
16. //上下文,方便获取到应用的各项资源,如图片、音乐、字符串等
17. private Context context;
18. //与Activity其他View交互用的handler
19. private Handler handler;
20. //由SurfaceView提供的SurfaceHolder
21. private SurfaceH 25、older surfaceHolder;
22. //游戏线程运行开关
23. private boolean running = false;
24. //游戏状态
25. private int gameState;
26. //当前surface/canvas的高度,在surfaceChanged方法中被设置
27. private int mCanvasHeight = 1;
28. //当前surface/canvas的宽度,在surfaceChanged方法中被设置
29. private int mCanvasWidth = 1;
30.
31. /**
3 26、2. * 游戏是否暂停
33. */
34.
35. private boolean isPaused = false;
36. public GameThread(SurfaceHolder holder, Context context, Handler handler) {
37. this.surfaceHolder = holder;
38. this.context = context;
39. this.handler = handler;
40. }
41.
42. /**
43. * 设置游戏状态
44. * @param mode 游戏状态
45. 27、 */
46.
47. public void setState(int mode) {
48. synchronized (surfaceHolder) {
49. setState(mode, null);
50. }
51. }
52.
53. /**
54. * 设置游戏状态
55. * @param mode 游戏状态
56. * @param message 设置游戏状态时的附加文字信息
57. */
58.
59. public void setState(int mode, CharSequence message) {
60. synchroni 28、zed (surfaceHolder) {
61. }
62.
63. }
64.
65. /**
66. * 暂停游戏
67. */
68. public void pause() {
69. synchronized (surfaceHolder) {
70. isPaused = true;
71. }
72.
73. }
74.
75. /**
76. * 恢复运行游戏
77. */
78. public void unpause() {
79. //如果游戏中有时间,别忘记应将其在这里调整到正常
80. synchronized (surfac 29、eHolder) {
81. isPaused = false;
82. }
83. }
84.
85. /**
86. * 当Activity因销毁而被重新创建时,在这里恢复游戏上次运行的数据
87. * @param saveState Activity传来的保存游戏数据的容器
88. */
89. public void restoreState(Bundle saveState) {
90. }
91.
92. /**
93. * 在Activity切到后台时保存游戏的数据
94. * @param outState 保存游戏数据的容器
95. */
9 30、6.
97. public void saveState(Bundle outState){
98. }
99.
100. /**
101. * 设置游戏线程运行开关
102. * @param b 开/关
103. */
104.
105. public void setRunning(boolean b) {
106. running = b;
107. }
108.
109. /**
110. * 处理按下按键的事件
111. * @param keyCode 按键事件动作值
112. * @param msg 按键事件对象
113. * @return 31、 是否处理完
114. */
115. public boolean doKeyDown(int keyCode, KeyEvent msg) {
116. synchronized (surfaceHolder) {
117. return false;
118. }
119. }
120.
121. /**
122. * 处理弹起按键的事件
123. * @param keyCode 按键事件动作值
124. * @param msg 按键事件对象
125. * @return 是否处理完
126. */
127.
128. public boolean do 32、KeyUp(int keyCode, KeyEvent msg) {
129. synchronized (surfaceHolder) {
130. }
131.
132. return false;
133. }
134.
135. /**
136. * 设置surface/canvas的宽度和高度
137. * @param width 由SurfaceHolder传来的宽度
138. * @param height 由SurfaceHolder传来的高度
139. */
140.
141. public void setSurfaceSize(int widt 33、h, int height) {
142. // synchronized to make sure these all change atomically
143. synchronized (surfaceHolder) {
144. mCanvasWidth = width;
145. mCanvasHeight = height;
146. //不要忘记每次画布的宽度和高度改变时, 在这里对图片等资源做缩放等相关适配屏幕的处理
147.
148. }
149.
150. }
151.
152. public void run() {
153. while (ru 34、nning) {
154. if (!isPaused) {
155. Canvas c = null;
156. try {
157. c = surfaceHolder.lockCanvas(null);
158. synchronized (surfaceHolder) {
159. doDraw(c);
160. }
161. logic();
162. } finally {
163. if (c != null) {
164. surfaceHolder.unlockCanvasAndPost(c);
165. }
166. }
167. try {
35、168. Thread.sleep(DELAY_TIME);
169. } catch (InterruptedException e) {
170. e.printStackTrace();
171. }
172. }
173. }
174.
175. }
176.
177. /**
178. * 游戏逻辑处理
179. */
180. public void logic(){
181. Log.v(this.getClass().getName(), "logic");
182. }
183.
184. /**
185. * 游戏绘画
186. */
187. private void doDraw(Canvas canvas) {
188. Log.v(this.getClass().getName(), "doDraw");
189. //TODO
190. }
191.
192. /**
193. * 初始化游戏开始时的参数
194. */
195. private void doStart() {
196. //TODO
197. }
198.
199. }
复制代码






