用J2ME在移动设备上实现动画(2) (2007-04-11 11:48)

使用图层

  在一个游戏中 (或者其他的图形程序),显示区域内通常包含不同的内容(图像可能是有关联的或者是没有关联的)。比如一只蜜蜂可以在森林,陆地,水面上飞翔,但是在一个迷宫中人却不能穿越围墙。

  MIDP 2.0游戏 API为此引进了图层。图层提供了控制屏幕上的对象或者上下文的方法。图层可以是TiledLayer (比如背景), Sprite (比如飞机), 或者通过继承Layer类自定义的类.

  下面代码是对图层使用的示例,本例中最重要的类是TiledLayer, LayerManager, 以及Image. Image 是用来保存具有相同大小的图像或者图象元素的类。 TiledLayer使用这些图像来布置背景

  当TiledLayer的实例被创建以时,构造方法要求五个参数,列数,行数,图像,图像元素的宽度和高度。这里的例子中背景表格包含40 , 16 , 图像时Tiles.png并且长宽都是7。代码开头的一些常量(TILE_GROUND etc.) 表示对图像元素的引用。



  当TiledLayer实例被创建后,图像元素的表格可以用 fillCells()方法来填充或者fillCell() 来填充。在代码的最后 TiledLayer被加入到LayerManager. append() 方法用来把图层加入到观察窗口最下面。使用insert()可以把图层插入到指定位置。

 

 

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

效果如下。

 

    使用精灵

  正如前面提到的那样, 精灵被定义为屏幕上的一个单独的对象. 这个对象可以是推石头的小人, 一架正在射击的飞机。Sprite类的工作方式有点类似 TilesLayer ( 实事上他们都是从Layer类继承来的). Sprite 也拥有一个包含几副等大小的图像的Image 对象。但是这些图像与组成背景的图像元素不同, 他们是表现游戏主角的动画的帧。因此精灵可以拥有动画效果,并且通过更换其中的一些帧就可以轻松改变精灵的形象。

  下面代码展示了怎么创建一个Sprite的实例。原理其实和TiledLayer一样.

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

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


  Layer类中的以下两个方法可以轻松的控制精灵的移动:

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


  通过 LayerManager来控制精灵的移动,绘制使非常方便的。下面的代码展示了怎样去控制一个精灵的移动。精灵的大小为7×7,并且每次移动的幅度也是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;
}


  游戏编写中还有一个重要的任务就是发现精灵间的碰撞。精灵可能必须呆在某个游戏区域或者指定的迷宫,同时判断精灵间的相互碰撞也是非常重要的。碰撞在有的游戏中意味着转换方向,有时候却意味着game over

  Sprite 提供了以下四个方法,使我们可以对精灵的碰撞作出判断:

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)


  当两个Sprite的实例(也可以时TiledLayerSprite Image)碰撞或者说重合时,我们可以对此作出响应。

  结束语

  本文结合几个例子介绍了MIDP 2.0中最常用游戏 API的新特性,有了这些特性,开发者不但可以方便的控制比屏幕大的游戏区域的绘制,而且可以方便的在不同图层上绘制物体

      Game API函数使用以下四个类为图层提供灵活的支持

  1 Layer类是所有图层类对象的抽象基类。它定义了一个图层的基本属性,包括位置,尺寸,和此图层是否可见。Layer类的每个子类必须定义一个paint()方法,用来把这个图层表现在一个图象上,这个图象将会被描画到屏幕表面上。两个确切的子类TiledLayerSprite应该能满足你的二维游戏的需要了。

   TiledLayer类用来建立背景图像。你可以用一个小的源图像贴的集合来高效的制作大的图像。

   Sprite类是一个动画层。你提供源帧就可以对整个动画进行完全的控制。Sprite类也提供镜像,并可对源帧作90度旋转。

   LayerManager类是一个非常有用的类,用来保存你的场景中的所有图层的动作轨迹。LayerManager paint()方法的一个简单调用就足以控制所包含的所有图层。

  使用TiledLayer

  尽管包含一些不是显而易见的微妙不同,TiledLayer类还是很容易理解。这个类的基本思想就是,用一个源图像提供一组图像贴片,这些贴片可以组合成一幅大的场景。例如,下面的图像是64*48像素的。


Source Image

  这个图像被分成了1216*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,
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;
}

 

  为了把这个TiledLayer类对象显示在屏幕上,你需要调用一个Graphics对象的paint()方法。

TiledLayer类还支持动画图像帖子,这样就使得通过一系列贴片来移动元胞集合很容易了。

若想得到更详细的说明,参看TiledLayer类相关的API文档。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值