本章目的
- 添加阻碍墙
- 敌方坦克无法穿越阻碍墙
一、添加阻碍墙
我们想想怎么添加阻碍墙?阻碍墙的作用有是什么?坦克、子弹与它有什么关系?
一般当我们对着阻碍墙发射炮弹,子弹与阻碍墙碰撞的话会消失
以及我们的坦克移动的时候,无法通过阻碍墙,那么根据前面子弹、坦克的思路
我们的阻碍墙是不是也可以使用面向对象的思路创建出来?
class Wall{
int x;//墙的x坐标
int y;//墙的y坐标
int w;//墙的宽度
int h;//墙的高度
public Wall(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
}
同时我们对于墙也是有相应的绘制方法、与包裹成方块的方法
class Wall{
//省略其他关键性代码....
public void draw(Graphics g){
//绘制墙体
g.fillRect(x,y,w,h);
}
//将墙包裹成方框方便碰撞测试
public Rectangle getRect(){
return new Rectangle(x,y,w,h);
}
}
现在我们在TankClinet类中定义一些墙,测试看看是否成功
public class TankClient extends Frame {
//绘制墙体
Wall w1 = new Wall(100,200,20,150);
@Override
public void paint(Graphics g) {
//画出墙体
w1.draw(g);
//省略其他关键性代码....
}
//省略其他关键性代码....
}
步骤总结
建Wall类、建立Wall对象、画出来
让每一颗子弹打击每一堵墙
- ✧ hitWall( )方法
- ✧ 注意:子弹速度不能太快,否则很容易穿过墙
二、敌方坦克无法穿越阻碍墙
我们的墙就出来了,但是有一些问题比如:坦克、子弹都可以穿过去
我们先对子弹进行处理,添加子弹与墙体之间的碰撞方法
public class TankClient extends Frame {
@Override
public void paint(Graphics g) {
public void paint(Graphics g) {
//画出容器里的子弹
for ( int i = 0; i < missles.size();i++){
//将墙体也放进来进行碰撞
m.hitWall(w1);
//省略其他关键性代码....
}
//省略其他关键性代码....
}
//省略其他关键性代码....
}
class Missle{
public boolean hitWall(Wall wall){
//要求:子弹是未消亡的并且子弹与墙体的方框碰撞到一块
if(this.live && this.getRect().intersects(wall.getRect())){
this.live = false;
return true;
}
return false;
}
//省略其他关键性代码....
}
这时我们对坦克进行优化与修改,添加与墙的碰撞方法处理
class Tank{
//坦克与墙碰撞的方法
public boolean collideWithWall(Wall wall){
//要求:坦克是未消亡的并且坦克与墙体的方框碰撞到一块
if(this.live && this.getRect().intersects(wall.getRect())){
//让坦克停下来
this.dir = Direction.STOP;
return true;
}
return false;
}
//省略其他关键性代码....
}
我们可以设置为敌方坦克不可穿过墙体,而我们的坦克可以拥有特权等等
public class TankClient extends Frame {
@Override
public void paint(Graphics g) {
//画出容器里的敌方坦克
for ( int i = 0; i < tanklist.size();i++){
Tank tank = tanklist.get(i);
tank.collideWithWall(w1);
tank.draw(g);
}
//省略其他关键性代码....
}
//省略其他关键性代码....
}
这时当我们的敌方坦克与墙体碰撞的时候,就会停下来不动。感觉不是很好
我们可不可以当它撞到墙时,让它回到未撞墙的位置呢?
class Tank{
int oldx;//坦克的上一个x坐标
int oldy;//坦克的上一个y坐标
public Tank(int x, int y,boolean camp) {
this.x = x;
this.y = y;
this.oldx = x;
this.oldy = y;
this.camp = camp;
}
void move() {
//每次移动前记录原来的位置
this.oldx = x;
this.oldy = y;
//省略其他关键性代码....
}
//省略其他关键性代码....
}
当我们的坦克与墙体发生碰撞时,回到上一个位置,就是oldX与oldY
class Tank{
//坦克与墙碰撞的方法
public boolean collideWithWall(Wall wall){
//要求:坦克是未消亡的并且坦克与墙体的方框碰撞到一块
if(this.live && this.getRect().intersects(wall.getRect())){
//让坦克回到原位置
this.stay();
return true;
}
return false;
}
//回到上一位置
public void stay(){
this.x = oldx;
this.y = oldy;
}
//省略其他关键性代码....
}
这时当我们的地方坦克撞向墙,也能根据上一个位置重新进行移动了
步骤总结
让敌方坦克不能穿墙:
- ✧ 记录上一次的位置oldX, oldY
- ✧ 修改构造函数
- ✧ 每次move之前纪录上一次位置
- ✧ 添加stay方法
- ✧ 记录移动前的位置
- ✧ 当撞到时回到移动前的位置
- ✧ 当碰到墙的时候stay
参考资料
尚学堂:坦克大战(马士兵老师)