韩顺平0基础学java——第28天

news2025/1/19 16:36:09

p569-591

坦克大战!(绘图+监听事件+线程+文件处理)


绘图

绘图原理

Component类提供了两个和绘图相关最重要的方法:

1. paint(Graphics g)绘制组件的外观

2. repaint()刷新组件的外观。

当组件第一次在屏幕显示的时候,程序会自动的调用paint()方法来绘制组件。

在以下情况paint0将会被调用:
1.窗口最小化再最大化
2窗口的大小发生变化
3. repaint方法被调用

绘图方法

Graphics类
Graphics类你可以理解就是画笔,为我们提供了各种绘制图形的方法:[参考jdk帮助文档]

1.画直线drawLine(int x1,int y1,int x2.int y2)
2.画矩形边框drawRect(int x, int y, int width, int height)

3.画椭圆边框drawOval(int x, int y, int width, int height)

4.填充矩形 fillRect(int x, int y, int width, int height)
5.填充椭圆fillOval(int x, int y, int width, int height)

6.画图片drawlmage(lmage img, int x, int y., ..)
7.画字符串drawString(String str, int x, int y)

8.设置画笔的字体setFont(Font font)
9设置画笔的颜色setColor(Color c)

使用代码:

class MyPanel extends JPanel{//panel是画板
    @Override
    public void paint(Graphics g) {//Graphics的g是画笔
        super.paint(g);//调用父类方法完成初始化。?初始化了谁?
       // g.drawOval(10,10,150,125);//画圆(椭圆
       // g.drawLine(10,10,100,100);//直线
        //g.drawRect(10,10,100,100);//矩形
       // g.setColor(Color.BLUE);//设置画笔颜色
        //g.fillRect(10,10,100,100);//填充矩形
        //g.setColor(Color.RED);//设置为红色
        //g.fillOval(10,10,100,100);//填充圆
       // Image im1 = Toolkit.getDefaultToolkit().getImage("D:\\madake\\02.jpg");//加载图片
        //g.drawImage(im1,10,10,175,221,this );//卧槽成功了!
        //g.setColor(Color.RED);//画字符串,设置字体等
        //g.setFont(new Font("隶书",Font.BOLD,50));//字体和颜色
        //g.drawString("四斋蒸鹅心",100,100);//小细节,这个100,100是字符串的左下角
    }
}

画坦克

package com.day28.TankGame;
import javax.swing.JPanel;
import java.awt.*;

public class MyPanel extends JPanel {
    Mytank hero = null;

    public MyPanel(){
        hero = new Mytank(100,100);//初始化自己坦克的位置
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0,0,1000,750);
        //专门写一个方法来画坦克
        drawTank(hero.getX(),hero.getY(),g,0,0);
        drawTank(hero.getX()+60,hero.getY(),g,0,1);

    }

    /**
     *
     * @param x 坦克的左上角坐标
     * @param y 坦克右上角坐标
     * @param g 画笔
     * @param direct 方向
     * @param type 坦克类型(敌人的还是我的?
     */

    public void drawTank(int x,int y,Graphics g,int direct,int type){

        switch (type){
            case 0://我的坦克
                g.setColor(Color.cyan);
                break;
            case 1://敌人的坦克
                g.setColor(Color.yellow);
                break;
        }
        //根据坦克的方向来绘制
        switch (direct){
            case 0:{
                Graphics2D g2d = (Graphics2D) g;
                g2d.setStroke(new BasicStroke(5));
                g.fill3DRect(x,y,10,60,false);//左轮子
                g.fill3DRect(x+30,y,10,60,false);//右轮子
                g.fill3DRect(x+10,y+10,20,40,false);//身体
                g.fillOval(x+10,y+20,20,20);//炮台
                g.drawLine(x+20,y,x+20,y+30);//炮
                break;
            }
            default:
                System.out.println("其他情况暂未处理!");
        }
    }
}

事件处理机制:移动控制 

监听键盘KeyListener

java事件处理是采取"委派事件模型"。当事件发生时,产生事件的对象,会把此"信息”传递·给"事件的监听者"处理,这里所说的“信息"实际上就是java.awt.event 事件类库里某个类所创建的对象,把它称为“事件的对象"。

1.前面我们提到几个重要的概念事件源,事件,事件监听器我们下面来全面的介绍它们。
2事件源:事件源是一个产生事件的对象,比如按钮,窗口等。
3.事件:事件就是承载事件源状态改变时的对象,比如当键盘事件、鼠标事件、窗口事件等等,会生成一个事件对象,该对象保存着当前事件很多信息,比如KeyEvent对象有含有被按下键的Cod值。java.awt.event包和javax.swing.event包中定义了各种事件类型
5.事件监听器接口:
⑴当事件源产生一个事件,可以传送给事件监听者处理
(2)事件监听者实际上就是一个类,该类实现了某个事件监听器接口比如前面我们案例中的MyPanle就是一个类,它实现了KeyListener接口,它就可以作为一个事件监听者,对接受到的事件进行处理
(3)事件监听器接口有多种,不同的事件监听器接口可以监听不同的事件,一个类可以实现多个监听接口
(4)这些接口在java.awt.event包和javax.swing.event包中定义。列出常用的事件监听器接口,查看jdk文档聚集了.

让坦克动起来

动了


请大家在HspTankGame02.java基础上画出三辆敌人的坦克,注意颜色。如图所示·分析:
1.因为敌人的坦克,是在MyPanel上,所以我们的代码在MyPanel
2.因为敌人的坦克,后面有自己特殊的属性和方法,可以单开一个EnemyTank

3.敌人坦克数量多,可以放入到集合Vector ,因为考虑多线程问题

线程基础

进程

1.进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为
该进程分配内存空间。当我们使用迅雷,又启动了一个进程,操作系统将为迅雷分配新的内存空间。
2.进程是程序的一次执行过程,或是正在运行的一个程序。是动态过程:有它自身的
产生、存在和消亡的过程

惊吓

什么是线程

1.线程由进程创建的,是进程的一个实体

2一个进程可以拥有多个线程,如“我使用迅雷的时候,可以同时下载多个文件,每一个下载任务就对应一个线程”。

3.单线程:同一个时刻,只允许执行一个线程
4.多线程:同一个时刻,可以执行多个线程,比如:一个qq进程,可以同时打开多个聊天窗口,一个迅雷进程,可以同时下载多个文件

5.并发:同一个时刻,多个任务交替执行,造成一种“貌似同时”的错觉,简单的说,单核cpu实现的多任务就是并发。
4.并行:同一个时刻,多个任务同时执行。多核cpu可以实现并行。

比如这个电脑就是8核cpu

Thread类

1.当一个类继承了Thread类,该类就可以当做一个线程。

2.我们通常会重写run方法,写上自己的业务代码。

3. run Thread类实现了Runnable接口的run方法


线程源码追踪

1.当我们点run的时候就进入一个进程

2.进程启动后就开启一个线程

System.out.println("喵喵喵~"+i+"次"+Thread.currentThread().getName());//这是线程名

3.当Cat.start()开始时,主线程不会阻塞,会继续执行。(间隔1000ms)

所以你们单核cpu就并发,多核就并行? 

4.JConsole可以监控线程执行的情况

public class Cup {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.start();//启动线程,我调用这个的时候就会调用run,为啥不直接run?
        //因为run只是个普通的方法,并不会真正启动线程。这样就会把run执行完毕才向下。
        //相当于它是main的一部分,在main线程里。

        for (int i = 0; i < 60; i++) {
            System.out.println("主线程!"+i+Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

class Cat extends Thread{
    @Override
    public void run() {
        int i =0;
        while(i++<65){
            System.out.println("喵喵喵~"+i+"次"+Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

最后都涉及到操作系统了。

线程的基本使用


.1. java是单继承的,在某些情况下一个类可能已经继承了某个父类,这时在用继承Thread类方法来创建线程显然不可能了。
2. java设计者们提供了另外一个方式创建线程,就是通过实现Runnable接口来创建线程

public class Xianche {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Thread t = new Thread(dog);//把狗放进去,静态代理。
        t.start();
    }
}

class Dog implements Runnable{
    int count =0;
    @Override
    public void run() {
        while(count++<10){
            System.out.println("狗叫!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

继承Thread vs 实现Runnable的区别

1.从java的设计来看,通过继承Thread或者实现Runnasle接口来创建线程本质上没有区别,从jdk帮助文档我们可以看到Thread类本身就实现了Runnable接口
2.实现Runnable接口方式更加适合多个线程共享一个资源的情况,并且避免了单继承的限制

线程终止

基本说明
1.当线程完成任务后,会自动退出。
2.还可以通过使用变量来控制run方法退出的方式停止线程,即通知方式
        说人话就是,再main线程里写个控制 小线程的loop的语句

        同时,小线程的loop默认为true,放在while里

线程常用方法

常用方法第一组
1.setName //设置线程名称,使之与参数name相同

2. getName //返回该线程的名称
3.start//使该线程开始执行;Java虚拟机底层调用该线程的startO 方法

4.run//调用线程对象 run方法;
5.setPriority //更改线程的优先级

6.getPriority //获取线程的优先级
7.sleep1/在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)

8. interrupt //中断线程
注意事项和细节
1.start底层会创建新的线程,调用run,run 就是一个简单的方法调用,不会启动新线程
2.线程优先级的范围:max,min,nom


3. interrupt,中断线程,但并没有真正的结束线程。所以一般用于中断正在休眠线程4.sleep:线程的静态方法,使当前线程休眠。

常用方法第二组
1. yield:线程的礼让。让出cpu,让其他线程执行,但礼让的时间不确定,所以也不一定礼让成功
2. join:线程的插队。插队的线程一旦插队成功,则肯定先执行完插入的线程所有的任务
案例:创建一个子线程,每隔1s输出hello,输出20次,主线程每隔1秒,输出hi,输出20次.要求:两个线程同时执行,当主线程输出5次后,就让子线程运行完毕,主线程再继续
 

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

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

相关文章

Dify知识库接入微信

Dify知识库接入微信 看到此文章&#xff0c;相信您已经搭建好了Dify知识库&#xff0c;还没有Dify知识库请先部署好后再来尝试将Dify接入微信 准备材料如下 搭建好的Dify知识库里的api接口和key24小时不关机的服务器一个 &#xff08;推荐浪浪云的服务器简单方便)需要一个微信…

数学建模整数规划学习笔记

与线性规划的本质区别在于决策变量是否取整。 &#xff08;1&#xff09;分支定界法 若不考虑整数限制先求出相应松弛问题的最优解&#xff1a; 若松弛问题&#xff08;线性规划&#xff09;无解&#xff0c;则ILP&#xff08;整数规划&#xff09;无解。 若求得的松弛问题最…

校园任务平台系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;论坛管理&#xff0c;任务咨询管理&#xff0c;用户管理&#xff0c;基础数据管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;任务资讯公告&#…

代码随想录第29天|贪心算法

基础知识 原理: 选择每一阶段的最优解, 从而达到全局最优解套路: 无, 只能举反例, 想不出反例则可以尝试用贪心算法 455. 分发饼干 思路: 使用贪心策略 每次用大饼干满足大胃口的孩子(用小饼干则会浪费)或用小饼干满足小胃口的孩子 一定是遍历孩子, 不能遍历饼干, 否则结果不…

大模型时代,新手和程序员如何转型入局AI行业?

在近期的全国两会上&#xff0c;“人工智能”再次被提及&#xff0c;并成为国家战略的焦点。这一举措预示着在接下来的十年到十五年里&#xff0c;人工智能将获得巨大的发展红利。技术革命正在从“互联网”向“人工智能”逐步迈进&#xff0c;我将迎来新一轮技术革新和人才需求…

鸿蒙开发:【组件启动规则(FA模型)】

组件启动规则&#xff08;FA模型&#xff09; 启动组件是指一切启动或连接应用组件的行为&#xff1a; 启动PageAbility、ServiceAbility&#xff0c;如使用startAbility()等相关接口。连接ServiceAbility、DataAbility&#xff0c;如使用connectAbility()、acquireDataAbili…

MySQL之复制(八)

复制 复制和容量规划 备库什么时候开始延迟 一个关于备库比较普遍的问题是如何预测备库会在何时跟不上主库。很难去描述备库使用的复制容量为5%与95%的区别&#xff0c;但是至少能够在接近饱和前预警并估计复制容量。首先应该古纳差复制延迟的尖刺。如果有复制延迟的曲线图&…

如何将现有系统逐步优化成微服务设计

目录 基础服务改造核心步骤准备阶段实施阶段 基础服务设计 本文诞生于学习架构实践专栏后的深思以及总结&#xff0c;结合公司之前“大泥球”的架构风格&#xff0c;改造服务设计的思维。 改造公司系统服务主要原因&#xff1a;1、代码类似“屎山”&#xff0c;牵一发而动全身&…

Freertos-----任务之间的消息传递(使用消息队列信号量方法)

这次来分享任务之间的数据传递的方法&#xff0c;方法有很多种&#xff0c;我展示2种&#xff0c;让大家对freertos有更深刻的印象 目录 消息队列 信号量 消息队列 首先直接打开普中的例程&#xff0c;然后在里面加上ADC的驱动代码&#xff0c;先初始化外设先&#xff0c;我…

亚足联官方公布18强赛抽签时间及规则,国足确认位列第五档,你们觉得国足能进世界杯吗?

亚足联官方公布18强赛抽签时间及规则&#xff0c;国足确认位列第五档&#xff0c;你们觉得国足能进世界杯吗&#xff1f; 今天亚足联官方宣布了世预赛18强赛分组抽签仪式时间&#xff0c;本次抽签仪式将于6月27日15点在马来西亚吉隆坡举行。除了抽签时间之外&#xff0c;足联还…

L55--- 257.二叉树的所有路径(深搜)---Java版

1.题目描述 2.思路 &#xff08;1&#xff09;因为是求二叉树的所有路径 &#xff08;2&#xff09;然后是带固定格式的 所以我们要把每个节点的整数数值换成字符串数值 &#xff08;3&#xff09;首先先考虑根节点&#xff0c;也就是要满足节点不为空 返回递归的形式dfs(根节…

Service方法增加@Asyn注解后导致bean无法找到 NoSuchBeanDefinitionException

Service方法增加Asyn注解后导致bean无法找到 NoSuchBeanDefinitionException 场景处理方法原因 场景 首先确认的是Service添加了Service或Component等注解&#xff0c;另外也增加了ComponentScan确定扫描的包路径是包含对应Service的&#xff0c;但就是无法找到这个bean。 通…

C51与MDK共存版本安装教程

目录 一、安装准备 1.1 新建文件夹 1.2 网盘链接-加Q 667198390 二、 双版本共存安装教程 2.1 安装Keil5 C51 2.2 安装Keil5 MDK 2.3 C51和MDK的共存 2.4 生成许可证 2.5 安装STM32Pack包 一、安装准备 1.1 新建文件夹 如下图&#xff1a; 在合适的网盘里&#xff08…

阿里云如何实现express的自动化部署(保姆级教程)

本篇文章将详细介绍一下阿里云如何实现express的自动化部署&#xff0c;作者本人总结的保姆级教程&#xff01;&#xff01;&#xff01; 首先去阿里云官网 &#xff08;阿里云-计算&#xff0c;为了无法计算的价值) 搜索函数计算fc 如果没有开通过选择免费开通&#xff0c;…

计算机组成原理 | 计算机系统概述

CPI:(Clockcycle Per Instruction)&#xff0c;指每条指令的时钟周期数。 时钟周期&#xff1a;对CPU来说&#xff0c;在一个时钟周期内&#xff0c;CPU仅完成一个最基本的动作。时钟脉冲是计算机的基本工作脉冲&#xff0c;控制着计算机的工作节奏。时钟周期 是一个时钟脉冲所…

【第24章】Vue实战篇之用户信息展示

文章目录 前言一、准备1. 获取用户信息2. 存储用户信息3. 加载用户信息 二、用户信息1.昵称2.头像 三、展示总结 前言 这里我们来展示用户昵称和头像。 一、准备 1. 获取用户信息 export const userInfoService ()>{return request.get(/user/info) }2. 存储用户信息 i…

服装连锁实体店bC一体化运营方案

一、引言 随着互联网的快速发展和消费者购物习惯的变化&#xff0c;传统服装连锁实体店在面对新的市场环境下亟需转型升级。BC&#xff08;Business to Consumer&#xff09;一体化运营方案的实施将成为提升服装连锁实体店竞争力和顾客体验的关键举掖。商淘云详细介绍服装连锁…

深度学习论文: Depth Anything V2

深度学习论文: Depth Anything V2 Depth Anything V2 PDF: https://arxiv.org/pdf/2406.09414v1 代码:https://depth-anything-v2.github.io/ PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: https://github.com/shanglianlm0525/PyTorch-Networks …

黑神话悟空-吉吉国王版本【抢先版】

在中国的游戏市场中&#xff0c;一款名为“黑神话悟空”的游戏引起了广泛的关注。这款游戏以中国传统的神话故事“西游记”为背景&#xff0c;创造了一个令人震撼的虚拟世界。今天&#xff0c;我们要来介绍的是这款游戏的一种特殊版本&#xff0c;那就是吉吉国王版本。 在吉吉国…

Go微服务: redis分布式锁在集群中可能遇到的问题及其解决方案

概述 我们的 redis 一般都是集群来给我们程序提供服务的&#xff0c;单体的redis现在也不多见 看到上面是主节点redis和下面是6个重节点redis&#xff0c;主节点和重节点的通讯都是畅通没问题的这个时候&#xff0c;我们有 gorouting 写我们的数据&#xff0c;那它就会用到我们…