1、邊界檢測(cè)
坦克的可以穿過(guò)四周的邊界,為了限制坦克的活動(dòng)范圍,需要作出如下更新:
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) {
//當(dāng)坦克觸碰到上下左右的邊界時(shí),將塔克的指令改為只朝向?qū)?yīng)方向而不移動(dòng),但不影響坦克其他方向的移動(dòng)
mytank.cmd = mytank.cmd.substring(0, 1);
}
}
2、繪制墻體
類似于坦克的繪制,但是可以將墻體的坐標(biāo)類型保存至文件中,通過(guò)IO流讀取出來(lái)
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<String[]> getWall() {
List<String[]> 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;
}
}
本地配置文件可用逗號(hào)","將各個(gè)參數(shù)分開(kāi),如下所示
200,200,b
300,270,b
410,300,b
510,260,w
800,230,b
700,360,b
620,430,p
注:X軸坐標(biāo),Y軸坐標(biāo),墻類型*(wall-*.png)
墻wall類只需要定義屬性,不需要具體繪制方法,統(tǒng)一在MyMap中實(shí)現(xiàn),以下為wall類
public class Wall {//墻的屬性與配置文件相同
private int x;//X軸坐標(biāo)
private int y;//Y軸坐標(biāo)
private String path;//墻圖片路徑,只需要其類型,在MyMap中通過(guò)字符串拼接形成完整路徑
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中創(chuàng)建wall類集合 List<Wall>,并調(diào)用讀取文件的方法形成墻類,然后再繪制:
private List<Wall> walls;
{
walls = new CopyOnWriteArrayList<>();
List<String[]> walltxt = new GetWallsFromFile().getWall();
for (String[] w : walltxt) {
walls.add(new Wall(Integer.parseInt(w[0]), Integer.parseInt(w[1]), w[2]));
}
}//在代碼塊中調(diào)用方法獲取墻的配置
public void show() {
//遍歷集合,畫出各個(gè)墻體
for (Wall w : walls) {
Image img = null;
try {
String str=w.getPath();
//通過(guò)字符串拼接,將墻的類型轉(zhuǎn)化為對(duì)應(yīng)的文件路徑
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、碰撞檢測(cè)
到了此時(shí),墻雖然畫好了,但是坦克在運(yùn)動(dòng)時(shí)可以穿墻,為了解決這個(gè)問(wèn)題,需要進(jìn)行二者之間的碰撞檢測(cè)。這里主要借用JDK中的Rectangle類進(jìn)行碰撞檢測(cè),所以需要將坦克和墻轉(zhuǎn)成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);
//判斷條件為:二者模型碰撞,并且前進(jìn)方向碰到對(duì)應(yīng)邊(類似邊界檢測(cè))
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);
}
}
}
至此坦克大戰(zhàn)的第二階段算完成了。