使用Game API函数制作二维动作游戏

n60ryh1wfn6xyh

n60ryh1wfn6xyh

2016-02-19 15:10

下面图老师小编要跟大家分享使用Game API函数制作二维动作游戏,简单的过程中其实暗藏玄机,还是要细心学习,喜欢还请记得收藏哦!

  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类用来建立背景图像。你可以用一个小的源图像贴的集合来高效的制作大的图像。

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

   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");

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

  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,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 7, 1, 0, 0, 0, 0, 0,
1, 1, 1, 1, 6, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 7, 11, 0,
0, 0, 0, 0, 0, 0, 7, 6, 0, 0,
0, 0, 0, 0, 0, 7, 6, 0, 0, 0
};
for (int i = 0; i map.length; i++) {
int column = i % 10;
int row = (i - column) / 10;
tiledLayer.setCell(column, row, map[i]);
}
return tiledLayer;
}

展开更多 50%)
分享

猜你喜欢

使用Game API函数制作二维动作游戏

编程语言 网络编程
使用Game API函数制作二维动作游戏

如何制作二维码

电脑网络
如何制作二维码

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

二维码使用教程 利用二维码识别快捷下载软件

手机软件 应用软件
二维码使用教程 利用二维码识别快捷下载软件

唱吧二维码如何使用

手机软件 应用软件
唱吧二维码如何使用

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

微信二维码怎么制作

手机软件 应用软件
微信二维码怎么制作

用函数读出数据表内容放入二维数组

PHP
用函数读出数据表内容放入二维数组

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

Excel函数嵌套的例子

Excel函数嵌套的例子

我们还需要JSP吗?

我们还需要JSP吗?
下拉加载更多内容 ↓