MinesweeperApp.java
2026/7/21 17:19:11 网站建设 项目流程

import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.metal.MetalLookAndFeel;

/**

  • 程序入口:设置系统外观并启动扫雷界面
    */
    public class MinesweeperApp {
    public static void main(String[] args) {
    try {
    UIManager.setLookAndFeel(new MetalLookAndFeel());
    } catch (Exception e) {
    e.printStackTrace();
    }
    SwingUtilities.invokeLater(() -> new MinesweeperUI().setVisible(true));
    }
    }
    三、项目三:星际射击游戏
    3.1 需求分析
    在扫雷的回合制基础上,升级为 实时动作游戏:玩家控制飞船,自动/手动发射子弹,消灭下落的敌人,支持粒子爆炸特效、暂停、难度梯度。

3.2 架构设计
采用 双 Timer 架构:

逻辑 Timer(16ms):更新实体位置、碰撞检测、生成敌人
渲染 Timer(16ms):触发 repaint(),与逻辑解耦
实体采用 抽象基类 + 匿名内部类 实现多态绘制。

3.3 程序界面
屏幕截图 2026-07-02 230114

屏幕截图 2026-07-02 230027

屏幕截图 2026-07-02 230012

3.4 完整代码
GameEntity.java
import java.awt.*;
import java.io.Serializable;

/**

  • 游戏实体基类:玩家、敌人、子弹都继承此类
    */
    public abstract class GameEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    protected double x, y;
    protected int width, height;
    protected double speedX, speedY;
    protected boolean alive = true;
    protected Color color;
    protected String type;

    public GameEntity(double x, double y, int width, int height, double speedX, double speedY, Color color, String type) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.speedX = speedX;
    this.speedY = speedY;
    this.color = color;
    this.type = type;
    }

    public void update() {
    x += speedX;
    y += speedY;
    }

    public Rectangle getBounds() {
    return new Rectangle((int)x, (int)y, width, height);
    }

    public boolean intersects(GameEntity other) {
    return getBounds().intersects(other.getBounds());
    }

    public abstract void draw(Graphics2D g2d);

    public double getX() { return x; }
    public double getY() { return y; }
    public int getWidth() { return width; }
    public int getHeight() { return height; }
    public boolean isAlive() { return alive; }
    public void setAlive(boolean alive) { this.alive = alive; }
    public String getType() { return type; }
    public void setX(double x) { this.x = x; }
    public void setY(double y) { this.y = y; }
    public void setSpeedX(double speedX) { this.speedX = speedX; }
    public void setSpeedY(double speedY) { this.speedY = speedY; }
    }
    ShootingGame.java
    import java.awt.*;
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Random;

/**

  • 射击游戏核心:管理所有实体、碰撞检测、分数、难度、存档
    */
    public class ShootingGame implements Serializable {
    private static final long serialVersionUID = 1L;

    public enum Difficulty { EASY, MEDIUM, HARD }

    private GameEntity player;
    private int playerLives = 3;
    private int maxLives = 3;

    private List enemies;
    private List bullets;
    private List particles;

    private boolean running = false;
    private boolean paused = false;
    private boolean gameOver = false;
    private int score = 0;
    private int killCount = 0;
    private int shotCount = 0;
    private int difficulty = 1;
    private String difficultyName = “简单”;

    private transient long startTime;
    private int elapsedTime = 0;

    private int enemySpawnTimer = 0;
    private int enemySpawnInterval = 60;
    private int enemySpeedBase = 2;
    private Random random = new Random();

    private int width = 600;
    private int height = 700;

    public void init(int width, int height, Difficulty diff) {
    this.width = width;
    this.height = height;
    this.difficulty = diff.ordinal() + 1;
    this.difficultyName = diff.name().equals(“EASY”) ? “简单” : diff.name().equals(“MEDIUM”) ? “中等” : “困难”;

    switch (diff) { case EASY: enemySpawnInterval = 80; enemySpeedBase = 1; maxLives = 5; break; case MEDIUM: enemySpawnInterval = 50; enemySpeedBase = 2; maxLives = 3; break; case HARD: enemySpawnInterval = 30; enemySpeedBase = 3; maxLives = 2; break; } playerLives = maxLives; score = 0; killCount = 0; shotCount = 0; elapsedTime = 0; gameOver = false; paused = false; player = new GameEntity(width / 2 - 20, height - 80, 40, 40, 0, 0, new Color(50, 130, 220), "player") { @Override public void draw(Graphics2D g2d) { g2d.setColor(color); int[] xs = {(int)x + width/2, (int)x, (int)x + width}; int[] ys = {(int)y, (int)y + height, (int)y + height}; g2d.fillPolygon(xs, ys, 3); g2d.setColor(Color.CYAN); g2d.fillOval((int)x + 15, (int)y + 20, 10, 10); } }; enemies = new ArrayList<>(); bullets = new ArrayList<>(); particles = new ArrayList<>(); running = true; startTime = System.currentTimeMillis();

    }

    public void update() {
    if (!running || paused || gameOver) return;

    elapsedTime = (int)((System.currentTimeMillis() - startTime) / 1000); player.update(); if (player.getX() < 0) player.setX(0); if (player.getX() > width - player.getWidth()) player.setX(width - player.getWidth()); enemySpawnTimer++; if (enemySpawnTimer >= enemySpawnInterval) { enemySpawnTimer = 0; spawnEnemy(); } Iterator<GameEntity> bit = bullets.iterator(); while (bit.hasNext()) { GameEntity b = bit.next(); b.update(); if (b.getY() < -10) b.setAlive(false); } Iterator<GameEntity> eit = enemies.iterator(); while (eit.hasNext()) { GameEntity e = eit.next(); e.update(); if (e.getY() > height) { e.setAlive(false); playerLives--; createExplosion(e.getX() + e.getWidth()/2, e.getY() + e.getHeight(), Color.RED); if (playerLives <= 0) { gameOver = true; running = false; } } } Iterator<GameEntity> pit = particles.iterator(); while (pit.hasNext()) { GameEntity p = pit.next(); p.update(); if (p.getY() > p.getY() + 50 || !p.isAlive()) pit.remove(); } for (GameEntity b : bullets) { if (!b.isAlive()) continue; for (GameEntity e : enemies) { if (!e.isAlive()) continue; if (b.intersects(e)) { b.setAlive(false); e.setAlive(false); score += 10; killCount++; createExplosion(e.getX() + e.getWidth()/2, e.getY() + e.getHeight()/2, e.color); break; } } } for (GameEntity e : enemies) { if (!e.isAlive()) continue; if (e.intersects(player)) { e.setAlive(false); playerLives--; createExplosion(player.getX() + 20, player.getY(), Color.ORANGE); if (playerLives <= 0) { gameOver = true; running = false; } } } bullets.removeIf(b -> !b.isAlive()); enemies.removeIf(e -> !e.isAlive());

    }

    private void spawnEnemy() {
    int w = 30 + random.nextInt(20);
    int h = 30 + random.nextInt(20);
    int ex = random.nextInt(width - w);
    int speed = enemySpeedBase + random.nextInt(2);
    Color[] colors = {Color.RED, Color.MAGENTA, Color.ORANGE, new Color(200, 50, 50)};
    Color c = colors[random.nextInt(colors.length)];

    GameEntity enemy = new GameEntity(ex, -h, w, h, 0, speed, c, "enemy") { @Override public void draw(Graphics2D g2d) { g2d.setColor(color); g2d.fillOval((int)x, (int)y, width, height); g2d.setColor(Color.WHITE); g2d.fillOval((int)x + 5, (int)y + 5, width - 10, height / 3); } }; enemies.add(enemy);

    }

    public void shoot() {
    if (!running || paused || gameOver) return;
    shotCount++;
    GameEntity bullet = new GameEntity(
    player.getX() + player.getWidth()/2 - 3,
    player.getY() - 10,
    6, 12, 0, -8, new Color(255, 220, 50), “bullet”
    ) {
    @Override
    public void draw(Graphics2D g2d) {
    g2d.setColor(color);
    g2d.fillRect((int)x, (int)y, width, height);
    g2d.setColor(Color.WHITE);
    g2d.fillRect((int)x + 2, (int)y, 2, 4);
    }
    };
    bullets.add(bullet);
    }

    public void movePlayer(int dx) {
    if (player != null) {
    player.setX(player.getX() + dx);
    }
    }

    public void setPlayerX(double x) {
    if (player != null) player.setX(x - player.getWidth()/2);
    }

    private void createExplosion(double cx, double cy, Color c) {
    for (int i = 0; i < 8; i++) {
    double angle = Math.random() * Math.PI * 2;
    double speed = 1 + Math.random() * 3;
    final double sx = Math.cos(angle) * speed;
    final double sy = Math.sin(angle) * speed;
    final Color pc = c;
    GameEntity p = new GameEntity(cx, cy, 4, 4, sx, sy, pc, “particle”) {
    private int life = 20;
    @Override
    public void update() {
    super.update();
    life–;
    if (life <= 0) setAlive(false);
    }
    @Override
    public void draw(Graphics2D g2d) {
    g2d.setColor(pc);
    g2d.fillOval((int)x, (int)y, width, height);
    }
    };
    particles.add§;
    }
    }

    public void draw(Graphics2D g2d) {
    g2d.setColor(new Color(20, 20, 40));
    g2d.fillRect(0, 0, width, height);

    g2d.setColor(new Color(255, 255, 255, 80)); for (int i = 0; i < 50; i++) { int sx = (i * 37 + 13) % width; int sy = (i * 23 + 7) % height; g2d.fillOval(sx, (sy + elapsedTime * 10) % height, 2, 2); } for (GameEntity p : particles) p.draw(g2d); for (GameEntity e : enemies) e.draw(g2d); for (GameEntity b : bullets) b.draw(g2d); if (player != null && playerLives > 0) player.draw(g2d); g2d.setColor(Color.WHITE); g2d.setFont(new Font("微软雅黑", Font.BOLD, 16)); g2d.drawString("分数: " + score, 15, 25); g2d.drawString("时间: " + elapsedTime + "秒", 150, 25); g2d.drawString("击杀: " + killCount, 280, 25); g2d.drawString("发射: " + shotCount, 400, 25); g2d.drawString("生命: ", 15, 50); for (int i = 0; i < maxLives; i++) { if (i < playerLives) { g2d.setColor(Color.RED); g2d.fillOval(60 + i * 20, 38, 12, 12); } else { g2d.setColor(Color.GRAY); g2d.drawOval(60 + i * 20, 38, 12, 12); } } g2d.setColor(Color.YELLOW); g2d.drawString("难度: " + difficultyName, width - 100, 25); if (gameOver) { g2d.setColor(new Color(0, 0, 0, 180)); g2d.fillRect(0, 0, width, height); g2d.setColor(Color.WHITE); g2d.setFont(new Font("微软雅黑", Font.BOLD, 40)); String msg = playerLives <= 0 ? "游戏结束" : "胜利"; int msgW = g2d.getFontMetrics().stringWidth(msg); g2d.drawString(msg, (width - msgW) / 2, height / 2 - 40); g2d.setFont(new Font("微软雅黑", Font.PLAIN, 20)); String info = "最终得分: " + score + " 击杀: " + killCount + " 用时: " + elapsedTime + "秒"; int infoW = g2d.getFontMetrics().stringWidth(info); g2d.drawString(info, (width - infoW) / 2, height / 2 + 10); g2d.setFont(new Font("微软雅黑", Font.PLAIN, 16)); String hint = "按 R 重新开始 或 空格 发射"; int hintW = g2d.getFontMetrics().stringWidth(hint); g2d.drawString(hint, (width - hintW) / 2, height / 2 + 50); } if (paused && !gameOver) { g2d.setColor(new Color(0, 0, 0, 120)); g2d.fillRect(0, 0, width, height); g2d.setColor(Color.YELLOW); g2d.setFont(new Font("微软雅黑", Font.BOLD, 36)); String msg = "暂 停"; int msgW = g2d.getFontMetrics().stringWidth(msg); g2d.drawString(msg, (width - msgW) / 2, height / 2); g2d.setFont(new Font("微软雅黑", Font.PLAIN, 16)); g2d.drawString("按 P 继续", (width - 60) / 2, height / 2 + 40); }

    }

    public boolean isRunning() { return running; }
    public boolean isPaused() { return paused; }
    public boolean isGameOver() { return gameOver; }
    public int getScore() { return score; }
    public int getKillCount() { return killCount; }
    public int getShotCount() { return shotCount; }
    public int getElapsedTime() { return elapsedTime; }
    public int getPlayerLives() { return playerLives; }
    public int getDifficulty() { return difficulty; }
    public String getDifficultyName() { return difficultyName; }
    public int getWidth() { return width; }
    public int getHeight() { return height; }

    public void setPaused(boolean paused) {
    this.paused = paused;
    if (!paused) {
    startTime = System.currentTimeMillis() - elapsedTime * 1000L;
    }
    }
    public void setRunning(boolean running) { this.running = running; }
    public void setGameOver(boolean gameOver) { this.gameOver = gameOver; }
    public void setScore(int score) { this.score = score; }
    public void setKillCount(int killCount) { this.killCount = killCount; }
    public void setShotCount(int shotCount) { this.shotCount = shotCount; }
    public void setElapsedTime(int elapsedTime) { this.elapsedTime = elapsedTime; }
    public void setPlayerLives(int playerLives) { this.playerLives = playerLives; }
    public void setDifficulty(int difficulty) { this.difficulty = difficulty; }
    public void setDifficultyName(String difficultyName) { this.difficultyName = difficultyName; }
    public void setStartTime(long startTime) { this.startTime = startTime; }

    public List getEnemies() { return enemies; }
    public List getBullets() { return bullets; }
    public List getParticles() { return particles; }
    public GameEntity getPlayer() { return player; }
    public void setPlayer(GameEntity player) { this.player = player; }
    public void setEnemies(List enemies) { this.enemies = enemies; }
    public void setBullets(List bullets) { this.bullets = bullets; }
    public void setParticles(List particles) { this.particles = particles; }
    public void setMaxLives(int maxLives) { this.maxLives = maxLives; }
    public int getMaxLives() { return maxLives; }
    public void setEnemySpawnInterval(int interval) { this.enemySpawnInterval = interval; }
    public void setEnemySpeedBase(int speed) { this.enemySpeedBase = speed; }
    public int getEnemySpawnInterval() { return enemySpawnInterval; }
    public int getEnemySpeedBase() { return enemySpeedBase; }
    }
    GameState.java(射击)
    import java.io.Serializable;
    import java.util.List;

/**

  • 射击游戏存档状态
    */
    public class GameState implements Serializable {
    private static final long serialVersionUID = 1L;

    private List enemies, bullets, particles;
    private GameEntity player;
    private int playerLives, maxLives;
    private int score, killCount, shotCount, elapsedTime;
    private boolean running, paused, gameOver;
    private int difficulty, enemySpawnInterval, enemySpeedBase;
    private String difficultyName;
    private int width, height;

    public GameState(ShootingGame game) {
    this.enemies = game.getEnemies();
    this.bullets = game.getBullets();
    this.particles = game.getParticles();
    this.player = game.getPlayer();
    this.playerLives = game.getPlayerLives();
    this.maxLives = game.getMaxLives();
    this.score = game.getScore();
    this.killCount = game.getKillCount();
    this.shotCount = game.getShotCount();
    this.elapsedTime = game.getElapsedTime();
    this.running = game.isRunning();
    this.paused = game.isPaused();
    this.gameOver = game.isGameOver();
    this.difficulty = game.getDifficulty();
    this.difficultyName = game.getDifficultyName();
    this.enemySpawnInterval = game.getEnemySpawnInterval();
    this.enemySpeedBase = game.getEnemySpeedBase();
    this.width = game.getWidth();
    this.height = game.getHeight();
    }

    public List getEnemies() { return enemies; }
    public List getBullets() { return bullets; }
    public List getParticles() { return particles; }
    public GameEntity getPlayer() { return player; }
    public int getPlayerLives() { return playerLives; }
    public int getMaxLives() { return maxLives; }
    public int getScore() { return score; }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询