前言需要
以咱们目前的思路文章,咱们发现只有一个坦克圆点,若咱们须要多个坦克时,则无奈分明怎么增加?
比如说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相干代码(键盘监听器重写键盘抬起事件)
参考资料
尚学堂:坦克大战(马士兵老师)