坦克大戰【3】 筆記目錄:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 坦克大戰0.6版 √增加功能 防止敵人坦克重疊運動 記錄玩家的成績(累積擊毀敵方坦克數),存檔退出【io流】 記錄當時的敵人坦克坐標與方向,存檔退出【io流】 玩游戲時 ...
坦克大戰【3】
筆記目錄:(https://www.cnblogs.com/wenjie2000/p/16378441.html)
坦克大戰0.6版
√增加功能
-
防止敵人坦克重疊運動
-
記錄玩家的成績(累積擊毀敵方坦克數),存檔退出【io流】
-
記錄當時的敵人坦克坐標與方向,存檔退出【io流】
-
玩游戲時,可以選擇是開新游戲還是繼續上局游戲
代碼
Tank
package tankgame06;
//坦克
public class Tank {
//坦克左上角坐標
private int x;
private int y;
private int direct;//坦克方向 0上 1右 2下 3左
boolean isLive = true;//是否存活
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
private int speed = 2;//坦克速度
//上右下左移動方法
public void moveUp() {
if (y - speed > 0) {
y -= speed;
}
}
public void moveDown() {
if (y + 60 + speed < 750) {
y += speed;
}
}
public void moveLeft() {
if (x - 10 - speed > 0) {
x -= speed;
}
}
public void moveRight() {
if (x - 10 + 60 + speed < 1000) {
x += speed;
}
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
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;
}
}
Hero
package tankgame06;
import java.util.Vector;
//玩家坦克
public class Hero extends Tank {
Shot shot = null;//射擊行為
//發射多個子彈
Vector<Shot> shots = new Vector<>();
public Hero(int x, int y) {
super(x, y);
}
//射擊
public void shotEnemyTank() {
//發多顆子彈怎麼辦,控制在我們的面板上,最多只有5顆
if (shots.size()==5){
return;
}
switch (getDirect()) {
case 0://上
shot = new Shot(getX() + 20, getY(), 0);
break;
case 1://右邊
shot = new Shot(getX() + 50, getY() + 30, 1);
break;
case 2:
shot = new Shot(getX() + 20, getY() + 60, 2);
break;
case 3:
shot = new Shot(getX() - 10, getY() + 30, 3);
break;
}
//把新創建的shot放入到shots
shots.add(shot);
//啟動我們的Shot線程
new Thread(shot).start();
}
}
EnemyTank
package tankgame06;
import java.util.Vector;
//敵方坦克
public class EnemyTank extends Tank implements Runnable {
//在敵人坦克類,使用Vector保存多個Shot
Vector<Shot> shots = new Vector<>();
static Vector<EnemyTank> enemyTanks = new Vector<>();//存放所有敵人坦克信息
public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
EnemyTank.enemyTanks = enemyTanks;
}
//編寫方法,判斷當前的這個敵人坦克,是否和 enemyTanks 中的其他坦克發生的重疊或者碰撞
public boolean isTouchEnemyTank() {
switch (this.getDirect()) {
case 0:
//讓當前敵人坦克和其它所有的敵人坦克比較
for (int i = 0; i < enemyTanks.size(); i++) {
//從vector中取出一個敵人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比較
if (enemyTank == this) {
continue;
}
//1.如果敵人坦克是上/下x的範圍[enemyTank.getX(),enemyTank.getX() +40]
// y的範圍 [enemyTank.getY(),enemyTank.getY() +60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
//2。當前坦克左上角的坐標[this.getX(),this.getY()]
if (this.getX() >= enemyTank.getX() && this.getX() <= enemyTank.getX() + 40 && this.getY() >= enemyTank.getY() && this.getY() <= enemyTank.getY() + 60) {
return true;
}
//3.當前坦克右上角的坐標[this.getX() +40, this.getY()]
if (this.getX() + 40 >= enemyTank.getX() && this.getX() + 40 <= enemyTank.getX() + 40 && this.getY() >= enemyTank.getY() && this.getY() <= enemyTank.getY() + 60) {
return true;
}
}
//如果敵人坦克是 右/左
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
//2。當前坦克左上角的坐標[this.getX(),this.getY()]
if (this.getX() >= enemyTank.getX() - 10 && this.getX() <= enemyTank.getX() + 50 && this.getY() >= enemyTank.getY() + 10 && this.getY() <= enemyTank.getY() + 50) {
return true;
}
//3.當前坦克右上角的坐標[this.getX() +40, this.getY()]
if (this.getX() + 40 >= enemyTank.getX() - 10 && this.getX() + 40 <= enemyTank.getX() + 50 && this.getY() >= enemyTank.getY() + 10 && this.getY() <= enemyTank.getY() + 50) {
return true;
}
}
}
break;
case 1:
//讓當前敵人坦克和其它所有的敵人坦克比較
for (int i = 0; i < enemyTanks.size(); i++) {
//從vector中取出一個敵人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比較
if (enemyTank == this) {
continue;
}
//1.如果敵人坦克是上/下
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
//2。當前坦克右上角的坐標[this.getX()+50,this.getY()+10]
if (this.getX()+50 >= enemyTank.getX() && this.getX()+50 <= enemyTank.getX() + 40 && this.getY()+10 >= enemyTank.getY() && this.getY()+10 <= enemyTank.getY() + 60) {
return true;
}
//3.當前坦克右下角的坐標[this.getX() +50, this.getY()+50]
if (this.getX() + 50 >= enemyTank.getX() && this.getX() + 50 <= enemyTank.getX() + 40 && this.getY()+50 >= enemyTank.getY() && this.getY()+50 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敵人坦克是 右/左
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
//2。當前坦克右上角的坐標[this.getX()+50,this.getY()+10]
if (this.getX()+50 >= enemyTank.getX() - 10 && this.getX()+50 <= enemyTank.getX() + 50 && this.getY()+10 >= enemyTank.getY() + 10 && this.getY()+10 <= enemyTank.getY() + 50) {
return true;
}
//3.當前坦克右下角的坐標[this.getX() +50, this.getY()+50]
if (this.getX() + 50 >= enemyTank.getX() - 10 && this.getX() + 50 <= enemyTank.getX() + 50 && this.getY()+50 >= enemyTank.getY() + 10 && this.getY()+50 <= enemyTank.getY() + 50) {
return true;
}
}
}
break;
case 2:
//讓當前敵人坦克和其它所有的敵人坦克比較
for (int i = 0; i < enemyTanks.size(); i++) {
//從vector中取出一個敵人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比較
if (enemyTank == this) {
continue;
}
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
//2。當前坦克左下角的坐標[this.getX(),this.getY()+60]
if (this.getX() >= enemyTank.getX() && this.getX() <= enemyTank.getX() + 40 && this.getY()+60 >= enemyTank.getY() && this.getY()+60 <= enemyTank.getY() + 60) {
return true;
}
//3.當前坦克右下角的坐標[this.getX() +40, this.getY()+60]
if (this.getX() + 40 >= enemyTank.getX() && this.getX() + 40 <= enemyTank.getX() + 40 && this.getY()+60 >= enemyTank.getY() && this.getY()+60 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敵人坦克是 右/左
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
//2。當前坦克左下角的坐標[this.getX(),this.getY()+60]
if (this.getX() >= enemyTank.getX() - 10 && this.getX() <= enemyTank.getX() + 50 && this.getY()+60 >= enemyTank.getY() + 10 && this.getY()+60 <= enemyTank.getY() + 50) {
return true;
}
//3.當前坦克右下角的坐標[this.getX() +40, this.getY()+60]
if (this.getX() + 40 >= enemyTank.getX() - 10 && this.getX() + 40 <= enemyTank.getX() + 50 && this.getY()+60 >= enemyTank.getY() + 10 && this.getY()+60 <= enemyTank.getY() + 50) {
return true;
}
}
}
break;
case 3:
//讓當前敵人坦克和其它所有的敵人坦克比較
for (int i = 0; i < enemyTanks.size(); i++) {
//從vector中取出一個敵人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比較
if (enemyTank == this) {
continue;
}
//1.如果敵人坦克是上/下
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
//2。當前坦克左上角的坐標[this.getX()-10,this.getY()+10]
if (this.getX()-10 >= enemyTank.getX() && this.getX()-10 <= enemyTank.getX() + 40 && this.getY()+10 >= enemyTank.getY() && this.getY()+10 <= enemyTank.getY() + 60) {
return true;
}
//3.當前坦克左下角的坐標[this.getX()-10, this.getY()+50]
if (this.getX() -10 >= enemyTank.getX() && this.getX() -10 <= enemyTank.getX() + 40 && this.getY()+50 >= enemyTank.getY() && this.getY()+50 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敵人坦克是 右/左
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
//2。當前坦克左上角的坐標[this.getX()-10,this.getY()+10]
if (this.getX()-10 >= enemyTank.getX() - 10 && this.getX()-10 <= enemyTank.getX() + 50 && this.getY()+10 >= enemyTank.getY() + 10 && this.getY()+10 <= enemyTank.getY() + 50) {
return true;
}
//3.當前坦克左下角的坐標[this.getX()-10, this.getY()+50]
if (this.getX() -10 >= enemyTank.getX() - 10 && this.getX() -10 <= enemyTank.getX() + 50 && this.getY()+50 >= enemyTank.getY() + 10 && this.getY()+50 <= enemyTank.getY() + 50) {
return true;
}
}
}
break;
}
return false;
}
public EnemyTank(int x, int y) {
super(x, y);
}
@Override
public void run() {
while (true) {
//這裡我們判斷如果shots size() =0,創建一顆子彈,放入到
//shots集合,並啟動
if (isLive && shots.size() <= 5) {//敵人同時只能存在五個子彈
Shot s = null;
switch (getDirect()) {
case 0://上
s = new Shot(getX() + 20, getY(), 0);
break;
case 1://右邊
s = new Shot(getX() + 50, getY() + 30, 1);
break;
case 2:
s = new Shot(getX() + 20, getY() + 60, 2);
break;
case 3:
s = new Shot(getX() - 10, getY() + 30, 3);
break;
}
shots.add(s);
new Thread(s).start();
}
//根據坦克方向繼續移動
for (int i = 0; i < 30; i++) {
if (isTouchEnemyTank()){//如果有碰撞
continue;
}
switch (getDirect()) {
case 0://向上
//讓坦克保持一個方向,走30步
moveUp();
break;
case 1://向右
moveRight();
break;
case 2://向下
moveDown();
break;
case 3://向左
moveLeft();
break;
}
//休眠50毫秒
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//然後隨機的改變坦克方向 0-3
setDirect((int) (Math.random() * 4));
if (!isLive) {
break;
}
}
}
}
Shot
package tankgame06;
//射擊事件
public class Shot implements Runnable {
private int x;
private int y;
private int direct;//方向 0上 1右 2下 3左
private int speed = 10;//子彈速度
boolean isAlive = true;
public Shot(int x, int y, int direct) {
this.x = x;
this.y = y;
this.direct = direct;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public void run() {
while (true) {
//休眠
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//根據方向移動
switch (direct) {
case 0:
y -= speed;
break;
case 1:
x += speed;
break;
case 2:
y += speed;
break;
case 3:
x -= speed;
break;
}
// System.out.println("子彈坐標(" + x + "," + y + ")");
//當子彈移動到面板的邊界時,就應該銷毀(把啟動的子彈的線程銷毀)
// 當子彈碰到敵人坦克時,也應該結束線程
if (x < 0 || x >= 1000 || y < 0 || y >= 750 || isAlive == false) {
// System.out.println("子彈線程退出");
isAlive = false;
break;
}
}
}
}
Bomb
package tankgame06;
//爆炸事件
public class Bomb {
int x, y;//炸彈的坐標
int life = 9;//炸彈的生命周期
boolean isLive = true;//是否還存活
public Bomb(int x, int y) {
this.x = x;
this.y = y;
}
//減少爆炸效果的生命值
public void lifeDown() {//配合出現圖片的爆炸效果
if (life > 0) {
life--;
} else {
isLive = false;
}
}
}
Record
package tankgame06;
//記錄信息,與文件交互
import java.io.*;
import java.util.Vector;
public class Recorder {
//定義變數,記錄我方擊毀敵人坦克數
private static int allEnemyTankNum = 0;//定義IO對象,準備寫數據到文件中
// private static BufferedWriter bw = null;
private static String recordFile = "d:\\myRecord.txt";
//保存游戲數據
//對keepRecord進行升級,保存敵人坦克的坐標和方向
public static void keepRecord() {
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(recordFile));
bw.write(allEnemyTankNum + "\n");
Vector<EnemyTank> enemyTanks = EnemyTank.enemyTanks;
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (enemyTank.isLive) {
String record = enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect();
bw.write(record + "\n");
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//讀取文件數據
public static void loadRecord() {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(recordFile));
allEnemyTankNum = Integer.parseInt(br.readLine());
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
String[] s = line.split(" ");
EnemyTank enemyTank = new EnemyTank(Integer.parseInt(s[0]), Integer.parseInt(s[1]));
enemyTank.setDirect(Integer.parseInt(s[2]));
EnemyTank.enemyTanks.add(enemyTank);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static int getAllEnemyTankNum() {
return allEnemyTankNum;
}
public static void setAllEnemyTankNum(int allEnemyTankNum) {
Recorder.allEnemyTankNum = allEnemyTankNum;
}
//當我方坦克擊毀一個敵人坦克,就應當allEnemyTankNum++
public static void addAllEnemyTankNum() {
Recorder.allEnemyTankNum++;
}
}
MyPanel
package tankgame06;
//面板
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
////為了監聽鍵盤事件,實現KeyListener
//為了讓Panel不停的重繪子彈,需要將MyPanel實現Runnable ,當做一個線程使用
public class MyPanel extends JPanel implements KeyListener, Runnable {
Hero hero = null;//定義我的坦克
Vector<EnemyTank> enemyTanks = new Vector<>();//定義敵人坦克
//定義一個Vector ,用於存放多個爆炸效果
//說明,當子彈擊中坦克時,加入一個Bomb對象到bombs
Vector<Bomb> bombs = new Vector<>();
int enemyTankSize = 5;//敵方坦克數量
//定義三張炸彈圖片,用於顯示爆炸效果
Image image1 = null;
Image image2 = null;
Image image3 = null;
public MyPanel(int key) {
hero = new Hero(800, 100);//初始化自己的坦克位置
switch (key){
case 1:
Recorder.loadRecord();
enemyTanks = EnemyTank.enemyTanks;
for (int i = 0; i < enemyTanks.size(); i++) {//初始化敵人的坦克位置
EnemyTank enemyTank = enemyTanks.get(i);
//啟動敵人坦克線程,讓他們動起來
new Thread(enemyTank).start();
}
break;
case 2:
for (int i = 0; i < enemyTankSize; i++) {//初始化敵人的坦克位置
EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
enemyTank.setDirect(2);//設置坦克方向
//啟動敵人坦克線程,讓他們動起來
new Thread(enemyTank).start();
enemyTanks.add(enemyTank);//加入敵方坦克集合
}
EnemyTank.setEnemyTanks(enemyTanks);//將enemyTanks 設置給enemyTank !!!
break;
}
// hero.setSpeed(5);
image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/(1).png"));
image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/(2).png"));
image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/(3).png"));
//圖片在被第一次使用時才真正載入
// 所以會出現第一次爆炸的圖程式找不到還沒載入好圖片導致這次爆炸效果缺失的情況。
//因此要提前自定義爆炸一次
// bombs.add(new Bomb(-100,-100));
}
public void showInfo(Graphics g) {
g.setColor(Color.BLACK);
Font font = new Font("宋體", Font.BOLD, 25);
g.setFont(font);
g.drawString("累積擊毀坦克", 1020, 30);
drawTank(1020, 60, g, 0, 1);
g.setColor(Color.BLACK);
g.drawString(Recorder.getAllEnemyTankNum() + "", 1080, 100);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//黑色背景
showInfo(g);
if (hero != null && hero.isLive) {//畫出hero坦克
drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 0);
}
//畫出hero發出的子彈
// if (hero.shot != null && hero.shot.isAlive == true) {
// g.fill3DRect(hero.shot.getX() - 1, hero.shot.getY() - 1, 3, 3, false);
// }
//將hero的子彈集合shots ,遍歷取出繪製
for (int i = 0; i < hero.shots.size(); i++) {
Shot shot = hero.shots.get(i);
if (shot != null && shot.isAlive) {
g.fill3DRect(shot.getX() - 1, shot.getY() - 1, 3, 3, false);
} else {//如果該shot對象已經無效,就從shots集合中拿掉
hero.shots.remove(shot);
}
}
for (int i = 0; i < bombs.size(); i++) {
//取出炸彈
Bomb bomb = bombs.get(i);
//根據當前這個bomb對象的life值去畫出對應的圖片
if (bomb.life > 6) {
g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);
} else if (bomb.life > 3) {
g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
} else {
g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
}
//讓這個炸彈的生命值減少
bomb.lifeDown();
//如果bomb life為0,就從bombs 的集合中刪除
if (bomb.life <= 0) {
bombs.remove(bomb);
}
}
//畫出敵人坦克
for (int i = 0; i < enemyTanks.size(); i++) {
//取出坦克
EnemyTank enemyTank = enemyTanks.get(i);
if (enemyTank.isLive) {//判斷敵方坦克是否存活
drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
//畫出 enemyTank所有子彈
for (int j = 0; j < enemyTank.shots.size(); j++) {
//取出子彈
Shot shot = enemyTank.shots.get(j);//繪製
if (shot.isAlive) { //isAlive = true
g.draw3DRect(shot.getX() - 1, shot.getY() - 1, 3, 3, false);
} else {
//從Vector移除
enemyTank.shots.remove(shot);
}
}
}
}
}
/**
* @param x 坦克左上角x坐標
* @param y 坦克左上角y坐標
* @param g 畫筆
* @param direct 坦克方向(上下左右)
* @param type 坦克類型
*/
public void drawTank(int x, int y, Graphics g, int direct, int type) {
switch (type) {
case 0://我們的坦克
g.setColor(Color.cyan);
break;
case 1://敵人的坦克
g.setColor(Color.yellow);
break;
}
//根據坦克方向,繪製坦克
switch (direct) {
case 0://向上
g.fill3DRect(x, y, 10, 60, false);//畫出坦克左邊輪子
g.fill3DRect(x + 30, y, 10, 60, false);//畫出坦克右邊輪子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//畫出坦克蓋子
g.fillOval(x + 10, y + 20, 20, 20);//畫出圓形蓋子
g.drawLine(x + 20, y + 30, x + 20, y);//畫出炮筒
break;
case 1://右
g.fill3DRect(x - 10, y + 10, 60, 10, false);//畫出坦克左邊輪子
g.fill3DRect(x - 10, y + 40, 60, 10, false);//畫出坦克右邊輪子
g.fill3DRect(x, y + 20, 40, 20, false);//畫出坦克蓋子
g.fillOval(x + 10, y + 20, 20, 20);//畫出圓形蓋子
g.drawLine(x + 20, y + 30, x + 50, y + 30);//畫出炮筒
break;
case 2://下
g.fill3DRect(x, y, 10, 60, false);//畫出坦克左邊輪子
g.fill3DRect(x + 30, y, 10, 60, false);//畫出坦克右邊輪子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//畫出坦克蓋子
g.fillOval(x + 10, y + 20, 20, 20);//畫出圓形蓋子
g.drawLine(x + 20, y + 30, x + 20, y + 60);//畫出炮筒
break;
case 3://左
g.fill3DRect(x - 10, y + 10, 60, 10, false);//畫出坦克左邊輪子
g.fill3DRect(x - 10, y + 40, 60, 10, false);//畫出坦克右邊輪子
g.fill3DRect(x, y + 20, 40, 20, false);//畫出坦克蓋子
g.fillOval(x + 10, y + 20, 20, 20);//畫出圓形蓋子
g.drawLine(x + 20, y + 30, x - 10, y + 30);//畫出炮筒
break;
}
}
//如果我們的坦克可以發射多個子彈
//在判斷我方子彈是否擊中敵人坦克時,就需要把我們的子彈集合中
//所有的子彈,都取出和敵人的所有坦克,進行判斷
public void hitEnemyTank() {
//遍歷我們的子彈
for (int j = 0; j < hero.shots.size(); j++) {
Shot shot = hero.shots.get(j);
if (shot != null && shot.isAlive) {
//遍歷敵人所有坦克,實時判斷坦克是否被擊中
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
hitTank(shot, enemyTank);
}
}
}
}
//編寫方法,判斷我子彈是否擊中對方坦克
//什麼時候判斷我方的子彈是否擊中對方坦克 ?run方法
//enemyTank可以是Hero,可以是EnemyTank
public void hitTank(Shot s, Tank enemyTank) {
switch (enemyTank.getDirect()) {
case 0://上
case 2://下
if (s.getX() > enemyTank.getX() && s.getX() < enemyTank.getX() + 40 &&
s.getY() > enemyTank.getY() && s.getY() < enemyTank.getY() + 60) {
s.isAlive = false;//設置子彈為死亡狀態
enemyTank.isLive = false;//設置該坦克為死亡狀態
//創建Bomb對象,加入到bombs集合
Bomb bomb = new Bomb(enemyTank.getX() - 10, enemyTank.getY());
bombs.add(bomb);
//當我的子彈擊中敵人坦克後,將enemyTank 從lector拿掉
enemyTanks.remove(enemyTank);//移除該坦克
if (enemyTank instanceof EnemyTank) {
Recorder.addAllEnemyTankNum();//增加摧毀坦克數量
}
}
break;
case 1:
case 3:
if (s.getX() > enemyTank.getX() - 10 && s.getX() < enemyTank.getX() + 50 &&
s.getY() > enemyTank.getY() + 10 && s.getY() < enemyTank.getY() + 50) {
s.isAlive = false;
enemyTank.isLive = false;
//創建Bomb對象,加入到bombs集合
Bomb bomb = new Bomb(enemyTank.getX() - 10, enemyTank.getY());
bombs.add(bomb);
//當我的子彈擊中敵人坦克後,將enemyTank 從lector拿掉
enemyTanks.remove(enemyTank);//移除該坦克
if (enemyTank instanceof EnemyTank) {
Recorder.addAllEnemyTankNum();//增加摧毀坦克數量
}
}
break;
}
}
//判斷敵方的子彈是否擊中我方坦克
public void hitHeroTank() {
//遍歷敵方子彈
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
for (int j = 0; j < enemyTank.shots.size(); j++) {
Shot shot = enemyTank.shots.get(j);
hitTank(shot, hero);
}
}
}
@Override
public void keyTyped(KeyEvent e) {
}
//處理WDSA鍵按下情況
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {
//改變坦克方向
hero.setDirect(0);
//修改坦克坐標
hero.moveUp();
} else if (e.getKeyCode() == KeyEvent.VK_D) {
hero.setDirect(1);
hero.moveRight();
} else if (e.getKeyCode() == KeyEvent.VK_S) {
hero.setDirect(2);
hero.moveDown();
} else if (e.getKeyCode() == KeyEvent.VK_A) {
hero.setDirect(3);
hero.moveLeft();
}
if (e.getKeyCode() == KeyEvent.VK_J) {
//判斷hero的子彈是否銷毀,發射一顆子彈
// if (hero.shot == null || !hero.shot.isAlive) {
// hero.shotEnemyTank();
// }
//發射多顆子彈
hero.shotEnemyTank();
}
// this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);//每停0.1s執行一次
} catch (InterruptedException e) {
e.printStackTrace();
}
hitEnemyTank();//檢測子彈是否打中坦克
hitHeroTank();
this.repaint();//刷新面板
}
}
}
HspTankGame06
package tankgame06;
//窗體
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;
public class HspTankGame06 extends JFrame {
MyPanel mp=null;
public static void main(String[] args) {
new HspTankGame06();
}
public HspTankGame06() {
Scanner in = new Scanner(System.in);
int key;
while (true){
System.out.println("是否繼續游戲?(1.是 2.否)");
String s = in.next();
key = Integer.parseInt(s);
if (key==1||key==2){
break;
}
}
mp=new MyPanel(key);
new Thread(mp).start();//另外開一線程一直刷新面板內容和麵板中一些需要同時執行的程式
this.add(mp);
this.setSize(1200,789);
this.addKeyListener(mp);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
//在JFrame中增加相應關閉視窗的處理
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
Recorder.keepRecord();
}
});
}
}
坦克大戰0.7版
增加功能
-
游戲開始時,播放經典的坦克大戰音樂(AePlayWave.java此類可直接使用成品,不自己寫)(需要準備wav格式音樂文件)
-
修正下文件存儲位置(保存到src目錄下)
-
處理文件相關異常=》提升程式健壯性(處理讀取游戲信息文件不存在出現的異常)
代碼
Tank
package tankgame07;
//坦克
public class Tank {
//坦克左上角坐標
private int x;
private int y;
private int direct;//坦克方向 0上 1右 2下 3左
boolean isLive = true;//是否存活
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
private int speed = 2;//坦克速度
//上右下左移動方法
public void moveUp() {
if (y - speed > 0) {
y -= speed;
}
}
public void moveDown() {
if (y + 60 + speed < 750) {
y += speed;
}
}
public void moveLeft() {
if (x - 10 - speed > 0) {
x -= speed;
}
}
public void moveRight() {
if (x - 10 + 60 + speed < 1000) {
x += speed;
}
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
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;
}
}
Hero
package tankgame07;
import java.util.Vector;
//玩家坦克
public class Hero extends Tank {
Shot shot = null;//射擊行為
//發射多個子彈
Vector<Shot> shots = new Vector<>();
public Hero(int x, int y) {
super(x, y);
}
//射擊
public void shotEnemyTank() {
//發多顆子彈怎麼辦,控制在我們的面板上,最多只有5顆
if (shots.size()==5){
return;
}
switch (getDirect()) {
case 0://上
shot = new Shot(getX() + 20, getY(), 0);
break;
case 1://右邊
shot = new Shot(getX() + 50, getY() + 30, 1);
break;
case 2:
shot = new Shot(getX() + 20, getY() + 60, 2);
break;
case 3:
shot = new Shot(getX() - 10, getY() + 30, 3);
break;
}
//把新創建的shot放入到shots
shots.add(shot);
//啟動我們的Shot線程
new Thread(shot).start();
}
}
EnemyTank
package tankgame07;
import java.util.Vector;
//敵方坦克
public class EnemyTank extends Tank implements Runnable {
//在敵人坦克類,使用Vector保存多個Shot
Vector<Shot> shots = new Vector<>();
static Vector<EnemyTank> enemyTanks = new Vector<>();//存放所有敵人坦克信息
public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
EnemyTank.enemyTanks = enemyTanks;
}
//編寫方法,判斷當前的這個敵人坦克,是否和 enemyTanks 中的其他坦克發生的重疊或者碰撞
public boolean isTouchEnemyTank() {
switch (this.getDirect()) {
case 0:
//讓當前敵人坦克和其它所有的敵人坦克比較
for (int i = 0; i < enemyTanks.size(); i++) {
//從vector中取出一個敵人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比較
if (enemyTank == this) {
continue;
}
//1.如果敵人坦克是上/下x的範圍[enemyTank.getX(),enemyTank.getX() +40]
// y的範圍 [enemyTank.getY(),enemyTank.getY() +60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
//2。當前坦克左上角的坐標[this.getX(),this.getY()]
if (this.getX() >= enemyTank.getX() && this.getX() <= enemyTank.getX() + 40 && this.getY() >= enemyTank.getY() && this.getY() <= enemyTank.getY() + 60) {
return true;
}
//3.當前坦克右上角的坐標[this.getX() +40, this.getY()]
if (this.getX() + 40 >= enemyTank.getX() && this.getX() + 40 <= enemyTank.getX() + 40 && this.getY() >= enemyTank.getY() && this.getY() <= enemyTank.getY() + 60) {
return true;
}
}
//如果敵人坦克是 右/左
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
//2。當前坦克左上角的坐標[this.getX(),this.getY()]
if (this.getX() >= enemyTank.getX() - 10 && this.getX() <= enemyTank.getX() + 50 && this.getY() >= enemyTank.getY() + 10 && this.getY() <= enemyTank.getY() + 50) {
return true;
}
//3.當前坦克右上角的坐標[this.getX() +40, this.getY()]
if (this.getX() + 40 >= enemyTank.getX() - 10 && this.getX() + 40 <= enemyTank.getX() + 50 && this.getY() >= enemyTank.getY() + 10 && this.getY() <= enemyTank.getY() + 50) {
return true;
}
}
}
break;
case 1:
//讓當前敵人坦克和其它所有的敵人坦克比較
for (int i = 0; i < enemyTanks.size(); i++) {
//從vector中取出一個敵人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比較
if (enemyTank == this) {
continue;
}
//1.如果敵人坦克是上/下
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
//2。當前坦克右上角的坐標[this.getX()+50,this.getY()+10]
if (this.getX()+50 >= enemyTank.getX() && this.getX()+50 <= enemyTank.getX() + 40 && this.getY()+10 >= enemyTank.getY() && this.getY()+10 <= enemyTank.getY() + 60) {
return true;
}
//3.當前坦克右下角的坐標[this.getX() +50, this.getY()+50]
if (this.getX() + 50 >= enemyTank.getX() && this.getX() + 50 <= enemyTank.getX() + 40 && this.getY()+50 >= enemyTank.getY() && this.getY()+50 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敵人坦克是 右/左
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
//2。當前坦克右上角的坐標[this.getX()+50,this.getY()+10]
if (this.getX()+50 >= enemyTank.getX() - 10 && this.getX()+50 <= enemyTank.getX() + 50 && this.getY()+10 >= enemyTank.getY() + 10 && this.getY()+10 <= enemyTank.getY() + 50) {
return true;
}
//3.當前坦克右下角的坐標[this.getX() +50, this.getY()+50]
if (this.getX() + 50 >= enemyTank.getX() - 10 && this.getX() + 50 <= enemyTank.getX() + 50 && this.getY()+50 >= enemyTank.getY() + 10 && this.getY()+50 <= enemyTank.getY() + 50) {
return true;
}
}
}
break;
case 2:
//讓當前敵人坦克和其它所有的敵人坦克比較
for (int i = 0; i < enemyTanks.size(); i++) {
//從vector中取出一個敵人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比較
if (enemyTank == this) {
continue;
}
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
//2。當前坦克左下角的坐標[this.getX(),this.getY()+60]
if (this.getX() >= enemyTank.getX() && this.getX() <= enemyTank.getX() + 40 && this.getY()+60 >= enemyTank.getY() && this.getY()+60 <= enemyTank.getY() + 60) {
return true;
}
//3.當前坦克右下角的坐標[this.getX() +40, this.getY()+60]
if (this.getX() + 40 >= enemyTank.getX() && this.getX() + 40 <= enemyTank.getX() + 40 && this.getY()+60 >= enemyTank.getY() && this.getY()+60 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敵人坦克是 右/左
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
//2。當前坦克左下角的坐標[this.getX(),this.getY()+60]
if (this.getX() >= enemyTank.getX() - 10 && this.getX() <= enemyTank.getX() + 50 && this.getY()+60 >= enemyTank.getY() + 10 && this.getY()+60 <= enemyTank.getY() + 50) {
return true;
}
//3.當前坦克右下角的坐標[this.getX() +40, this.getY()+60]
if (this.getX() + 40 >= enemyTank.getX() - 10 && this.getX() + 40 <= enemyTank.getX() + 50 && this.getY()+60 >= enemyTank.getY() + 10 && this.getY()+60 <= enemyTank.getY() + 50) {
return true;
}
}
}
break;
case 3:
//讓當前敵人坦克和其它所有的敵人坦克比較
for (int i = 0; i < enemyTanks.size(); i++) {
//從vector中取出一個敵人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比較
if (enemyTank == this) {
continue;
}
//1.如果敵人坦克是上/下
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
//2。當前坦克左上角的坐標[this.getX()-10,this.getY()+10]
if (this.getX()-10 >= enemyTank.getX() && this.getX()-10 <= enemyTank.getX() + 40 && this.getY()+10 >= enemyTank.getY() && this.getY()+10 <= enemyTank.getY() + 60) {
return true;
}
//3.當前坦克左下角的坐標[this.getX()-10, this.getY()+50]
if (this.getX() -10 >= enemyTank.getX() && this.getX() -10 <= enemyTank.getX() + 40 && this.getY()+50 >= enemyTank.getY() && this.getY()+50 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敵人坦克是 右/左
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
//2。當前坦克左上角的坐標[this.getX()-10,this.getY()+10]
if (this.getX()-10 >= enemyTank.getX() - 10 && this.getX()-10 <= enemyTank.getX() + 50 && this.getY()+10 >= enemyTank.getY() + 10 && this.getY()+10 <= enemyTank.getY() + 50) {
return true;
}
//3.當前坦克左下角的坐標[this.getX()-10, this.getY()+50]
if (this.getX() -10 >= enemyTank.getX() - 10 && this.getX() -10 <= enemyTank.getX() + 50 && this.getY()+50 >= enemyTank.getY() + 10 && this.getY()+50 <= enemyTank.getY() + 50) {
return true;
}
}
}
break;
}
return false;
}
public EnemyTank(int x, int y) {
super(x, y);
}
@Override
public void run() {
while (true) {
//這裡我們判斷如果shots size() =0,創建一顆子彈,放入到
//shots集合,並啟動
if (isLive && shots.size() <= 5) {//敵人同時只能存在五個子彈
Shot s = null;
switch (getDirect()) {
case 0://上
s = new Shot(getX() + 20, getY(), 0);
break;
case 1://右邊
s = new Shot(getX() + 50, getY() + 30, 1);
break;
case 2:
s = new Shot(getX() + 20, getY() + 60, 2);
break;
case 3:
s = new Shot(getX() - 10, getY() + 30, 3);
break;
}
shots.add(s);
new Thread(s).start();
}
//根據坦克方向繼續移動
for (int i = 0; i < 30; i++) {
if (isTouchEnemyTank()){//如果有碰撞
continue;
}
switch (getDirect()) {
case 0://向上
//讓坦克保持一個方向,走30步
moveUp();
break;
case 1://向右
moveRight();
break;
case 2://向下
moveDown();
break;
case 3://向左
moveLeft();
break;
}
//休眠50毫秒
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//然後隨機的改變坦克方向 0-3
setDirect((int) (Math.random() * 4));
if (!isLive) {
break;
}
}
}
}
Shot
package tankgame07;
//射擊事件
public class Shot implements Runnable {
private int x;
private int y;
private int direct;//方向 0上 1右 2下 3左
private int speed = 10;//子彈速度
boolean isAlive = true;
public Shot(int x, int y, int direct) {
this.x = x;
this.y = y;
this.direct = direct;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public void run() {
while (true) {
//休眠
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//根據方向移動
switch (direct) {
case 0:
y -= speed;
break;
case 1:
x += speed;
break;
case 2:
y += speed;
break;
case 3:
x -= speed;
break;
}
// System.out.println("子彈坐標(" + x + "," + y + ")");
//當子彈移動到面板的邊界時,就應該銷毀(把啟動的子彈的線程銷毀)
// 當子彈碰到敵人坦克時,也應該結束線程
if (x < 0 || x >= 1000 || y < 0 || y >= 750 || isAlive == false) {
// System.out.println("子彈線程退出");
isAlive = false;
break;
}
}
}
}
Bomb
package tankgame07;
//爆炸事件
public class Bomb {
int x, y;//炸彈的坐標
int life = 9;//炸彈的生命周期
boolean isLive = true;//是否還存活
public Bomb(int x, int y) {
this.x = x;
this.y = y;
}
//減少爆炸效果的生命值
public void lifeDown() {//配合出現圖片的爆炸效果
if (life > 0) {
life--;
} else {
isLive = false;
}
}
}
Recorder
package tankgame07;
//記錄信息,與文件交互
import java.io.*;
import java.util.Vector;
public class Recorder {
//定義變數,記錄我方擊毀敵人坦克數
private static int allEnemyTankNum = 0;//定義IO對象,準備寫數據到文件中
// private static BufferedWriter bw = null;
private static String recordFile = "src\\myRecord.txt";
public static String getRecordFile() {
return recordFile;
}
//保存游戲數據
//對keepRecord進行升級,保存敵人坦克的坐標和方向
public static void keepRecord() {
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(recordFile));
bw.write(allEnemyTankNum + "\n");
Vector<EnemyTank> enemyTanks = EnemyTank.enemyTanks;
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (enemyTank.isLive) {
String record = enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect();
bw.write(record + "\n");
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//讀取文件數據
public static void loadRecord() {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(recordFile));
allEnemyTankNum = Integer.parseInt(br.readLine());
String line = null;
while ((line = br.readLine()) != null) {
String[] s = line.split(" ");
EnemyTank enemyTank = new EnemyTank(Integer.parseInt(s[0]), Integer.parseInt(s[1]));
enemyTank.setDirect(Integer.parseInt(s[2]));
EnemyTank.enemyTanks.add(enemyTank);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static int getAllEnemyTankNum() {
return allEnemyTankNum;
}
public static void setAllEnemyTankNum(int allEnemyTankNum) {
Recorder.allEnemyTankNum = allEnemyTankNum;
}
//當我方坦克擊毀一個敵人坦克,就應當allEnemyTankNum++
public static void addAllEnemyTankNum() {
Recorder.allEnemyTankNum++;
}
}
MyPanel
package tankgame07;
//面板
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.FileWriter;
import java.util.Vector;
////為了監聽鍵盤事件,實現KeyListener
//為了讓Panel不停的重繪子彈,需要將MyPanel實現Runnable ,當做一個線程使用
public class MyPanel extends JPanel implements KeyListener, Runnable {
Hero hero = null;//定義我的坦克
Vector<EnemyTank> enemyTanks = new Vector<>();//定義敵人坦克
//定義一個Vector ,用於存放多個爆炸效果
//說明,當子彈擊中坦克時,加入一個Bomb對象到bombs
Vector<Bomb> bombs = new Vector<>();
int enemyTankSize = 5;//敵方最開始坦克數量
//定義三張炸彈圖片,用於顯示爆炸效果
Image image1 = null;
Image image2 = null;
Image image3 = null;
public MyPanel(int key) {
hero = new Hero(800, 100);//初始化自己的坦克位置
//判斷游戲信息文件是否存在
File file = new File(Recorder.getRecordFile());
if (!file.exists()) {
System.out.println("文件不存在");
key = 2;
}
switch (key) {
case 1:
Recorder.loadRecord();
enemyTanks = EnemyTank.enemyTanks;
for (int i = 0; i < enemyTanks.size(); i++) {//初始化敵人的坦克位置
EnemyTank enemyTank = enemyTanks.get(i);
//啟動敵人坦克線程,讓他們動起來
new Thread(enemyTank).start();
}
break;
case 2:
for (int i = 0; i < enemyTankSize; i++) {//初始化敵人的坦克位置
EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
enemyTank.setDirect(2);//設置坦克方向
//啟動敵人坦克線程,讓他們動起來
new Thread(enemyTank).start();
enemyTanks.add(enemyTank);//加入敵方坦克集合
}
EnemyTank.setEnemyTanks(enemyTanks);//將enemyTanks 設置給enemyTank !!!
break;
}
// hero.setSpeed(5);
image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/(1).png"));
image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/(2).png"));
image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/(3).png"));
//播放音樂
new AePlayWave("src/坦克大戰_BGM.wav").start();
}
public void showInfo(Graphics g) {
g.setColor(Color.BLACK);
Font font = new Font("宋體", Font.BOLD, 25);
g.setFont(font);
g.drawString("累積擊毀坦克", 1020, 30);
drawTank(1020, 60, g, 0, 1);
g.setColor(Color.BLACK);
g.drawString(Recorder.getAllEnemyTankNum() + "", 1080, 100);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//黑色背景
showInfo(g);
if (hero != null && hero.isLive) {//畫出hero坦克
drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 0);
}
//畫出hero發出的子彈
// if (hero.shot != null && hero.shot.isAlive == true) {
// g.fill3DRect(hero.shot.getX() - 1, hero.shot.getY() - 1, 3, 3, false);
// }
//將hero的子彈集合shots ,遍歷取出繪製
for (int i = 0; i < hero.shots.size(); i++) {
Shot shot = hero.shots.get(i);
if (shot != null && shot.isAlive) {
g.fill3DRect(shot.getX() - 1, shot.getY() - 1, 3, 3, false);
} else {//如果該shot對象已經無效,就從shots集合中拿掉
hero.shots.remove(shot);
}
}
for (int i = 0; i < bombs.size(); i++) {
//取出炸彈
Bomb bomb = bombs.get(i);
//根據當前這個bomb對象的life值去畫出對應的圖片
if (bomb.life > 6) {
g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);
} else if (bomb.life > 3) {
g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
} else {
g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
}
//讓這個炸彈的生命值減少
bomb.lifeDown();
//如果bomb life為0,就從bombs 的集合中刪除
if (bomb.life <= 0) {
bombs.remove(bomb);
}
}
//畫出敵人坦克
for (int i = 0; i < enemyTanks.size(); i++) {
//取出坦克
EnemyTank enemyTank = enemyTanks.get(i);
if (enemyTank.isLive) {//判斷敵方坦克是否存活
drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
//畫出 enemyTank所有子彈
for (int j = 0; j < enemyTank.shots.size(); j++) {
//取出子彈
Shot shot = enemyTank.shots.get(j);//繪製
if (shot.isAlive) { //isAlive = true
g.draw3DRect(shot.getX() - 1, shot.getY() - 1, 3, 3, false);
} else {
//從Vector移除
enemyTank.shots.remove(shot);
}
}
}
}
}
/**
* @param x 坦克左上角x坐標
* @param y 坦克左上角y坐標
* @param g 畫筆
* @param direct 坦克方向(上下左右)
* @param type 坦克類型
*/
public void drawTank(int x, int y, Graphics g, int direct, int type) {
switch (type) {
case 0://我們的坦克
g.setColor(Color.cyan);
break;
case 1://敵人的坦克
g.setColor(Color.yellow);
break;
}
//根據坦克方向,繪製坦克
switch (direct) {
case 0://向上
g.fill3DRect(x, y, 10, 60, false);//畫出坦克左邊輪子
g.fill3DRect(x + 30, y, 10, 60, false);//畫出坦克右邊輪子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//畫出坦克蓋子
g.fillOval(x + 10, y + 20, 20, 20);//畫出圓形蓋子
g.drawLine(x + 20, y + 30, x + 20, y);//畫出炮筒
break;
case 1://右
g.fill3DRect(x - 10, y + 10, 60, 10, false);//畫出坦克左邊輪子
g.fill3DRect(x - 10, y + 40, 60, 10, false);//畫出坦克右邊輪子
g.fill3DRect(x, y + 20, 40, 20, false);//畫出坦克蓋子
g.fillOval(x + 10, y + 20, 20, 20);//畫出圓形蓋子
g.drawLine(x + 20, y + 30, x + 50, y + 30);//畫出炮筒
break;
case 2://下
g.fill3DRect(x, y, 10, 60, false);//畫出坦克左邊輪子
g.fill3DRect(x + 30, y, 10, 60, false);//畫出坦克右邊輪子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//畫出坦克蓋子
g.fillOval(x + 10, y + 20, 20, 20);//畫出圓形蓋子
g.drawLine(x + 20, y + 30, x + 20, y + 60);//畫出炮筒
break;
case 3://左
g.fill3DRect(x - 10, y + 10, 60, 10, false);//畫出坦克左邊輪子
g.fill3DRect(x - 10, y + 40, 60, 10, false);//畫出坦克右邊輪子
g.fill3DRect(x, y + 20, 40, 20, false);//畫出坦克蓋子
g.fillOval(x + 10, y + 20, 20, 20);//畫出圓形蓋子
g.drawLine(x + 20, y + 30, x - 10, y + 30);//畫出炮筒
break;
}
}
//如果我們的坦克可以發射多個子彈
//在判斷我方子彈是否擊中敵人坦克時,就需要把我們的子彈集合中
//所有的子彈,都取出和敵人的所有坦克,進行判斷
public void hitEnemyTank() {
//遍歷我們的子彈
for (int j = 0; j < hero.shots.size(); j++) {
Shot shot = hero.shots.get(j);
if (shot != null && shot.isAlive) {
//遍歷敵人所有坦克,實時判斷坦克是否被擊中
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
hitTank(shot, enemyTank);
}
}
}
}
//編寫方法,判斷我子彈是否擊中對方坦克
//什麼時候判斷我方的子彈是否擊中對方坦克 ?run方法
//enemyTank可以是Hero,可以是EnemyTank
public void hitTank(Shot s, Tank enemyTank) {
switch (enemyTank.getDirect()) {
case 0://上
case 2://下
if (s.getX() > enemyTank.getX() && s.getX() < enemyTank.getX() + 40 &&
s.getY() > enemyTank.getY() && s.getY() < enemyTank.getY() + 60) {
s.isAlive = false;//設置子彈為死亡狀態
enemyTank.isLive = false;//設置該坦克為死亡狀態
//創建Bomb對象,加入到bombs集合
Bomb bomb = new Bomb(enemyTank.getX() - 10, enemyTank.getY());
bombs.add(bomb);
//當我的子彈擊中敵人坦克後,將enemyTank 從lector拿掉
enemyTanks.remove(enemyTank);//移除該坦克
if (enemyTank instanceof EnemyTank) {
Recorder.addAllEnemyTankNum();//增加摧毀坦克數量
}
}
break;
case 1:
case 3:
if (s.getX() > enemyTank.getX() - 10 && s.getX() < enemyTank.getX() + 50 &&
s.getY() > enemyTank.getY() + 10 && s.getY() < enemyTank.getY() + 50) {
s.isAlive = false;