MIDP2.0游戏编程

     GameAPI是架构在底层图像累之上的,高层GameAPI能联络各种图形的简单操作。

    在很多情况下,常常将GameAPI和底层API结合使用。路径为:javax.microedition.lcdui.game ,含有5个类

GameCanvas、Layer、LayerManager、Sprite和TiledLayer

  基本思想: 游戏界面有涂层组成,也即背景和游戏人物分布在不同的图层上,而每一个图层都可以分别通过程序控制,功能强大的图层能够帮助开发者高效的建立复杂的场景。

 GameCanvas :提供了基本的 屏幕功能,还提供了游戏专用的功能, 检测当前游戏键盘状态,利用双缓冲进行图像绘制,简化了游戏开发的流程提高了运行性能。

2)、 Layer:  一个抽象类,代表了游戏中的一个可视化元素及相关属性,例如:位置,大小,可视。

 Sun希望开发者继承TiledLayer或Sprite,而不允许直接产生Layer的子类,包外继承。

3)、LayerManager :用于管理游戏中的层次,通过实现分层次的自动绘制,从而实现期望的图像显示效果。它允许开发者设置一个可视化窗口,表示玩家在游戏中的可见范围。

4)、Sprite  用以表示一帧或者多帧的连续图像,这些帧都是相同大小,并且由一个Image对象提供。Sprite通过控制,可以显示任何一帧,从而实现任意顺序的动画;Sprite提供了许多旋转模式和碰撞检测方法,能大大简化游戏逻辑

5)、TiledLayer  :用来显示游戏地图,允许开发者在不使用非常大的Image对象的情况下创建一大的图像内容。在游戏中绘制的地图通常由很多单元组成,每个单元都显示一个Image对象提供的一组图元中的某一图元(TIle)。Cell格也能被动态图元(Animated Tile)填充,从而使地图 动起来

2、 游戏容器:GameCanvas类

 一个提供游戏基本接口的抽象类,除了原来的功能外,还提供开发游戏的便利,如提供屏幕缓冲绘制机制,并能直接得到手机键盘的物理状态

   2.1、 GameCanvas的实现

  GameCanvas虚基类的构造方法如下:

    protected GameCanvas(boolean suppressKeyEvents)

 2.2、绘制缓冲屏幕

   Graphic对象的绘制功能和使用方法和绘制Canvas画布完全相同,但是所有的绘制都是在缓冲屏幕上进行的,并不会影响实际屏幕。  由于每一个GameCanvas都只有一个缓冲屏幕,因此每次调用getGraphics方法,获得的Graphics对象都指向同一个缓冲屏幕,为了不浪费内存,通常只获取一次以供后面使用。

2.3、获取键盘状态

  int getKeyStates()

  返回的bit数据分别代表了不同的按键。当按下键后,对应的位设置为1,否则为0,好处是无论游戏主循环执行得多慢,键盘事件都不会被忽略。每一次getKeyState()方法的调用都会清除当前键盘缓冲区,从理论上说,后一次会覆盖上一次,而后一次会得到当前键盘状态的理想值。当然getKeyState()的返回值会在另一个线程中更新,所以在游戏主循环中最好稍微等上一会,以保证这个值被更新。

   获取键盘状态后,利用位运算就可以得知某个按钮被按下了,GameCanvas之中定义的状态为UP_PRESSED    

GAME_A_PRESSED 分别对应游戏的A,B..

2.4、实现游戏主循环

    GameCanvas类是附加了功能的Canvas类。GameCanvas作为游戏画布,可将他想象成游戏的容器,在这个容器中将容纳游戏相关的其他元素,这些元素以图层的形式封装在GameCanvas类中,交给MIDlet主类创建并设置为当前显示界面。游戏画布也可以看做是个游戏控制器,负责等待并获得用户的输入,进行相应的处理(改变游戏的状态和移动图层),绘制改变后的游戏界面。一般情况下,GameCanvas实现线程接口(Runnable),在该类的run方法中实现游戏主循环。

  在MIDO2.0中使用GameCanvas实现游戏循环的代码框架,当然这种游戏循环也可以用定时器Timer来实现,后面所提到实例中的游戏循环都是采用者2中方法来实现的

  通常,在技巧和动作类游戏中包含了大量的视频操作,因此需要刷新频率至少为10fps帧每秒,并且要有足够的动感能够激起玩家的挑战欲。那些著名的动作类游戏通常都对用户的输入具有灵敏的反应,这些游戏要求玩家有快速的反应能力并且眼疾手快,故此,我们设计游戏的时候,都需要预先设定我们的游戏的刷新速度,假设我们希望每秒刷新10帧,那么我们的程序需要在1/10s,循环一次。

    另一现象,为了避免游戏动画出现时快时慢的现象,应该让线程停止一段时间,在此调用Thread.sleep(long millis)方法,从而让游戏保持固定的刷新频率,反之,如果每次循环无法在设定的时间内完成,我们就要考虑优化代码,甚至跑出异常结束游戏。

    当我们采用了定时器驱动游戏,游戏画布的代码也做了一些改变,主要是取消了关于线程创建、启动线程和判断线程是否运行的代码,其他地方基本没有变化

posted @ 2013-02-28 20:47  小薇林  阅读(259)  评论(0编辑  收藏  举报