J2SE坦克大战(Demo学习总结)(一)

2014-11-24 10:09:32 · 作者: · 浏览: 3

( 纯手绘版坦克大战)


1:制作出显示应用程序窗口


定义好窗口的大小,布局和背景颜色


这里主要覆写了父类的paint()和update()方法,在update方法中加入了双缓冲机制具体代码如下:


Image offScreenImage = null;


public void update(Graphics g) {


if(offScreenImage == null) {


offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT);


}


Graphics gOffScreen = offScreenImage.getGraphics();


Color c = gOffScreen.getColor();


gOffScreen.setColor(Color.GREEN);


gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);


gOffScreen.setColor(c);


paint(gOffScreen); //调用paint方法


g.drawImage(offScreenImage, 0, 0, null);


}



其次在重绘和按键监听的时候,定义了两个内部类:


/**重绘内部类*/


private class PaintThread implements Runnable{



@Override


public void run() {


while(true){


repaint();


try {


Thread.sleep(50);


} catch (InterruptedException e) {


e.printStackTrace();


}


}


}



}




/**事件监听内部类*/


private class KeyMonitor extends KeyAdapter{


public void keyReleased(KeyEvent e){


myTank.keyReleased(e);


}



public void keyPressed(KeyEvent e){


myTank.keyPressed(e);


}


}




this.addKeyListener(new KeyMonitor());


new Thread(new PaintThread()).start();



这里在按键的时候,定义了八个方向。代码如下所示:


private boolean bL=false, bU=false, bR=false, bD = false;


enum Direction {L, LU, U, RU, R, RD, D, LD, STOP};



public void keyPressed(KeyEvent e) {


int key = e.getKeyCode();


switch(key) {


case KeyEvent.VK_F2 :


if(!this.live) {


this.live = true;


this.life = 100;


}


break;


case KeyEvent.VK_LEFT :


bL = true;


break;


case KeyEvent.VK_UP :


bU = true;


break;


case KeyEvent.VK_RIGHT :


bR = true;


break;


case KeyEvent.VK_DOWN :


bD = true;


break;


}


locateDirection();


}



void locateDirection() {


if(bL && !bU && !bR && !bD) dir = Direction.L;


else if(bL && bU && !bR && !bD) dir = Direction.LU;


else if(!bL && bU && !bR && !bD) dir = Direction.U;


else if(!bL && bU && bR && !bD) dir = Direction.RU;


else if(!bL && !bU && bR && !bD) dir = Direction.R;


else if(!bL && !bU && bR && bD) dir = Direction.RD;


else if(!bL && !bU && !bR && bD) dir = Direction.D;


else if(bL && !bU && !bR && bD) dir = Direction.LD;


else if(!bL && !bU && !bR && !bD) dir = Direction.STOP;


}



在区分敌方坦克和自己的坦克的时候,通过一个Boolean变量来区分。


创建敌方坦克的时候,默认给他一个方向,然后通过一个random数值来随机敌方坦克的方向, 放弹也是根据一个随机数来获得。 下面是示例代码:


private static Random r = new Random(); //定义成静态的,使内存区中只存在一个该实例对象。


private int step = r.nextInt(12) + 3;



然后在move()方法中,开始监听这个变量


if(!good) { //如果不是好的坦克(说明是敌方)


Direction[] dirs = Direction.values();


if(step == 0) {


step = r.nextInt(12) + 3;


int rn = r.nextInt(dirs.length);


dir = dirs[rn];


}


step --; //根据step数值来改变敌方玩家的方向



if(r.nextInt(40) > 38) this.fire();


}


在和其他物体作碰撞检测的时候,如果碰到某个物体的话,则该坦克不允许再移动,这里解决这个问题的办法是定义另外两个变量oldX, oldY来保存之前的x, y变量。如果碰到物体不可行走则将oldX ,oldY 再付给x,y坐标。


2:在制作爆炸物特效的时候用到了这样一个判断:


int[] diameter = {4, 7, 12, 18, 26, 32, 49, 30, 14, 6