Java入门小游戏之一:弹球游戏
运行结果:
源代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main {
// 创建窗口对象
private Frame frame = new Frame("弹球游戏");
// 桌面宽度
private final int TABLE_WIDTH = 300;
// 桌面高度
private final int TABLE_HEIGHT = 400;
// 球拍的高度和宽度
private final int RACKET_WIDTH = 60;
private final int RACKET_HEIGHT = 20;
// 小球的大小
private final int Ball_SIZE = 16; // 这个是直径的大小
// 定义变量 记录小球的坐标
private int ballX = 120;
private int ballY = 20;
// 定义变量 记录小球在x和y轴方向上分别的移动速度
private int speedY = 10;
private int speedX = 5;
// 定义变量 记录球拍的坐标
private int racketX = 120;
private final int racketY = 340; // 这里设置为常量 是因为我们只需要 这个球拍沿着x轴移动
// 定有变量 标识当前游戏是否已结束
private boolean isOver = false;
// 声明一个定时器
private Timer timer;
// 自定义一个类 继承canves 充当画布
private class MyCanves extends Canvas {
@Override
public void paint(Graphics g) {
// TODO 这里绘制内容
if (isOver) {
// 游戏结束
g.setColor(Color.BLUE); // 设置字体为蓝色
g.setFont(new Font("Times", Font.BOLD, 30)); // 第一个参数是给这个字体类型取的名字
// 第二个参数表示的是 把这个字体加粗 第三个参数表示 这个字体的大小
g.drawString("游戏结束!", 50, 200); // 结束的文字 和 这个文字的位置
} else {
// 游戏中
// 绘制 小球
g.setColor(Color.RED); // 设置小球为红色
g.fillOval(ballX, ballY, Ball_SIZE, Ball_SIZE); // 前两个参数是小球的位置 后两个是 小球的长宽
// 绘制 球拍
g.setColor(Color.PINK); // 设置为 粉色
g.fillRect(racketX, racketY, RACKET_WIDTH, RACKET_HEIGHT); // 参数含义同上
}
}
}
MyCanves drawArea = new MyCanves(); // 创建一块属于自己的画布
public void init() {
// 组装视图 游戏逻辑控制
// 完成球拍坐标的变化
KeyListener listener = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
// 获取当前按下的键
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) { // VK_LEFT表示的是向左的标
// <-向左移动
if (racketX > 0) { // 防止左边越界
racketX -= 5;
}
}
// -> 向右移动
if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) { // VK_RIGHT 表示的是右标
if (racketX < TABLE_WIDTH - RACKET_WIDTH) {
racketX += 5;
}
}
}
};
// 给Frame和drawArea注册监听器
frame.addKeyListener(listener);
drawArea.addKeyListener(listener);
// 小球坐标控制
ActionListener task = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 根据边界范围 修正速度
if (ballX <= 0 || ballX >= (TABLE_WIDTH - Ball_SIZE)) {
speedX = -speedX;
}
if (ballY <= 0 || (ballY > racketY - Ball_SIZE && ballX > racketX && ballX < racketX + RACKET_WIDTH)) {
speedY = -speedY;
}
if (ballY > racketY - Ball_SIZE && (ballX < racketX || ballX > racketX + RACKET_WIDTH)) {
// 当前小球超出了球拍的范围 游戏结束
// 停止计时器
timer.stop();
// 修改游戏是否结束的标记
isOver = true;
// 重绘界面
}
// 更新小球的坐标 重绘界面
ballX += speedX;
ballY += speedY;
// 重绘界面
drawArea.repaint();
}
};
timer = new Timer(100, task); // 第一个参数单位为毫秒 这个是 让这个界面0.1s更新一次
timer.start();
drawArea.setPreferredSize(new Dimension(TABLE_WIDTH, TABLE_HEIGHT)); // 设置画布的大小
frame.add(drawArea);
// 设置关闭按钮
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// 设置合适的大学
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
new Main().init();
}
}