本章目标

  • 解决坦克出界问题
  • 让坦克发射多发炮弹问题

一、解决坦克出界问题


咱们发现当初以后版本,如果管制这个坦克始终往左或者往右的话是会移出边界的

那么怎么解决这个问题呢?其实与子弹有殊途同归之处

public class Tank {        void move() {            //省略其余关键性代码.......                if (x < 0){ x = 0;}//若坦克x小于0则等于0                //小于30 是因为要思考题目的宽度        if (y < 30){ y = 30;}//若坦克y小于30则等于30        //当坦克的x坐标加上坦克的宽度大于游戏窗口的宽度        if (x + Tank.WIDTH > TankClient.GAME_WINDTH ) {            x = TankClient.GAME_WINDTH - Tank.WIDTH;        }        //当坦克的y坐标加上坦克的高度大于游戏窗口的高度        if (y + Tank.HEIGHT > TankClient.GAME_HEIGHT ) {            y = TankClient.GAME_HEIGHT - Tank.HEIGHT;        }    }        //省略其余关键性代码.......}

这时咱们的坦克则无奈再跑到里面了

然而咱们发现以后这个版本只有咱们一个坦克,那么咱们能不能加点坦克进来玩呢?

二、增加机器坦克


个别咱们玩坦克大战都会有一个营垒的标识符辨别是好是坏的坦克

public class Tank {        //辨别营垒好坏    private boolean camp = false;    public Tank(int x, int y, TankClient tc, boolean camp) {        this.x = x;        this.y = y;        this.tc = tc;        this.camp = camp;    }    //省略其余关键性代码.......}

这时咱们批改一下办法,并且创立多一个坦克

public class TankClient extends Frame {        //营垒:好的坦克    Tank mytank = new Tank(50,50,this,true);    //营垒:坏的坦克    Tank enemytank = new Tank(100,100,this,false);        //省略其余关键性代码.......        @Override    public void paint(Graphics g) {        //省略其余关键性代码.......        //画出 好的 坦克        mytank.draw(g);        //画出 坏的 坦克        enemytank.draw(g);    }}

这时机器坦克就进去了,如果你感觉不好辨别色彩,能够在绘制办法里辨别

public class Tank {        //增加办法实现坦克的绘画    public void draw(Graphics g) {        //省略其余关键性代码.......        if(camp){            //将营垒好的坦克色彩为红色            g.setColor(Color.red);        }else{            //将营垒坏的坦克色彩为蓝色            g.setColor(Color.blue);        }    }    //省略其余关键性代码.......}

步骤总结

  • ✧退出区别敌我的变量camp
  • ✧依据敌我的不同设置不同的色彩
  • ✧更新Tank的构造函数,退出camp
  • ✧TankClient中new 出敌人的坦克并画出

这时咱们就有一个新的想法进去了:怎么将这个坦克给干掉呢?

三、击毙机器坦克


在咱们发射炮弹的时候,那么如何检测到是否击中坦克呢?咱们称为碰撞检测

游戏中的碰撞检测形式有很多,不同的算法之间次要是在精度和速度之间衡量

咱们这里介绍一个类:Rectangle,它指的是坐标空间中的一块区域,通过坐标空间中Rectangle对象左上方的点 (x,y)、宽度和高度能够定义这个区域

上面是其比拟罕用的几个办法://-->断定点(x,y)是否蕴含在指定区域内boolean contains(int x,int y)//-->断定指定区域是否在其指定区域内boolean contains(int x,int y,int width,int height)

而咱们只须要判断子弹与坦克之间是否碰撞到一块来确定是否击中

public class Tank {        //创立子弹的坐标空间区域    public Rectangle getRect(){        return new Rectangle(x,y,WIDTH,HEIGHT);    }    //省略其余关键性代码.......}class Missle{    //创立子弹的坐标空间区域    public Rectangle getRect(){        return new Rectangle(x,y,WIDTH,HEIGHT);    }    public boolean hitTank(Tank t){        if(this.getRect().intersects(t.getRect())){            return true;        }        return false;    }    //省略其余关键性代码.......}

那么咱们怎么让这个坦克隐没呢?回忆一下咱们子弹是怎么隐没的?

是不是有一个变量管制着存活状态呀?所以咱们坦克也增加一个变量管制

public class Tank {        //用于判断管制坦克存活变量    private boolean live = true;    public boolean isLive() {        return live;    }    public void setLive(boolean live) {        this.live = live;    }        //增加办法实现坦克的绘画    public void draw(Graphics g) {        //死掉的坦克不必绘制        if(!live){            return;        }        //省略其余关键性代码.......    }    //省略其余关键性代码.......}

同时当咱们的子弹与坦克进行碰撞时,则将它批改为false状态即可

class Missle{    public boolean hitTank(Tank t){        if(this.getRect().intersects(t.getRect())){            t.setLive(false);            return true;        }        return false;    }    //省略其余关键性代码.......}

当咱们运行起来的时候,还须要调用该办法实现碰撞检测

public class TankClient extends Frame {        //省略其余关键性代码.......    @Override    public void paint(Graphics g) {        //画出容器里的子弹        for ( int i = 0; i < missles.size();i++){            Missle m = missles.get(i);            //将营垒坏的坦克放进来进行碰撞            m.hitTank(enemytank);            m.draw(g);        }        //省略其余关键性代码.......    }}

咱们发现子弹与坦克产生碰撞后,坦克是隐没了然而打中坦克的子弹没有隐没

这是因为咱们没有对这颗子弹也进行沦亡,移出

class Missle{    public boolean hitTank(Tank t){        if(this.getRect().intersects(t.getRect())){            t.setLive(false);            this.live = false;            return true;        }        return false;    }    //增加办法实现子弹的绘画    public void draw(Graphics g) {        if(!live){            //若沦亡则进行移出            tc.missles.remove(this);        }        //省略其余关键性代码.......    }    //省略其余关键性代码.......}

然而为什么这时咱们打一堆子弹进来,也会一并沦亡呢?为什么?

因为咱们在判断碰撞的时候,并没有将坦克的存活状态思考进去

class Missle{        public boolean hitTank(Tank t){        if(this.getRect().intersects(t.getRect()) && t.isLive()){            t.setLive(false);            this.live = false;            return true;        }        return false;    }    //省略其余关键性代码.......}

这时咱们打中坦克则实现了子弹移出、沦亡成果

步骤总结

  • ✧Missle中 退出hitTank(Tank)办法,返回布尔类型
  • ✧碰撞检测的辅助类Rectangle
  • ✧为Tank 和Missle都退出getRect办法
  • ✧当击中敌人坦克时,坦克被打死,子弹也死去
  • ✧减少管制Tank生死的量live
  • ✧如果坦克死去就不画了

咱们这里的碰撞检测采纳的是最简略的形式,将子弹与坦克用Rectangle类生成的方框包装起来

判断这两个方框是否相交来判断证实是否击中,击中后进行相干解决

参考资料


尚学堂:坦克大战(马士兵老师)