您现在的位置: 中国IT实验室 >> 游戏开发 >> 初学入门 >> 文章正文
用GameAPI函数制作二维动作游戏
来源:chinaitlab整理收集 作者: 时间:2005-3-8


  MIDP 2.0里面包括一个用来简化编写二维游戏的API函数。这个API函数是非常简凑的,只包括javax.microedition.lcdui.game包里的五个类。这五个类主要提供了两个重要的功能:
  ◆ 新的GameCanvas类使得在一个游戏循环体内画一个screen和响应键盘输入成为可能,而不需要调用系统的paint和input线程。
  ◆ 功能强大而复杂的图层(layer)API函数可以轻松高效地建立复杂的场景。
  muTank Example
  利用GameCanvas类创建一个游戏循环(game loop)
  GameCanvas类是附加了功能的Canvas类,它提供了立即重画和检查设备按键状态的方法。这些新的方法把一个游戏的所有函数(功能)封装在一个循环体内,并由一个单线程进行控制。为什么这样做就非常吸引人阿?先让我们考虑一下你是如何执行一个使用了Canvas类的典型游戏的:
  public void MicroTankCanvas
  extends Canvas
  implements Runnable {
  public void run() {
  while (true) {
  // Update the game state.
  repaint();
  // Delay one time step.
  }
  }
  public void paint(Graphics g) {
  // Painting code goes here.
  }
  protected void keyPressed(int keyCode) {
  // Respond to key presses here.
  }
  }
  这不是一个美丽的画面 。运行在应用程序线程中的run()方法,每一个时间段都会刷新游戏。典型的任务是刷新小球或飞行物的位置,绘制人物或飞行器动画。每一次通过循环体,repaint()方法被用来刷新屏幕。系统把按键事件传送给KeyPressed(),它能适当地刷新游戏状态。
  问题是,每样东西都在不同的线程里,游戏代码在以上三种不同方法里传递很容易混淆。当run()方法里的主动画循环体调用repaint()方法时,将没有办法确切知道系统什么时候调用paint()方法。当系统调用KeyPressed()时,也没有办法知道程序的另一部分正在进行什么。如果你KeyPressed()中的代码将要刷新游戏的状态,而同一时刻paint()方法将表现屏幕,这时屏幕将会持续非常奇怪的状态。如果表现屏幕所用时间超过一个单时间段,动画会看起来颠簸不定或是很奇怪。
  GameCanvas类允许你避开常用绘画(painting)和按键消息(key-event)机制,所以所有的游戏逻辑都可以被包括在一个单循环中。首先,GameCanvas类允许你用getGraphics()方法直接访问Graphics对象。对于所返回的Graphics对象的任何表现(rendering)都可以通过屏幕外缓冲区(offscreen buffer)来实现。你可以用flushGraphics()复制缓冲区到屏幕上,直到屏幕被刷新才会返回。这种方式给你提供比调用repaint()方法更完善的控制。Repaint()方法会立即返回值,以至于你的应用程序不能确定系统什么时候会调用paint()来刷新屏幕。
  GameCanvas类也包含一个用来获得设备按键当前状态的方法,即所谓得polling技术。你可以通过调用GameCanvas类的getKeyStates()方法,马上确定哪一个按键被按下,从而取代了等待系统调用KeyPressed()方法。
  下面是一个使用GameCanvas类的典型的游戏循环体:
  public void MicroTankCanvas
  extends GameCanvas
  implements Runnable {
  public void run() {
  Graphics g = getGraphics();
  while (true) {
  // Update the game state.
  int keyState = getKeyStates();
  // Respond to key presses here.
  // Painting code goes here.
  flushGraphics();
  // Delay one time step.
  }
  }
  }
  接下来的例子描述了一个基本的游戏循环体。它向你展现了一个旋转的“X”,你可以用方向键在屏幕上移动它。这里的Run()方法特别的瘦小,这要多亏了GameCanvas。
  import javax.microedition.lcdui.*;
  import javax.microedition.lcdui.game.*;
  public class SimpleGameCanvas
  extends GameCanvas
  implements Runnable {
  private boolean mTrucking;
  private long mFrameDelay;
  private int mX, mY;
  private int mState;
  public SimpleGameCanvas() {
  super(true);
  mX = getWidth() / 2;
  mY = getHeight() / 2;
  mState = 0;
  mFrameDelay = 20;
  }
  public void start() {
  mTrucking = true;
  Thread t = new Thread(this);
  t.start();
  }
  public void stop() { mTrucking = false; }
  public void run() {
  Graphics g = getGraphics();
  while (mTrucking == true) {
  tick();
  input();
  render(g);
  try { Thread.sleep(mFrameDelay); }
  catch (InterruptedException ie) {}
  }
  }
  private void tick() {
  mState = (mState + 1) % 20;
  }
  private void input() {
  int keyStates = getKeyStates();
  if ((keyStates & LEFT_PRESSED) != 0)
  mX = Math.max(0, mX - 1);
  if ((keyStates & RIGHT_PRESSED) != 0)
  mX = Math.min(getWidth(), mX + 1);
  if ((keyStates & UP_PRESSED) != 0)
  mY = Math.max(0, mY - 1);
  if ((keyStates & DOWN_PRESSED) != 0)
  mY = Math.min(getHeight(), mY + 1);
  }
  private void render(Graphics g) {
  g.setColor(0xffffff);
  g.fillRect(0, 0, getWidth(), getHeight());
  g.setColor(0x0000ff);
  g.drawLine(mX, mY, mX - 10 + mState, mY - 10);
  g.drawLine(mX, mY, mX + 10, mY - 10 + mState);
  g.drawLine(mX, mY, mX + 10 - mState, mY + 10);
  g.drawLine(mX, mY, mX - 10, mY + 10 - mState);
  flushGraphics();
  }
  }
  本文所举示例的代码包括一个使用了这个canvas的MIDlet。你可以尝试着运行SimpleGameMIDlet这个小程序,看看它是怎样工作的。你将会看到一个像正在做健身操的海星的东西(或许它正在寻找自己失掉的腿)。
  SimpleGameMIDlet Screen Shot
  游戏场景就像是洋葱(有层次)
  典型的二维动作游戏常包含一个背景和若干动画人物。尽管你可以自己来描绘出这种场景,不过Game API函数使你能够用图层来建立场景。你可以做一个城市的背景图层,另外再做一个含有一辆小汽车的图层。将小汽车图层放在背景上,你就创造出了一个完整的场景。把小汽车放在一个单独的图层中,可以很容易的熟练操控它,而不受背景和其他图层的影响。
  Game API函数使用以下四个类为图层提供灵活的支持
  Layer类是所有图层类对象的抽象基类。它定义了一个图层的基本属性,包括位置,尺寸,和此图层是否可见。Layer类的每个子类必须定义一个paint()方法,用来把这个图层表现在一个图象上,这个图象将会被描画到屏幕表面上。两个确切的子类TiledLayer和Sprite应该能满足你的二维游戏的需要了。
  TiledLayer类用来建立背景图像。你可以用一个小的源图像贴的集合来高效的制作大的图像。
  Sprite类是一个动画层。你提供源帧就可以对整个动画进行完全的控制。Sprite类也提供镜像,并可对源帧作90度旋转。
  LayerManager类是一个非常有用的类,用来保存你的场景中的所有图层的动作轨迹。LayerManager类 paint()方法的一个简单调用就足以控制所包含的所有图层。
  使用TiledLayer类
  尽管包含一些不是显而易见的微妙不同,TiledLayer类还是很容易理解。这个类的基本思想就是,用一个源图像提供一组图像贴片,这些贴片可以组合成一幅大的场景。例如,下面的图像是64*48像素的。
  Source Image
  这个图像被分成了12块16*16的图像贴片。TiledLayer类分配给每个图像贴片编号,左上角的图片规定为1,以此类推。上面源图像的各个贴片如下编号:
  Tile Numbering
  用代码创建一个TiledLayer类是非常简单的。你需要确定行数和列数,源图像以及这个源图像里每个贴片的像素大小。下面的代码片断告诉你如何装载图像和创建TiledLayer类。
  Image image = Image.createImage("/board.png");
  TiledLayer tiledLayer = new TiledLayer(10, 10, image, 16, 16);
  在例子中,新的TiledLayer类有10行,10列。这些来自image的图像贴片大小是16*16像素。
  有趣的部分还是用这些图像贴片来创建一幕场景。利用setCell()方法可以把一个图像贴片分配到一个数组元胞里。你需要提供这个数组元胞所在行列数以及图像贴片的编号。例如,你可以通过调用setCelll(2,1,5)方法把编号为5的图像贴片分配到第2行中的第3个数组元胞里。如果你觉得这些参数看起来不对,请注意,图像贴片编号是从1开始计数,而行和列的编号是从0开始的。参数缺省情况下,新的TiledLayer类对象中的所有数组元胞的图像贴片标号为0,这就意味着它们是空的。
  下面的代码片断向你说明一种使用整数数组来填充TiledLayer类对象。在实际图像中,TiledLayer类可以从资源文件里定义,这就使得定义背景时可以有更多的灵活性,并能提供新的背景和级别来增强游戏的可玩性。
  private TiledLayer createBoard() {
  Image image = null;
  try { image = Image.createImage("/board.png"); }
  catch (IOException ioe) { return null; }
  TiledLayer tiledLayer = new TiledLayer(10, 10, image, 16, 16);
  int[] map = {
  1, 1, 1, 1, 11, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
收藏本文 责编:admin 


相关文章
游戏开发新手入门之Windows编程
自己研究的一个场景物体剔除方法
教你实现卡通渲染的另类勾边方法
Lua的function、closure和upvalue
Visual C#编写 3D游戏框架示例
推荐文章


 精彩友情推荐
·神州数码交换机
·神州数码交换机价格
·神州数码网络交换机
·netgear交换机
·网件交换机
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
 基础入门  开发文档
 最新推荐
  多数的Windows程序都需要Windows.h和Windowsx.h这两个头文件,要确保使用它们。当然,你还需要其它......
游戏引擎演化史
在Windows上安装OGRE的方法
关于滤镜遮罩概念,Sobel 遮罩
游戏开发新手入门之Windows编程
游戏开发新手入门之位图化图形
教你实现卡通渲染的另类勾边方法
游戏设计大师谈如何成为一名游戏设
Visual C#编写 3D游戏框架示例
真正的 Java 学习从入门到精通
游戏开发经验——游戏开发的基本常
  针对于移动新出台的政策,需要尽快地把我们公司的游戏对应到不同的手机平台,这是针对市场策略的有利调整............
Quake-III代码里神奇的浮点开方函数
基于Dialogue的MFC程序调用DirectX
关于Kjava手机平台移植可行性报告
网络游戏的数据传输处理和防火墙穿
浅谈网游的数据传输处理和防火墙穿
向量几何在游戏编程中的使用(六)
向量几何在游戏编程中的使用(五)
向量几何在游戏编程中的使用(四)
向量几何在游戏编程中的使用(三)
向量几何在游戏编程中的使用(二)
  培训中心