3G123
发短消息
关注Ta
积分 130
帖子 26
威望 4738 个
礼品券 0 个
专家指数 0
注册 2010-9-10
回答问题数 0
回答被采纳数 0
回答采纳率 0%
|
|
|
|
作者介绍
张久军,乐成数字通信学院高级讲师。6年手机软件开发经验,曾开发多款 手机游戏和多款手机应用软件。擅长短信、wap、 手机游戏、手机应用软件开发。二年多手机软件培训经验,所带班级毕业后一个月内实现100%就业。
在手机软件开发当中,游戏的收入近几年收入可观,据统计在2009年,中国的手机游戏市场收入大概在12亿左右。Mobile Market将会成为中国手机游戏的主要销售渠道。OPhone是中国移动推出的手机操作系统,每部OPhone的手机都内置了Mobile Market。有中国移动的大力支持,使用OPhone手机的用户会越来越多。以后会有很多OPhone用户从Mobile Market上下载手机游戏。市场也需要大量的OPhone手机游戏。本人曾有Mobile Market手机游戏开发经验,对Mobile Market开发规范有一定的了解。用OPhone写出了一个符合Mobile Market开发的手机游戏框架,供大家参考。
运行效果如下:

Mobile Market开发规范说明
在《中国移动Mobile Market应用开发要求v1.2.2(517版本).doc》中对手机软件和手机游戏的开发规范做了详细的要求,主要有界面,安装卸载,联网,程序进程,数据读写,计费功能等要求。本篇文章主要讲述如何让游戏的界面符合Mobile Market的界面规范,下面将规范中与界面有关的要求摘录出来。
应用(游戏、软件)的启动画面使用统一的中国移动Mobile Market标识图片
文字内容:中国移动Mobile Market让你的手机更加精彩,感谢你的支持!
“关于”项中,增加说明:“本应用经过中国移动测试认证中心安全测试,感谢您的支持!”
“关于”可合并到帮助中。
应用必须提供“帮助”(主题除外)功能,包括开发者信息、软件名称、版本信息、基本的使用说明。
应用必须提供“退出”(主题除外)功能,退出时不能产生新的链接或界面。
代码的整体思路
在单机手机游戏开发当中,游戏的框架主要有MVC,state。state中文意思是指状态,将一个单机游戏分成多个状态,程序员分别对每一个状态的界面,按键,业务逻辑进行编程。以一个RPG游戏为例来说,可以分成Mobile Market Logo,公司Logo,标题,主菜单,游戏介绍,游戏场景,对话,战斗,物品,任务,游戏结束,帮助,关于,设置等状态。本篇文章按照Mobile Market规范要求实现了4个状态分别是Mobile Market Logo,公司Logo,主菜单,关于四个状态。读者可以参考本文章的代码把其它状态也实现了。在单机手机游戏开发中,使用state框架非常成熟,国内有很多单机手机游戏就是使用state 框架开发的。State框架的优点是简单,易学,易用,减少对象个数,占内存少。
代码详细介绍
程序的入口是MobileMarketGame类中的onCreate方法,在onCreate方法中创建一个Main对象,Main是View的子类,Main对像能放在手机屏幕上。代码如下
main = new Main(this);- setContentView(main);
在Main的构造方法中,通过this.updateState(stateMobileMarket, (byte) -1);使程序进入stateMobileMarket状态. 代码如下
- this.updateState(stateMobileMarket, (byte) -1);
在onDraw方法中,判断当前状态如果是stateMobileMarket就把Mobile Market Logo显示在手机屏幕上。代码如下
switch (this.currentState) {- case stateMobileMarket:drawMobileMarketLogo(g, paint);
- break;
- }
在run方法中调用logic,在logic中让线程睡眠1秒,然后切换到stateLdci,代码如下
private void logic() throws InterruptedException {- switch (this.currentState) { case stateMobileMarket:
- thread.sleep(1000);this.updateState(stateLdci, stateMobileMarket);
- break; }
- }
在onDraw方法中,判断当前状态如果是stateLdci就把公司Logo显示在手机屏幕上。
在stateLdci状态下,让线程执行10次,然后切换到主菜单,代码如下
private void logic() throws InterruptedException {- switch (this.currentState) { case stateLdci:
- this.count++;if (this.count > 10) {
- this.updateState(stateMainMenu, stateLdci);}
- break; }
- }
按下键后,执行onKeyDown方法,在onKeyDown方法中根据键值做相应的处理。代码如下
public boolean onKeyDown(int keyCode, KeyEvent event) { - switch (this.currentState) {case stateMainMenu:
- keyMainMenu(keyCode);break;
- case stateAbout:this.updateState(this.stateMainMenu, this.stateAbout);
- break;}
- }
在主菜单状态下,选中关于,按下中间键后,程序切换到关于状态。代码如下
private void keyMainMenu(int keyCode) {- switch (keyCode) { case KeyEvent.KEYCODE_ENTER:// 中间键
- switch (this.menuIndex) {case 3:
- this.updateState(stateAbout, stateMainMenu);break;
- }break;
- }
- }
在onDraw调用drawAbout,在drawAbout方法中将关于信息画出来,代码如下
private void drawAbout(Canvas g, Paint paint) {- g.drawText("本应用经过中国移动测试认证中心安全测试,感谢您的支持", 0, 50, paint); g.drawText("电子邮件:zhangjiujun@ldci.com.cn", 0, 100, paint);
- g.drawText("公司主页:www.ldci.com.cn", 0, 150, paint); g.drawText("乐成", 0, 200, paint);
- }
在关于状态下,用户按下任意键后调用onKeyDown,在onKeyDown通过调用updateState返回到主菜单
public boolean onKeyDown(int keyCode, KeyEvent event) { - switch (this.currentState) { case stateAbout:
- this.updateState(this.stateMainMenu, this.stateAbout);break;
- }
OPhone实现的完整代码
本项目由两个程序实现。 Mobile MarketGame.java是程序的入口。Main.java负责实现界面绘制,按键处理,业务逻辑。Mobile MarketGame的代码如下:
package com.ldci;
import android.app.Activity;- import android.os.Bundle;import android.view.KeyEvent;
- import android.view.Window;
- /*** 程序入口
- * * @author 乐成 张久军
- * */
- public class Mobile MarketGame extends Activity {Main main = null;
public void onCreate(Bundle savedInstanceState) {- super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);
main = new Main(this); setContentView(main);- }
- public boolean onKeyDown(int keyCode, KeyEvent event) { main.onKeyDown(keyCode, event);
- return super.onKeyDown(keyCode, event);}
public boolean onKeyUp(int keyCode, KeyEvent event) {- main.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
- }
- }
Main.java的代码如下:
package com.ldci;
import android.content.Context;- import android.graphics.*;import android.graphics.Paint.Style;
- import android.util.AttributeSet;import android.view.*;
import java.io.*;
/**- * 主类,实现界面绘制,按键处理,业务逻辑*
- * @author 乐成 张久军*
- */public class Main extends View implements Runnable {
/**- * Mobile Market Logo */
- Bitmap bmMobileMarketLogo = null;/**
- * 公司Logo */
- Bitmap bmLdciLogo = null;
- /** * MobileMarket要求的主菜单
- */private final static String[] menuStr = { "开始", "帮助", "设置", "关于", "退出" };
- /** * 当前状态
- */byte currentState = -1;
- /** * MobileMarket Logo状态
- */final static byte stateMobileMarket = 1;
- /** * 公司Logo状态
- */final static byte stateLdci = 2;
- /** * 主菜单状态
- */final static byte stateMainMenu = 3;
- /** * 关于状态
- */final static byte stateAbout = 4;
public Main(Context context) {- super(context);
this.context = context; - this.updateState(stateMobileMarket, (byte) -1);
thread = new Thread(this); - thread.start();}
/**- * 画图 */
- protected void onDraw(Canvas g) { try {
- Paint paint = new Paint();paint.setColor(0xFFff0000);
- switch (this.currentState) {case stateMobileMarket:
- drawMobileMarketLogo(g, paint);break;
- case stateLdci:drawLdciLogo(g, paint);
- break;case stateMainMenu:
- drawMainMenu(g, paint);break;
- case stateAbout:drawAbout(g, paint);
- break;}
- } catch (Exception e) {e.printStackTrace();
- }}
/**- * 业务逻辑 */
- public void run() { long beginTime = 0, endTime = 0, useTime = 0;
- while (true) {try {
beginTime = System.currentTimeMillis();logic();
endTime = System.currentTimeMillis();
useTime = endTime - beginTime;- if (useTime > 100) {
useTime = 100; - }thread.sleep(100 - useTime);// 线程每秒运行10次
- this.postInvalidate();
- } catch (Exception e) {e.printStackTrace();
- } }
}
/**- * 按键处理 */
- public boolean onKeyDown(int keyCode, KeyEvent event) { try {
- switch (this.currentState) {case stateMainMenu:
- keyMainMenu(keyCode);break;
- case stateAbout:this.updateState(this.stateMainMenu, this.stateAbout);
- break;}
- } catch (Exception e) {e.printStackTrace();
- } return super.onKeyDown(keyCode, event);
- }
- private void keyMainMenu(int keyCode) { switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_UP:// 上键this.menuIndex--;
- if (this.menuIndex <
0) {
thisthis.menuIndex = this.menuStr.length - 1; - }break;
- case KeyEvent.KEYCODE_DPAD_DOWN:// 下键this.menuIndex++;
- if (this.menuIndex > this.menuStr.length - 1) {
this.menuIndex = 0; - }break;
- case KeyEvent.KEYCODE_ENTER:// 中间键switch (this.menuIndex) {
- case 3:this.updateState(stateAbout, stateMainMenu);
- break;}
- break; }
- }
- /** * 逻辑
- ** @throws InterruptedException
- */private void logic() throws InterruptedException {
- switch (this.currentState) { case stateMobileMarket:
- thread.sleep(1000);this.updateState(stateLdci, stateMobileMarket);
- break; case stateLdci:
- this.count++;if (this.count > 10) {
- this.updateState(stateMainMenu, stateLdci);}
- break; }
- }
- /** * 状态转换负责加载下一个状态的资源,释放前一个状态资源
- ** @param nextState
- * @param preState */
- private void updateState(byte nextState, byte preState) { try {
this.currentState = nextState;// 加载资源- switch (nextState) {case stateMobileMarket:
- InputStream is = context.getResources().openRawResource(R.drawable.mobilemarketlogo);
bmMobileMarketLogo = BitmapFactory.decodeStream(is);is.close();
is = null;break;- case stateLdci:InputStream is2 = context.getResources().openRawResource(
- R.drawable.ldcilogo);
bmLdciLogo = BitmapFactory.decodeStream(is2); - is2.close();
is2 = null; - break;}
// 释放资源- switch (preState) {case stateMobileMarket:
this.bmMobileMarketLogo = null;break;- }System.gc();// 调用垃圾回收器,
- } catch (Exception e) {e.printStackTrace();
- }}
private void drawAbout(Canvas g, Paint paint) {- g.drawText("本应用经过中国移动测试认证中心安全测试,感谢您的支持", 0, 50, paint); g.drawText("电子邮件:zhangjiujun@ldci.com.cn", 0, 100, paint);
- g.drawText("公司主页:www.ldci.com.cn", 0, 150, paint); g.drawText("乐成", 0, 200, paint);
- }
- private void drawMainMenu(Canvas g, Paint paint) { int rectLeft = 110;
- int rectTop = 30 + menuIndex * 50; int rectRight = 220;
- int rectBottom = 30 + menuIndex * 50 + 30;
- paint.setColor(0xFF0000FF); paint.setStyle(Style.STROKE);
- RectF r = new RectF(rectLeft, rectTop, rectRight, rectBottom); g.drawRect(r, paint);
paint.setColor(0xFFFF0000);- for (int i = 0; i <
this.menuStr.length; i++) {g.drawText(this.menuStr, 150, 50 + i * 50, paint);- }}
private void drawLdciLogo(Canvas g, Paint paint) {- g.drawBitmap(this.bmLdciLogo, 60, 200, paint);
- paint.setColor(0xFFFF0000); paint.setStyle(Style.STROKE);
- // 外边空心的矩形 float rectLeft = 60;
- float rectTop = 400; float rectRight = 260;
- float rectBottom = 420; RectF r = new RectF(rectLeft, rectTop, rectRight, rectBottom);
- g.drawRect(r, paint);
- paint.setStyle(Style.FILL); RectF fillRect = new RectF(rectLeft, rectTop, rectLeft + 20 * count,
- rectBottom); g.drawRect(fillRect, paint);
- }
- private void drawMobileMarketLogo(Canvas g, Paint paint) { g.drawBitmap(bmMobileMarketLogo, 60, 81, paint);
- }
- /** * 触摸事件
- */public boolean onTouchEvent(MotionEvent event) {
- return super.onTouchEvent(event);}
public boolean onKeyUp(int keyCode, KeyEvent event) {- return super.onKeyUp(keyCode, event);}
int count = 0;- Thread thread = null;Context context = null;
- int menuIndex = 0;/**
- * 键值 */
- public static int keyCode = 0;
- }
总结
本文介绍了如何按照MobileMarket的界面规范来开发Ophone 手机游戏。并使用state框架给出一个案例。欢迎开发者沟通讨论,邮箱 zhangjiujun@ldci.com.cn。
扫码关注5G通信官方公众号,免费领取以下5G精品资料
1、回复“YD5GAI”免费领取《中国移动:5G网络AI应用典型场景技术解决方案白皮书》
2、回复“5G6G”免费领取《5G_6G毫米波测试技术白皮书-2022_03-21》
3、回复“YD6G”免费领取《中国移动:6G至简无线接入网白皮书》
4、回复“LTBPS”免费领取《《中国联通5G终端白皮书》》
5、回复“ZGDX”免费领取《中国电信5G NTN技术白皮书》
6、回复“TXSB”免费领取《通信设备安装工程施工工艺图解》
7、回复“YDSL”免费领取《中国移动算力并网白皮书》
8、回复“5GX3”免费领取《 R16 23501-g60 5G的系统架构1》
| |