坦克大战二

1、边界检测

坦克的可以穿过四周的边界,为了限制坦克的活动范围,需要作出如下更新:

private void stageEdge() {
    
        boolean stage_d = mytank.x > this.getWidth() - 64 && mytank.cmd.equals("dd");
        boolean stage_s = mytank.y > this.getHeight() - 64 && mytank.cmd.equals("ss");
        boolean stage_a = mytank.x < 0 && mytank.cmd.equals("aa");
        boolean stage_w = mytank.y < 0 && mytank.cmd.equals("ww");
        if (stage_d || stage_s || stage_a || stage_w) {
     //当坦克触碰到上下左右的边界时,将塔克的指令改为只朝向对应方向而不移动,但不影响坦克其他方向的移动
            mytank.cmd = mytank.cmd.substring(0, 1);
        }
    }

2、绘制墙体

类似于坦克的绘制,但是可以将墙体的坐标类型保存至文件中,通过IO流读取出来

import java.io.*;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class GetWallsFromFile {
    private static final String WALLS_PATH = "staticTank/walls.txt";//墙配置文件路径

    public List getWall() {
        List walls = new CopyOnWriteArrayList<>();
        try {
            InputStream in = new FileInputStream(WALLS_PATH);
            InputStreamReader rd = new InputStreamReader(in);
            BufferedReader br = new BufferedReader(rd);//读取wall的配置文件
            String str;
            while ((str = br.readLine()) != null) {
                String[] strs = str.split(",");
                walls.add(strs);
            }
            br.close();
            rd.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return walls;
    }
}

本地配置文件可用逗号","将各个参数分开,如下所示

200,200,b
300,270,b
410,300,b
510,260,w
800,230,b
700,360,b
620,430,p


注:X轴坐标,Y轴坐标,墙类型*(wall-*.png)

墙wall类只需要定义属性,不需要具体绘制方法,统一在MyMap中实现,以下为wall类

public class Wall {//墙的属性与配置文件相同
    private int x;//X轴坐标
    private int y;//Y轴坐标
    private String path;//墙图片路径,只需要其类型,在MyMap中通过字符串拼接形成完整路径

    public Wall() {
    }

    public Wall(int x, int y, String path) {
        this.x = x;
        this.y = y;
        this.path = path;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }
}

完成以上两步骤后,在MyMap中创建wall类集合 List,并调用读取文件的方法形成墙类,然后再绘制:

private List walls;
{
        walls = new CopyOnWriteArrayList<>();
        List walltxt = new GetWallsFromFile().getWall();
        for (String[] w : walltxt) {
            walls.add(new Wall(Integer.parseInt(w[0]), Integer.parseInt(w[1]), w[2]));
        }
    }//在代码块中调用方法获取墙的配置

public void show() {
    //遍历集合,画出各个墙体
        for (Wall w : walls) {
            Image img = null;
            try {
                String str=w.getPath();
                //通过字符串拼接,将墙的类型转化为对应的文件路径
                img = ImageIO.read(new File("staticTank/wall-" + w.getPath() + ".png"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            g.drawImage(img, w.getX(), w.getY(), 64, 64, stage);
        }
    }

3、碰撞检测

到了此时,墙虽然画好了,但是坦克在运动时可以穿墙,为了解决这个问题,需要进行二者之间的碰撞检测。这里主要借用JDK中的Rectangle类进行碰撞检测,所以需要将坦克和墙转成Rectangle类。

private void collision() {
        Rectangle rect_mytank = new Rectangle(mytank.x, mytank.y, 64, 64);
        for (Wall w : mymap.getWalls()) {
            Rectangle rect_wall = new Rectangle(w.getX(), w.getY(), 64, 64);
            //判断条件为:二者模型碰撞,并且前进方向碰到对应边(类似边界检测)
            boolean wall_d = rect_mytank.intersects(rect_wall) && mytank.x < w.getX() && mytank.cmd.equals("dd");
            boolean wall_s = rect_mytank.intersects(rect_wall) && mytank.y < w.getY() && mytank.cmd.equals("ss");
            boolean wall_a = rect_mytank.intersects(rect_wall) && mytank.x > w.getX() && mytank.cmd.equals("aa");
            boolean wall_w = rect_mytank.intersects(rect_wall) && mytank.y > w.getY() && mytank.cmd.equals("ww");
            if (wall_d || wall_s || wall_a || wall_w) {
                mytank.cmd = mytank.cmd.substring(0, 1);
            }
        }
    }

至此坦克大战的第二阶段算完成了。

你可能感兴趣的:(坦克大战二)