下面是一个使用Java Swing实现的简易版穿越火线游戏,包含玩家控制、敌人AI、射击系统、生命值和得分系统等核心功能。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;

public class CrossFireGame extends JFrame {

    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;
    private static final int PLAYER_SIZE = 50;
    private static final int ENEMY_SIZE = 40;
    private static final int BULLET_SIZE = 8;
    private static final int PLAYER_SPEED = 8;
    private static final int ENEMY_SPEED = 3;
    private static final int BULLET_SPEED = 15;
    
    private Player player;
    private ArrayList<Enemy> enemies = new ArrayList<>();
    private ArrayList<Bullet> bullets = new ArrayList<>();
    private int score = 0;
    private int enemySpawnTimer = 0;
    private boolean gameOver = false;
    private Random random = new Random();
    
    public CrossFireGame() {
        setTitle("简易版穿越火线");
        setSize(WIDTH, HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setResizable(false);
        
        player = new Player(WIDTH/2, HEIGHT - 100);
        
        // 添加键盘监听器
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                handleKeyPress(e);
            }
        });
        
        // 添加鼠标监听器
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                player.setTarget(e.getX(), e.getY());
            }
        });
        
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (!gameOver) {
                    bullets.add(new Bullet(player.x, player.y, player.targetX, player.targetY));
                } else {
                    resetGame();
                }
            }
        });
        
        // 游戏主循环
        Timer timer = new Timer(30, e -> {
            if (!gameOver) {
                updateGame();
            }
            repaint();
        });
        timer.start();
    }
    
    private void handleKeyPress(KeyEvent e) {
        int key = e.getKeyCode();
        
        if (key == KeyEvent.VK_A || key == KeyEvent.VK_LEFT) {
            player.move(-PLAYER_SPEED, 0);
        } else if (key == KeyEvent.VK_D || key == KeyEvent.VK_RIGHT) {
            player.move(PLAYER_SPEED, 0);
        } else if (key == KeyEvent.VK_W || key == KeyEvent.VK_UP) {
            player.move(0, -PLAYER_SPEED);
        } else if (key == KeyEvent.VK_S || key == KeyEvent.VK_DOWN) {
            player.move(0, PLAYER_SPEED);
        } else if (key == KeyEvent.VK_R) {
            resetGame();
        }
    }
    
    private void updateGame() {
        // 生成敌人
        enemySpawnTimer++;
        if (enemySpawnTimer >= 30 && enemies.size() < 10) {
            spawnEnemy();
            enemySpawnTimer = 0;
        }
        
        // 更新敌人位置
        for (int i = 0; i < enemies.size(); i++) {
            Enemy enemy = enemies.get(i);
            enemy.update(player.x, player.y);
            
            // 敌人攻击玩家
            if (enemy.isAttackReady()) {
                bullets.add(new Bullet(enemy.x, enemy.y, player.x, player.y, false));
            }
            
            // 检测敌人是否碰到玩家
            if (player.collidesWith(enemy)) {
                player.takeDamage(10);
                enemies.remove(i);
                i--;
            }
        }
        
        // 更新子弹位置
        for (int i = 0; i < bullets.size(); i++) {
            Bullet bullet = bullets.get(i);
            bullet.update();
            
            // 移除超出屏幕的子弹
            if (bullet.x < 0 || bullet.x > WIDTH || bullet.y < 0 || bullet.y > HEIGHT) {
                bullets.remove(i);
                i--;
                continue;
            }
            
            // 检测子弹击中目标
            if (bullet.isPlayerBullet) {
                for (int j = 0; j < enemies.size(); j++) {
                    Enemy enemy = enemies.get(j);
                    if (bullet.collidesWith(enemy)) {
                        enemy.takeDamage(25);
                        if (enemy.isDead()) {
                            enemies.remove(j);
                            score += 100;
                            j--;
                        }
                        bullets.remove(i);
                        i--;
                        break;
                    }
                }
            } else {
                if (bullet.collidesWith(player)) {
                    player.takeDamage(15);
                    bullets.remove(i);
                    i--;
                }
            }
        }
        
        // 检查游戏结束条件
        if (player.isDead()) {
            gameOver = true;
        }
    }
    
    private void spawnEnemy() {
        int side = random.nextInt(4); // 0:上, 1:右, 2:下, 3:左
        int x, y;
        
        switch (side) {
            case 0: // 上边
                x = random.nextInt(WIDTH - ENEMY_SIZE);
                y = -ENEMY_SIZE;
                break;
            case 1: // 右边
                x = WIDTH;
                y = random.nextInt(HEIGHT - ENEMY_SIZE);
                break;
            case 2: // 下边
                x = random.nextInt(WIDTH - ENEMY_SIZE);
                y = HEIGHT;
                break;
            case 3: // 左边
            default:
                x = -ENEMY_SIZE;
                y = random.nextInt(HEIGHT - ENEMY_SIZE);
                break;
        }
        
        enemies.add(new Enemy(x, y));
    }
    
    private void resetGame() {
        player = new Player(WIDTH/2, HEIGHT - 100);
        enemies.clear();
        bullets.clear();
        score = 0;
        enemySpawnTimer = 0;
        gameOver = false;
    }
    
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        
        // 绘制背景
        g.setColor(new Color(30, 30, 40));
        g.fillRect(0, 0, WIDTH, HEIGHT);
        
        // 绘制网格
        g.setColor(new Color(50, 50, 60));
        for (int i = 0; i < WIDTH; i += 40) {
            g.drawLine(i, 0, i, HEIGHT);
        }
        for (int i = 0; i < HEIGHT; i += 40) {
            g.drawLine(0, i, WIDTH, i);
        }
        
        // 绘制玩家
        player.draw(g);
        
        // 绘制敌人
        for (Enemy enemy : enemies) {
            enemy.draw(g);
        }
        
        // 绘制子弹
        for (Bullet bullet : bullets) {
            bullet.draw(g);
        }
        
        // 绘制HUD
        drawHUD(g);
        
        // 游戏结束画面
        if (gameOver) {
            drawGameOver(g);
        }
    }
    
    private void drawHUD(Graphics g) {
        // 分数
        g.setColor(Color.WHITE);
        g.setFont(new Font("Arial", Font.BOLD, 20));
        g.drawString("得分: " + score, 20, 40);
        
        // 生命值条
        int healthBarWidth = 200;
        int healthBarHeight = 20;
        int healthBarX = WIDTH - healthBarWidth - 20;
        int healthBarY = 30;
        
        g.setColor(Color.DARK_GRAY);
        g.fillRect(healthBarX, healthBarY, healthBarWidth, healthBarHeight);
        
        double healthPercentage = player.health / 100.0;
        g.setColor(healthPercentage > 0.6 ? Color.GREEN : 
                  healthPercentage > 0.3 ? Color.YELLOW : Color.RED);
        g.fillRect(healthBarX, healthBarY, (int)(healthBarWidth * healthPercentage), healthBarHeight);
        
        g.setColor(Color.WHITE);
        g.drawRect(healthBarX, healthBarY, healthBarWidth, healthBarHeight);
        g.drawString("生命值: " + (int)player.health, healthBarX + 5, healthBarY + 16);
        
        // 敌人数量
        g.drawString("敌人: " + enemies.size(), WIDTH/2 - 40, 40);
        
        // 控制说明
        g.setFont(new Font("Arial", Font.PLAIN, 14));
        g.drawString("移动: WASD | 射击: 鼠标左键 | 重新开始: R", 20, HEIGHT - 20);
    }
    
    private void drawGameOver(Graphics g) {
        g.setColor(new Color(0, 0, 0, 180));
        g.fillRect(0, 0, WIDTH, HEIGHT);
        
        g.setColor(Color.RED);
        g.setFont(new Font("Arial", Font.BOLD, 48));
        String gameOverText = "游戏结束!";
        int textWidth = g.getFontMetrics().stringWidth(gameOverText);
        g.drawString(gameOverText, WIDTH/2 - textWidth/2, HEIGHT/2 - 50);
        
        g.setColor(Color.WHITE);
        g.setFont(new Font("Arial", Font.BOLD, 36));
        String scoreText = "最终得分: " + score;
        textWidth = g.getFontMetrics().stringWidth(scoreText);
        g.drawString(scoreText, WIDTH/2 - textWidth/2, HEIGHT/2 + 20);
        
        g.setFont(new Font("Arial", Font.PLAIN, 24));
        String restartText = "点击屏幕或按R键重新开始";
        textWidth = g.getFontMetrics().stringWidth(restartText);
        g.drawString(restartText, WIDTH/2 - textWidth/2, HEIGHT/2 + 80);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            CrossFireGame game = new CrossFireGame();
            game.setVisible(true);
        });
    }
    
    class Player {
        double x, y;
        double targetX, targetY;
        double health = 100;
        
        Player(double x, double y) {
            this.x = x;
            this.y = y;
            this.targetX = x;
            this.targetY = y;
        }
        
        void move(double dx, double dy) {
            x += dx;
            y += dy;
            
            // 边界检查
            if (x < 0) x = 0;
            if (x > WIDTH - PLAYER_SIZE) x = WIDTH - PLAYER_SIZE;
            if (y < 0) y = 0;
            if (y > HEIGHT - PLAYER_SIZE) y = HEIGHT - PLAYER_SIZE;
        }
        
        void setTarget(double x, double y) {
            targetX = x;
            targetY = y;
        }
        
        void takeDamage(double amount) {
            health -= amount;
            if (health < 0) health = 0;
        }
        
        boolean isDead() {
            return health <= 0;
        }
        
        void draw(Graphics g) {
            // 绘制玩家主体
            g.setColor(new Color(70, 130, 180));
            g.fillOval((int)x, (int)y, PLAYER_SIZE, PLAYER_SIZE);
            
            // 绘制玩家方向指示器
            double dx = targetX - (x + PLAYER_SIZE/2);
            double dy = targetY - (y + PLAYER_SIZE/2);
            double length = Math.sqrt(dx*dx + dy*dy);
            
            if (length > 0) {
                dx /= length;
                dy /= length;
                
                int lineX = (int)(x + PLAYER_SIZE/2 + dx * PLAYER_SIZE/2);
                int lineY = (int)(y + PLAYER_SIZE/2 + dy * PLAYER_SIZE/2);
                
                g.setColor(Color.YELLOW);
                g.drawLine((int)(x + PLAYER_SIZE/2), (int)(y + PLAYER_SIZE/2), lineX, lineY);
                
                // 绘制枪
                g.setColor(Color.DARK_GRAY);
                int gunX = (int)(x + PLAYER_SIZE/2 + dx * PLAYER_SIZE);
                int gunY = (int)(y + PLAYER_SIZE/2 + dy * PLAYER_SIZE);
                g.drawLine(lineX, lineY, gunX, gunY);
            }
        }
        
        boolean collidesWith(GameObject other) {
            return (x < other.x + other.width &&
                   x + PLAYER_SIZE > other.x &&
                   y < other.y + other.height &&
                   y + PLAYER_SIZE > other.y);
        }
    }
    
    class Enemy extends GameObject {
        private int attackCooldown = 0;
        
        Enemy(double x, double y) {
            super(x, y, ENEMY_SIZE, ENEMY_SIZE);
            health = 100;
        }
        
        void update(double playerX, double playerY) {
            // 简单AI:向玩家移动
            double dx = playerX - x;
            double dy = playerY - y;
            double distance = Math.sqrt(dx*dx + dy*dy);
            
            if (distance > 0) {
                dx /= distance;
                dy /= distance;
                
                // 如果距离较远,则靠近玩家
                if (distance > 200) {
                    x += dx * ENEMY_SPEED;
                    y += dy * ENEMY_SPEED;
                } 
                // 如果距离较近,则保持距离
                else if (distance < 150) {
                    x -= dx * ENEMY_SPEED/2;
                    y -= dy * ENEMY_SPEED/2;
                }
            }
            
            // 边界检查
            if (x < 0) x = 0;
            if (x > WIDTH - width) x = WIDTH - width;
            if (y < 0) y = 0;
            if (y > HEIGHT - height) y = HEIGHT - height;
            
            // 攻击冷却
            if (attackCooldown > 0) {
                attackCooldown--;
            }
        }
        
        boolean isAttackReady() {
            if (attackCooldown == 0) {
                attackCooldown = 60; // 2秒冷却时间
                return true;
            }
            return false;
        }
        
        void draw(Graphics g) {
            // 绘制敌人主体
            g.setColor(new Color(180, 70, 70));
            g.fillOval((int)x, (int)y, width, height);
            
            // 绘制敌人眼睛
            g.setColor(Color.WHITE);
            g.fillOval((int)x + 8, (int)y + 10, 10, 10);
            g.fillOval((int)x + 22, (int)y + 10, 10, 10);
            g.setColor(Color.BLACK);
            g.fillOval((int)x + 10, (int)y + 12, 5, 5);
            g.fillOval((int)x + 24, (int)y + 12, 5, 5);
            
            // 绘制生命值条
            double healthPercentage = health / 100.0;
            g.setColor(Color.DARK_GRAY);
            g.fillRect((int)x, (int)y - 10, width, 5);
            g.setColor(healthPercentage > 0.5 ? Color.GREEN : Color.RED);
            g.fillRect((int)x, (int)y - 10, (int)(width * healthPercentage), 5);
        }
    }
    
    class Bullet extends GameObject {
        double dx, dy;
        boolean isPlayerBullet;
        
        Bullet(double startX, double startY, double targetX, double targetY) {
            this(startX, startY, targetX, targetY, true);
        }
        
        Bullet(double startX, double startY, double targetX, double targetY, boolean isPlayerBullet) {
            super(startX, startY, BULLET_SIZE, BULLET_SIZE);
            this.isPlayerBullet = isPlayerBullet;
            
            dx = targetX - startX;
            dy = targetY - startY;
            double length = Math.sqrt(dx*dx + dy*dy);
            
            if (length > 0) {
                dx = (dx / length) * BULLET_SPEED;
                dy = (dy / length) * BULLET_SPEED;
            }
        }
        
        void update() {
            x += dx;
            y += dy;
        }
        
        void draw(Graphics g) {
            g.setColor(isPlayerBullet ? Color.YELLOW : Color.RED);
            g.fillOval((int)x, (int)y, width, height);
        }
        
        boolean collidesWith(GameObject other) {
            double centerX = x + width/2;
            double centerY = y + height/2;
            
            double otherCenterX = other.x + other.width/2;
            double otherCenterY = other.y + other.height/2;
            
            double distance = Math.sqrt(
                Math.pow(centerX - otherCenterX, 2) + 
                Math.pow(centerY - otherCenterY, 2)
            );
            
            return distance < (width/2 + other.width/2);
        }
    }
    
    abstract class GameObject {
        double x, y;
        double width, height;
        double health;
        
        GameObject(double x, double y, double width, double height) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }
        
        void takeDamage(double amount) {
            health -= amount;
        }
        
        boolean isDead() {
            return health <= 0;
        }
    }
}

运行说明

要运行此游戏,只需将代码复制到名为CrossFireGame.java的文件中,然后使用以下命令编译和运行:

javac CrossFireGame.java
java CrossFireGame

游戏将在新窗口中启动,使用键盘和鼠标进行游戏控制。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐