龟兔赛跑(基于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);
        }
        @Override
        public void run() {}
    }

    class Tortoise extends JLabel implements Runnable{
        public Tortoise(Icon image) {
            super(image);
        }
        @Override
        public void run() {}
    }

}

 

3、兔子和乌龟跑起来?

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

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

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

public abstract class Component
    public 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;//默认false
        int speed=4;
        int x,y;

        @Override
        public 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;

        @Override
        public void run() {
            x=getLocation().x;
            y=getLocation().y;

            while (!stop){
                x+=speed;
                setLocation(x,y);

                try {
                    Thread.sleep(500);//彼此彼此你也用您也用用cpu
                    if(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);
            }
        });

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习实战(35)】数据处理之数据增强(不修改标签)

一、简介 不需要修改标签的数据增强有变明&#xff0c;变暗&#xff0c;hsv增强&#xff0c;color增强&#xff0c;cutout&#xff0c;模拟太阳光&#xff0c;雨水&#xff0c;雾等。 二、 代码 import random import numpy as np import os.path import cv2 from PIL impor…

发布GPT-5的方式可能会与以往不同;开源vocode使用 AI 自动拨打电话;开源gpt智能对话客服工具;AI自动写提示词

✨ 1: vocode 用AI通过声音与用户进行实时交流 Vocode是一个旨在帮助开发者快速构建基于声音的大型语言模型&#xff08;LLM&#xff09;应用程序的开源库。简单来说&#xff0c;如果你想要开发一个能够通过声音与用户进行实时交流的应用&#xff0c;比如电话机器人、语音助手…

三层交换机与路由器连通上网实验

三层交换机是一种网络交换机&#xff0c;可以实现基于IP地址的高效数据转发和路由功能&#xff0c;通常用于大型企业、数据中心和校园网络等场景。此外&#xff0c;三层交换机还支持多种路由协议&#xff08;如OSPF、BGP等&#xff09;&#xff0c;以实现更为复杂的网络拓扑结构…

一、Prometheus介绍及部署

目录 一、什么是Prometheus&#xff1f; 二、特点 三、prometheus 的生态组件&#xff1a; 四、Prometheus架构图 五、prometheus 的工作模式 六、Prometheus 的工作流程 七、部署Prometheus 1、prometheus配置文件介绍 2、配置文件详解 3、配置systemd服务 用systemct…

原子学习笔记4——GPIO 应用编程

一、应用层如何操控 GPIO 与 LED 设备一样&#xff0c;GPIO 同样也是通过 sysfs 方式进行操控&#xff0c;进入到/sys/class/gpio 目录下&#xff0c;如下所示&#xff1a; gpiochipX&#xff1a;当前 SoC 所包含的 GPIO 控制器&#xff0c;我们知道 I.MX6UL/I.MX6ULL 一共包…

r语言数据分析案例-北京市气温预测分析与研究

一、选题背景 近年来&#xff0c;人类大量燃烧煤炭、天然气等含碳燃料导致温室气 体过度排放&#xff0c;大量温室气体强烈吸收地面辐射中的红外线&#xff0c;造 成温室效应不断累积&#xff0c;使得地球温度上升&#xff0c;造成全球气候变暖。 气象温度的预测一直以来都是…

Java基础(三):Java异常机制以及底层实现原理

&#x1f337;一、异常 ☘️1.1 什么是异常 Java异常是程序发生错误的一种处理机制&#xff0c;异常的顶级类是Throwable&#xff0c;Throwable字面意思就是可抛出的&#xff0c;该类是所有的错误和异常的超类&#xff0c;只有Throwable类或者Throwable子类的实例对象才可以被…

【小红书采集软件】根据关键词批量爬取小红书笔记正文、笔记链接、发布时间、转评赞藏等

一、背景介绍 1.1 爬取目标 熟悉我的小伙伴可能了解&#xff0c;我之前开发过2款软件&#xff1a; 【GUI软件】小红书搜索结果批量采集&#xff0c;支持多个关键词同时抓取&#xff01; 【GUI软件】小红书详情数据批量采集&#xff0c;含笔记内容、转评赞藏等&#xff0c;支…

开启异步线程的方法

1&#xff0c;开启异步线程&#xff0c;在启动类上加注解&#xff1a; 2&#xff0c;自定义线程池&#xff1a; Configuration public class PromotionConfig {Beanpublic Executor generateExchangeCodeExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExec…

ROS2 安装与测试

文章目录 ROS2 安装与测试ROS2 安装1. 设置编码2. 添加源3. 安装 ROS24. 设置环境变量 ROS2 示例测试实例一&#xff1a;命令行实例实例二&#xff1a;小海龟仿真实例 参考链接 ROS2 安装与测试 ROS2 安装 基于 Ubuntu 22.04 LTS 操作系统。 1. 设置编码 sudo apt update &…

获取Android开发板已连接WiFi密码

硬件/软件环境&#xff1a; 1&#xff09;全志芯片开发板A40i 2&#xff09;Android Studio Giraffe | 2022.3.1 Patch 3 连接条件&#xff1a; 1)两端都是USB-A接口线&#xff0c;一端插入电脑端USB接口&#xff0c;另一端插入开发板USB接口&#xff1b; 2&#xff09;Andr…

Spring-Bean 作用域

作用域 作用域案例 public class BeanScopeDemo {AutowiredQualifier("singletonPerson")Person person;AutowiredQualifier("prototypePerson")Person person1;AutowiredQualifier("prototypePerson")Person person2;AutowiredSet<Person&g…

perf 中的 cpu-cycles event 介绍

perf 中的 cpu-cycles event 介绍 cycles简介 cycles事件记录处理器核心执行的时钟周期数。每个时钟周期代表处理器内部时钟振荡器的一个周期。这个事件通常用于衡量处理器的执行速度&#xff0c;因为它直接反映了指令执行所需的时间。一个较高的cycles计数可能意味着代码执行…

【数据结构】顺序表与链表的差异

顺序表和链表都是线性表&#xff0c;它们有着相似的部分&#xff0c;但是同时也有着很大的差异。 存储空间上的差异&#xff1a; 对于插入上的不同点&#xff0c;顺序表在空间不够时需要扩容&#xff0c;而如果在使用realloc函数去扩容&#xff0c;会有原地扩容和异地扩容两种情…

Blender细节补充

1.饼状菜单&#xff0c;用于快速切换/选择 例如&#xff1a; ~&#xff1a;切换视图 Z&#xff1a;切换着色方式 &#xff0c;&#xff1a;切换坐标系 .&#xff1a;切换基准点 Shift S&#xff1a;吸附 有两种使用方式&#xff1a; -点选 -滑选&#xff0c;按快捷键…

在Tiled中制作动画瓦片图

什么是瓦片图&#xff1f;瓦片图是指用图块把游戏场景评出来 工具安装链接&#xff1a;Tiled | Flexible level editor 资源下载教程 资源下载&#xff1a;Mystic Woods - 16x16 Pixel Art Asset Pack by Game Endeavor 解压后得到一些资源 新建图块集合 Tiled的安装就不介绍…

Nginx或Tengine服务器配置SSL证书

目录 前提条件 步骤一&#xff1a;下载SSL证书 步骤二&#xff1a;在Nginx服务器安装证书 步骤三&#xff1a;验证SSL证书是否配置成功 前提条件 已通过数字证书管理服务控制台签发证书SSL证书绑定的域名已完成DNS解析&#xff0c;即您的域名与主机IP地址相互映射已在Web服…

全志ARM-SG90舵机

控制转角 向黄色信号线“灌入”PWM信号。 PWM波的频率不能太高&#xff0c;50hz&#xff0c;即周期1/频率1/500.02s&#xff0c;20ms左右数据&#xff1a; 不同的PWM波形对应不同的旋转角度&#xff0c;以20ms为周期&#xff0c;50hz为频率的PWM波 定时器需要定时20ms,关心的单…

Ubuntu24安装搜狗输入法,修复闪屏问题

下载deb安装包&#xff1a;搜狗输入法linux-首页 安装&#xff1a;sudo dpkg -i 1.deb 搜狗输入法linux-安装指导 重启&#xff0c;但是完成后闪烁。按以下步骤更改桌面配置。 sudo gedit /etc/gdm3/custom.conf 取消WaylandEnable的注释即可

Python 函数式编程

匿名函数 Python 允许用 lambda 关键字创造匿名函数。匿名顾名思义就是没有名字&#xff0c;即不需要以标准的方式来声明&#xff0c;比如说&#xff0c;使用 def 加函数名来声明。一个完整的 lambda “语句”代表了一个表达式&#xff0c;这个表达式的定义体必须和声明放在同…