package com.bird.main;
import com.bird.domain.FlyDirectionEnum;
import com.bird.utils.GameUtils;
import java.awt.*;
import java.awt.image.BufferedImage;
import static com.bird.constants.BirdConstants.*;
public class GameBird {
// 小鸟三种状态图片
private final BufferedImage[] birdImages;
// 飞行方向
private FlyDirectionEnum direction = FlyDirectionEnum.PARALLEL;
// 小鸟坐标
private int x = 200, y = 200;
// 当前Y方向移动速度
private int speedY = 0;
// 每一帧增加的下落速度
private static final int FALL_SPEED = 1;
// 按下空格后的上升速度
private static final int FLY_SPEED = -10;
// 最大下落速度
private static final int MAX_SPEED = 12;
// 是否存活
private boolean alive = true;
// 分数
private int score = 0;
/**
* 构造方法
* 初始化小鸟图片资源
*/
public GameBird() {
birdImages = new BufferedImage[BIRD_IMAGES.length];
for (int i = 0; i < BIRD_IMAGES.length; i++) {
birdImages[i] =
GameUtils.loadBufferedImage(BIRD_IMAGES[i]);
}
}
/**
* 绘制小鸟
*/
public void draw(Graphics g) {
g.drawImage(
birdImages[direction.getCode()],
x,
y,
null
);
}
/**
* 每一帧更新小鸟状态
*/
public void move() {
// 下落速度逐渐增加
speedY += FALL_SPEED;
// 限制最大下落速度
if (speedY > MAX_SPEED) {
speedY = MAX_SPEED;
}
// 更新小鸟位置
y += speedY;
// 根据速度切换图片状态
if (speedY < -2) {
direction = FlyDirectionEnum.UP;
} else if (speedY > 2) {
direction = FlyDirectionEnum.DOWN;
} else {
direction = FlyDirectionEnum.PARALLEL;
}
// 防止飞出顶部
if (y < 0) {
y = 0;
speedY = 0;
}
// 防止掉出底部
int maxY =
FRAME_HEIGHT - birdImages[0].getHeight();
if (y > maxY) {
y = maxY;
speedY = 0;
}
}
/**
* 小鸟向上飞
*/
public void fly() {
speedY = FLY_SPEED;
direction = FlyDirectionEnum.UP;
}
// 获取位置
public Rectangle getRect() {
return new Rectangle(
x,
y,
birdImages[0].getWidth(),
birdImages[0].getHeight()
);
}
public void die() {
alive = false;
}
public boolean isAlive() {
return alive;
}
public void addScore(int v) {
score += v;
}
public int getScore() {
return score;
}
public int getX() {
return x;
}
}
package com.bird.main;
import java.awt.*;
import java.util.List;
public class BarrierCollisionSystem {
public void update(GameBird bird, List<Barrier> barriers) {
if (!bird.isAlive()) return;
Rectangle birdRect = bird.getRect();
for (Barrier b : barriers) {
if (birdRect.intersects(b.getTopRect())
|| birdRect.intersects(b.getBottomRect())) {
bird.die();
return;
}
if (!b.isPassed()
&& b.getX() + b.getWidth() < bird.getX()) {
bird.addScore(1);
b.setPassed(true);
}
}
}
}
package com.bird.main;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import static com.bird.constants.BirdConstants.*;
public class GamePanel extends JPanel {
private final GameBackground background;
private final GameFrontGround frontGround;
private final GameBird gameBird;
private final BarrierManager barrierManager;
private final BarrierCollisionSystem collisionSystem;
public GamePanel() {
setPreferredSize(
new Dimension(FRAME_WIDTH, FRAME_HEIGHT)
);
background = new GameBackground();
frontGround = new GameFrontGround();
gameBird = new GameBird();
barrierManager = new BarrierManager();
collisionSystem = new BarrierCollisionSystem();
setFocusable(true);
// 空格控制
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
// 死亡后禁止操作(可选)
if (gameBird.isAlive()) {
gameBird.fly();
}
}
}
});
SwingUtilities.invokeLater(this::requestFocusInWindow);
new RunThread().start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// 绘制背景
background.draw(g);
// 绘制云彩
frontGround.draw(g);
// 绘制管道障碍物
barrierManager.draw(g);
// 绘制小鸟
gameBird.draw(g);
// 计算分数
g.setColor(Color.BLACK);
g.setFont(new Font("Arial", Font.BOLD, 20));
g.drawString("分数: " + gameBird.getScore(), 20, 30);
// 判断是否死亡
if (!gameBird.isAlive()) {
String text = "游戏结束";
// 字体样式
g.setColor(Color.RED);
g.setFont(new Font("Arial", Font.BOLD, 40));
FontMetrics fm = g.getFontMetrics();
int textWidth = fm.stringWidth(text);
int textHeight = fm.getAscent();
int x = (getWidth() - textWidth) / 2;
int y = (getHeight() - textHeight) / 2 + textHeight;
g.drawString(text, x, y);
}
}
// 循环检测
class RunThread extends Thread {
@Override
public void run() {
while (true) {
// 更新小鸟位置
gameBird.move();
// 更新云彩位置
frontGround.move();
// 更新管道位置
barrierManager.move();
// 碰撞检测
collisionSystem.update(
gameBird,
barrierManager.getBarriers()
);
// 重绘
repaint();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
break;
}
}
}
}
}