1、实现思路
一个简单的双人乒乓球游戏的实现,让你能够了解游戏的基本逻辑和 Swing 组件的使用。以下是代码的详细逻辑解释:
- 导入必要的 Java Swing 类和事件处理类,这些类将用于创建游戏窗口、画布和事件处理。
- 定义游戏面板类 MultiplayerPongGame,它继承自 JPanel,这将用于绘制游戏的界面。
- 定义一些常量,包括挡板的宽度、高度,球的大小以及球的速度。
- 声明游戏中需要使用的变量,包括左边和右边玩家挡板的垂直位置、球的位置和速度,以及一个标志来表示游戏是否结束。
- 在 main 方法中,使用 SwingUtilities.invokeLater
来创建游戏窗口。设置窗口的大小、关闭操作和位置。然后创建 MultiplayerPongGame
实例,并将其添加到窗口中。使用定时器来触发游戏逻辑的更新和重新绘制。- MultiplayerPongGame
的构造函数设置了键盘事件监听器,这将允许玩家使用键盘控制挡板的移动。同时设置了焦点,以便能够接收键盘事件。- updateGame
方法是游戏的主要逻辑。它在每一帧中更新球的位置,并处理碰撞和游戏结束的情况。球的位置根据速度进行更新,碰撞检测会检查球是否撞到了上下边界或挡板。如果一方未接住球,游戏结束标志将被设置为
true。- paintComponent 方法负责绘制游戏界面。它首先绘制背景,然后绘制左右玩家的挡板和球。如果游戏结束,它会绘制一个红色的
“游戏结束” 文字。
2、操作方式
使用键盘来控制游戏中的挡板。 下面是操作方式的说明:
对于左边玩家:
按下键盘上的 “A” 键,可以让左边玩家的挡板向上移动。
按下键盘上的 “S” 键,可以让左边玩家的挡板向下移动。
对于右边玩家:
使用键盘上的上箭头键,可以让右边玩家的挡板向上移动。
使用键盘上的下箭头键,可以让右边玩家的挡板向下移动。 游戏的目标是让球在挡板之间来回弹跳,每当一方未能接到球时,游戏就会结束并显示
“游戏结束” 的文本。
3、代码实现
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class MultiplayerPongGame extends JPanel {
private static final int PADDLE_WIDTH = 10;
private static final int PADDLE_HEIGHT = 100;
private static final int BALL_SIZE = 20;
private static final int BALL_SPEED = 5;
private int player1Y = 250; // 左边玩家挡板的垂直位置
private int player2Y = 250; // 右边玩家挡板的垂直位置
private int ballX = 400; // 球的水平位置
private int ballY = 300; // 球的垂直位置
private int ballXSpeed = BALL_SPEED; // 球的水平速度
private int ballYSpeed = BALL_SPEED; // 球的垂直速度
private boolean gameOver = false; // 游戏结束标志
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("双人乒乓游戏");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
MultiplayerPongGame game = new MultiplayerPongGame();
frame.add(game);
Timer timer = new Timer(30, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!game.gameOver) {
game.updateGame();
game.repaint();
}
}
});
timer.start();
frame.setVisible(true);
});
}
public MultiplayerPongGame() {
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_A && player1Y > 0) {
player1Y -= 10; // 左边玩家向上移动
} else if (keyCode == KeyEvent.VK_S && player1Y < getHeight() - PADDLE_HEIGHT) {
player1Y += 10; // 左边玩家向下移动
} else if (keyCode == KeyEvent.VK_UP && player2Y > 0) {
player2Y -= 10; // 右边玩家向上移动
} else if (keyCode == KeyEvent.VK_DOWN && player2Y < getHeight() - PADDLE_HEIGHT) {
player2Y += 10; // 右边玩家向下移动
}
}
});
setFocusable(true);
requestFocus();
}
public void updateGame() {
ballX += ballXSpeed;
ballY += ballYSpeed;
// 球撞到上下边界
if (ballY <= 0 || ballY >= getHeight() - BALL_SIZE) {
ballYSpeed = -ballYSpeed;
}
// 球撞到挡板
if (ballX <= PADDLE_WIDTH && ballY >= player1Y && ballY <= player1Y + PADDLE_HEIGHT) {
ballXSpeed = -ballXSpeed;
}
if (ballX >= getWidth() - PADDLE_WIDTH - BALL_SIZE && ballY >= player2Y && ballY <= player2Y + PADDLE_HEIGHT) {
ballXSpeed = -ballXSpeed;
}
// 判断是否有一方没有接到球
if (ballX <= 0 || ballX >= getWidth() - BALL_SIZE) {
gameOver = true;
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.WHITE);
g.fillRect(0, player1Y, PADDLE_WIDTH, PADDLE_HEIGHT);
g.fillRect(getWidth() - PADDLE_WIDTH, player2Y, PADDLE_WIDTH, PADDLE_HEIGHT);
g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE);
if (gameOver) {
g.setColor(Color.RED);
g.setFont(new Font("Arial", Font.BOLD, 40));
g.drawString("GAME OVER", getWidth() / 2 - 100, getHeight() / 2);
}
}
}
4、运行实例
双人乒乓球游戏