Java-Swing火娃冰娃2D闯关游戏程序
g.drawString("收集品: " + (8 - collectibles.size()) + "/8", 20, 70);g.setFont(new Font("微软雅黑", Font.PLAIN, 24));g.setFont(new Font("微软雅黑", Font.PLAIN, 24));g.setFont(new Font("微软雅黑", Font.BOLD, 40));g.se
下面是一个使用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)。
更多推荐



所有评论(0)