作者:潇潇 出处:www.j2mefans.com
该文章为本站原创,如有引用,请注明出处和作者
前一节我们使用图层建立一个背景地图,使用该技术,如果仅仅表示陆地的话倒还可以,对于像太空中闪烁的群星和波澜壮阔的大海就显得太单调了。那么我们怎样实现太空中闪烁的群星呢?
一个直接的想法就是,继续调用TiledLayer类的setCell方法,不断的改变背景贴图。当然这也是一个方法,但并不是一个好的方法。试想如果游戏中同时有许多动态背景,那么我们的工作量就大了。有没有更好的方法呢?
通过前面的的例子,我们看到静态背景的贴图索引(包括空白)都是大于等于0的数值,所以要实现背景图层动画,在TiledLayer类中就要求我们使用负数作为动态背景贴图的索引。这样我们就可以设定贴图索引相同的负值统一进行更改背景图层,进而形成动画。
具体地说,需要注意下面几点:
(1)动画贴图是需要额外创建的,并且它的贴图索引必须为负数。创建的第一个动画贴图的序号为-1,第二个为-2,依此类推。
(2)在创建动画贴图时,需要设定一个静态贴图(也就是题图索引为正数的贴图),作为初始图像,然后在要变换图像画面的时候,用另一个静态贴图替换贴图索引为负数的图像。并多次的重复更换贴图,从而实现动态的效果。
(3)在TiledLayer类中对动态贴图支持,表现在下面的两个方法中:
create-1matedTile(),用来创建一个动画贴图。
set-1matedTile(),用来为指定的动画贴图索引设置静态贴图。
还是看一个实例吧!下面我们应用TiledLayer类来创建一个动态背景,背景内容为夜空中闪烁的星星。
首先我们来看一下我们要使用的图片:
其中是5张32*32的图片。
设置动画贴图的步骤如下:
(1)加在图像。
Image image = Image.createImage("/star.png");//加载背景图片
(2)创建背景贴图对象tiledLayer。设定单元数组为6*6。
TiledLayer tiledLayer = new TiledLayer(6, 6, image, 32, 32);
(3)创建动态贴图,并将其与第三帧图像相关联。该方法的参数就是为动画贴图而显示得初始静态贴图。A为整形变量,用来记录create-1matedTile方法的返回值,该值表示新创建的动画贴图的索引。
A = tiledLayer.create-1matedTile(3);
(4)设定地图,然后将地图数组所对应的贴图填充进单元中。
int[] map = {//地图数组
4,4,4,4,4, 4,
4,-1,4,4, 3,4,
4,4,3,4,, -1,4,
,4,4,1, 4,3,4,
4,4,3,3,4, 4,
4,4,3,4,-1, 4,
};//显示地图
for (int i = 0; i < map.length; i++) {
int column = i % 6;
int row = (i – column) / 6;
tiledLayer.setCell(column, row, map[i]);//通过一个循环来设置tiledLayer
}
(5)将动态贴图与其他动态贴图相关联,形成动画。在这里就是要让他与第2帧贴图和第5帧贴图相关联,产生一闪一闪的星星效果。
aniCounter++;//计数器,每次游戏线程,自动加1
if(aniCounter%6)
mBackground.setAnimatedTile(-1,2);//当计数器增加到6,显示一次动画
else
mBackground.setAnimatedTile(-1,3);//设置动画背景为不闪烁的星星
(6)绘制背景,并将缓冲区内容强制输出到屏幕上。
mBackground.paint(g);
flushGraphics();
下面是源代码:
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import java.util.*;
import java.io.*;
public class OCanvas extends GameCanvas implements Runnable {
private Display display;
private boolean sleeping;
private long frameDelay;
private TiledLayer backgroundLayer;
private LayerManager mLayerManager;
private int aniCounter;
public OCanvas(Display d) {
super(true);
display = d;
// 设定帧频 (30 fps)
frameDelay = 33;
}
public void start() {
// 设定这个画布为当前屏幕显示
display.setCurrent(this);
// 创建背景图层
try {
backgroundLayer = new TiledLayer(6, 6, Image.createImage("/star.png"), 32, 32);
}
catch (IOException e) {
System.err.println("Failed loading images!");
}
backgroundLayer.createAnimatedTile(3);
// 设定背景图层地图
int[] layerMap = {
4,-1,4,4,3, 4,
-1,4,4,3, 4,3,
4,4,1,4, -1,4,
4,-1,3, 4,3,4,
3,4,3,4,4, 4,
4,4,3,4,-1, 3,
};
for (int i = 0; i < layerMap.length; i++) {
int column = i % 6;
int row = (i – column) / 6;
backgroundLayer.setCell(column, row, layerMap[i]);
}
backgroundLayer.setPosition((getWidth() – backgroundLayer.getWidth()) / 2,
(getHeight() – backgroundLayer.getHeight()) / 2);
// 开始动画线程
sleeping = false;
Thread t = new Thread(this);
t.start();
}
public void stop() {
// 停止动画
sleeping = true;
}
public void run() {
Graphics g = getGraphics();
// 游戏主循环
while (!sleeping) {
//更新数据
update();
//显示图像
draw(g);
try {
Thread.sleep(frameDelay);
}
catch (InterruptedException ie) {}
}
}
private void update()
{
aniCounter++;
if(aniCounter<6)
{
backgroundLayer.setAnimatedTile(-1,3);//设置动画背景为不闪烁的星星
}
else if(aniCounter>6 && aniCounter<12)
{
backgroundLayer.setAnimatedTile(-1,2);//当计数器增加到6,显示一次动画
}
else if(aniCounter>12 && aniCounter<18)
{
backgroundLayer.setAnimatedTile(-1,5); //当计数器增加到6,再次显示一次动画
aniCounter=0;
}
}
private void draw(Graphics g) {
// 绘制背景图层
backgroundLayer.paint(g);
//刷新屏幕显示缓冲区
flushGraphics();
}
}