我 的游戏实现其实很简陋,没有炫美的地图,没有惊险的战斗。只是实现了基本功能。如果某位同仁,看到了我的笔记,可以一起讨论,学习。
下面是我做这 个游戏的全过程。用时3个小时,初学者。
用位图工具iconxp画图, 这是用来做地图的
这 个就是坦克。画图可是需要耐心和技巧的。这些都不是我画的,是我复制到工具里修改的。不过要实现计算好,小图都是16*16的,屏幕是240*291的。
虚拟机是DefaultColorPhone
TankGAME类,主要实现显示的,主要代码如下
private Display dis;
private TankGameCanvas tgc=new TankGameCanvas();
startApp 函数内的代码
dis=Display.getDisplay(this);
dis.setCurrent(tgc);
这个类很简单的,没有添加任何按钮什么的。
TankGameCanvas类,游戏代码
private int[][] mapArray = new int[][] {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },// 5
{ 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },// 10
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },// 14
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
这 是地图,1是边界,2是内部障碍。
构造函数内代码
下面父类构造方法
super(true);禁用上下左右键的,后面需要getKeyStates来做按键控制。
添加两个按钮到画布上。
this.addCommand(cmdP);
this.setCommandListener(this);
实例化两 个链表,这两个链表是一一对应的。
bullets = new Vector();用来装子弹的
dos = new Vector();控制子弹方向的
下面是两个TiledLayer类对象
stone = new TiledLayer(mapArray.length, mapArray[1].length, img,
img.getWidth() / 2, img.getHeight());
wall = new TiledLayer(mapArray.length, mapArray[1].length, img, img
.getWidth() / 2, img.getHeight());
img = Image.createImage("/Tank-map.png"); “ /”表示图片资源在res包内找,当然也可以放到src下,但是为了管理还是放在res包内。
因为Image类没有构造方法,所以只能通过它的静 态方法来获得他的实例化对象。
下面是按照给好的二维数组,来填图。这里把地图分成两层,一层是边界,一层是图内的障碍。
for (int i = 0; i < mapArray.length; i++) {
for (int j = 0; j < mapArray[i].length; j++) {
if (mapArray[i][j] == 1) {
stone.setCell(i, j, mapArray[i][j]);
} else if (mapArray[i][j] == 2) {
wall.setCell(i, j, mapArray[i][j]);
}
}
}
把图层添加到map = new LayerManager();图层管理器上
map.append(wall);
map.append(stone);
下面是两个Sprite类对象
tank = new Sprite(Image.createImage("/tank.png"));//
bullet = new Sprite(Image.createImage("/bullet.png"));//
设置坦克的初始
tank.setPosition(13 * 16, 16 * 16);
设置坦克的悬挂点
tank.defineReferencePixel(tank.getWidth()>>1, tank.getHeight()>>1);
tank.getWidth()>>1,意思是除以2,为了避免除法运算带 来的额外性能损耗。
下面是获得画笔
g = this.getGraphics();
最后是开启线程
command 监听器代码
commandAction(Command c, Displayable d)
if (c == cmdP) {
this.removeCommand(cmdP);
this.addCommand(cmdRS);
this.run = false;
t.notify();
} else if (c == cmdRS) {
this.removeCommand(cmdRS);
this.addCommand(cmdP);
this.run = true;
new Thread(this).start();
}
run() 代码
一下所有代码都在while (run)循环内。
g.setColor(0, 0, 196);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
try {
//
tank.move(x, y);
// 按键控制
if ((this.getKeyStates() & GameCanvas.RIGHT_PRESSED) != 0) {
x = 2;
y = 0;
tank.setTransform(Sprite.TRANS_ROT90);
} else if ((this.getKeyStates() & GameCanvas.LEFT_PRESSED) != 0) {
x = -2;
y = 0;
tank.setTransform(Sprite.TRANS_ROT270);
} else if ((this.getKeyStates() & GameCanvas.UP_PRESSED) != 0) {
y = -2;
x = 0;
tank.setTransform(Sprite.TRANS_NONE);
} else if ((this.getKeyStates() & GameCanvas.DOWN_PRESSED) != 0) {
y = 2;
x = 0;
tank.setTransform(Sprite.TRANS_ROT180);
} else if ((this.getKeyStates() & GameCanvas.FIRE_PRESSED) != 0) {
bullettemp = new Sprite(bullet);
bullettemp.setPosition(tank.getX() + 8, tank.getY() + 8);
bullets.addElement(bullettemp);
p = new Point(x * 2, y * 2);
dos.addElement(p);
}
//坦克的碰撞检测
if(tank.collidesWith(stone, true)){
x=0;y=0;
}else if(tank.collidesWith(wall, true)){
wall.setCell(tank.getX()/16, tank.getY()/16, 0);
}
// 重绘图像
tank.paint(g);
tank1.paint(g);
map.paint(g, 0, 0);
// 子弹移动
if (bullets.size() != 0) {
for (int i = 0; i < bullets.size(); i++) {
bullettemp = (Sprite) bullets.elementAt(i);
//子弹的碰撞检测
if(bullettemp.collidesWith(stone, true)){
bullets.removeElementAt(i);
dos.removeElementAt(i);
break;
}else if(bullettemp.collidesWith(wall, true)){
bullets.removeElementAt(i);
dos.removeElementAt(i);
wall.setCell(bullettemp.getX()/16, bullettemp.getY()/16, 0);
break;
}
//画子弹
p = (Point) dos.elementAt(i);
bullettemp.move(p.getX(), p.getY());
bullettemp.paint(g);
}
}
// 刷新
this.flushGraphics();
t.currentThread().sleep(50);
} catch (Exception e) {
}
这里用到两个全局变量x,y用来控制坦克的移动方向和速度的。
Point类,是用来保存子弹移动的方向和速 度的,保存在链表dos内。
Sprite类和TiledLayer类是为游戏制作提供了很多方便之处。Layer类是这两个类的父类。
移 动对象很方便,只需要调用move方法就可以了
Sprite类的设置悬挂点和碰撞检测,可以更好的转动对象和控制对象的状态。
TiledLayer 类提供了很方便的地图制作。只需要画出不同的地图元素png图,然后根据二维数组把绘制处理
LayerManager 类方便了图层的管理,还可以设置浏览窗口来浏览地图。
J2ME--坦克之战
最新推荐文章于 2024-08-12 19:28:19 发布