文章来源:J2ME开发网
上次我们已经成功的完成地图和英雄的编写。这次我们将为英雄加入碰撞检测和人物对话。
(笔者对j2me只是业余爱好者,实现以上功能的代码全部原创,不知道各位专业人士的做法是什么,还
有什么更有效的方法来解决这些问题,请大家多多指教。MSN:zhagy-1981@hotmail.com)
在开始前,我们需要确定在地图中哪些地方不允许走动,那些地方可以触发对话,这就需要在地图中事
先把这些事件定义好。我们改变先前的Scene类。利用二维数组为地图加入事件。
Scene.java
//这次的代码和上次有点出入,这次我们利用getMap()方法来读取地图数组,这样方便以后改为
//从外部文件读取
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 int[][] getMap()
{
//生成地图数组,在原来的每个地图元素后面都加了一个事件。
//事件id为99是不允许通过
//事件id为98是激活对话
//其实在这里定义二维数组并不是很方便,个人感觉还是三维比较直观和方便,
//这里为了方便,只定义二维数组
int[][] maplist =
{
//30*32
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,1}, {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}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {28,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99},
{29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99},
{29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {30,0},
{0 ,0},
{0 ,0}, {34,99}, {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}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {1 ,99}, {2 ,99}, {3 ,99}, {4 ,99}, {5 ,99}, {0
,0}, {0 ,0}, {0 ,0}, {1 ,99}, {2 ,99}, {3 ,99}, {3 ,99}, {26,99}, {3 ,99}, {3 ,99}, {4 ,99}, {5
,99}, {0 ,0}, {0 ,0}, {1 ,0}, {2 ,0}, {3 ,0}, {4 ,0}, {5 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {7 ,99}, {8 ,99}, {46,99}, {10,99}, {11,99}, {0
,0}, {0 ,0}, {0 ,0}, {7 ,99}, {8 ,99}, {47,99}, {31,99}, {32,99}, {33,99}, {47,99}, {10,99},
{11,99}, {0 ,0}, {0 ,0}, {7 ,0}, {8 ,0}, {46,0}, {10,0}, {11,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {13,99}, {14,99}, {15,99}, {16,99}, {17,99}, {0
,0}, {0 ,0}, {0 ,0}, {13,99}, {14,99}, {14,99}, {37,99}, {38,99}, {39,99}, {14,99}, {16,99},
{17,99}, {0 ,0}, {0 ,0}, {13,0}, {14,0}, {15,0}, {16,0}, {17,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {19,99}, {20,99}, {21,99}, {22,99}, {23,99}, {6
,99}, {0 ,0}, {0 ,0}, {19,99}, {20,99}, {20,99}, {43,99}, {44,99}, {45,99}, {20,99}, {20,99},
{23,99}, {0 ,0}, {0 ,0}, {19,0}, {20,0}, {21,0}, {22,0}, {23,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {24,99}, {24,99}, {24,99}, {13,99}, {15,99}, {17,99}, {24,99}, {24,99}, {24,99},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {19,99}, {21,99}, {23,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0
,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {12,0}, {12,0}, {12,0},
{12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0},
{12,0}, {12,0}, {12,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {1 ,0}, {2 ,0}, {3 ,0}, {4 ,0}, {5 ,0}, {0 ,0},
{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},
{0 ,0}, {1 ,0}, {2 ,0}, {3 ,0}, {4 ,0}, {5 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {7 ,0}, {8 ,0}, {46,0}, {10,0}, {11,0}, {0 ,0},
{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},
{0 ,0}, {7 ,0}, {8 ,0}, {46,0}, {10,0}, {11,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {13,0}, {14,0}, {15,0}, {16,0}, {17,0}, {0 ,0},
{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},
{0 ,0}, {13,0}, {14,0}, {15,0}, {16,0}, {17,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {19,0}, {20,0}, {21,0}, {22,0}, {23,0}, {0 ,0},
{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},
{0 ,0}, {19,0}, {20,0}, {21,0}, {22,0}, {23,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0},
{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},
{0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0},
{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},
{0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0},
{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},
{0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {12,0}, {12,0}, {12,0},
{12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0},
{12,0}, {12,0}, {12,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {1 ,0}, {2 ,0}, {3 ,0}, {4 ,0}, {5 ,0}, {0 ,0},
{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {1 ,0}, {3 ,0}, {5 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
{0 ,0}, {1 ,0}, {2 ,0}, {3 ,0}, {4 ,0}, {5 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {7 ,0}, {8 ,0}, {46,0}, {10,0}, {11,0}, {0 ,0},
{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {7 ,0}, {48,0}, {11,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
{0 ,0}, {7 ,0}, {8 ,0}, {46,0}, {10,0}, {11,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {13,0}, {14,0}, {15,0}, {16,0}, {17,0}, {0 ,0},
{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {6 ,0}, {13,0}, {15,0}, {17,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
{0 ,0}, {13,0}, {14,0}, {15,0}, {16,0}, {17,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {19,0}, {20,0}, {21,0}, {22,0}, {23,0}, {0 ,0},
{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {6 ,0}, {19,0}, {21,0}, {23,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
{0 ,0}, {19,0}, {20,0}, {21,0}, {22,0}, {23,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0},
{12,0}, {18,98}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
{0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {12,0}, {12,0}, {12,0},
{12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0},
{12,0}, {12,0}, {12,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {12,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {12,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {36,99}, {0 ,0},
{0 ,0}, {40,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99},
{29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {12,0}, {12,0}, {12,0}, {29,99}, {29,99},
{29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {42,99}, {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}, {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}
};
return maplist;
}
public static TiledLayer createTiledLayerByForeground(Image image)
{
//生成地图
int[][] maplist = Scene.getMap();
TiledLayer tiledLayer = new TiledLayer(30, 32, image, 16, 16);
for(int i = 0 ; i < maplist.length ; i++)
{
int col = i % 30;
int row = (i - col) / 30;
tiledLayer.setCell(col, row, maplist[i][0]);
}
return tiledLayer;
}
public static int getEvent(int x, int y)
{
//根据地图单元格的x和y得到该单元格的事件,这里的30应该根据地图的实际大小来确定
return Scene.getMap()[x + (y * 30)][1];
}
}
ok,地图完成!下面是检测上面定义的事件。
我们知道在Sprite类中已经有了一个检测Sprite(人物)和TiledLayer(地图)的方法:collidesWith()。可
是该检测方法必须在Sprite和TiledLayer交错时才能检测出来,个人感觉使用不是很方便,所以我决定重新写一
检测碰撞的方法,该方法可以检测出当前Sprite在四个方向时下一个将要移动的地图单元是什么。
基本如下:
int xmax = (getX() + getWidth()) / 16;
int ymax = (getY() + getHeight()) / 16;
int xmin = getX() / 16;
int ymin = getY() / 16;
//如果当前的人物方向等于上,并且在地图单元之间的交错处,开始判断他的下一个将要移动的
//地图单元是什么
if(BraveCanvas.way == BraveCanvas.UP_PRESSED && getY() % 16 == 0)
{
if((getX() + getWidth()) % 16 == 0)
xmax -= 1;
for(int i = xmin ; i <= xmax ; i++)
{
//这里的i,ymin-1即表示人物将要移动的地图单元。而且并不是一个,是由他的
//getX()和getWidth()来决定
System.out.print(i+","+ymin-1)
}
}
其他的几个方向实现原理是一样的。
该方法置于Hero类中,代码如下:
Hero.java
package brave;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.Image;
import java.io.IOException;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.TiledLayer;
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();
//如果事件不为99,98才允许移动
//(随着事件的增加,这里的的条件也会增加,如果采取3维数组则不会出现该问题)
if(!eventActionExist(99) && !eventActionExist(98))
this.y = Math.max(0, y - 1);
}
public void moveDown(Image image) throws IOException
{
setImage(image, 17, 26);
nextFrame();
//如果事件不为99,98才允许移动
//(随着事件的增加,这里的的条件也会增加,如果采取3维数组则不会出现该问题)
if(!eventActionExist(99) && !eventActionExist(98))
this.y = Math.min(braveManager.getLayerAt(1).getHeight(), y + 1);
}
public void moveLeft(Image image) throws IOException
{
setImage(image, 17, 26);
nextFrame();
//如果事件不为99,98才允许移动
//(随着事件的增加,这里的的条件也会增加,如果采取3维数组则不会出现该问题)
if(!eventActionExist(99) && !eventActionExist(98))
this.x = Math.max(0, x - 1);
}
public void moveRight(Image image) throws IOException
{
setImage(image, 17, 26);
nextFrame();
//如果事件不为99,98才允许移动
//(随着事件的增加,这里的的条件也会增加,如果采取3维数组则不会出现该问题)
if(!eventActionExist(99) && !eventActionExist(98))
this.x = Math.min(braveManager.getLayerAt(1).getWidth(), x + 1);
}
/**
* 根据事件id得到当前人物将要移动的位置能否触发该事件
* @param eventID 时间id
* @return 存在:true 不存在:false
*/
public boolean eventActionExist(int eventID)
{
int xmax = (getX() + getWidth()) / 16;
int ymax = (getY() + getHeight()) / 16;
int xmin = getX() / 16;
int ymin = getY() / 16;
if(BraveCanvas.way == BraveCanvas.UP_PRESSED && getY() % 16 == 0)
{
if((getX() + getWidth()) % 16 == 0)
xmax -= 1;
for(int i = xmin ; i <= xmax ; i++)
{
if(Scene.getEvent(i, ymin-1) == eventID)
return true;
}
}
else if(BraveCanvas.way == BraveCanvas.DOWN_PRESSED && (getY()+getHeight()) % 16
== 0)
{
if((getX() + getWidth()) % 16 == 0)
xmax -= 1;
for(int i = xmin ; i <= xmax ; i++)
{
if(Scene.getEvent(i, ymax) == eventID)
return true;
}
}
else if(BraveCanvas.way == BraveCanvas.LEFT_PRESSED && getX() % 16 == 0)
{
if((getY() + getHeight()) % 16 == 0)
ymax -= 1;
for(int i = ymin ; i <= ymax ; i++)
{
if(Scene.getEvent(xmin-1, i) == eventID)
return true;
}
}
else if(BraveCanvas.way == BraveCanvas.RIGHT_PRESSED && (getX()+getWidth()) % 16
== 0)
{
if((getY() + getHeight()) % 16 == 0)
ymax -= 1;
for(int i = ymin ; i <= ymax ; i++)
{
if(Scene.getEvent(xmax, i) == eventID)
return true;
}
}
return false;
}
}
BraveCanvas类需要增加一个静态变量,这里为了篇幅,暂不给出原码,大家可以在下面看到。
运行后,只有左上角、中间的房子和栅栏,可以正常检测,这是因为其他的单元格为了方便都没有加上事
件。
一点缺陷:
其实这里的地图并不是很完善,比如说人物如果在房子上面的话,屋顶应该会把人物遮住一部分,而人物在
房子下面的话,人物应该把房子遮住一点。大家如果感兴趣的话可以用图层来解决这问题。
下面说说人物的对话实现。
需要用到的图片:
在实现人物对话的时候,我想实现对话的打字机效果,这就需要一个循环来实现它。循环结束后,打字机的效果结束,对话并没有结束。应该显示对话内容并进入等待状态直到用户再次按键,才真正的结束对话。
流程图如下:
代码如下:
Hero.java
package brave;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.Image;
import java.io.IOException;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.TiledLayer;
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();
if(!eventActionExist(99) && !eventActionExist(98))
this.y = Math.max(0, y - 1);
}
public void moveDown(Image image) throws IOException
{
setImage(image, 17, 26);
nextFrame();
if(!eventActionExist(99) && !eventActionExist(98))
this.y = Math.min(braveManager.getLayerAt(1).getHeight(), y + 1);
}
public void moveLeft(Image image) throws IOException
{
setImage(image, 17, 26);
nextFrame();
if(!eventActionExist(99) && !eventActionExist(98))
this.x = Math.max(0, x - 1);
}
public void moveRight(Image image) throws IOException
{
setImage(image, 17, 26);
nextFrame();
if(!eventActionExist(99) && !eventActionExist(98))
this.x = Math.min(braveManager.getLayerAt(1).getWidth(), x + 1);
}
//实现人物的对话
public void talk(String addressor,Image talkImage, String s, Graphics g)
{
g.drawImage(talkImage, 0, 0, Graphics.TOP|Graphics.LEFT);
g.drawString(addressor+":", 7, 6, Graphics.TOP|Graphics.LEFT);
for(int i = 0 ; i < s.length() ; i++)
{
g.drawString(s.substring(i, i+1), (i*12)+12, 21,
Graphics.TOP|Graphics.LEFT);
try
{
Thread.sleep(100);
}
catch(Exception e)
{
e.printStackTrace();
}
braveCanvas.flushGraphics();
}
//对话的文字形式结束,进入等待状态,直到
//再次按下对话键
while(BraveCanvas.isTalk)
{
try
{
int keystates = braveCanvas.getKeyStates();
//再次按下对话键
if(keystates == BraveCanvas.FIRE_PRESSED)
{
//是否对话标志位置为false
BraveCanvas.isTalk = false;
//是否可以重新开始对话标志位置为false
//之所以这样做是保证在在下一次检测按键时,不重新开始对话
BraveCanvas.isTalkSign = false;
break;
}
Thread.sleep(50);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public boolean eventActionExist(int eventID)
{
…………
}
}
修改BraveCanvas.java 如下
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 Image talkImage;
private TiledLayer backgroundMap;
private TiledLayer foregroundMap;
private BraveManager braveManager;
//该标志位判断对话是否开始
public static boolean isTalk;
//该标志为判断对话是否可以重新开始,默认可以重新开始
public static boolean isTalkSign = true;
//当前的人物方向(碰撞检测用)
public static int way = 0;
public BraveCanvas()
{
super(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");
talkImage = Image.createImage("/talk.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(120, 120);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void startup()
{
this.sign = true;
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);
BraveCanvas.isTalkSign = true;
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:
BraveCanvas.way = UP_PRESSED;
hero.moveUp(upimage);
break;
case DOWN_PRESSED:
BraveCanvas.way = DOWN_PRESSED;
hero.moveDown(downimage);
break;
case LEFT_PRESSED:
BraveCanvas.way = LEFT_PRESSED;
hero.moveLeft(leftimage);
break;
case RIGHT_PRESSED:
BraveCanvas.way = RIGHT_PRESSED;
hero.moveRight(rightimage);
break;
case FIRE_PRESSED:
//当用户按下对话键时候,首先判断对话是否可以重新开始
//只有对话可以重新开始后才能再次开始对话
if(hero.eventActionExist(98))
{
if(BraveCanvas.isTalkSign)
{
BraveCanvas.isTalk = true;
}
}
break;
}
hero.afresh();
braveManager.afresh();
}
public void paint(Graphics g)
{
g.setColor(0x000000);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0x000000);
braveManager.paint(g, 0, 0);
if(BraveCanvas.isTalk)
{
//加入对话,这里只是简单做个例子。应该给对话规定编号,然后从文件中相应的编号中读取
hero.talk("英雄", talkImage, "这是一个小镇", g);
}
else
{
flushGraphics();
}
}
}
运行后,可以在小镇开始的小木牌处按[射击键]实现对话。
这一篇就写到这,在下一篇中,我将实现地图的场景转换。