swing快速入门(二十三)弹球小游戏

发布时间:2023年12月21日

注释很详细,直接上代码

上一篇

新增内容

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 {
        @Override
        public 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() {
            @Override
            public 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() {
            @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 ((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();
    }
}


效果演示:

在这里插入图片描述

文章来源:https://blog.csdn.net/m0_73756108/article/details/135137665
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。