坦克大战游戏增强版:防重叠、存档与音效实现
功能增强概述
本版本在原有坦克大战基础上,新增以下核心功能:
- 防止敌方坦克相互重叠移动
- 持久化玩家总战绩(累计击毁敌方坦克数量)
- 退出时保存敌方坦克位置与朝向
- 支持新游戏或继续上局
- 启动时播放经典背景音乐
- 增强文件读写异常处理能力
关键类设计
Bomb 爆炸效果管理
public class Explosion {
int x, y;
int lifeCycle = 9;
boolean active = true;
public Explosion(int x, int y) {
this.x = x;
this.y = y;
}
public void decay() {
if (lifeCycle > 0) {
lifeCycle--;
} else {
active = false;
}
}
}
EnemyTank 敌方坦克逻辑
public class EnemyTank extends Tank implements Runnable {
private List<Bullet> bullets = new ArrayList<>();
private List<EnemyTank> allEnemies = new ArrayList<>();
private boolean alive = true;
public void setAllEnemies(List<EnemyTank> enemies) {
this.allEnemies = enemies;
}
public boolean collidesWithOthers() {
Rectangle currentBounds = getBounds();
for (EnemyTank other : allEnemies) {
if (other != this && other.alive &&
currentBounds.intersects(other.getBounds())) {
return true;
}
}
return false;
}
private Rectangle getBounds() {
if (direction == 0 || direction == 2) {
return new Rectangle(x, y, 40, 60);
} else {
return new Rectangle(x, y, 60, 40);
}
}
@Override
public void run() {
while (alive) {
// 发射子弹逻辑
if (bullets.isEmpty()) {
Bullet bullet = createBullet();
bullets.add(bullet);
new Thread(bullet).start();
}
// 移动逻辑(避免碰撞)
for (int steps = 0; steps < 30; steps++) {
if (!canMove()) break;
moveStep();
try { Thread.sleep(50); } catch (InterruptedException e) { }
}
direction = (int)(Math.random() * 4);
}
}
private boolean canMove() {
switch (direction) {
case 0: return y > 0 && !collidesWithOthers();
case 1: return x + getWidth() < 1000 && !collidesWithOthers();
case 2: return y + getHeight() < 750 && !collidesWithOthers();
case 3: return x > 0 && !collidesWithOthers();
default: return false;
}
}
}
GameRecorder 存档系统
public class GameRecorder {
private static int totalKills = 0;
private static final String SAVE_FILE = "game_record.txt";
private static List<EnemyTank> enemyList;
public static void saveProgress() {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(SAVE_FILE))) {
writer.write(totalKills + "\n");
for (EnemyTank tank : enemyList) {
if (tank.isAlive()) {
writer.write(String.format("%d %d %d\n",
tank.getX(), tank.getY(), tank.getDirection()));
}
}
} catch (IOException e) {
System.err.println("保存失败: " + e.getMessage());
}
}
public static List<TankState> loadProgress() {
List<TankState> states = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(SAVE_FILE))) {
totalKills = Integer.parseInt(reader.readLine());
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(" ");
states.add(new TankState(
Integer.parseInt(parts[0]),
Integer.parseInt(parts[1]),
Integer.parseInt(parts[2])
));
}
} catch (IOException e) {
System.err.println("加载存档失败: " + e.getMessage());
}
return states;
}
}
AudioPlayer 音频播放器
public class AudioPlayer extends Thread {
private final String audioFile;
public AudioPlayer(String file) {
this.audioFile = file;
}
@Override
public void run() {
try {
AudioInputStream stream = AudioSystem.getAudioInputStream(new File(audioFile));
AudioFormat format = stream.getFormat();
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
byte[] buffer = new byte[512];
int bytesRead;
while ((bytesRead = stream.read(buffer)) != -1) {
line.write(buffer, 0, bytesRead);
}
line.drain();
line.close();
stream.close();
} catch (Exception e) {
System.err.println("音频播放错误: " + e.getMessage());
}
}
}
游戏主循环优化
通过分离渲染与逻辑线程,确保游戏流畅运行:
public class GamePanel extends JPanel implements KeyListener, Runnable {
// ... 初始化代码 ...
@Override
public void run() {
AudioPlayer player = new AudioPlayer("tank_music.wav");
player.start();
while (true) {
checkCollisions(); // 碰撞检测
updateExplosions(); // 更新爆炸效果
repaint(); // 重绘界面
try { Thread.sleep(100); } catch (InterruptedException e) { }
}
}
private void checkCollisions() {
// 玩家子弹 vs 敌人
if (playerBullet != null && playerBullet.isActive()) {
for (EnemyTank enemy : enemies) {
if (enemy.isAlive() && detectHit(playerBullet, enemy)) {
destroyTarget(enemy);
}
}
}
// 敌人子弹 vs 玩家
for (EnemyTank enemy : enemies) {
for (Bullet bullet : enemy.getBullets()) {
if (bullet.isActive() && detectHit(bullet, playerTank)) {
destroyTarget(playerTank);
}
}
}
}
}
