J2ME--坦克之战

J2ME--坦克之战 - nix - 大连小子
我 的游戏实现其实很简陋,没有炫美的地图,没有惊险的战斗。只是实现了基本功能。如果某位同仁,看到了我的笔记,可以一起讨论,学习。
下面是我做这 个游戏的全过程。用时3个小时,初学者。
用位图工具iconxp画图,J2ME--坦克之战 - nix - 大连小子 这是用来做地图的J2ME--坦克之战 - nix -  大连小子 这 个就是坦克。画图可是需要耐心和技巧的。这些都不是我画的,是我复制到工具里修改的。不过要实现计算好,小图都是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 类方便了图层的管理,还可以设置浏览窗口来浏览地图。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值