龟兔赛跑(基于GUI与多线程实现)

直击龟兔赛跑现场

下面这张图是我们设计龟兔赛跑界面的初始效果与基本组成结构:

接下来是我仅代表我个人提出的一些疑问与解答:

1、俩动物以图片的形式显示?

其实在这里两个动物类就像标签一样

标签组件是什么?用于短文本字符串或图片显示固定提示信息。

下面给出这个初始界面的代码与效果图:

class Race extends JFrame{JPanel p;private JButton b=new JButton("开始");//开始按钮private JLabel stateOfRabbit=new JLabel("乌龟和兔子的比赛现场");//显示比赛/兔子状态private JLabel rabbit =new JLabel(new ImageIcon("images/rabbit.jpg"));//兔子private JLabel tortoise =new JLabel(new ImageIcon("images/tortoise.jpg"));//乌龟public Race(){super("龟兔赛跑");//标题p=new JPanel(null);b.setBounds(20, 10, 70, 30);rabbit.setBounds(20, 100, 150, 166);tortoise.setBounds(20, 390, 150, 136);stateOfRabbit.setBounds(300, 20, 260, 50);stateOfRabbit.setFont(new Font("", Font.BOLD, 22));p.add(b);p.add(stateOfRabbit);p.add(rabbit);p.add(tortoise);this.add(p);this.setBounds(200,150,1000,650);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);}
}

2、多线程实现俩小动物比赛

在上面的代码中,我们把兔子乌龟都定为标签类,但是俩东西参加比赛,是要同时参与比赛过程的,这里要利用多线程实现,也就是兔子、乌龟这俩标签要在比赛过程中(进程)移动,他俩的行为都属于这个进程(比赛)中的俩线程。

我们知道线程的创建方式有很多种:

  • 继承Thread,重写run()(创建单独的类/匿名内部类)
  • 实现Runnable,重写run()(创建单独的类/匿名内部类)
  • 实现Callable,重写call()(创建单独的类/匿名内部类)
  • 使用lambda表达式
  • 线程工厂 ThreadFactory
  • 线程池 ThreadPoolEcecutor

在GUI的学习中我们知道可以把Rabblt定位一个类,继承JFrame类再改写可以实现我们想要的窗口效果。同样标签类也是这样,可以把Rabbit类继承Jlabel类实现想要的兔子标签。

一个类可以实现多个接口,但只能继承一个父类。这里很明显要么实现Runnable,要么实现Callable接口,那就拿实现Runnable来举例

class Race extends JFrame{......private Rabbit rabbit =new Rabbit(new ImageIcon("images/rabbit.jpg"));//兔子private Tortoise tortoise =new Tortoise(new ImageIcon("images/tortoise.jpg"));//乌龟.......class Rabbit extends JLabel implements Runnable{public Rabbit(Icon image) {super(image);}@Overridepublic void run() {}}class Tortoise extends JLabel implements Runnable{public Tortoise(Icon image) {super(image);}@Overridepublic void run() {}}}

 

3、兔子和乌龟跑起来?

这里就表示一下俩东西的x方向的位移就行了,窗口里的效果相当于是50米跑一样的。

俩东西一起出发,兔子领先过不了一会就闭了(不动-位移不变),乌龟此时依旧锲而不舍!˃̣̣̥᷄⌓˂̣̣̥᷅  但是很可惜!兔子居然就睡了4000ms就醒了!难道兔子是外星兔嘛!不过好在我龟也不是太慢!老天不负有心龟,🐢胜利!

利用组件可以在窗口里访问更新位置来实现兔子乌龟的移动效果

public abstract class Componentpublic Point getLocation() {return location();}public void setLocation(int x, int y) {move(x, y);}public void move(int x, int y) {synchronized(getTreeLock()) {setBoundsOp(ComponentPeer.SET_LOCATION);setBounds(x, y, width, height);}}
}

实现代码如下: 

乌龟状态:(一直低俗慢跑)

 class Tortoise extends JLabel implements Runnable{public Tortoise(Icon image) {super(image);}boolean stop;//默认falseint speed=4;int x,y;@Overridepublic void run() {//easy一直低速跑(未停时-未到终点前)while (!stop){//获取起始坐标x=getLocation().x;y=getLocation().y;//移动-更新坐标x+=speed;setLocation(x,y);//循环一次太快了不符合乌龟龟设,慢点慢点...同时也把cpu给人兔子让一让try {Thread.sleep(50);} catch (InterruptedException e) {throw new RuntimeException(e);}if(x>=MAX_LENGTH)stop=true;}}}

兔子状态:(快速跑-睡大觉-快速跑)

 class Rabbit extends JLabel implements Runnable{public Rabbit(Icon image) {super(image);}boolean stop;int speed=10;int x,y;@Overridepublic void run() {x=getLocation().x;y=getLocation().y;while (!stop){x+=speed;setLocation(x,y);try {Thread.sleep(500);//彼此彼此你也用您也用用cpuif(x<300)//小白兔全力冲刺!stateOfRabbit.setText("无敌飞毛腿!");//因为等下要大睡4000毫秒,所以直接在这里面写了,就不用在解决一边异常了if(x==300){//兔子此时跑到300px树下->睡大觉->又冲刺!stateOfRabbit.setText("兔子睡大觉!");Thread.sleep(4000);/** ->(x=300)时更改为 speed=0* ->x+=0(x=300)->slepp(50)->speed=10;setText(兔子惊讶..)*/if(speed==0){speed=10;stateOfRabbit.setText("兔子惊讶!全力冲刺吧!");}else {speed=0;}}if (x>=MAX_LENGTH){stateOfRabbit.setText("啊?乌龟赢了?哈哈哈哈啊哈哈哈");stop=true;}} catch (InterruptedException e) {throw new RuntimeException(e);}}}}

4、开始按钮-处理事件 

 b.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {new Thread(rabbit).start();new Thread(tortoise).start();b.setVisible(false);}});

完整代码见这里这里请点击吧!

文本形式的龟兔赛跑代码请点击

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单链表经典算法LeetCode--203.移除链表元素(两种方法解)

1.链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;【点击即可跳转】 分析此题提供两种思路&#xff1a; 1.遍历原链表&#xff0c;将值为val的节点释放掉&#xff08;双指针法&#xff09; 定义一个pcur指针指向头节点&#xff0c;定义一个prev指针指向NULL 需要注…

【全开源】微凌客洗护小程序FastAdmin+Uniapp(源码搭建/上线/运营/售后/维护更新)

一款基于FastAdminUniapp开发的洗护小程序系统&#xff0c;适用于线上下单到店核销的业务场景&#xff0c;拥有会员卡、优惠券、充值提现、商户管理等功能&#xff0c;提供Uniapp后台无加密源代码。 线上线下融合&#xff1a;微凌客洗护小程序适用于线上下单到店核销的业务场景…

基于SpringBoot+Vue社区老人健康信息管理系统

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统社区老人健康信息管理系统信息管理难度大&#xff0c;容错…

Python-VBA函数之旅-staticmethod函数

目录 一、staticmethod函数的常见应用场景 二、staticmethod函数使用注意事项 三、如何用好staticmethod函数&#xff1f; 1、staticmethod函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a; https://blog…

鸿蒙开发-ArkTS语言-XML

鸿蒙开发-UI-web 鸿蒙开发-UI-web-页面 鸿蒙开发-ArkTS语言-基础类库 鸿蒙开发-ArkTS语言-并发 鸿蒙开发-ArkTS语言-并发-案例 鸿蒙开发-ArkTS语言-容器 鸿蒙开发-ArkTS语言-非线性容器 文章目录 前言 一、XML概述 二、XML生成 三、XML解析 1.解析XML标签和标签值 2.解析XML属性…

Matlab 验证 复数的幂计算规则

复数的幂计算规则 close all a9; b0:0.1:5;result1 exp(1j*2*pi*a.*b); result2 (exp(1j*2*pi*a)).^b; idxfind(result1result2); b_idxb(idx);figure plot(b,angle(result1(:)),-r*) hold on plot(b,angle(result2(:)),bo) grid on

QT如何增删安装的组件

打开 uninstall QT 往下会看到让你选择 add or remove component。 接下去就可以修改组件了

Qt开发常见报错大全与解决办法

下面的报错是我日常开发经常遇到的,对着下面的解决方法一招搞定就行了。 我们没必要都去记住,只需要见方抓药即可。 目前版本有27个常见报错,持续更新中。 常见报错 翻译不起作用 你可能改了类名字,但是.ts文件里没有跟着改。 Cannot send events to objects owned by a…

目标检测算法YOLOv8简介

YOLOv8论文尚未发布&#xff0c;YOLOv8由Ultralytics公司推出并维护&#xff0c;源码见&#xff1a;https://github.com/ultralytics/ultralytics &#xff0c;于2024年1月发布v8.1.0版本&#xff0c;最新发布版本为v8.2.0&#xff0c;License为AGPL-3.0。 以下内容主要来自&am…

Linux-vi、vim

使用Xshell远程登录到Linux主机进行操作 命令行不用全部掌握&#xff0c; 一般编辑大文件&#xff0c;比较复杂的情况下&#xff0c; 我们还是使用Xftp工具&#xff0c; down下来再恢复回去。

day02-运算符和流程控制语句

Day 02 Java基础语法 1 .运算符 运算符:对字面量或者变量进行操作的符号 表达式:用运算符把字面量或者变量连接起来符合java语法的式子就可以称为表达式。不同运算符连接的表达式体现的是不同类型的表达式 例如:int a 10; int b 20; int c a b; 就叫做运算符 a b就叫表…

用hMailServer+roundcubemail+宝塔安装配置一个自己的邮箱服务

用hMailServerroundcubemail安装配置一个自己的邮箱服务 1、准备工具与资料&#xff1a; 云服务器一台 基础配置就行 2核4G。域名一个 以下用lizipro.cn示例。hMailServer安装包roundcubemail安装包异常处理插件补丁&#xff1a; libmysql.zip 2、hMailServer服务安装&#…