基于JAVA的简易坦克大战(六)

来源:互联网 发布:局域网教学广播软件 编辑:程序博客网 时间:2024/05/16 19:29

4.2.2 坦克类算法

1、坦克类是坦克大战的重要模块,这里包含了坦克应该有的成员属性(详见逻辑结构设计)。坦克大战管理类的按键监听使用的就是在坦克类中实现的keyPressed方法和KeyReleased方法。

2、在这个类中还包含了坦克的draw方法,方向判断方法以及移动方法(包含敌我双方坦克的相关操作)。

3、坦克类还实现了坦克血条的方法,实现了计算坦克分数和等级的功能,以及发射炮弹,击杀敌方的方法。我方击杀敌方一辆坦克将获得100分。子弹的有效攻击是通过判断子弹的类型和坦克的类型是否一致来实现的,有效的打击必须保证子弹的类型和坦克的类型相反,再通过碰撞检测来确定是否击中目标最终达到击杀的效果。

4、碰撞检测是通过判断两个对象所占的对应方框范围是否重合来实现的。

5、在坦克类的KeyReleased监听方法中实现了游戏的各种模式和功能。它们的实现都是通过修改对应的对象实例的信息来实现的。

6、敌方坦克的简易人工智能是通过随机步数,即让敌方坦克在移动随机的步数之后再随机的切换移动方向,在方向切换的同时打开敌方坦克的攻击开关。即完成敌方坦克的自我随机移动和攻击,达到基本人工智能的要求。

7、超级火力功能是通过连续创建8个不同方向的炮弹来实现的。而炮弹的移动采用的是只要赋予了方向便朝相应的方向移动,从而达到打开“超级火力”攻击按钮的时候,坦克可以朝8个方向同时发射炮弹的效果。

8、坦克类设计源码:import java.awt.*;import java.awt.event.*;import java.util.Random;public class Tank {private static final int Speech = 5;//坦克速度private static int Level = 0;//坦克等级private static int Score = 0;//坦克分数    private int x;    private int y;//坦克坐标    private int oldX;    private int oldY;    private int life = 30;//坦克生命    private int width = 30;    private int height = 30;//坦克宽高    private boolean live = true;//存活与否private boolean good;//坦克敌我分别    private TankClient tc = null;    private boolean bU = false,bL = false,bR = false,bD = false;    enum Direction {L,LU,LD,R,RU,RD,U,D,STOP}    Direction dir = Direction.STOP;//移动方向    Direction ptDir = Direction.D;//炮筒方向    //以下成员作为eTank()方法的成员使用Random r = new Random();    private int step = r.nextInt(12) + 3;//移动的步数,移动随即的步数然后改变方向(加3是为了不让随机数为0)public static void main(String[] args) {// TODO Auto-generated method stub}public int getLife() {return life;}public void setLife(int life) {this.life = life;}public static void setLevel(int level) {Level = level;}public static void setScore(int score) {Score = score;}public static int getScore() {return Score;}public static int getLevel() {return Level;}public boolean isLive() {return live;}public void setLive(boolean live) {this.live = live;}    public void setGood(boolean good) {this.good = good;}public Tank(int x,int y,boolean good,TankClient tc){this.x = x;this.y = y;this.good = good;this.tc = tc;}public void drawTank(Graphics g){Color c = g.getColor();if(this.isGood()){g.setColor(Color.RED);g.fillOval(x, y, width, height);}else{    g.setColor(Color.BLUE);    g.fillOval(x, y, width, height);}g.setColor(c);drawPT(g);if(isGood()){  drawBloodBar(g);  move();//每画一次调用移动方法一次 }}public void drawBloodBar(Graphics g){int bHeight = 10;Color c = g.getColor();g.setColor(Color.orange);g.drawRect(x, y - 10, 30, 10);g.setColor(Color.RED);g.fillRect(x, y - 10, life, bHeight);g.setColor(c);}//炮筒绘制public void drawPT(Graphics g){Color c = g.getColor();g.setColor(Color.WHITE);switch(ptDir){case L:g.drawLine(getX() + width/2, getY() + height/2, getX() - 5, getY() + height/2);break; case LU:g.drawLine(getX() + width/2, getY() + height/2, getX(), getY());break; case LD:g.drawLine(getX() + width/2, getY() + height/2, getX(), getY() + height);break; case R:g.drawLine(getX() + width/2, getY() + height/2, getX() + width + 5, getY() + height/2);break; case RU:g.drawLine(getX() + width/2, getY() + height/2, getX() + width, getY());break; case RD:g.drawLine(getX() + width/2, getY() + height/2, getX() + width, getY() + height);break; case U:g.drawLine(getX() + width/2, getY() + height/2, getX() + width/2, getY() - 5);break; case D:g.drawLine(getX() + width/2, getY() + height/2, getX() + width/2, getY() + height + 5);break; }g.setColor(c);}//敌方坦克移动public void eTank(){if(!isGood()){   Direction[] dirs = Direction.values();if(step == 0){step = r.nextInt(20) + 3;if(tc.isChallenge())superFire();else    fire();//敌方坦克开火  int rn = r.nextInt(dirs.length);dir = dirs[rn];}  move();step--;}}//按键监听public void keyPressed(KeyEvent e){int key = e.getKeyCode();switch(key){case KeyEvent.VK_W:bU = true;break;case KeyEvent.VK_D:bR = true;break;case KeyEvent.VK_S:bD = true;break;case KeyEvent.VK_A:bL = true;break;}setDirection();}public void keyReleased(KeyEvent e) {int key = e.getKeyCode();switch(key){case KeyEvent.VK_W:bU = false;break;case KeyEvent.VK_D:bR = false;break;case KeyEvent.VK_S:bD = false;break;case KeyEvent.VK_A:bL = false;break;case KeyEvent.VK_J:if(tc.myTank.isLive())fire();break;case KeyEvent.VK_F2:if(!tc.myTank.isLive())tc.myTank = new Tank(50,50,true,tc);break;case KeyEvent.VK_F3:tc.num += 1;if(tc.tanks.size() == 0)for(int i = 0;i < 10 + tc.num;i++){tc.tanks.add(new Tank(200 + 40*i,30,false,tc));}if(10 + tc.num == 15)tc.num -= 1;break;case KeyEvent.VK_O:if(tc.myTank.isLive() && tc.myTank.getLevel() >= 5 )    superFire();break;case KeyEvent.VK_F12:if(tc.myTank.isLive())tc.myTank.killmyTank();break;case KeyEvent.VK_F4:if(tc.tanks.size() != 0){if(!tc.isChallenge())tc.setChallenge(true);elsetc.setChallenge(false);}break;}setDirection();}//设置坦克方向public void setDirection(){if(!bU && !bL && !bR && bD) dir = Direction.D;else if(!bU && !bL && bR && !bD) dir = Direction.R;else if(!bU && bL && !bR && !bD) dir = Direction.L;else if(bU && !bL && !bR && !bD) dir = Direction.U;else if(!bU && bL && !bR && bD) dir = Direction.LD;else if(!bU && !bL && bR && bD) dir = Direction.RD;else if(bU && bL && !bR && !bD) dir = Direction.LU;else if(bU && !bL && bR && !bD) dir = Direction.RU;else if(!bU && !bL && !bR && !bD) dir = Direction.STOP;}public void move(){oldX = getX();oldY = getY();//if(isGood())switch(dir){case L:x -= Speech;break; case LU:x -= Speech;y -= Speech;break; case LD:x -= Speech;y += Speech;break; case R:x += Speech;break; case RU:x += Speech;y -= Speech;break; case RD:x += Speech;y += Speech;break; case U:y -= Speech;break; case D:y += Speech;break; case STOP:stay();break;}if(dir != Direction.STOP){ptDir = dir;}if(getX() < 0 || getY() < 30 || getX() > 770 || getY() > 570)stay();}public void stay(){x = oldX;y = oldY;}//超级火力public void superFire(){Direction dirs[] = Direction.values();Shell s = null;if(isGood()){for(int i = 0;i < dirs.length;i++){if(dirs[i] != Direction.STOP){s = new Shell(getX() + 10,getY() + 10,true,dirs[i],tc);tc.shells.add(s);}}}else{for(int i = 0;i < dirs.length;i++){if(dirs[i] != Direction.STOP){s = new Shell(getX() + 10,getY() + 10,false,dirs[i],tc);tc.shells.add(s);}}}}//一般火力public Shell fire(){Shell s = null;if(isGood())    s = new Shell(getX() + 10,getY() + 10,true,ptDir,tc);else{s = new Shell(getX() + 10,getY() + 10,false,ptDir,tc);}tc.shells.add(s);return s;}public int getX() {return x;}public int getY() {return y;}public boolean isGood() {return good;}//碰撞检测public boolean hitTank(Tank t,Graphics g){for(int i = 0;i < tc.shells.size();i++){Shell s = tc.shells.get(i);//挡子弹的图形区域碰撞到坦克的图形区域,且子弹的类型与坦克的类型为敌对时,且子弹和坦克都还活着时,打击成功if(s.getRect().intersects(t.getRect()) && (s.isGood() != t.isGood()) && s.isLive() && t.isLive()){s.setLive(false);//子弹打中目标后死亡//tc.shells.remove(s);//从集合中去除子弹if(t.isGood() == tc.myTank.isGood())//如果被打中的是我放坦克    {tc.myTank.life -= 10;     if(tc.myTank.life == 0)    {    tc.myTank.setLive(false);    tc.myTank.setScore(0);    tc.myTank.setLevel(0);    }    }else{t.setLive(false);//坦克死亡tc.tanks.remove(t);//从集合中移除死亡坦克}Explosion e = new Explosion(t.getX(),t.getY(),tc);    e.drawExplosion(g);return true;}}return false;}public boolean hitTanks(Graphics g){for(int i = 0;i < tc.tanks.size();i++){Tank t = tc.tanks.get(i);if(hitTank(t,g)){Score += 100;if(isGood())   levelUp(g);Explosion e = new Explosion(t.getX(),t.getY(),tc);    e.drawExplosion(g);    return true;}}return false;}//获取坦克图形区域(方块)    public Rectangle getRect(){    return new Rectangle(x,y,width,height);    }    public void levelUp(Graphics g){    Color c = g.getColor();    if(Score % 1000 == 0 & Score > 0)    {    Level++;    g.setColor(Color.ORANGE);    for(int i = 0;i < 500;i++)       g.drawString(" --LEVEL UP-- ", x - width/2 - 1, y + height/2);    }     g.setColor(c);    }    public void killmyTank(){    setLive(false);    setLevel(0);    setScore(0);    }}