使用LayerManager管理多个游戏图层
该文章为本站原创,如有引用,请注明出处和作者
前 面我们看到了使用图层的方法为手机游戏创造了许多有趣的东西。但是不足之处在于,一旦我们要使用更多的图层和精灵的话,那么为了更好的控制每一层我们就需 要付出更多的精力。比如说,哪一图层在上面,哪一图层在下面;更新屏幕显示时按照怎样的顺序进行更新;以及当屏幕移动时各图层怎样移动;怎样根据状态添加 或删除图层等等。
如果我们能有一个类专门用来管理图层就好了。这就是我们这篇文章的重点,LayerManager类。LayerManager提供了一种简单有效的方式来绘制、布置和管理多个图层上的视图。
我们还是先通过看他所提供的方法,来了解一下他给我们提供的功能吧。
append方法,用来向被管理的图层的底部添加一个新的图层。
insert方法,用来在被管理的图层中的特定位置插入一个图层。
remove方法,用来在指定的索引处移除一个图层。
getSize方法,用来访问被管理的图层的编号。
getLayerAt方法,按照指定的索引访问图层。
paint方法,绘制被管理的所有图层。
setViewWindow方法,设置视图窗口的位置和大小。
怎么样更能很丰富吧!我们还是重点来看一下怎样使用吧!
首先我们要知道的是图层管理类和其他的类一样,在使用它之前,我们必须创建一个LayerManager的一个实例。如下面语句所示:
LayerManager layersM =new LayerManager() ;
有 了管理器,我们就可以添加被管理的对象了。也就是说我们可以使用append和insert方法在其中添加图层了。其中append方法,是在管理层的底 部添加一个新图层,这样新添加的图层是不会被前面的图层所阻挡,因此我们在绘制屏幕时必须处理好绘制图层的顺序。看一下下面的代码:
layerM.append( zidan ) ;
layerM.append( feiji );
layerM.append( beijing );
在这三句代码中,zidan层被分配索引为0,并放置到屏幕的最前面;后一层为feiji层,被分配索引为1;最后才绘制beijing层。
insert方法除了指定插入的图层外,还要设定添加的哪一层(使用索引号),如果该层已经存在,将在添加前删除原先的索引号的图层。
要删除一个图层可以调用remover方法,要获得LayerManager中的图层的数目可以调用getSize方法;获得指定图层的位置的Layer可以调用getLayerAt方法。
需要注意的是,图层的序号都是连续的。
当某一图层被插入或者删除,后续图层的序号都会作出相应的变动一直保持连续。
创建图层管理器的最后一步就是建立视图窗口。下面的代码在整个图层管理器区域的左上角设置了视图窗口,并且视图窗口和游戏屏幕同样大小。
layerM.setViewWindow( 0 , 0 , getWidth() , getHeight() );
如果你需要移动视图窗口来显示图层的其他区域,只要再次调用setViewWindow方法,并且在头两个参数中使用不同的坐标。这就是使用LayerManager管理图层所需要做的所有工作。
像以往一样,我们还是看一个例子吧!
下面的例子,我们实现一个小人向右走动经过草地的情景。小人是精灵类的实例图片,如下所示:
另外还有一个和精灵移动相反的背景类。
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import java.util.*;
import java.io.*;
import javax.microedition.media.*;
import javax.microedition.media.control.*;
public class WCanvas extends GameCanvas implements Runnable {
private Display display;
private boolean sleeping;
private long frameDelay;
private int inputDelay;
private int drawX = 0;
private int drawY = 0;
private int dx=0,dy=0;
private int i, j;
rivate Sprite sprite;
private Image titledImage, spriteImage;
private Graphics g;
private TiledLayer background;
private LayerManager layManager;
//设置精灵往右行走的数组
private int down_seq[] = { 9, 10, 11 };
public WCanvas(Display d) {
super(true);
display = d;
frameDelay = 33;
inputDelay = 0;
}
public void start() {
display.setCurrent(this);
drawX = this.getWidth() / 2 - 16;
drawY = this.getHeight() / 2;
try {
spriteImage = Image.createImage("/man.png");
titledImage = Image.createImage("/ScrollPic.png");
} catch (Exception e) {
}
//精灵单元宽32高48
sprite = new Sprite(spriteImage, 32, 48);
sprite.setFrameSequence(down_seq);
g = this.getGraphics();
background = new TiledLayer(1, 1, titledImage, 586, 121);
background.setCell(0,0,1);
background.move(0,drawY - 50);
layManager = new LayerManager();
// Start the animation thread
sleeping = false;
Thread t = new Thread(this);
t.start();
}
public void stop() {
// Stop the animation
sleeping = true;
}
public void run() {
Graphics g = getGraphics();
// The main game loop
while (!sleeping) {
update();
draw(g);
try {
Thread.sleep(frameDelay);
}
catch (InterruptedException ie) {}
}
}
private void update() {
if(dx < 586 - getWidth())
dx = dx+5;
else
dx = 0;
}
private void draw(Graphics g) {
//移动到下一帧
sprite.nextFrame();
//在屏幕正中间偏下走动
sprite.setPosition(drawX + dx , drawY);
layManager.append(sprite);
layManager.append(background);
layManager.setViewWindow(dx,0,getWidth() - 40 ,150);
g.setColor(0, 0, 0);
g.drawString("Hello",0,0,Graphics.TOP|Graphics.LEFT);
g.drawLine(0,19,getWidth(),19);
layManager.paint(g,20,20);
flushGraphics();
}
}