下面是一个使用Java Swing实现的简单火娃与冰娃闯关游戏。

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

public class FireIceAdventure extends JFrame {
    
    private GamePanel gamePanel;
    
    public FireIceAdventure() {
        setTitle("火娃与冰娃的冒险");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        
        gamePanel = new GamePanel();
        add(gamePanel);
        
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new FireIceAdventure());
    }
}

class GamePanel extends JPanel implements ActionListener, KeyListener {
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;
    private static final int TILE_SIZE = 40;
    
    // 角色
    private Player fireBoy;
    private Player iceGirl;
    
    // 游戏元素
    private ArrayList<Obstacle> obstacles;
    private ArrayList<Platform> platforms;
    private ArrayList<Collectible> collectibles;
    private Goal goal;
    
    // 游戏状态
    private boolean gameRunning;
    private boolean gameWon;
    private int level;
    private int score;
    
    private Timer timer;
    
    public GamePanel() {
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setBackground(new Color(30, 30, 50));
        setFocusable(true);
        addKeyListener(this);
        
        initGame();
        
        timer = new Timer(16, this); // ~60 FPS
        timer.start();
    }
    
    private void initGame() {
        fireBoy = new Player(100, HEIGHT - 150, Color.ORANGE, "火娃");
        iceGirl = new Player(200, HEIGHT - 150, Color.CYAN, "冰娃");
        
        obstacles = new ArrayList<>();
        platforms = new ArrayList<>();
        collectibles = new ArrayList<>();
        
        // 创建平台
        createPlatforms();
        
        // 创建障碍物
        createObstacles();
        
        // 创建收集品
        createCollectibles();
        
        // 创建目标
        goal = new Goal(WIDTH - 100, HEIGHT - 180);
        
        gameRunning = true;
        gameWon = false;
        level = 1;
        score = 0;
    }
    
    private void createPlatforms() {
        // 地面
        platforms.add(new Platform(0, HEIGHT - 100, WIDTH, 100));
        
        // 平台
        platforms.add(new Platform(200, HEIGHT - 200, 200, 20));
        platforms.add(new Platform(500, HEIGHT - 250, 150, 20));
        platforms.add(new Platform(300, HEIGHT - 350, 200, 20));
        platforms.add(new Platform(100, HEIGHT - 400, 150, 20));
    }
    
    private void createObstacles() {
        // 火障碍 - 只有冰娃能通过
        obstacles.add(new Obstacle(400, HEIGHT - 120, 40, 80, Obstacle.Type.FIRE));
        
        // 冰障碍 - 只有火娃能通过
        obstacles.add(new Obstacle(600, HEIGHT - 120, 40, 80, Obstacle.Type.ICE));
        
        // 尖刺
        obstacles.add(new Obstacle(300, HEIGHT - 100, 100, 20, Obstacle.Type.SPIKE));
    }
    
    private void createCollectibles() {
        // 火娃收集品
        collectibles.add(new Collectible(250, HEIGHT - 240, Color.ORANGE));
        collectibles.add(new Collectible(550, HEIGHT - 290, Color.ORANGE));
        
        // 冰娃收集品
        collectibles.add(new Collectible(350, HEIGHT - 390, Color.CYAN));
        collectibles.add(new Collectible(150, HEIGHT - 440, Color.CYAN));
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        // 绘制背景
        drawBackground(g);
        
        // 绘制平台
        for (Platform p : platforms) {
            p.draw(g);
        }
        
        // 绘制障碍物
        for (Obstacle o : obstacles) {
            o.draw(g);
        }
        
        // 绘制收集品
        for (Collectible c : collectibles) {
            c.draw(g);
        }
        
        // 绘制目标
        goal.draw(g);
        
        // 绘制角色
        fireBoy.draw(g);
        iceGirl.draw(g);
        
        // 绘制UI
        drawUI(g);
        
        // 游戏结束画面
        if (!gameRunning) {
            drawGameOverScreen(g);
        }
        
        // 游戏胜利画面
        if (gameWon) {
            drawWinScreen(g);
        }
    }
    
    private void drawBackground(Graphics g) {
        // 渐变背景
        Graphics2D g2d = (Graphics2D) g;
        GradientPaint gradient = new GradientPaint(0, 0, new Color(10, 10, 30), 0, HEIGHT, new Color(50, 20, 70));
        g2d.setPaint(gradient);
        g2d.fillRect(0, 0, WIDTH, HEIGHT);
        
        // 星星
        g.setColor(Color.WHITE);
        for (int i = 0; i < 50; i++) {
            int x = (int) (Math.random() * WIDTH);
            int y = (int) (Math.random() * HEIGHT / 2);
            int size = (int) (Math.random() * 3) + 1;
            g.fillOval(x, y, size, size);
        }
    }
    
    private void drawUI(Graphics g) {
        g.setColor(new Color(255, 255, 255, 150));
        g.fillRect(10, 10, 200, 60);
        
        g.setColor(Color.BLACK);
        g.setFont(new Font("微软雅黑", Font.BOLD, 16));
        g.drawString("关卡: " + level, 20, 30);
        g.drawString("分数: " + score, 20, 50);
        g.drawString("收集品: " + (8 - collectibles.size()) + "/8", 20, 70);
        
        // 角色状态
        g.setColor(fireBoy.getColor());
        g.fillRect(WIDTH - 150, 10, 20, 20);
        g.setColor(Color.BLACK);
        g.drawString("火娃: " + (fireBoy.isActive() ? "活跃" : "等待"), WIDTH - 120, 25);
        
        g.setColor(iceGirl.getColor());
        g.fillRect(WIDTH - 150, 40, 20, 20);
        g.setColor(Color.BLACK);
        g.drawString("冰娃: " + (iceGirl.isActive() ? "活跃" : "等待"), WIDTH - 120, 55);
    }
    
    private void drawGameOverScreen(Graphics g) {
        g.setColor(new Color(0, 0, 0, 180));
        g.fillRect(0, 0, WIDTH, HEIGHT);
        
        g.setColor(Color.WHITE);
        g.setFont(new Font("微软雅黑", Font.BOLD, 40));
        String gameOver = "游戏结束!";
        g.drawString(gameOver, (WIDTH - g.getFontMetrics().stringWidth(gameOver)) / 2, HEIGHT / 2 - 50);
        
        g.setFont(new Font("微软雅黑", Font.PLAIN, 24));
        String scoreText = "最终分数: " + score;
        g.drawString(scoreText, (WIDTH - g.getFontMetrics().stringWidth(scoreText)) / 2, HEIGHT / 2);
        
        String restart = "按R键重新开始";
        g.drawString(restart, (WIDTH - g.getFontMetrics().stringWidth(restart)) / 2, HEIGHT / 2 + 50);
    }
    
    private void drawWinScreen(Graphics g) {
        g.setColor(new Color(0, 0, 0, 180));
        g.fillRect(0, 0, WIDTH, HEIGHT);
        
        g.setColor(Color.YELLOW);
        g.setFont(new Font("微软雅黑", Font.BOLD, 40));
        String winText = "恭喜过关!";
        g.drawString(winText, (WIDTH - g.getFontMetrics().stringWidth(winText)) / 2, HEIGHT / 2 - 50);
        
        g.setColor(Color.WHITE);
        g.setFont(new Font("微软雅黑", Font.PLAIN, 24));
        String scoreText = "分数: " + score;
        g.drawString(scoreText, (WIDTH - g.getFontMetrics().stringWidth(scoreText)) / 2, HEIGHT / 2);
        
        String nextLevel = "按空格键进入下一关";
        g.drawString(nextLevel, (WIDTH - g.getFontMetrics().stringWidth(nextLevel)) / 2, HEIGHT / 2 + 50);
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        if (gameRunning && !gameWon) {
            // 更新角色位置
            fireBoy.update(platforms, obstacles);
            iceGirl.update(platforms, obstacles);
            
            // 检查收集品
            checkCollectibles();
            
            // 检查游戏胜利
            checkWin();
            
            // 检查游戏结束
            checkGameOver();
        }
        
        repaint();
    }
    
    private void checkCollectibles() {
        // 创建临时列表防止并发修改异常
        ArrayList<Collectible> toRemove = new ArrayList<>();
        
        for (Collectible c : collectibles) {
            if (fireBoy.getBounds().intersects(c.getBounds()) && c.getColor().equals(fireBoy.getColor())) {
                toRemove.add(c);
                score += 50;
            } else if (iceGirl.getBounds().intersects(c.getBounds()) && c.getColor().equals(iceGirl.getColor())) {
                toRemove.add(c);
                score += 50;
            }
        }
        
        collectibles.removeAll(toRemove);
    }
    
    private void checkWin() {
        if (fireBoy.getBounds().intersects(goal.getBounds()) && 
            iceGirl.getBounds().intersects(goal.getBounds()) &&
            collectibles.isEmpty()) {
            gameWon = true;
            score += 500;
        }
    }
    
    private void checkGameOver() {
        // 检查是否掉出屏幕
        if (fireBoy.getY() > HEIGHT || iceGirl.getY() > HEIGHT) {
            gameRunning = false;
        }
        
        // 检查碰到尖刺
        for (Obstacle o : obstacles) {
            if (o.getType() == Obstacle.Type.SPIKE) {
                if (fireBoy.getBounds().intersects(o.getBounds()) || 
                    iceGirl.getBounds().intersects(o.getBounds())) {
                    gameRunning = false;
                }
            }
        }
    }
    
    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        
        // 火娃控制
        if (fireBoy.isActive()) {
            if (key == KeyEvent.VK_A) {
                fireBoy.moveLeft();
            } else if (key == KeyEvent.VK_D) {
                fireBoy.moveRight();
            } else if (key == KeyEvent.VK_W) {
                fireBoy.jump();
            }
        }
        
        // 冰娃控制
        if (iceGirl.isActive()) {
            if (key == KeyEvent.VK_LEFT) {
                iceGirl.moveLeft();
            } else if (key == KeyEvent.VK_RIGHT) {
                iceGirl.moveRight();
            } else if (key == KeyEvent.VK_UP) {
                iceGirl.jump();
            }
        }
        
        // 切换角色
        if (key == KeyEvent.VK_TAB) {
            fireBoy.toggleActive();
            iceGirl.toggleActive();
        }
        
        // 重新开始游戏
        if (key == KeyEvent.VK_R && !gameRunning) {
            initGame();
        }
        
        // 下一关
        if (key == KeyEvent.VK_SPACE && gameWon) {
            nextLevel();
        }
    }
    
    private void nextLevel() {
        level++;
        initGame();
    }
    
    @Override
    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();
        
        if (fireBoy.isActive()) {
            if (key == KeyEvent.VK_A || key == KeyEvent.VK_D) {
                fireBoy.stopMoving();
            }
        }
        
        if (iceGirl.isActive()) {
            if (key == KeyEvent.VK_LEFT || key == KeyEvent.VK_RIGHT) {
                iceGirl.stopMoving();
            }
        }
    }
    
    @Override
    public void keyTyped(KeyEvent e) {}
}

class Player {
    private int x, y;
    private int width = 30, height = 50;
    private int velX, velY;
    private Color color;
    private String name;
    private boolean active;
    private boolean onGround;
    
    public Player(int x, int y, Color color, String name) {
        this.x = x;
        this.y = y;
        this.color = color;
        this.name = name;
        this.active = true;
    }
    
    public void update(ArrayList<Platform> platforms, ArrayList<Obstacle> obstacles) {
        // 应用重力
        if (!onGround) {
            velY += 1;
        }
        
        // 更新位置
        x += velX;
        y += velY;
        
        // 边界检查
        if (x < 0) x = 0;
        if (x > GamePanel.WIDTH - width) x = GamePanel.WIDTH - width;
        
        // 重置地面状态
        onGround = false;
        
        // 平台碰撞检测
        Rectangle playerBounds = getBounds();
        for (Platform p : platforms) {
            Rectangle platformBounds = p.getBounds();
            
            if (playerBounds.intersects(platformBounds)) {
                // 从上方碰撞平台
                if (velY > 0 && y < platformBounds.y) {
                    y = platformBounds.y - height;
                    velY = 0;
                    onGround = true;
                }
            }
        }
        
        // 障碍物碰撞检测(火娃不能通过冰障碍,冰娃不能通过火障碍)
        for (Obstacle o : obstacles) {
            if (playerBounds.intersects(o.getBounds())) {
                // 火障碍
                if (o.getType() == Obstacle.Type.FIRE && color == Color.ORANGE) {
                    // 火娃不能通过火障碍
                    if (velX > 0 && x < o.getX()) {
                        x = o.getX() - width;
                    } else if (velX < 0 && x > o.getX()) {
                        x = o.getX() + o.getWidth();
                    }
                }
                // 冰障碍
                else if (o.getType() == Obstacle.Type.ICE && color == Color.CYAN) {
                    // 冰娃不能通过冰障碍
                    if (velX > 0 && x < o.getX()) {
                        x = o.getX() - width;
                    } else if (velX < 0 && x > o.getX()) {
                        x = o.getX() + o.getWidth();
                    }
                }
            }
        }
    }
    
    public void draw(Graphics g) {
        // 绘制角色
        g.setColor(color);
        g.fillRect(x, y, width, height);
        
        // 绘制眼睛
        g.setColor(Color.WHITE);
        g.fillOval(x + 5, y + 10, 8, 8);
        g.fillOval(x + width - 13, y + 10, 8, 8);
        g.setColor(Color.BLACK);
        g.fillOval(x + 7, y + 12, 4, 4);
        g.fillOval(x + width - 11, y + 12, 4, 4);
        
        // 绘制名称
        g.setColor(Color.WHITE);
        g.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        g.drawString(name, x, y - 5);
        
        // 绘制活跃状态指示器
        if (active) {
            g.setColor(Color.GREEN);
            g.fillRect(x, y + height - 5, width, 3);
        }
    }
    
    public void moveLeft() {
        velX = -5;
    }
    
    public void moveRight() {
        velX = 5;
    }
    
    public void stopMoving() {
        velX = 0;
    }
    
    public void jump() {
        if (onGround) {
            velY = -15;
            onGround = false;
        }
    }
    
    public void toggleActive() {
        active = !active;
    }
    
    public Rectangle getBounds() {
        return new Rectangle(x, y, width, height);
    }
    
    public int getX() { return x; }
    public int getY() { return y; }
    public Color getColor() { return color; }
    public boolean isActive() { return active; }
}

class Platform {
    private int x, y, width, height;
    
    public Platform(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }
    
    public void draw(Graphics g) {
        g.setColor(new Color(100, 70, 40));
        g.fillRect(x, y, width, height);
        
        // 平台顶部
        g.setColor(new Color(120, 90, 60));
        g.fillRect(x, y, width, 5);
        
        // 平台纹理
        g.setColor(new Color(80, 50, 30));
        for (int i = x + 10; i < x + width; i += 20) {
            g.drawLine(i, y + 5, i, y + height - 5);
        }
    }
    
    public Rectangle getBounds() {
        return new Rectangle(x, y, width, height);
    }
}

class Obstacle {
    enum Type { FIRE, ICE, SPIKE }
    
    private int x, y, width, height;
    private Type type;
    
    public Obstacle(int x, int y, int width, int height, Type type) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.type = type;
    }
    
    public void draw(Graphics g) {
        switch (type) {
            case FIRE:
                // 火焰效果
                g.setColor(new Color(255, 100, 0));
                g.fillRect(x, y, width, height);
                
                g.setColor(Color.YELLOW);
                for (int i = 0; i < 5; i++) {
                    int flameHeight = (int) (Math.random() * 10) + 5;
                    int flameWidth = (int) (Math.random() * 10) + 5;
                    int flameX = x + (int) (Math.random() * width);
                    int flameY = y - flameHeight;
                    g.fillOval(flameX, flameY, flameWidth, flameHeight * 2);
                }
                break;
                
            case ICE:
                // 冰效果
                g.setColor(new Color(100, 200, 255, 200));
                g.fillRect(x, y, width, height);
                
                // 冰纹理
                g.setColor(new Color(180, 240, 255));
                for (int i = 0; i < 10; i++) {
                    int iceX = x + (int) (Math.random() * width);
                    int iceY = y + (int) (Math.random() * height);
                    g.fillOval(iceX, iceY, 3, 3);
                }
                break;
                
            case SPIKE:
                // 尖刺
                g.setColor(new Color(100, 100, 100));
                Polygon spike = new Polygon();
                spike.addPoint(x, y + height);
                spike.addPoint(x + width/2, y);
                spike.addPoint(x + width, y + height);
                g.fillPolygon(spike);
                break;
        }
    }
    
    public Rectangle getBounds() {
        return new Rectangle(x, y, width, height);
    }
    
    public Type getType() {
        return type;
    }
    
    public int getX() { return x; }
    public int getWidth() { return width; }
}

class Collectible {
    private int x, y;
    private int size = 20;
    private Color color;
    
    public Collectible(int x, int y, Color color) {
        this.x = x;
        this.y = y;
        this.color = color;
    }
    
    public void draw(Graphics g) {
        // 绘制闪烁效果
        double pulse = (System.currentTimeMillis() % 1000) / 1000.0;
        int alpha = (int) (150 + 105 * Math.sin(pulse * Math.PI * 2));
        
        if (color == Color.ORANGE) {
            g.setColor(new Color(255, 150, 0, alpha));
        } else {
            g.setColor(new Color(0, 200, 255, alpha));
        }
        
        g.fillOval(x, y, size, size);
        
        // 绘制外圈
        g.setColor(color);
        g.drawOval(x, y, size, size);
        
        // 绘制内部图案
        if (color == Color.ORANGE) {
            g.fillOval(x + 5, y + 5, size - 10, size - 10);
        } else {
            Polygon star = new Polygon();
            star.addPoint(x + size/2, y + 2);
            star.addPoint(x + size - 5, y + size - 5);
            star.addPoint(x + 2, y + size/2);
            star.addPoint(x + size - 2, y + size/2);
            star.addPoint(x + 5, y + size - 5);
            g.fillPolygon(star);
        }
    }
    
    public Rectangle getBounds() {
        return new Rectangle(x, y, size, size);
    }
    
    public Color getColor() {
        return color;
    }
}

class Goal {
    private int x, y;
    private int width = 80, height = 100;
    
    public Goal(int x, int y) {
        this.x = x;
        this.y = y;
    }
    
    public void draw(Graphics g) {
        // 绘制门框
        g.setColor(new Color(150, 100, 50));
        g.fillRect(x, y, width, height);
        
        // 绘制门
        g.setColor(new Color(180, 150, 100));
        g.fillRect(x + 10, y + 10, width - 20, height - 20);
        
        // 绘制门把手
        g.setColor(Color.YELLOW);
        g.fillOval(x + width - 25, y + height/2, 10, 10);
        
        // 绘制终点标志
        g.setColor(Color.GREEN);
        g.setFont(new Font("微软雅黑", Font.BOLD, 14));
        g.drawString("终点", x + 25, y + height/2);
    }
    
    public Rectangle getBounds() {
        return new Rectangle(x, y, width, height);
    }
}

运行说明:

直接运行程序即可开始游戏,确保你的系统已安装Java运行环境(JRE)或Java开发工具包(JDK)。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐