Java JFrame 接元宝游戏:控制小人移动,收集奖励,获取积分
这是一个使用 Java JFrame 实现接元宝游戏的示例代码,玩家可以控制小人移动来收集掉落的元宝和铜钱,并获得积分。
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class CatchingGame extends JFrame implements KeyListener {
private static final int FRAME_WIDTH = 800;
private static final int FRAME_HEIGHT = 600;
private static final int PLAYER_WIDTH = 50;
private static final int PLAYER_HEIGHT = 50;
private static final int ITEM_WIDTH = 30;
private static final int ITEM_HEIGHT = 30;
private static final int ITEM_SPEED = 5;
private static final int GAME_DURATION = 60;
private int playerX;
private int playerY;
private int score;
private int timeLeft;
private boolean isGameRunning;
private List<Point> items;
public CatchingGame() {
setTitle('接元宝游戏');
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
addKeyListener(this);
playerX = (FRAME_WIDTH - PLAYER_WIDTH) / 2;
playerY = FRAME_HEIGHT - PLAYER_HEIGHT;
score = 0;
timeLeft = GAME_DURATION;
isGameRunning = true;
items = new ArrayList<>();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (isGameRunning) {
generateItem();
timeLeft--;
if (timeLeft <= 0) {
endGame();
}
}
}
}, 1000, 1000);
Timer timer2 = new Timer();
timer2.schedule(new TimerTask() {
@Override
public void run() {
if (isGameRunning) {
moveItems();
checkCollision();
repaint();
}
}
}, 0, 20);
setVisible(true);
}
private void generateItem() {
Random random = new Random();
int itemX = random.nextInt(FRAME_WIDTH - ITEM_WIDTH);
int itemY = 0;
items.add(new Point(itemX, itemY));
}
private void moveItems() {
for (Point item : items) {
item.y += ITEM_SPEED;
}
items.removeIf(item -> item.y >= FRAME_HEIGHT);
}
private void checkCollision() {
Rectangle playerRect = new Rectangle(playerX, playerY, PLAYER_WIDTH, PLAYER_HEIGHT);
for (Point item : items) {
Rectangle itemRect = new Rectangle(item.x, item.y, ITEM_WIDTH, ITEM_HEIGHT);
if (playerRect.intersects(itemRect)) {
score++;
items.remove(item);
break;
}
}
}
private void endGame() {
isGameRunning = false;
JOptionPane.showMessageDialog(this, '游戏结束,您的得分为:' + score);
dispose();
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.BLUE);
g.fillRect(playerX, playerY, PLAYER_WIDTH, PLAYER_HEIGHT);
g.setColor(Color.YELLOW);
for (Point item : items) {
g.fillOval(item.x, item.y, ITEM_WIDTH, ITEM_HEIGHT);
}
g.setColor(Color.BLACK);
g.drawString('得分:' + score, 10, 20);
g.drawString('剩余时间:' + timeLeft + '秒', 10, 40);
}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
if (isGameRunning) {
int keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_UP:
playerY -= 10;
break;
case KeyEvent.VK_DOWN:
playerY += 10;
break;
case KeyEvent.VK_LEFT:
playerX -= 10;
break;
case KeyEvent.VK_RIGHT:
playerX += 10;
break;
}
playerX = Math.max(0, Math.min(playerX, FRAME_WIDTH - PLAYER_WIDTH));
playerY = Math.max(0, Math.min(playerY, FRAME_HEIGHT - PLAYER_HEIGHT));
}
}
@Override
public void keyReleased(KeyEvent e) {}
public static void main(String[] args) {
new CatchingGame();
}
}
游戏逻辑:
- 使用 JFrame 作为游戏窗口。
- 使用 KeyListener 监听键盘事件,控制小人移动。
- 使用 Timer 定时生成元宝或铜钱,并让它们以一定速度下降。
- 使用 Rectangle 检测小人与元宝或铜钱的碰撞,并计分。
- 游戏时间 60 秒,结束后显示最终得分。
代码解释:
CatchingGame类继承 JFrame,并实现了 KeyListener 接口,用于监听键盘事件。playerX和playerY用于记录小人的坐标。score用于记录玩家得分。timeLeft用于记录剩余时间。isGameRunning用于控制游戏是否正在运行。items用于存储所有元宝或铜钱的坐标。generateItem()用于随机生成元宝或铜钱。moveItems()用于移动所有元宝或铜钱。checkCollision()用于检测碰撞并计分。endGame()用于结束游戏并显示得分。paint()用于绘制游戏画面。
注意:
由于 JFrame 的绘制方法 paint 是在事件调度线程中被调用的,因此我们在绘制方法中直接更新游戏状态可能会导致线程安全问题。在这个示例中,我们没有使用多线程,所以不会出现问题。但如果在实际项目中,最好使用 SwingUtilities.invokeLater() 将更新游戏状态的代码放在事件调度线程中执行。
希望这能帮助你理解这个简单的接元宝游戏示例。
原文地址: https://www.cveoy.top/t/topic/pTO 著作权归作者所有。请勿转载和采集!