很就没有关心J2ME的情况了,今天看到一篇介绍MIDP 2.0的文章就翻译了出来,虽然不是很新。偶的E文不好,有错的地方希望大家谅解!

原文出处:http://www.microjava.com/articles/techtalk/game_api
MIDP 2.0: The Game API
by Mikko Kontio

MIDP 2.0 为移动开发者带来几项新特性,比如支持媒体、更好的用户界面、新的连通协议、enabled push、空中下载和更好的安全性。然而一个最让人感兴趣的新特性就是GAME API。

这篇文章重点介绍GAME API里的新类和它们的用法,开发环境使用J2ME Wireless Toolkit 2.0 Beta。

The Game API

The Game API 帮助开发者(游戏开发者或其他想得到更好用户界面的人)快速开发有较好可用性且节约设备资源(比如内存)的用户界面。The Game API也有利减小jar文件的大小。在MIDP 1.0中,开发者必须写自己的绘图程序来得到好的效果,这导致jar文件的增大。使用MIDP提供的程序可以得到较好的效果并且减小jar文件的大小,因此开发者应该信任所有支持MIDP 2.0 GAME API的设备。

Game API的基本概念是game screen包含了layers,背景在一个层上,道路在一层上,而英雄
的配角在其他层上。所有这些层能被分别的操作。API甚至允许直接在层上绘图。因此游戏区域也比screen大很多,并且在游戏代码卷屏也成为可能。The Game API提供一个观察窗口,它能观察整个游戏区域。这个窗口能很容易的被移动,观察窗口上的点可以对于实际屏幕上点。

The Game API能在javax.microedition.lcdui.game中找到。API中有5个新类,它们是:GameCanvas, Layer, LayerManager, Sprite和TiledLayer.

GameCanvas是个抽象类,它提供了游戏用户界面的基本。它比Canvas有2点益处。它拥有off-screen buffer;它能得到设备物理键的状态

Layer是个抽象类。它能描绘从Layer继承来的game.Sprite和TiledLayer元素。Layer通常被用做它自己的子类。

LayerManager是管理几个层物体并将它们绘到屏幕上的类。

Sprite是一个能包含存储在一个image里几帧的类。例如一个image包含4个图片表示运动的小狗。Sprite能用image的一部分表示一帧并构造一个显示序列来建立一个运做。它也被用来在其他Sprite或TiledLayer里检测碰撞。

TiledLayer有点象Sprite,但它主要用来显示背景、道路或其他大的区域。TiledLayer由单元网格组成,它能被图片和标题填充。因此背景要由

处理用户输入

在MIDP 2.0里处理用户输入和1.0里有少许的不同。在1.0里你能用getGameAciton()方法来得到游戏动作。但在2.0里你要用 getKeyStates()方法来得到按键状态。下面的代码显示了怎么样做,首先我们通过检测变量keyState得到4个按键(up,down, left,right)的状态并做我们想做的。

protected void keyPressed(int keyCode) {
    int move = 0;
    int keyState = getKeyStates();
    if ((keyState & LEFT_PRESSED) != 0) {
        // do something
    }
    if ((keyState & RIGHT_PRESSED) != 0) {
        // do something
    }
    if ((keyState & UP_PRESSED) != 0) {
        // do something
    }
    if ((keyState & DOWN_PRESSED) != 0) {
        // do something
    }
}

使用off-screen buffer

使用off-screen buffer很容易创建无闪烁的动画而开发者不用额外的图形对象去建立两个缓冲。在GameCanvas里的off-screen buffer提供一个off-screen图形物体,它能被用来绘象素或层或sprites到canvas上。当有任何东西被绘的它都能立即被更新。

在下面的代码中getGraphics()方法被用来得到off-screen buffer。在循环里,buffer被用来绘LayerManager(layers object)的内容。当调用flushGraphics()方法时buffer被更新。这儿也有flushGraphics(int x,int y,int width,int hight)方法,被用来刷新特点范围的off-screen buffer。

public void run() {
    Graphics g = getGraphics();
    while (play) {
        try {
            // First draw all the layers
            layers.paint(g, 0, 0);
            // If the game is on, flush the graphics
            if (play) {
                flushGraphics();
            }

            try {
                mythread.sleep(sleepTime);
            } catch (java.lang.InterruptedException e) {}

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

使用层

在游戏里(或在绘图应用程序里)Screen经常由不同的物体组成,他们任何一个都可能和其他一个或几个有联系。举个例子,一只蜜蜂能在森林、陆地、水面和空中飞,但在迷宫里主角去不能穿墙。
在MIDP2.0 Game API里介绍了层,它提供了方法来管理物体或屏幕上的内容。层能够是TiledLayer(背景,墙)、Sprite(蜜蜂)或其他从Layer继承来的类。

下面的代码是把程序里不同的部分重叠在一起,如图所示来介绍Layer的用法。代码中重要的类是TiledLayer,LayerManager,Image。image类是保存几个相同大小图片的。TiledLayer使用这些图片把他们绘在栅格里。

当一个TiledLayer实例被创建时,构造函数需要5个参数。这些参数是列号、行号、图片、宽、高。在例子中,栅格有40列,16行,图片是Tiles.png,高和宽是7个象素。代码开始最后一个整数参考具体的用法。

在TiledLayer 实例被创建后,调用fillCells()方法来填充栅格。在代码最后一行TiledLayer被加到LayerManage中。append()方法是观察者最大限度的安置layer。当然你可以用insert()方法插入你的layer在任何位置。

private TiledLayer tiles;
private LayerManager layers;
private Image tilesImage;

public final int TILE_GROUND = 1;
public final int TILE_WATER = 2;
public final int TILE_SHORE_LEFT = 3;
public final int TILE_FOREST = 4;
public final int TILE_AIR = 5;
public final int TILE_SHORE_RIGHT = 5;

// ...
// Creating an instance of the TiledLayer
layers = new LayerManager();
try {
    tilesImage = Image.createImage("/Tiles.png");
} catch (IOException e) {}
tiles = new TiledLayer(40, 16, tilesImage, 7, 7);
// ...
// Filling the TiledLayer with tiles
tiles.fillCells(0, 0, 40, 16, TILE_AIR);
tiles.fillCells(14, 12, 12, 4, TILE_WATER);
tiles.fillCells(0, 10, 14, 6, TILE_GROUND);
// and more tiles like FOREST and the shores...
layers.append(tiles);

使用Sprites

如前所述,Sprites描绘了屏幕上的一个单一物体。这个物体可以是推石头的小孩、一个射击敌人的战舰。Sprite类的工作方式有点类似 tilesLayer类(他们都是从Layer继承来的)。Sprites也可以将几个相同大小图片当作一个图片来显示,无论如何这些图片没有标题,他们是动画里的帧。Sprites可以是活动的,可以显示帧让它看起来是活动的。

下面的代码说明怎样创建一个Sprites的实例,这个正确的原则也适用于TiledLayer.

try {
    spriteImage = Image.createImage("/Sprite.png");
} catch (IOException e) {}

sprite = new Sprite(spriteImage, 7, 7);

在Layer类里,有2种方法让Sprites在游戏区域里移动

move(int dx, int dy)
setPositions(int x, int y)

让LayerManage控制Sprites的绘制和移动是重要的,在代码里设置和存储Sprites也是很重要的。下面的代码说明了怎么样移动Sprites。Sprites里的图片是7个象素高宽的,因此Sprites每次移动7个象素。

public static final int UP = 0;
public static final int RIGHT = 1;
public static final int DOWN = 2;
public static final int LEFT = 3;

// ...

switch (direction) {
case UP:
    sprite.move(0, -7);
    break;
case DOWN:
    sprite.move(0, 7);
    break;
case RIGHT:
    sprite.move(7, 0);
    break;
case LEFT:
    sprite.move( -7, 0);
    break;
default:
    break;
}

在游戏中另一个重要的就是判断碰撞。Sprites可以停留在游戏区域中一个特定位置,这对判断Sprites是否和其他物体碰撞是很重要的。在游戏里碰撞意味着改变方向或游戏结束。Sprites用下面4个方法帮助开发者判断碰撞:

collidesWith(Image image, int x, int y,
            boolean pixelLevel)
collidesWith(Sprite s, boolean pixelLevel)
collidesWith(TiledLayer t, boolean pixelLevel)
defineCollisionRectangle(int x, int y,
                        int width, int height)

总结

这篇文章介绍了MIDP2.0里的一个新特性,Game API并给出了一个例子,它用到了API里的许多特性。这些可以帮助开发者应付游戏区域比屏幕大很多的情况,并可以在多个层上绘物体。

来自Wireless Toolkit 2.0 Beta的竞争者不很快,事实上这些特性中的一些使用起来仍然有点慢,但它带给我们基本的支持。重要的是这些已经被软件开发者开始设计。你不得不思考2次你想做什么;怎样做更好。最后没有平台和API提供坏的设计。