J2ME--弹球

首先写一个类BallMidlet继承Midlet类,主要是显示输出,相对比较简单
成员变量只有两个,
Display dis
BallGameCanvas bgc记得要实例化。
startApp函数中,代码一般就是这样,比较固定。
dis=Display.getDisplay(this);
        dis.setCurrent(bgc);
接下来游戏的全部都在这里实现,
BallGameCanvas 继承GameCanvas 继承Runnable,CommandListener两个接口
需要多线程,所以必须重写run函数,需要按键控制也 必须重写commandAction(Command, Displayable)。

开始之前还要做些准备工作,小球,挡板素材还没有准 备。这时用到IconXP_3.1位图软件。主要没有颜色的地方就画透明。

开始写代码之前,必须要介绍一下J2ME游戏中常用到的类
GameCanvas 类 ,游戏画布类,它继承了Canvas。它有一个构造函数,其参数是一个布尔值,当为真时,游戏按键上下左右中间按键不能使用,这时要使用这些 按键时需要getKeyStates获得按键状态,让后做判断,类如:
int keyState = getKeyStates();
if ((keyState & LEFT_KEY) != 0)
{ positionX--; }
else if ((keyState & RIGHT_KEY) != 0)
{ positionX++; }
这样做似乎系统不会分一部分资源去调用keyPressed, keyRepeated and keyReleased 方法。
还有不 需要paint函数,可以由getGraphics得到画笔
Sprite类 ,用来描述会移动的物体,不让车,子弹等。他有三个构造 函数,其中有可以将行图片切割的,可以制作出动态的效果。不过,需要有好的位图制作。此类可以设置悬挂点,然后可以绕悬挂点任意旋转。有碰撞检测方法。
TiledLayer 类,用来描述地图的类。它只有一个构造方法,不过参数够多的。其中前两个参数是定义地图的行数和列数;第三个参数是待切割的图片,最后两个参数是,每一个 小块的宽度和高度。然后用setCell方法填图。不过在作图的时候一定要注意地图的分层,为了便于碰撞检测。
LayerManager类 , 使用来管理图层的。

先来写commandAction里的代码。
在此之前,定义了两个Command对象
private Command cmdP = new Command("暂停", Command.SCREEN, 1);
private Command cmdRS = new Command("继续", Command.SCREEN, 1);
一开始显示“暂停”按钮,当“暂停”按钮被按下 时,按钮变成“继续”按钮,同时游戏暂停,保存现场;当按下“继续”按钮时,游戏继续,恢复现场。
     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)循环内。其中run是全局布尔变量,开始是true,当停止线程时,只需将run置false。
在这里不需要paint函数来作图,只 需要获得画笔,在缓冲内绘画,然后刷新缓存即可。
g = this.getGraphics();
每次画完后,记得调用 this.flushGraphics();否则没有图像的。

第一步,是要清屏
g.setColor(0, 128, 0);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
第二步,碰撞检测。在这里,球是与挡板之间成45度角反弹的, 所以球有四种移动轨迹。每次放生碰撞后轨迹会改变,线程内要做碰撞检测。
开始定义个五个不同的Sprite对象,
    private Sprite ball;
    private Sprite rawUp;// 上挡板
    private Sprite rawDown;// 下挡板
    private Sprite colLeft;// 左挡板
    private Sprite colRight;// 右挡板
实例化
            ball = new Sprite(Image.createImage("/ball.png"));
            rawUp = new Sprite(Image.createImage("/W.png"));
            rawDown = new Sprite(rawUp);
            colLeft = new Sprite(Image.createImage("/H.png"));
            colRight = new Sprite(colLeft);
Sprite类collidesWith方法 是用来做碰撞检测的
它可以检测是否和 TiledLayer对象发生碰撞,也可以检测是否和Sprite对象放生碰撞。
                // 碰撞检测
                if (ball.collidesWith(rawUp, true)) {与上挡板放生碰撞时
                    if (state == 3) {其中的state 是方向变量,
                        state = 2;
                    } else {
                        state = 1;
                    }
                } else if (ball.collidesWith(rawDown, true)) {与下挡板放生碰撞时
                    if (state == 1) {
                        state = 4;
                    } else {
                        state = 3;
                    }
                } else if (ball.collidesWith(colLeft, true)) {与左挡板放生碰撞时
                    if (state == 2) {
                        state = 1;
                    } else {
                        state = 4;
                    }
                } else if (ball.collidesWith(colRight, true)) {与右挡板发生碰撞时
                    if (state == 4) {
                        state = 3;
                    } else {
                        state = 2;
                    }
                } else if (ball.getX() > (this.getWidth() - ball.getWidth())
                        || ball.getY() > (this.getHeight() - ball.getHeight())
                        || ball.getX() < 0 || ball.getY() < 0) {边界控制,游戏停止条件判断,
                    run = false;

                    g.setColor(255, 255, 255);
                    g.fillRect(0, 0, this.getWidth(), this.getHeight());
                    new Sprite(Image.createImage("/over.png")).paint(g);显示游戏结束
                    this.flushGraphics();
                }
第三步,改变运动轨迹。
              switch (state) {
                case 1:
                    ball.move(1, 1);
                    break;
                case 2:
                    ball.move(-1, 1);
                    break;
                case 3:
                    ball.move(-1, -1);
                    break;
                case 4:
                    ball.move(1, -1);
                    break;
                }
                ball.paint(g);
第五步,按键控制
主要控制挡板的。
                if ((this.getKeyStates() & GameCanvas.RIGHT_PRESSED) != 0) {
                    x += 4;
                } else if ((this.getKeyStates() & GameCanvas.LEFT_PRESSED) != 0) {
                    x -= 4;
                } else if ((this.getKeyStates() & GameCanvas.UP_PRESSED) != 0) {
                    y -= 4;
                } else if ((this.getKeyStates() & GameCanvas.DOWN_PRESSED) != 0) {
                    y += 4;
                }

                rawUp.setPosition(x, 0);
                rawDown.setPosition(x, 260);
                colRight.setPosition(210, y);
                colLeft.setPosition(0, y);

                rawDown.paint(g);
                rawUp.paint(g);
                colLeft.paint(g);
                colRight.paint(g);
最后,不要忘记this.flushGraphics();刷新
t.currentThread().sleep(30); 线程控制,此处可以设置游戏的难度。

你可能感兴趣的:(多线程,thread,游戏,UP)