Java图形化界面编程——弹球游戏 笔记

news2024/12/26 11:50:27

Java也可用于开发一些动画。所谓动画,就是间隔一定的时间(通常小于0 . 1秒 )重新绘制新的图像,两次绘制的图像之间差异较小,肉眼看起来就成了所谓的动画 。

​ 为了实现间隔一定的时间就重新调用组件的 repaint()方法,可以借助于 Swing 提供的Timer类,Timer类是一个定时器, 它有如下一个构造器 :
Timer(int delay, ActionListener listener): 每间隔 delay 毫秒,系统自动触发 ActionListener 监听器里的事件处理器方法,在方法内部我们就可以调用组件的repaint方法,完成组件重绘。

案例2:

​ 使用AWT画图技术及Timer定时器,完成下图中弹球小游戏。

请添加图片描述
请添加图片描述

使用键盘左右键来控制粉色球拍的水平移动,小球碰到窗口边界和球拍会反弹,并且落到球拍下方就会游戏结束并出现结束界面。

package Draw;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PinBall {
    //创建窗口对象
    private Frame frame = new Frame("弹球游戏");

    //1.设置桌面和球拍各自的宽度和高度
    private final int TABLE_WIDTH = 300;
    private final int TABLE_HEIGHT = 400;


    private final int RACKET_WIDTH = 60;
    private final int RACKET_HEIGHT = 20;

    //2.设置小球的大小,即小球的直径
    private final int BALL_SIZE = 16;

    //3.记录小球的坐标
    //注意坐标原点是窗口左上角
    private int ballX = 120;    //并且初始化小球的坐标
    private int ballY = 20;

    //4.设置小球在X和Y方向上分别移动的速度
    private int speedY = 10;
    private int speedX = 5;

    //5.记录球拍的坐标
    private int racketX = 120;
    private final int racketY = 340;       //球拍的Y坐标一直不变,即球拍一直在水平移动

    //6.游戏是否结束的标识
    private boolean isOver = false;

    //7.定时器:声明一个定时器
    private Timer timer;

    //8.画布:自定义一个类,继承Canvas,充当画布
    //只实现画面的绘制,不管游戏逻辑的变换
    private class MyCanvas 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);  //设置球拍的坐标和大小
            }
        }
    }

    //9.画笔:创建绘画区域
    MyCanvas drawArea = new MyCanvas();

    public void init() {
        //组装视图,游戏逻辑的控制
        //如何控制小球和球拍的变换

        //10.完成球拍坐标的变化,通过键盘左右键来实现
        KeyListener listener = new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                //获取当前按下的键
                int keyCode = e.getKeyCode();
                if(keyCode == KeyEvent.VK_LEFT) { //这个KeyEvent.VK_LEFT意味这是键盘的左箭头
                    //向左移动
                    //TODO
                    if(racketX <= 10) racketX = 0;
                    else racketX -= 10;

                }
                if(keyCode == KeyEvent.VK_RIGHT) {
                    //向右移动
                    if(racketX > (TABLE_WIDTH - RACKET_WIDTH - 10)) racketX = TABLE_WIDTH - RACKET_WIDTH;
                    else racketX += 10;
                }
            }
        };

        //给Frame和drawArea注册监听器
        frame.addKeyListener(listener);
        drawArea.addKeyListener(listener);

        //11.小球坐标的控制
        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)) {
                    //碰到上边界,以及碰到球拍,判定条件是小球y>球拍y,并且小球在球拍宽度的范围内
                    speedY = -speedY;
                }

                if(ballY>racketY-BALL_SIZE && (ballX < racketX || ballX >racketX+RACKET_WIDTH)){
                    //当前小球超出了球拍能接到的范围,游戏结束

                    //停止定时器
                    timer.stop();
                    //修改游戏结束的标记
                    isOver = true;
                    //重绘界面
                    drawArea.repaint();
                }

                ballX += speedX;
                ballY += speedY;

                //重绘界面
                drawArea.repaint();
            }
        };
        timer = new Timer(100,task);  //一百毫秒执行一次
        timer.start();

        //组装界面
        drawArea.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));
        frame.add(drawArea);

        //设置frame最佳大小和可见性
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new PinBall().init();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1444034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos7之忘记Root用户密码的处理方式

Centos7之忘记Root用户密码的处理方式 文章目录 Centos7之忘记Root用户密码的处理方式1.场景描述2. 重置密码1. 重启系统进入编辑界面2. 按方向键下键↓&#xff0c;找到设置语言的地方3. 进入bash界面后&#xff0c;可以输入passwd命令重新设置root密码 1.场景描述 长时间未使…

vue中没有hooks

文章目录 一、前言二、啥是 hooks&#xff1f;三、React hooks 是什么&#xff1f;四、vue composition API 与 react hooks 的对比五、总结六、最后 一、前言 经常在网上看到有很多同学说&#xff1a;“在 Vue 中创建 hooks&#xff1f;提升 什么什么什么” 我每次看到这样的…

电商小程序07显示用户个人信息

目录 1 全局变量2 控制登录按钮显示3 设置布局4 搭建我的页面5 修改个人信息总结 在登录章节我们已经实现了用户名和密码登录首页的功能&#xff0c;在登录之后&#xff0c;可以切换到我的页面&#xff0c;显示用户的头像和名称&#xff0c;可以修改个人信息。本篇我们介绍一下…

机器学习系列——(十八)K-means聚类

引言 在众多机器学习技术中&#xff0c;K-means聚类以其简洁高效著称&#xff0c;成为了数据分析师和算法工程师手中的利器。无论是在市场细分、社交网络分析&#xff0c;还是图像处理等领域&#xff0c;K-means都扮演着至关重要的角色。本文旨在深入解析K-means聚类的原理、实…

【计算机网络】Web HTTP

Web和HTTP HTTP 超文本传输协议 HyperText Transfer Protocol HTTP使用TCP作为支撑传输协议 由一个客户程序和一个服务器程序实现一些常见名词。。。无状态协议 stateless protocol 不保存关于客户的任何信息非持续/持续链接 non-persistent con…

PKI - 借助Nginx 实现Https_使用CA签发证书

文章目录 Pre概述操作步骤1. 生成 CA 密钥对2. 生成自签名的 CA 证书3. 生成服务器密钥对和证书签名请求 (CSR)4. 使用 CA 签署服务器证书 Nginx Https 自签证书1. 生成自签名证书和私钥2. 配置 Nginx 使用 CA签发的 HTTPS 证书3. 重启 Nginx 服务4. 直接访问5. 不验证证书直接…

Linux文本三剑客(2)

文章目录 一、Linux文本三剑客之awk使用方法awk 的原理实例一&#xff1a;只查看test.txt文件&#xff08;100行&#xff09;内第20到第30行的内容&#xff08;企业面试&#xff09;实例二&#xff1a;已知test.txt文件内容为 BEGIN 和 END 模块实例一&#xff1a;统计/etc/pas…

【C++】类的6个默认成员函数

目录 1. 类的6个默认成员函数 2. 构造函数 3. 析构函数 4. 拷贝构造函数 5. 运算符重载 5.1运算符重载 5.2赋值运算符重载 5.3前置和后置重载 5.4日期类的实现 6. const成员函数 7. 取地址及const取地址操作符重载 1. 类的6个默认成员函数 对于一个空类&#xff0c;编…

echarts 曲线图自定义提示框

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>曲线图</title><!-- 引入 ECharts 库 -->…

[word] word参考文献怎么对齐 #学习方法#微信#笔记

word参考文献怎么对齐 word参考文献怎么对齐&#xff1f; 未对齐的参考文献如下 全部选中参考文献内容 选中段落快捷窗口显示/隐藏编辑标记快捷方式和标号快捷方式中左对齐 选中之后参考文献又自动加了标号 把之前的角标和文字之间全部删除 完成图

黄金交易策略(Nerve Nnife.mql4):1秒救地球的第六单

一轮趋势做单&#xff0c;正常情况是5单便可以完成一轮盈利。但当开仓后快速追加5单也无法止盈的话&#xff0c;我们得找准极其苛刻的条件开出第6单&#xff0c;并指望完成利润覆盖。代码如下&#xff1a; if(count > 5 && count < 10 && isDown(small_…

JDK新特性

JDK新特性 函数式接口和Lambda 表达式Stream流操作新日期API操作其他新特性 Lambda 是一个匿名函数&#xff0c;我们可以把 Lambda表达式理解为是一段可以传递的代码&#xff08;将代码 像数据一样进行传递&#xff09;。可以写出更简洁、更 灵活的代码。作为一种更紧凑的代码…

STL - map 和 set

1、关联式容器 vector、list、deque、 forward_list(C11)等&#xff0c;这些容器统称为序列式容器&#xff0c;因为其底层为线性序列的数据结构&#xff0c;里面 存储的是元素本身 关联式容器也是用来存储数据的&#xff0c;与序列式容器不同的是&#xff0c;其里面存储的是<…

单片机与外设的交互

单片机与外设的交互是嵌入式系统中非常重要的一个基础知识点。单片机是一个集成在同一芯片上的中央处理器、存储器和输入/输出接口,它可以根据用户编写的程序与各种外部设备即外设进行交互。单片机与外设之间的交互主要通过单片机上的输入/输出口(I/O口)来实现。 I/O口的工作原…

HSM加密机原理:密钥管理和加密操作从软件层面转移到物理设备中 DUKPT 安全行业基础8

HSM加密机原理 硬件安全模块&#xff08;HSM&#xff09;是一种物理设备&#xff0c;设计用于安全地管理、处理和存储加密密钥和数字证书。HSM广泛应用于需要高安全性的场景&#xff0c;如金融服务、数据保护、企业安全以及政府和军事领域。HSM提供了一种比软件存储密钥更安全…

rsyslog远程记录系统日志

rsyslog是一个快速处理手机系统日志的开源程序&#xff0c;提供了高性能&#xff0c;安全功能和模块化设计&#xff0c;rsyslog是syslog的升级版&#xff0c;他讲多重来源输入输出转换结果到目的地&#xff0c;rsyslog被广泛用于Linux系统以通过TCP/UDP协议转发或接收日志消息。…

OpenCV每日函数 结构分析和形状描述符(9) ApproxPolyDP函数 拟合曲线

一、Douglas -Peucker 算法 也称为Ramer-Douglas-Peucker 算法或迭代端点拟合算法,是一种通过减少点数来平滑折线(由线性线段组成的线)的算法。简化曲线应保留原始曲线的粗略形状,但仅包含定义原始曲线的点的子集。 粗化程度由单个参数 ε 控制,该参数定义原始点和简化曲线…

【开源】JAVA+Vue.js实现森林火灾预警系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 系统基础模块2.3 烟雾传感器模块2.4 温度传感器模块2.5 历史记录模块2.6 园区数据模块 三、系统设计3.1 用例设计3.1.1 森林园区基础系统用例设计3.1.2 森林预警数据用例设计 3.2 数据库设计3.2.1 烟雾…

Oracle数据字典学习1

之前查看了几个用户的默认表空间&#xff0c;是从user_users来查看的&#xff1b; 根据资料&#xff1b; ORACLE中数据字典视图分为3大类,用前缀区别&#xff0c;分别为&#xff1a;USER&#xff0c;ALL 和 DBA&#xff1b; 许多数据字典视图包含相似的信息&#xff1b; USER_…

读书笔记之《运动改造大脑》:运动是最佳的健脑丸

《运动改造大脑》的作者是约翰•瑞迪&#xff08;John Ratey&#xff09; / 埃里克•哈格曼&#xff08;Eric Hagerman&#xff09;&#xff0c;原著名称为&#xff1a;Spark&#xff1a;the revolutionary new science of exercise and the brain&#xff0c;于 2013年出版约翰…