UML软件工程组织

初涉游戏开发:J2ME RPG游戏边学边做
作者:zhagy 来源:J2ME开发网 

笔者以前是做J2EE的,一个月前由于兴趣所致开始利用业余时间学习J2ME游戏开发。在网上看了一通教程后,便准备动手一边学一边做一个简单的rpg游戏。虽然起点比较高,但感觉游戏难度越大,遇到的问题也就越多。

这样在问题全部解决后,也就学的差不多了。另外只有做这种游戏才有学下去的兴趣。以后我会每次把写成的源码及思路整理成文章的形式供大家参考,互相学习进步。

下面是游戏中所需要的部分图片,还有的图片下次写到了再上传:

hero_left.png:
  
 
 hero_right.png:
 

 hero_up.png:
 

hero_down.png:
 

整个程序的主体在BraveCanvas类中完成,该类继承于GameCanvas实现Runnable接口,由BraveMIDlet类启动他,BraveMIDlet继承MIDlet实现CommandListener接口。BraveMIDlet类代码如下:(由于只是一个简单的rpg,开头画面和菜单全部省略了,改为由一个按扭启动游戏)

BraveMIDlet.java
package brave;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class BraveMIDlet extends MIDlet implements CommandListener
{
private Display d ;
private Command exitCommand ;
private Command startCommand ;

private BraveCanvas braveCanvas;

public BraveMIDlet()
{
d = Display.getDisplay(this);
exitCommand = new Command("退出",Command.EXIT,1);
startCommand = new Command("开始",Command.SCREEN,1);
}

public void startApp()
{
//创建BraveCanvas
braveCanvas = new BraveCanvas();
braveCanvas.addCommand(exitCommand);
braveCanvas.addCommand(startCommand);
braveCanvas.setCommandListener(this);
//装载BraveCanvas
d.setCurrent(braveCanvas);
}

public void pauseApp()
{
}

public void destroyApp(boolean unconditional)
{
}

public void commandAction(Command c , Displayable dpa)
{

String str_co = c.getLabel();
if(str_co.equals("开始"))
{
//运行BraveCanvas中的线程(启动游戏)
braveCanvas.startup();
}
else if(str_co.equals("退出"))
{
destroyApp(false);
notifyDestroyed();
}
}
}

BraveCanvas.java

package brave;

import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.Graphics;
import java.io.IOException;

public class BraveCanvas extends GameCanvas implements Runnable
{
private boolean sign;
private Graphics g;
//设置@符号的当前位置
private int x,y;
public BraveCanvas()
{
super(true);
//初始化@位置
x = getWidth()/2;
y = getHeight()/2;
}

public void startup()
{
this.sign = true;
Thread thread = new Thread(this);
//启动线程
thread.start();
}

public void run()
{
g = getGraphics();
while(sign)
{
try
{
//@符号的移动
input(g);
//@符号的显示
paint(g);
//这里应该有详细的计算,方便为上,置为15
Thread.sleep(15);
}
catch(Exception e)
{
System.out.println("2:"+e);
}
}
}

public void input(Graphics g) throws IOException
{
int keystates = getKeyStates();
switch(keystates)
{
case UP_PRESSED:
y = Math.max(0, y - 1);
break;
case DOWN_PRESSED:
y = Math.min(getHeight(), y + 1);
break;
case LEFT_PRESSED:
x = Math.max(0, x - 1);
break;
case RIGHT_PRESSED:
x = Math.min(getWidth(), x + 1);
break;
}
}

public void paint(Graphics g)
{
//设置画布的背景色
g.setColor(0x000000);
//把背景色画满画布
g.fillRect(0, 0, getWidth(), getHeight());
//设置画布的前景色
g.setColor(0xffffff);
//在画布上写上@
g.drawString("@", x, y, Graphics.TOP|Graphics.LEFT);
//刷新画布
flushGraphics();
}
}

上面代码运行后,画面上会出现一个"@"字符随着键盘的左右而移动。虽然这离rpg游戏相差很远,但这是一

个游戏的基本框架。下面我们要做的就是把"@"换成我们的英雄。为了程序清晰,我们还要设计一个英雄类Hero,该类继承于Sprite,这个类里面要用到上面的图片。

Hero.java
package brave;

import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.Image;
import java.io.IOException;

public class Hero extends Sprite
{
//设置英雄的当前位置
private int x, y;
private BraveCanvas braveCanvas;

public Hero(Image image, int frameWidth, int frameHeight)
{
//英雄的初始化
super(image, frameWidth, frameHeight);
}

public void setBraveCanvas(BraveCanvas braveCanvas)
{
this.braveCanvas = braveCanvas;
}

public void init(int x, int y)
{
//英雄位置的初始化
this.x = x;
this.y = y;
}

public void afresh()
{
//刷新英雄的位置
setPosition(this.x, this.y);
}

public void moveUp() throws IOException
{
//英雄上移,并改为相应的图片
setImage(Image.createImage("/hero_up.png"), 17, 26);
nextFrame();
this.y = Math.max(0, y - 1);
}

public void moveDown() throws IOException
{
//英雄下移,并改为相应的图片
setImage(Image.createImage("/hero_down.png"), 17, 26);
nextFrame();
this.y = Math.min(braveCanvas.getHeight(), y + 1);
}

public void moveLeft() throws IOException
{
//英雄左移,并改为相应的图片
setImage(Image.createImage("/hero_left.png"), 17, 26);
nextFrame();
this.x = Math.max(0, x - 1);
}

public void moveRight() throws IOException
{
//英雄右移,并改为相应的图片
setImage(Image.createImage("/hero_right.png"), 17, 26);
nextFrame();
this.x = Math.min(braveCanvas.getWidth(), x + 1);
}

}

然后把BraveCanvas类稍做修改,把"@"换成英雄


BraveCanvas.java
package brave;

import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.Graphics;
import java.io.IOException;
import javax.microedition.lcdui.Image;

public class BraveCanvas extends GameCanvas implements Runnable
{
private boolean sign;
private Graphics g;
private Hero hero;
public BraveCanvas()
{
super(true);
}

public void startup()
{
this.sign = true;
try
{
Image heroimage = Image.createImage("/hero_up.png");
hero = new Hero(heroimage, 17, 26);
hero.setBraveCanvas(this);
hero.init(40,40);
}
catch(Exception e)
{
e.printStackTrace();
}
Thread thread = new Thread(this);
thread.start();
}

public void run()
{
g = getGraphics();
while(sign)
{
try
{
input(g);
paint(g);
Thread.sleep(15);
}
catch(Exception e)
{
System.out.println("2:"+e);
}
}
}

public void input(Graphics g) throws IOException
{
int keystates = getKeyStates();
switch(keystates)
{
case UP_PRESSED:
hero.moveUp();
break;
case DOWN_PRESSED:
hero.moveDown();
break;
case LEFT_PRESSED:
hero.moveLeft();
break;
case RIGHT_PRESSED:
hero.moveRight();
break;
}
hero.afresh();
}

public void paint(Graphics g)
{
g.setColor(0x000000);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0xffffff);
hero.paint(g);
flushGraphics();
}
}

这样,我们的英雄就可以在画面上移动了,不过英雄比较简单,没有hp,mp等等,只是一个图片。而且如果大家感觉英雄的脚步过快,可以在BraveCanvas类中的Hero初始化时设置:

hero.setFrameSequence(new int[]{0, 0, 1, 1, 0, 0, 2, 2 });

1、public void moveDown() throws IOException

{
//英雄下移,并改为相应的图片
setImage(Image.createImage("/hero_down.png"), 17, 26);
nextFrame();
this.y = Math.min(braveCanvas.getHeight(), y + 1);
}

在io包中的读取是非常耗内存的,所以Image.createImage("/hero_down.png")放在线程的循环中确实不好,现在已经改成图象在BraveCanvas类中创建(下面的代码已更改),然后由moveDown(Image image)方法接收传递进来的图象。

2、RPG是个大工程,一个人的力量是很难完成的,我只想实现基本的RPG功能,比如人物的对话,场景的转换,战斗等等,希望大家多多给予帮助。

这一篇我将给游戏加入地图,以下是该篇所需要的图片:

 background.png
 

 foreground.png
 

一个RPG中的游戏地图是非常大而且多的,为了方便以后的维护,我创建了一个Scene类,该类主要是产生游戏所需要的地图。

Scene.java
package brave;

import javax.microedition.lcdui.game.TiledLayer;
import javax.microedition.lcdui.Image;

public class Scene
{
public static TiledLayer createTiledLayerByBackground(Image image)
{
//使用TiledLayer创建地图
TiledLayer tiledLayer = new TiledLayer(10, 8, image, 48, 64);
tiledLayer.fillCells(0, 0, 10, 8, 2);
return tiledLayer;
}
}

修改BraveCanvas类,加入地图

BraveCanvas.java

package brave;

import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.Graphics;
import java.io.IOException;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.TiledLayer;


public class BraveCanvas extends GameCanvas implements Runnable
{
private boolean sign;
private Graphics g;
private Hero hero;
private Image upimage;
private Image downimage;
private Image leftimage;
private Image rightimage;
private TiledLayer backgroundMap;

public BraveCanvas()
{
super(true);
}

public void startup()
{
this.sign = true;
try
{
//产生地图
backgroundMap = Scene.createTiledLayerByBackground(
Image.createImage("/background.png"));

//改正上一篇的错误
upimage = Image.createImage("/hero_up.png");
downimage = Image.createImage("/hero_down.png");
leftimage = Image.createImage("/hero_left.png");
rightimage = Image.createImage("/hero_right.png");

hero = new Hero(upimage, 17, 26);
hero.setFrameSequence(new int[]{1, 1, 0, 0, 1, 1, 2, 2});
hero.setBraveCanvas(this);
hero.init(40,40);
}
catch(Exception e)
{
e.printStackTrace();
}
Thread thread = new Thread(this);
thread.start();
}

public void run()
{
g = getGraphics();
while(sign)
{
try
{
input(g);
paint(g);
Thread.sleep(15);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

public void input(Graphics g) throws IOException
{
int keystates = getKeyStates();
switch(keystates)
{
case UP_PRESSED:
//由这里传入需要改变的图片
hero.moveUp(upimage);
break;
case DOWN_PRESSED:
hero.moveDown(downimage);
break;
case LEFT_PRESSED:
hero.moveLeft(leftimage);
break;
case RIGHT_PRESSED:
hero.moveRight(rightimage);
break;
}
hero.afresh();
}

public void paint(Graphics g)
{
g.setColor(0x000000);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0xffffff);
//显示地图
backgroundMap.paint(g);
hero.paint(g);
flushGraphics();
}
}

现在我们的英雄虽然能在草地上行走了,但感觉给他移动的空间太小了。而且我们在创建背景地图的时候,地图大小明明是512*480的。好,接下来我们要做的就是让英雄可以在更大的天地中活动。这里就需要一个BraveManager类来管理这些屏幕上的Sprite和TiledLayer,该类继承LayerManager。

BraveManager.java

package brave;

import javax.microedition.lcdui.game.LayerManager;

public class BraveManager extends LayerManager
{
rivate BraveCanvas braveCanvas;

public void setBraveCanvas(BraveCanvas braveCanvas)
{
this.braveCanvas = braveCanvas;
}

public void afresh()
{
//确定当前试图的坐标
//这里用一个比较简单的算法来使英雄永远在屏幕的中央
int viewX = Math.max(0, getLayerAt(0).getX() - braveCanvas.getWidth()/2);
int viewY = Math.max(0, getLayerAt(0).getY() - braveCanvas.getHeight()/2);
viewX = Math.min(viewX, getLayerAt(1).getWidth() - braveCanvas.getWidth());
viewY = Math.min(viewY, getLayerAt(1).getHeight() - braveCanvas.getHeight());
setViewWindow(viewX, viewY, braveCanvas.getWidth(), braveCanvas.getHeight());
}
}

修改BraveCanvas类

BraveCanvas.java

package brave;

import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.Graphics;
import java.io.IOException;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.TiledLayer;


public class BraveCanvas extends GameCanvas implements Runnable
{
private boolean sign;
private Graphics g;
private Hero hero;
private Image upimage;
private Image downimage;
private Image leftimage;
private Image rightimage;
private TiledLayer backgroundMap;
//创建Layer管理视图类
private BraveManager braveManager;

public BraveCanvas()
{
super(true);
}

public void startup()
{
this.sign = true;
try
{
backgroundMap = Scene.createTiledLayerByBackground(
Image.createImage("/background.png"));
upimage = Image.createImage("/hero_up.png");
downimage = Image.createImage("/hero_down.png");
leftimage = Image.createImage("/hero_left.png");
rightimage = Image.createImage("/hero_right.png");
//创建Layer管理视图类
braveManager = new BraveManager();
braveManager.setBraveCanvas(this);

hero = new Hero(upimage, 17, 26);
hero.setFrameSequence(new int[]{1, 1, 0, 0, 1, 1, 2, 2});
hero.setBraveCanvas(this);
hero.setBraveManager(braveManager);
hero.init(0,0);

}
catch(Exception e)
{
e.printStackTrace();
}
Thread thread = new Thread(this);
thread.start();
}

public void run()
{
g = getGraphics();
//插入图层
braveManager.insert(hero, 0);
braveManager.insert(backgroundMap, 1);
while(sign)
{
try
{
input(g);
paint(g);
Thread.sleep(15);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

public void input(Graphics g) throws IOException
{
int keystates = getKeyStates();
switch(keystates)
{
case UP_PRESSED:
hero.moveUp(upimage);
break;
case DOWN_PRESSED:
hero.moveDown(downimage);
break;
case LEFT_PRESSED:
hero.moveLeft(leftimage);
break;
case RIGHT_PRESSED:
hero.moveRight(rightimage);
break;
}
hero.afresh();
//刷新视图的位置
braveManager.afresh();
}

public void paint(Graphics g)
{
g.setColor(0x000000);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0xffffff);
//显示视图
braveManager.paint(g, 0, 0);
flushGraphics();
}
}

这样英雄就可以在地图上任何地方行动了,不过还得改一个小地方:

不知道大家还记的不,在Hero类中,我们定义英雄移动的范围最大为屏幕的尺寸。

这显然是不行的,最大的移动范围应改成地图的大小:

this.y = Math.min(braveManager.getLayerAt(1).getHeight(), y + 1);
this.x = Math.min(braveManager.getLayerAt(1).getWidth(), x + 1);

代码如下:

Hero.java

package brave;

import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.Image;
import java.io.IOException;
import javax.microedition.lcdui.Graphics;

public class Hero extends Sprite
{
private int x;
private int y;

private BraveCanvas braveCanvas;
private BraveManager braveManager;

public Hero(Image image, int frameWidth, int frameHeight)
{
super(image, frameWidth, frameHeight);
}

public void setBraveCanvas(BraveCanvas braveCanvas)
{
this.braveCanvas = braveCanvas;
}

public void setBraveManager(BraveManager braveManager)
{
this.braveManager = braveManager;
}

public void setManager(BraveCanvas braveCanvas)
{
this.braveCanvas = braveCanvas;
}

public void init(int x, int y)
{
this.x = x;
this.y = y;
}

public void afresh()
{
setPosition(this.x, this.y);
}

public void moveUp(Image image) throws IOException
{
setImage(image, 17, 26);
nextFrame();
this.y = Math.max(0, y - 1);
}

public void moveDown(Image image) throws IOException
{
setImage(image, 17, 26);
nextFrame();
this.y = Math.min(braveManager.getLayerAt(1).getHeight(), y + 1);
}

public void moveLeft(Image image) throws IOException
{
setImage(image, 17, 26);
nextFrame();
this.x = Math.max(0, x - 1);

}

public void moveRight(Image image) throws IOException
{
setImage(image, 17, 26);
nextFrame();
this.x = Math.min(braveManager.getLayerAt(1).getWidth(), x + 1);
}
}

现在英雄的移动范围大了,但只英雄一人,也太孤单了,我们给他创造一个小镇吧。

修改Scene类如下:

Scene.java
package brave;

import javax.microedition.lcdui.game.TiledLayer;
import javax.microedition.lcdui.Image;

public class Scene
{
public static TiledLayer createTiledLayerByBackground(Image image)
{
TiledLayer tiledLayer = new TiledLayer(10, 8, image, 48, 64);
tiledLayer.fillCells(0, 0, 10, 8, 2);
return tiledLayer;
}

public static TiledLayer createTiledLayerByForeground(Image image)
{
TiledLayer tiledLayer = new TiledLayer(30, 32, image, 16, 16);
// 30 * 32
int[] maplist =
{
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24 25

26 27 28 29
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 ,0 ,//00

,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
29,29,29,29,29,29,29,29,29,29,29,30,0 ,//1
0 ,34,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 ,36,0 ,//2
0 ,34,0 ,1 ,2 ,3 ,4 ,5 ,0 ,0 ,0 ,1 ,2 ,3 ,3 ,26,3 ,
3 ,4 ,5 ,0 ,0 ,1 ,2 ,3

,4 ,5 ,0 ,36,0 ,//3
0 ,34,0 ,7 ,8 ,46,10,11,0 ,0 ,0 ,7 ,8 ,47,31,
32,33,47,10,11,0 ,0 ,7 ,8

,46,10,11,0 ,36,0 ,//4
0 ,34,0 ,13,14,15,16,17,0 ,0 ,0 ,13,14,14,37,
38,39,14,16,17,0 ,0

,13,14,15,16,17,0 ,36,0 ,//5
0 ,34,0 ,19,20,21,22,23,6 ,0 ,0 ,19,20,
20,43,44,45,20,20,23,0 ,0

,19,20,21,22,23,0 ,36,0 ,//6
0 ,34,0 ,0 ,0 ,12,0 ,0 ,0 ,0 ,0 ,24,24,24,
13,15,17,24,24,24,0 ,0 ,0 ,0

,12,0 ,0 ,0 ,36,0 ,//7
0 ,34,0 ,0 ,0 ,12,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
19,21,23,0 ,0 ,0 ,0 ,0 ,0 ,0

,12,0 ,0 ,0 ,36,0 ,//8
0 ,34,0 ,0 ,0 ,12,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
12,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0

,12,0 ,0 ,0 ,36,0 ,//9
0 ,34,0 ,0 ,0

,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,0 ,0 ,0 ,36,0 ,//10
0 ,34,0 ,0 ,0 ,0 ,0 ,0 ,0 ,12,25,25,25,25,
25,25,25,25,25,25,12,0 ,0 ,0 ,0

,0 ,0 ,0 ,36,0 ,//11
0 ,34,0 ,1 ,2 ,3 ,4 ,5 ,0 ,12,25,25,25,25,25,
25,25,25,25,25,12,0 ,1 ,2 ,3

,4 ,5 ,0 ,36,0 ,//12
0 ,34,0 ,7 ,8 ,46,10,11,0 ,12,25,25,25,25,25,
25,25,25,25,25,12,0 ,7 ,8

,46,10,11,0 ,36,0 ,//13
0 ,34,0 ,13,14,15,16,17,0 ,12,25,25,25,25,25,
25,25,25,25,25,12,0

,13,14,15,16,17,0 ,36,0 ,//14
0 ,34,0 ,19,20,21,22,23,0 ,12,25,25,25,25,25,
25,25,25,25,25,12,0

,19,20,21,22,23,0 ,36,0 ,//15
0 ,34,0 ,0 ,0 ,12,0 ,0 ,0 ,12,25,25,25,25,25,
25,25,25,25,25,12,0 ,0 ,0

,12,0 ,0 ,0 ,36,0 ,//16
0 ,34,0 ,0 ,0 ,12,0 ,0 ,0 ,12,25,25,25,25,25,
25,25,25,25,25,12,0 ,0 ,0

,12,0 ,0 ,0 ,36,0 ,//17
0 ,34,0 ,0 ,0 ,12,0 ,0 ,0 ,12,25,25,25,25,25,
25,25,25,25,25,12,0 ,0 ,0

,12,0 ,0 ,0 ,36,0 ,//18
0 ,34,0 ,0 ,0

,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,0 ,0 ,0 ,36,0 ,//19
0 ,34,0 ,0 ,0 ,0 ,0 ,0 ,0 ,12,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,12,0 ,0 ,0 ,0

,0 ,0 ,0 ,36,0 ,//20
0 ,34,0 ,0 ,0 ,0 ,0 ,0 ,0 ,12,0 ,0 ,0 ,0 ,0 ,0 ,
0 ,0 ,0 ,0 ,12,0 ,0 ,0 ,0

,0 ,0 ,0 ,36,0 ,//21
0 ,34,0 ,1 ,2 ,3 ,4 ,5 ,0 ,12,0 ,0 ,0 ,0 ,1 ,3 ,
5 ,0 ,0 ,0 ,12,0 ,1 ,2 ,3

,4 ,5 ,0 ,36,0 ,//22
0 ,34,0 ,7 ,8 ,46,10,11,0 ,12,0 ,0 ,0 ,0 ,7 ,48,
11,0 ,0 ,0 ,12,0 ,7 ,8

,46,10,11,0 ,36,0 ,//23
0 ,34,0 ,13,14,15,16,17,0 ,12,0 ,0 ,0 ,6 ,13,15,
17,0 ,0 ,0 ,12,0

,13,14,15,16,17,0 ,36,0 ,//24
0 ,34,0 ,19,20,21,22,23,0 ,12,0 ,0 ,0 ,6 ,19,21,
23,0 ,0 ,0 ,12,0

,19,20,21,22,23,0 ,36,0 ,//25
0 ,34,0 ,0 ,0 ,12,0 ,0 ,0 ,12,18,0 ,0 ,0 ,0 ,12,
0 ,0 ,0 ,0 ,12,0 ,0 ,0

,12,0 ,0 ,0 ,36,0 ,//26
0 ,34,0 ,0 ,0

,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,0 ,0 ,0 ,36,0 ,//27
0 ,34,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,12,12,12,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0

,0 ,0 ,0 ,36,0 ,//28
0 ,34,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,12,12,12,0 ,
0 ,0 ,0 ,0 ,0 ,0 ,0

,0 ,0 ,0 ,36,0 ,//29
0

,40,29,29,29,29,29,29,29,29,29,29,29,29,12,12,12,29,29,29,
29,29,29,29,29,29,29,29,42,0 ,//30
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 ,0 //31
};
for(int i = 0 ; i < maplist.length ; i++)
{
int col = i % 30;
int row = (i - col) / 30;
tiledLayer.setCell(col, row, maplist[i]);
}
return tiledLayer;
}
}

修改BraveCanvas类如下:

BraveCanvas.java

package brave;

import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.Graphics;
import java.io.IOException;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.TiledLayer;


public class BraveCanvas extends GameCanvas implements Runnable
{
private boolean sign;
private Graphics g;
private Hero hero;
private Image upimage;
private Image downimage;
private Image leftimage;
private Image rightimage;
private TiledLayer backgroundMap;
private TiledLayer foregroundMap;
private BraveManager braveManager;

public BraveCanvas()
{
super(true);
}

public void startup()
{
this.sign = true;
try
{
backgroundMap = Scene.createTiledLayerByBackground(
Image.createImage("/background.png"));
//生成小镇地图
foregroundMap = Scene.createTiledLayerByForeground(
Image.createImage("/foreground.png"));

upimage = Image.createImage("/hero_up.png");
downimage = Image.createImage("/hero_down.png");
leftimage = Image.createImage("/hero_left.png");
rightimage = Image.createImage("/hero_right.png");
braveManager = new BraveManager();
braveManager.setBraveCanvas(this);
hero = new Hero(upimage, 17, 26);
hero.setFrameSequence(new int[]{1, 1, 0, 0, 1, 1, 2, 2});
hero.setBraveCanvas(this);
hero.setBraveManager(braveManager);
hero.init(0,0);

}
catch(Exception e)
{
e.printStackTrace();
}
Thread thread = new Thread(this);
thread.start();
}

public void run()
{
g = getGraphics();
braveManager.insert(hero, 0);
//插入小镇地图
braveManager.insert(foregroundMap, 1);
braveManager.insert(backgroundMap, 2);
while(sign)
{
try
{
input(g);
paint(g);
Thread.sleep(15);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

public void input(Graphics g) throws IOException
{
int keystates = getKeyStates();
switch(keystates)
{
case UP_PRESSED:
hero.moveUp(upimage);
break;
case DOWN_PRESSED:
hero.moveDown(downimage);
break;
case LEFT_PRESSED:
hero.moveLeft(leftimage);
break;
case RIGHT_PRESSED:
hero.moveRight(rightimage);
break;
}
hero.afresh();
braveManager.afresh();
}

public void paint(Graphics g)
{
g.setColor(0x000000);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0xffffff);
braveManager.paint(g, 0, 0);
flushGraphics();
}
}

运行结果如图:

这一篇就写到这了。

现在终于有点RPG游戏的样子了,不过我们的英雄似乎可以穿墙走壁啊。在下一篇中我将加入碰撞检测和人物对话。

写到这已经创建五个类了(J2EE写习惯了),不知道是不是多了,大家多提点意见。而且也有很多地方设计的不是很合理,以后的开发也许会出现点问题,好在我只是单纯的实现功能。


版权所有:UML软件工程组织