JavaGUI-坦克大戰04 7.線程的應用03 7.3坦克大戰4.0版 7.3.4功能3:敵方坦克自由移動 功能3:讓敵人的坦克也可以自由隨機地上下左右移動 思路: 因為要求敵人的坦克自由移動,因此需要將敵人坦克當做線程使用,EnemyTank類實現Runnable介面 線程的run方法的具體操作 ...
JavaGUI-坦克大戰04
7.線程的應用03
7.3坦克大戰4.0版
7.3.4功能3:敵方坦克自由移動
功能3:讓敵人的坦克也可以自由隨機地上下左右移動
思路:
- 因為要求敵人的坦克自由移動,因此需要將敵人坦克當做線程使用,EnemyTank類實現Runnable介面
- 線程的run方法的具體操作為:根據當前的方向繼續移動敵坦,然後改變敵坦移動方向,再繼續移動,如此不斷迴圈。break的條件是當前的敵人坦克被擊中,即enemy.isLive == false。
- 在MyPanel類中,每創建一個敵人坦克對象就啟動一個線程。
EnemyTank:
package li.TankGame.version04;
import java.util.Vector;
public class EnemyTank extends Tank implements Runnable {
//在敵人坦克類使用Vector保存多個Shot
Vector<Shot> shots = new Vector<>();
boolean isLive = true;
public EnemyTank(int x, int y) {
super(x, y);
}
@Override
public void run() {
while (true) {
//根據坦克的方法來繼續移動
switch (getDirect()) {
case 0://上
//讓坦克保持一個方向走30步
for (int i = 0; i < 100; i++) {
moveUp();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 1://右
//讓坦克保持一個方向走30步
for (int i = 0; i < 100; i++) {
moveRight();//走一步
try {
Thread.sleep(50);//每走一步就休眠50毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 2://下
for (int i = 0; i < 100; i++) {
moveDown();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 3://左
for (int i = 0; i < 100; i++) {
moveLeft();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
}
//隨機地改變坦克的方向 0-3
setDirect((int) (Math.random() * 4));//[0,4)的取整
//如果被擊中了,就退出線程
if (!isLive) {
break;//退出線程
}
}
}
}
MyPanel:line 46-47
7.3.5功能4: 控制坦克移動範圍
如圖,坦克的繪圖以圖案的左上方坐標為參考。
在向上時,坦克的縱坐標限製為y>0,向下時,y+60<面板高度;向左時,x>0,向右時,x+60<面板寬度
EnemyTank:控制敵人的坦克不出界
package li.TankGame.version04;
import java.util.Vector;
public class EnemyTank extends Tank implements Runnable {
//在敵人坦克類使用Vector保存多個Shot
Vector<Shot> shots = new Vector<>();
boolean isLive = true;
public EnemyTank(int x, int y) {
super(x, y);
}
@Override
public void run() {
while (true) {
//根據坦克的方法來繼續移動
switch (getDirect()) {
case 0://上
//讓坦克保持一個方向走30步
for (int i = 0; i < 100; i++) {
if (getY() > 0) {
moveUp();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 1://右
//讓坦克保持一個方向走30步
for (int i = 0; i < 100; i++) {
if (getX() + 60 < 700) {//700為面板寬度
moveRight();//走一步
}
try {
Thread.sleep(50);//每走一步就休眠50毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 2://下
for (int i = 0; i < 100; i++) {
if (getY() + 60 < 550) {//550為面板寬度
moveDown();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 3://左
for (int i = 0; i < 100; i++) {
if (getX() > 0) {
moveLeft();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
}
//隨機地改變坦克的方向 0-3
setDirect((int) (Math.random() * 4));//[0,4)的取整
//如果被擊中了,就退出線程
if (!isLive) {
break;//退出線程
}
}
}
}
修改MyPanel類中的keyPressed方法,使我方坦克也不能走出邊界:
//控制方向--處理 WSAD 鍵按下的情況
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {//按下W鍵-向上
//改變坦克的方向
hero.setDirect(0);
//修改坦克的坐標
if (hero.getY() > 0) {//向上
hero.moveUp();
}
} else if (e.getKeyCode() == KeyEvent.VK_D) {//按下D鍵-向右
hero.setDirect(1);
if (hero.getX() + 60 < 750) {//向右
hero.moveRight();
}
} else if (e.getKeyCode() == KeyEvent.VK_S) {//按下S鍵-向下
hero.setDirect(2);
if (hero.getY() + 60 < 550) {//向下
hero.moveDown();
}
} else if (e.getKeyCode() == KeyEvent.VK_A) {//按下A鍵-向左
hero.setDirect(3);
if (hero.getX() > 0) {//向左
hero.moveLeft();
}
}
//如果用戶按下j鍵,hero就發射子彈
if (e.getKeyCode() == KeyEvent.VK_J) {
hero.shotEnemyTank();
}
//讓面板重繪
this.repaint();
}