前言需要


以咱们目前的思路文章,咱们发现只有一个坦克圆点,若咱们须要多个坦克时,则无奈分明怎么增加?

比如说100个坦克,那么就须要有100个坦克的地位

若应用数组寄存100个坦克的地位,那么当坦克有不同属性:圆点色彩、名称、营垒等

则也须要增加绝对应的数组去治理,所以这时咱们须要应用面向对象来创立一个坦克类

一、坦克类寄存属性


class Tank{    int x;//坦克x坐标    int y ;//坦克y坐标    public Tank(int x, int y) {        this.x = x;        this.y = y;    }}

这时咱们在应用一辆坦克的时候,则间接创立即可

public class TankClient extends Frame {    Tank mytank = new Tank(50,50);        @Override    public void paint(Graphics g) {        //获取默认的色彩Color        Color c = g.getColor();        //将坦克色彩为红色        g.setColor(Color.red);        //画一个圆        g.fillOval(mytank.x,mytank.y,30,30);        //将原色彩填充回        g.setColor(c);    }            //省略其余关键性代码....}

咱们发现如果应用这种形式去绘画一个坦克的话,是没有问题的

然而若有100个坦克的时候,反而还须要去治理这个绘画的办法

那么咱们可不可以应用一种思维,让坦克本人去绘制本人呢?

class Tank{   //省略其余关键性代码....        //增加办法实现坦克的绘画    public void draw(Graphics g){        //获取默认的色彩Color        Color c = g.getColor();        //将坦克色彩为红色        g.setColor(Color.red);        //画一个圆        g.fillOval(x, y, 30, 30);        //将原色彩填充回        g.setColor(c);        //刷新圆点地位        x += 5;//x坐标        y += 5;//y坐标    }}public class TankClient extends Frame {    Tank mytank = new Tank(50,50);        @Override    public void paint(Graphics g) {        mytank.draw(g)    }        //省略其余关键性代码....}

同时咱们的键盘管制也是,这样咱们前面机器人本人动的时候则无需治理

class Tank{   //省略其余关键性代码....   public void keyPressed(KeyEvent e) {      int key = e.getKeyCode();      switch (key) {         case KeyEvent.VK_LEFT:            x -= 5;            break;         case KeyEvent.VK_UP:            y -= 5;            break;         case KeyEvent.VK_RIGHT:            x += 5;            break;         case KeyEvent.VK_DOWN:            y += 5;            break;       }   }}
public class TankClient extends Frame {    Tank mytank = new Tank(50,50);        //继承抽象类实现键盘监听    private class KeyMonitor extends KeyAdapter {        @Override        public void keyPressed(KeyEvent e) {            mytank.keyPressed(e);//这样起到中间人的作用        }    }    //省略其余关键性代码....}

这样当咱们治理一辆坦克的时候,也是能够跑起来的,多个的时候也可

二、让坦克八个方向走

之前咱们有篇文章是让坦克能够上下左右的挪动,然而咱们发有一些方向漏掉了,并且没有提供给坦克挪动

比如说:左上、右上、左下、右下

咱们刚刚在后面封装了坦克的类,这时咱们怎么增加这四个方向呢?

同时咱们个别实现左上走形式在键盘里是怎么做到的呢?

是不是须要先按住左、再按上,这样造成左上走的斜线操作

第一步:增加↑↓←→方向是否被按下的标识符

class Tank{    //省略其余关键性代码....    //↑↓←→的四个方向键    private boolean BU = false;    private boolean BD = false;    private boolean BL = false;    private boolean BR = false;    }

当按下对应的方向,地位标识符则更改为true,同时提供八个方向的枚举

class Tank{    //省略其余关键性代码....    //定义枚举八个方向:上、下、左、右、左上、右上、右下、左下、进行不动    enum Direction{L,LU,U,RU,R,RD,D,LD,STOP}        //默认动作方向为进行不动    private Direction dir = Direction.STOP;    }

当咱们触发八个方向的时候,则依据方向进行挪动批改间隔

class Tank{    //省略其余关键性代码....    //每次挪动x坐标的步骤间隔    public static final int XSPEED = 5;    //每次挪动y坐标的步骤间隔    public static final int YSPEED = 5;        void move() {        switch (dir) {            case L:                x -= XSPEED;                break;            case LU:                x -= XSPEED;                y -= YSPEED;                break;            case U:                y -= YSPEED;                break;            case RU:                x += XSPEED;                y -= YSPEED;                break;            case R:                x += XSPEED;                break;            case RD:                x += XSPEED;                y += YSPEED;                break;            case D :                y += YSPEED;                break;            case LD:                x -= XSPEED;                y += YSPEED;                break;            case STOP:                break;        }    }}

同时当咱们从新绘画的时候,进行挪动地位,以及键盘按下批改标识符

class Tank{    //省略其余关键性代码....        //增加办法实现坦克的绘画    public void draw(Graphics g){        //省略其余关键性代码....        move();    }        public void keyPressed(KeyEvent e) {        int key = e.getKeyCode();        switch (key) {            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;        }    }}

这时咱们则能够依据标识符,来组合具体的坦克方向地位了

比如说咱们按键程序:左、上,这时咱们的方向应该是左上

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;    }

步骤思路总结

  • ✧增加记录按键状态的布尔量
  • ✧增加代表方向的量(应用枚举)
  • ✧依据按键状态确定Tank方向
  • ✧依据方向进行下一步的挪动(move)

然而当咱们运行main办法的时候,发现只须要按下方向键的确走了

比如说咱们按先按右再按下,发现他是斜着走的?这是什么状况呢?

起因是:当咱们按下方向键时就为True,开释时并没有更改为false

所以当咱们按下右,再按下时,右和下都为Ture了

第二步:增加键盘开释的监听器事件

给坦克增加键盘开释的监听事件,当咱们抬起键盘的时候更改为false

public void keyReleased(KeyEvent e) {    int key = e.getKeyCode();    switch (key) {        case KeyEvent.VK_LEFT:            BL = false;            break;        case KeyEvent.VK_UP:            BU = false;            break;        case KeyEvent.VK_RIGHT:            BR = false;            break;        case KeyEvent.VK_DOWN:            BD = false;            break;    }    locateDirection();}
public class TankClient extends Frame {        //省略其余关键性代码.......    //继承抽象类实现键盘监听    private class KeyMonitor extends KeyAdapter {        //当键盘按下的事件        @Override        public void keyPressed(KeyEvent e) {            mytank.keyPressed(e);//这样起到中间人的作用        }        //当键盘抬起的事件        @Override        public void keyReleased(KeyEvent e) {            mytank.keyReleased(e);//这样起到中间人的作用        }    }}

这下咱们的坦克就能够实现坦克的八个方向行走了

步骤思路总结

  • ✧解决键抬起的音讯
  • ✧批改TankClient相干代码(键盘监听器重写键盘抬起事件)

参考资料


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