当前位置: 首页 > news >正文

绘图(一)弹球小游戏

AWT编程 · 语雀

仓库:Java图形化界面: Java图形化界面学习demo与资料 (gitee.com)

很多程序如各种小游戏都需要在窗口中绘制各种图形,除此之外,即使在开发JavaEE项目时, 有 时候也必须"动态"地向客户 端生成各种图形、图表,比如 图形验证码、统计图等,这都需要利用AWT的绘图功能。

组件绘图原理

之前我们已经学习过很多组件,例如Button、Frame、Checkbox等等,不同的组件,展示出来的图形都不一样,其实这些组件展示出来的图形,其本质就是用AWT的绘图来完成的。

在AWT中,真正提供绘图功能的是Graphics对象,那么Component组件和Graphics对象存在什么关系,才能让Component绘制自身图形呢?在Component类中,提供了下列三个方法来完成组件图形的绘制与刷新:

paint(Graphics g):绘制组件的外观;

update(Graphics g):内部调用paint方法,刷新组件外观;

repaint():调用update方法,刷新组件外观;

一般情况下,update和paint方法是由AWT系统负责调用,如果程序要希望系统重新绘制组件,可以调用repaint方法完成。

Graphics类的使用

实际生活中如果需要画图,首先我们得准备一张纸,然后在拿一支画笔,配和一些颜色,就可以在纸上画出来各种各样的图形,例如圆圈、矩形等等。

程序中绘图也一样,也需要画布,画笔,颜料等等。AWT中提供了Canvas类充当画布,提供了Graphics类来充当画笔,通过调用Graphics对象的setColor()方法可以给画笔设置颜色。

画图的步骤:

1.自定义类,继承Canvas类,重写paint(Graphics g)方法完成画图;

2.在paint方法内部,真正开始画图之前调用Graphics对象的setColor()、setFont()等方法设置画笔的颜色、字体等属性;

3.调用Graphics画笔的drawXxx()方法开始画图。

其实画图的核心就在于使用Graphics画笔在Canvas画布上画出什么颜色、什么样式的图形,所以核心在画笔上,下表中列出了Graphics类中常用的一些方法:

案例:

使用AWT绘图API,完成下图效果

演示代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;public class SimpleDraw {private final String RECT_SHAPE="rect";private final String OVAL_SHAPE="oval";private Frame frame = new Frame("这里测试绘图");private Button drawRectBtn = new Button("绘制矩形");private Button drawOvalBtn = new Button("绘制椭圆");//用来保存当前用户需要绘制什么样的图形private String shape="";private MyCanvas drawArea = new MyCanvas();public void init(){//为按钮添加点击事件drawRectBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {shape = RECT_SHAPE;drawArea.repaint();}});drawOvalBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {shape = OVAL_SHAPE;drawArea.repaint();}});//定义一个Panel,装载两个按钮Panel p = new Panel();p.add(drawRectBtn);p.add(drawOvalBtn);//把panel添加到frame底部frame.add(p,BorderLayout.SOUTH);//设置画布的大小drawArea.setPreferredSize(new Dimension(300,200));//把画布添加到frame中frame.add(drawArea);frame.pack();frame.setVisible(true);}public static void main(String[] args) {new SimpleDraw().init();}//1.自定义类,继承Canvas类,重写paint方法private class MyCanvas extends Canvas{@Overridepublic void paint(Graphics g) {Random r = new Random();if (shape.equals(RECT_SHAPE)){//绘制矩形g.setColor(Color.BLACK);g.drawRect(r.nextInt(200),r.nextInt(100),40,60);}if(shape.equals(OVAL_SHAPE)){//绘制椭圆g.setColor(Color.RED);g.drawOval(r.nextInt(200),r.nextInt(100),60,40);}}}
}

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

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

案例2:

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

演示代码2:

package awt_swimg.day03;import awt_swimg.day01.Utils;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class PinBall {//桌面宽度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 ySpeed = 10;//小球横向运行速度private int xSpeed = 5;//定义小球的初始坐标private int ballX = 120;private int ballY = 20;//定义球拍的初始坐标,x坐标会发生变化,y坐标不会发生变化private int RACKET_X = 120;private final int RACKET_Y = 340;//声明定时器private Timer timer;private JFrame frame=new JFrame("弹球游戏");private MyCanvas canvas=new MyCanvas();//定义游戏结束的标记private boolean isLose = false;private KeyListener event = new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();if (keyCode == KeyEvent.VK_LEFT) {if (RACKET_X > 0) {RACKET_X -= 10;}}if (keyCode == KeyEvent.VK_RIGHT) {if (RACKET_X < TABLE_WIDTH - RACKET_WIDTH) {RACKET_X += 10;}}}};private ActionListener timerTask=new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (ballX<=0||ballX>=TABLE_WIDTH-BALL_SIZE) {xSpeed=-xSpeed;}if (ballY<=0||ballY>=RACKET_Y-BALL_SIZE&&ballX>= RACKET_X &&ballX<= RACKET_X +RACKET_WIDTH) {ySpeed = -ySpeed;}if (ballY>RACKET_Y&&(ballX<RACKET_X||ballX>RACKET_X+RACKET_WIDTH)) {timer.stop();isLose=true;canvas.repaint();}ballX += xSpeed;ballY += ySpeed;canvas.repaint();}};private MenuBar menuBar=new MenuBar();private Menu option=new Menu("选项");private MenuItem reStart=new MenuItem("重新开始");private MenuItem exit=new MenuItem("退出");public void init(){frame.add(canvas);frame.setMenuBar(menuBar);menuBar.add(option);option.add(reStart);option.add(exit);exit.addActionListener(e -> System.exit(0));reStart.addActionListener(e -> {isLose=false;ballX = 120;ballY = 20;RACKET_X = 120;canvas.repaint();timer.start();});canvas.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));canvas.addKeyListener(event);frame.addKeyListener(event);timer=new Timer(50,timerTask);timer.start();Utils.setJFrame(frame);}public static void main(String[] args) {new PinBall().init();}public class MyCanvas extends Canvas{@Overridepublic void paint(Graphics g) {if (isLose) {g.setColor(Color.BLUE);g.setFont(new Font("Times",Font.BOLD,30));g.drawString("游戏结束!",80,200);}else{g.setColor(Color.red);g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE);g.setColor(Color.green);g.fillRect(RACKET_X, RACKET_Y, RACKET_WIDTH, RACKET_HEIGHT);}}}
}

相关文章:

绘图(一)弹球小游戏

AWT编程 语雀 仓库&#xff1a;Java图形化界面: Java图形化界面学习demo与资料 (gitee.com) 很多程序如各种小游戏都需要在窗口中绘制各种图形&#xff0c;除此之外&#xff0c;即使在开发JavaEE项目时&#xff0c; 有 时候也必须"动态"地向客户 端生成各种图形、…...

uniapp滑动事件

在Uniapp中&#xff0c;可以通过touchstart、touchmove和touchend等事件来监听滑动操作。以下是对这些事件的简要说明&#xff1a; touchstart&#xff1a;当手指触摸屏幕时触发该事件。可以通过event.touches属性获取到触摸点的信息。 touchmove&#xff1a;当手指在屏幕上滑…...

入门人工智能 —— 学习 python 使用 IDE :vscode 完成编程 (2)

入门人工智能 —— 学习 python 使用 IDE &#xff1a;vscode 完成编程 &#xff08;2&#xff09; 安装和配置 VSCode创建和运行 Python 代码使用 VSCode 的调试功能 在上一篇文章中&#xff0c;介绍了如何入门人工智能编程&#xff0c;并开始了学习 Python 编程语言的基础知识…...

MyBatis字段名和属性名不一样的解决方案

一、给字段起别名&#xff0c;保持和属性名一样 <! --List<Emp> getAllEmp( ); --><select id"getAllEmp" resultType"Emp">select eid , emp_name empName , age , sex, email from t_emp</ select>如上面的SQL语句将emp_name取别…...

Postman应用——Collection、Folder和Request

文章目录 Collection新建CollectionCollection重命名保存Request到Collection在Collection下创建Request删除Collection Folder新建FolderFolder重命名保存Request到Folder在Folder下创建Request在Folder下创建Folder删除Folder Request创建临时RequestRequest重命名删除Reques…...

驱动开发,stm32mp157a开发板的led灯控制实验

1.实验目的 编写LED灯的驱动&#xff0c;在应用程序中编写控制LED灯亮灭的代码逻辑实现LED灯功能的控制&#xff1b; 2.LED灯相关寄存器分析 LED1->PE10 LED1亮灭&#xff1a; RCC寄存器[4]->1 0X50000A28 GPIOE_MODER[21:20]->01 (输出) 0X50006000 GPIOE_ODR[10]-&g…...

黑客入侵机构,导致2万条信息被卖

近日据厦门日报报道&#xff0c;厦门一教育培训机构遭黑客入侵&#xff0c;2万条职工、学员信息被出售&#xff0c;教培机构被罚。 今年2月底&#xff0c;多名在厦门某教育培训机构学习的学员接到自称是该机构工作人员的电话&#xff0c;对方能准确说出学员的学科信息、缴费情…...

循环购:让消费者和商家共赢的新型电商模式

对于消费者来说&#xff0c;循环购可以让他们享受到优惠价格和高品质商品的同时&#xff0c;还能获得额外的收益和奖励。循环购可以激发消费者的积极性和忠诚度&#xff0c;增加他们对平台的信任和满意度。 对于商家来说&#xff0c;循环购可以让他们节省大量的营销成本和人力…...

分布式缓冲-Redis

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…...

C# 流Stream详解(3)——FileStream源码

【FileStream】 构造函数 如果创建一个FileStream&#xff0c;常见的参数例如路径Path、操作方式FileMode、权限FileAccess。 这里说下FileShare和SafeFileHandle。 我们知道在读取文件时&#xff0c;通常会有两个诉求&#xff1a;一是如何更快的读取文件内容&#xff1b;二…...

C语言的文件操作(炒详解)

⭐回顾回顾文件操作的相关细节⭐ 欢迎大家指正错误 &#x1f4dd;在之前的学习中&#xff0c;不管增加数据&#xff0c;减少数据&#xff0c;当程序退出时&#xff0c;所有的数据都会销毁&#xff0c;等下次运行程序时&#xff0c;又要重新输入相关数据&#xff0c;如果一直像这…...

27.基于ADS的不等分威尔金森功分器设计

27.基于ADS的不等分威尔金森功分器设计 等分的威尔金森功分器可以使用ADS非常快速的设计出来&#xff0c;但是不等分的功分器却没有便捷的设计方法&#xff0c;在此给出快速的设计方法与案例&#xff0c;方便大家实际设计。 等分版本的威尔金森功分器设计教程&#xff1a;12、…...

Linux自用命令

sudo su/sudo -i&#xff1a;获取root权限 cd&#xff1a;目录切换 cd / 切换到根目录 cd … 切换到上一级目录 cd ~ 切换到home目录 cd - 切换到上次访问的目录 ls&#xff1a;目录查看 ls 查看当前目录下的所有目录和文件 ls -a 查看当前目录下的所有目录和文件&#xff08;…...

clickhouse union all之后数据量不一致

环境&#xff1a; clickhouse版本&#xff1a;22.8.16.32 问题&#xff1a;clickhouse使用union all查询结果与每一段sql查询结果只和不一致 原因&#xff1a;因为clickhouse版本问题&#xff0c;官方给出不同的解释 解决方案&#xff1a;将union all的每一段sql用括号括起来…...

力扣刷题19-删除链表的倒数第N个节点

题目来源 题目描述&#xff1a; class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {//为了删除的格式一样&#xff0c;引入虚拟头节点ListNode dummyNodenew ListNode(1);dummyNode.nexthead;ListNode slowdummyNode;ListNode fastdummyNode;for(int…...

Unity中的简单数据存储办法

这段代码演示了Unity中的简单数据存储办法 当涉及到不同类型的存储时&#xff0c;下面是一些示例代码来演示在Unity中如何使用不同的存储方法&#xff1a; 1. 临时存储示例代码&#xff08;内存变量&#xff09;&#xff1a; csharp // 定义一个静态变量来存储临时计分 pub…...

Pytorch-MLP-CIFAR10

文章目录 model.pymain.py参数设置注意事项运行图 model.py import torch.nn as nn import torch.nn.functional as F import torch.nn.init as initclass MLP_cls(nn.Module):def __init__(self,in_dim3*32*32):super(MLP_cls,self).__init__()self.lin1 nn.Linear(in_dim,1…...

SQL2 查询多列

描述 题目&#xff1a;现在运营同学想要用户的设备id对应的性别、年龄和学校的数据&#xff0c;请你取出相应数据 示例&#xff1a;user_profile iddevice_idgenderageuniversityprovince12138male21北京大学Beijing23214male复旦大学Shanghai36543female20北京大学Beijing42…...

算法分享三个方面学习方法(做题经验,代码编写经验,比赛经验)

目录 0 . 前言&#xff1a;&#xff08;遇到OI不要慌&#xff09;&#xff08;只要道路对了&#xff0c;就不怕遥远&#xff09; 1. 做题经验谈 1.1 做题的目的 1.2 我对于算法比赛的题目的看法 1.2.1 类似题 1.2.2 套模型&#xff1a; 1.3 在训练过程中如何做题 1.4 一些建议&…...

爬虫 — 验证码反爬

目录 一、超级鹰二、图片验证模拟登录1、页面分析1.1、模拟用户正常登录流程1.2、识别图片里面的文字 2、代码实现 三、滑块模拟登录1、页面分析2、代码实现&#xff08;通过对比像素获取缺口位置&#xff09; 四、openCV1、简介2、代码3、案例 五、selenium 反爬六、百度智能云…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...