日期:2014-05-20  浏览次数:20876 次

J2ME程序教程,程序+讲解,很好的入门教程(转载) 【2】

J2ME RPG游戏边学边做(二)
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

{

private 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 ,//0
?? 0
,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();
}
}

运行结果如图:

?