注释很详细,直接上代码
上一篇
新增内容
1. 键盘响应监听
2. 使用定时器事件更新画板
3. 定时器事件的开始与暂停
4. 弹球小游戏的坐标逻辑判断
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class swing_test_19 {//创建一个窗口private Frame frame = new Frame("swing_test_19");//桌面宽度private int TABLE_WIDTH = 300;//桌面高度private 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 speedX = 10;private int speedY = 5;//定义变量,记录球拍的坐标private int racketX = 120;private final int racketY = 340;//定义变量,标识当前游戏是否结束private boolean isOver = false;//声明一个定时器private Timer timer;//自定义一个类,继承canvas类,充当画布class MyCanvas extends Canvas {@Overridepublic void paint(Graphics g) {//绘制游戏内容if (isOver) {//游戏结束//画笔设置为蓝色g.setColor(Color.BLUE);//设置游戏字体g.setFont(new Font("Times", Font.BOLD, 30));//在游戏屏幕中间输出“游戏结束”g.drawString("游戏结束", TABLE_WIDTH / 2 - 100, TABLE_HEIGHT / 2);} 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);//绘制球拍}}}//创建绘画区MyCanvas drawArea = new MyCanvas();//组装视图public void init() {//游戏逻辑控制//完成键盘按键对球拍坐标的移动改变KeyListener listener = new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {//获取键盘按键的代码int keyCode = e.getKeyCode();if (keyCode == KeyEvent.VK_LEFT) {//左键if (racketX > 0) {racketX -= 10;}} else if (keyCode == KeyEvent.VK_RIGHT) {//右键if (racketX < TABLE_WIDTH - RACKET_WIDTH) {racketX += 10;}}}};//给frame和drawArea注册监听器frame.addKeyListener(listener);drawArea.addKeyListener(listener);ActionListener task = new ActionListener() {@Overridepublic 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 ((ballx > racketX + RACKET_WIDTH || ballx < racketX) && bally > racketY - BALL_SIZE) {//停止定时器timer.stop();isOver = true;//游戏结束//重绘界面drawArea.repaint();}//更新小球的坐标,重绘界面ballx += speedX;bally += speedY;drawArea.repaint();//重绘界面}};//对小球坐标的控制timer = new Timer(100, task);timer.start();//启动定时器//设置drawArea的大小drawArea.setPreferredSize(new Dimension(TABLE_WIDTH, TABLE_HEIGHT));frame.add(drawArea);//将drawArea添加到frame中frame.pack();frame.setVisible(true);}public static void main(String[] args) {new swing_test_19().init();}
}
效果演示: