[Java基础揉碎]坦克大战 java事件处理机制

目录

坦克大战游戏演示

​编辑

为什么要写这个项目 

java绘图坐标体系

java绘图技术

Graphics的常用方法

// 画直线 

​编辑

// 画矩形边框 

// 画填充矩形 

// 画填充椭圆

// 获取图片资源 

// 写字 

绘出坦克 

新建一个tankgame包, 新建一个类Tank, 里面包含横坐标和纵坐标

 新建一个Hero, 自己的坦克类, 去继承Tank

新建一个绘图区域类, 继承JPanel 

新建一个窗口类 

​编辑

 运行现在就拥有了一个窗口

在MyPanel里面写一个坦克的封装方法, 将坦克的坐标, 画笔, 方向, 类型传进去, 并根据不同类型坦克设置不同颜色

根据坦克方向, 来绘制坦克 

 将封装的坦克放到绘制类里面去

这一步运行看到已经有一个矩形了 

MyPanel的坦克方法里面继续添加 右边的轮子

 此时运行能看到两个轮子了

 MyPanel的坦克方法里面继续添加

  此时运行能看到

  MyPanel的坦克方法里面继续添加

  此时运行能看到

​编辑

  MyPanel的坦克方法里面继续添加

​编辑

更改以下颜色我方为黄色

继续画出向右的坦克

继续画出向下的坦克 

​编辑

继续画出向左的坦克  

java事件处理机制

具体实现是面板绘制类实现KeyListener接口, 监听键盘事件 

重写监听接口的三个方法 

假如在这里实现一些操作 

让窗口可以监听到键盘事件

运行就可以发现方法a里面的操作就打印出来了 

当向下的箭头触发的时候, 就坐标y++ , 然后重绘面板, 就可以实现向下移动了 

我们将上下左右都加进去 

Java的事件处理机制系统说明

 Java的事件处理机制深入理解

让坦克动起来

​编辑

实现keyListener 

重写接口的方法 

处理按下的时候的操作 

因为坦克那里的方向目前是写死的, 要在按下的时候能够改变它的方向, 需要把方向作为成员变量

绘制类里面将方向改为hero.getDirect() 

 处理按下wdsa就改变它的方向

在窗口类将事件加进去 

此时按下对应的键就可以改变它的方向了 

在Tank类里面增加移动的方法 

在绘制类增加移动 , 此时坦克就可以移动了

可不可以控制坦克移动的速度呢, 关键点就在移动的方法里面加的多少, 我们增加一个speed来控制它的速度 

同时加入speed的get, set

在绘制类初始化坦克的时候就可以直接set它的速度, 此时面向对象的感觉就上来了 

绘制敌人的坦克

新建一个敌人的坦克类, 继承坦克 

在绘制类里面将敌人的坦克放在线程安全的Vector里面, 并初始化三个坦克 

画出敌人的坦克

此时运行效果

更改以下方向默认为0 

坦克大战游戏(1.0版)

新建一个子弹类

增加子弹的属性 

增加一个构造器 

run方法里面相当于射击动作

子弹触碰到面板边界就销毁 

设计一个变量表示子弹是否还存活

 当子弹销毁时, 改变子弹的存活状态

在我们自己的坦克创建射击

​编辑

向右子弹的坐标 

 向下子弹的坐标 

​编辑

 向左子弹的坐标 

启动线程 

回到面板类, 按下j 就调用发射这个子弹 

画出自己坦克射击的子弹

绘制敌人坦克的子弹

​编辑

使用Vector保存多个shot 

​编辑

创建坦克对象时, 初始化一个Shot对象, 并启动

 绘制出子弹, 不存活的需要在集合中移除

我方坦克子弹打中敌人坦克

​编辑

给敌人坦克增加一个存活变量 

​编辑

判断我方子弹是否击中敌人坦克

在不断绘制的run方法里面去判断我方子弹是否碰到敌人坦克

增加一个判断, 否则会空异常

增加判断,在敌人坦克还活着的时候再去画

坦克爆炸

敌方坦克自由移动

 ​编辑

控制敌方坦克范围​编辑

​编辑

控制我方坦克范围

​编辑

实现防止发射一棵子弹时, 还没有消亡可以在打出一颗问题

​编辑如果要发射多颗子弹怎么实现(思考演示)暂时不实行

敌方移动发射 

我方坦克被击中爆炸 

IO流应用到坦克大战

防止坦克重叠的八种情况 

记录玩家总成绩 

为了实现"继续游戏", 保存退出界面坦克的坐标​编辑 ​编辑

恢复保存的坐标

增加坦克大战音乐

修改文件位置 

处理异常提高健壮性​编辑


​​​​​​​坦克大战游戏演示

为什么要写这个项目 

√好玩

√涉及到java各个方面的技术

        1. java面向对象编程

        2.多线程

        3. 文件i/o操作

        4. 数据库

        5. 巩固旧知识,学习新知识

java绘图坐标体系

java绘图技术

快速入门-画一个圆形

// 继承JPanel类 

找到画一个圆形的方法 

 

// 调用这个方法 

// 窗口类继承JFrame, 将面板放入窗口中

 

Graphics的常用方法

// 画直线 

// 画矩形边框 

// 画填充矩形 

// 画填充椭圆

// 获取图片资源 

// 写字 

绘出坦克 

新建一个tankgame包, 新建一个类Tank, 里面包含横坐标和纵坐标

 新建一个Hero, 自己的坦克类, 去继承Tank

新建一个绘图区域类, 继承JPanel 

新建一个窗口类 

-- 设置为了1000 

 运行现在就拥有了一个窗口

在MyPanel里面写一个坦克的封装方法, 将坦克的坐标, 画笔, 方向, 类型传进去, 并根据不同类型坦克设置不同颜色

根据坦克方向, 来绘制坦克 

使用file3DRect方法

 坦克坐标分析图

 将封装的坦克放到绘制类里面去

这一步运行看到已经有一个矩形了 

MyPanel的坦克方法里面继续添加 右边的轮子

 此时运行能看到两个轮子了

 MyPanel的坦克方法里面继续添加

  此时运行能看到

  MyPanel的坦克方法里面继续添加

  此时运行能看到

  MyPanel的坦克方法里面继续添加

  此时运行能看到

更改以下颜色我方为黄色

继续画出向右的坦克

继续画出向下的坦克 

继续画出向左的坦克  

java事件处理机制

具体实现是面板绘制类实现KeyListener接口, 监听键盘事件 

重写监听接口的三个方法 

 

假如在这里实现一些操作 

让窗口可以监听到键盘事件

运行就可以发现方法a里面的操作就打印出来了 

当向下的箭头触发的时候, 就坐标y++ , 然后重绘面板, 就可以实现向下移动了 

 

我们将上下左右都加进去 

Java的事件处理机制系统说明

事件源可以是个窗口, 鼠标, 键, 按钮...

事件对象就是刚才我们用到的KeyEvent 

生活中的例子

 Java的事件处理机制深入理解

 

让坦克动起来

实现keyListener 

重写接口的方法 

处理按下的时候的操作 

因为坦克那里的方向目前是写死的, 要在按下的时候能够改变它的方向, 需要把方向作为成员变量

 

绘制类里面将方向改为hero.getDirect() 

 处理按下wdsa就改变它的方向

在窗口类将事件加进去 

此时按下对应的键就可以改变它的方向了 

在Tank类里面增加移动的方法 

在绘制类增加移动 , 此时坦克就可以移动了

可不可以控制坦克移动的速度呢, 关键点就在移动的方法里面加的多少, 我们增加一个speed来控制它的速度 

同时加入speed的get, set

在绘制类初始化坦克的时候就可以直接set它的速度, 此时面向对象的感觉就上来了 

绘制敌人的坦克

新建一个敌人的坦克类, 继承坦克 

在绘制类里面将敌人的坦克放在线程安全的Vector里面, 并初始化三个坦克 

画出敌人的坦克

此时运行效果

更改以下方向默认为0 

初始化敌人的坦克同时增加一个方向

坦克大战游戏(1.0版)

新建一个子弹类

增加子弹的属性 

增加一个构造器 

run方法里面相当于射击动作

休眠50是为了让子弹不算停留形成轨迹,  通过方向改变字段坐标

子弹触碰到面板边界就销毁 

也就是跳出死循环while

设计一个变量表示子弹是否还存活

 当子弹销毁时, 改变子弹的存活状态

在我们自己的坦克创建射击

子弹要在炮筒的位置, 先找到向上炮筒的位置, 坦克的x+20 , y不变的坐标, 方向还是0

向右子弹的坐标 

 

 向下子弹的坐标 

 向左子弹的坐标 

启动线程 

回到面板类, 按下j 就调用发射这个子弹 

画出自己坦克射击的子弹

实现不停重绘 

绘制敌人坦克的子弹

使用Vector保存多个shot 

创建坦克对象时, 初始化一个Shot对象, 并启动

 绘制出子弹, 不存活的需要在集合中移除

我方坦克子弹打中敌人坦克

给敌人坦克增加一个存活变量 

判断我方子弹是否击中敌人坦克

 

在不断绘制的run方法里面去判断我方子弹是否碰到敌人坦克

增加一个判断, 否则会空异常

增加判断,在敌人坦克还活着的时候再去画

坦克爆炸

写一个炸弹类

定义一个炸弹Vector 

准备三张图片, 用于显示炸弹效果 

初始化三张图片 

一被击中就加一一个炸弹, 这个炸弹是有三张图片组成的 

画出炸弹 

敌人坦克被打掉之后应该在集合中删掉 

敌方坦克自由移动

 

 实现runnable接口

根据方向继续移动

休眠50毫秒, 随机改变方向 

退出线程,因为在被击中的时候isLive被置为false, 也就是非真为真的时候退出线程 

启动线程 

run里面上下左右都实现移动时实现走30步 , 让坦克不是走一步就转向

加入break;

控制敌方坦克范围

控制我方坦克范围


将窗口增加一点, 让绘制区域完全展示出来, 方便查看是否控制住了范围 

tip:绘制区域仍然是1000*750的 

实现防止发射一棵子弹时, 还没有消亡可以在打出一颗问题

首先实现防止发射一棵子弹时, 还没有消亡可以在打出一颗, 在hero为空的时候, 就是第一次按j的时候, 或者isLive为false碰到边界销毁的时候可以触发shotEnemyTank发射行为

如果要发射多颗子弹怎么实现(思考演示)暂时不实行

 

 

要实现控制只能发射5颗怎么控制

是否击中坦克改为判断多颗子弹 

敌方移动发射 

 

我方坦克被击中爆炸 

给坦克增加存活属性

判断我方子弹是否击中敌人坦克的方法改为坦克父类, 即所有坦克 ​​​​​​

编写我方坦克是否被击中方法 

判断我们的子弹是否击中了敌人坦克 移动到hitEnemyTank()下面

 

增加一个判断, 让敌方子弹击中我们的时候, 我方坦克消失

IO流应用到坦克大战

防止坦克重叠的八种情况 

一个坦克不管是那个朝向, 都会可能面对另外一个坦克是上下或者左右移动的, 上下或者左右移动它的长宽会发生变化

 

判断下标为0的这个坦克是否和后面的坦克发生重叠

 

 

一二两种情况

 

三四两种情况

 

五六种情况 

七八种情况 

 

最后, 如果没有进入switch语句, 返回一个false

 Mypanel设置给enemyTank

记录玩家总成绩 

 

 

写一个类用于文件交互

 

 

为了实现"继续游戏", 保存退出界面坦克的坐标
 

 

恢复保存的坐标

 

 

 

case 1 开始新游戏 case 2 是继续上局游戏

 

 

增加坦克大战音乐

//音乐播放类

拷贝音乐文件到src下面

启动播放文件

修改文件位置 

处理异常提高健壮性

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

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

相关文章

01_初识微服务

文章目录 一、微服务概述1.1 什么是微服务1.2 对比微服务架构与单体架构1.3 微服务设计原则1.4 微服务开发框架1.5 简单理解分布式部署与集群部署 二、微服务的核心概念2.1 服务注册与发现2.2 微服调用(通信)2.3 服务网关2.4 服务容错2.5 链路追踪参考链…

前端科举八股文-VUE篇

前端科举八股文-VUE篇 Vue响应式的基本原理?computed和watch的区别computed和methods的区别Slot是什么 ? 作用域插槽是什么?组件缓冲keep-alive是什么? 讲讲原理v-if,v-show的区别v-modal如何实现双向绑定组件中的data属性为什么是一个函数而不是对象…

python SciPy 和 NumPy 版本冲突

UserWarning: A NumPy version >1.19.5 and <1.23.0 is required for this version of SciPy (detected version 1.17.2) warnings.warn(f"A NumPy version >{np_minversion} and <{np_maxversion}"在使用 Python 的科学计算库时&#xff0c;经常会遇到各…

CSAPP Lab04——Cache Lab大师手笔,匠心制作

浮沉浪似人潮 哪会没有思念 你我伤心到 讲不出再见 ——讲不出再见 完整代码见&#xff1a;CSAPP/cachelab-handout at main SnowLegend-star/CSAPP (github.com) Part A: Cache Simulator 这个lab描述背大锅&#xff0c;开始我是真有点没看懂题目的描述。特别是“M 20,1”“…

基于Nodejs的简易邮件SMTP服务器

仅用于内部开发环境无法访问邮件服务器的情况下&#xff0c;测试SMTP邮件发送有没有成功。收到邮件发送请求后仅打印内容和保存附件用于测试验证。 安装库 实验环境使用了Nodejs版本16。 npm install smtp-server mailparser JS版SMTP服务器代码 没有使用TSL/SSL&#xff0c…

构建大型语言模型(LLM)产品的实战指南

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

双击bat文件查看ip地址

echo off echo Running batch file as administrator...:: 下面这行是以管理员身份运行 ipconfig 命令&#xff0c;并将结果输出到控制台 cmd /c "ipconfig"echo Batch file execution completed. pause注意文件名不能为 ipconfig.bat 可以是 ipconfigs.bat 另一种…

【JavaScript】JS 的 btoa 和 atob 全局函数

在 JavaScript 中&#xff0c;btoa 和 atob 是两个处理 Base64 编码的全局函数&#xff0c;它们通常用于在浏览器环境中对二进制数据进行编码和解码。 不过&#xff0c;需要注意的是&#xff0c;这两个函数并非 JavaScript 标准规范&#xff08;ECMAScript&#xff09;的一部分…

MATLAB .m文件的命名规则

matlab的.m文件的命名规则&#xff1a; 文件名命名要用英文字符&#xff0c;首字符不能是数字或下划线。 文件名不能与matlab的内部函数名相同。 .m文件名的命名尽量不要是简单的英文单词&#xff0c;最好是由大小写英文/数字/下划线等组成。 原因是简单的单词命名容易与mat…

基于多尺度相关小波分解的单幅图像去雾和去噪方法(MATLAB)

小波变换具有优美的数学背景和强大的多分辨率分析能力。它集成和发展了短时傅里叶变换的思想并克服了其时间窗口不可变的缺点。小波变换通过使用具有局部感受野和多尺度的基函数。形成了同时具有局部和全局性质的信号表征。与DCT等全局变换相比&#xff0c;小波变换可以防止局部…

58、试除法求约数

试除法求约数 题目描述 给定n个正整数ai&#xff0c;对于每个整数ai,请你按照从小到大的顺序输出它的所有约数。 输入格式 第一行包含整数n。 接下来n行&#xff0c;每行包含一个整数ai。 输出格式 输出共n行&#xff0c;其中第 i 行输出第 i 个整数ai的所有约数。 数据…

oracle查看序列

在Oracle数据库中&#xff0c;查看序列的方式主要有以下几种&#xff1a; 查看当前用户下的所有序列名称&#xff1a; sql复制代码 SELECT sequence_name FROM user_sequences; 查看所有用户的序列&#xff1a; sql复制代码 SELECT sequence_name FROM all_sequences; 查看…

Java面试八股之Executors可以创建哪几种类型的线程池

Executors可以创建哪几种类型的线程池 newSingleThreadExecutor&#xff1a; 创建一个单线程的线程池&#xff0c;此线程池确保所有的任务都在同一个线程中按顺序执行。适用于需要保证任务顺序执行&#xff0c;或者在单线程中运行的任务。 newFixedThreadPool&#xff1a; …

知识蒸馏——讨论区

更多内容请了解&#xff1a; 知识蒸馏——基础知识 知识蒸馏——学生模型 知识蒸馏——代码实现 知识蒸馏——讨论区 知识蒸馏——讨论区 一、教师模型的预测结果&#xff08;软标签&#xff09;与传统标签的区别&#xff1f;二、教师模型的软标签与真实标签的关系三、为什么学…

YOLOv5改进 | Conv篇 | 利用YOLOv10提出的UIB模块二次创新C3(附代码 + 完整修改教程)

一、本文介绍 本文给大家带来的改进机制是利用利用YOLOv10提出的UIB模块二次创新C3助力YOLOv5进行有效涨点,其中C2fUIB模块所用到的CIB模块是一种紧凑的倒置块结构,它采用廉价的深度卷积进行空间混合,并采用成本效益高的点卷积进行通道混合。本文针对该方法给出多种使用方法…

每日两题 / 34. 在排序数组中查找元素的第一个和最后一个位置 33. 搜索旋转排序数组(LeetCode热题100)

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; 根据二分函数&#xff0c;得到>target和<target的两个&#xff0c;分别是答案的l和r class Solution { public:vector<int> searchRange(vector<int>& nums,…

Python | Leetcode Python题解之第130题被围绕的区域

题目&#xff1a; 题解&#xff1a; class Solution:def solve(self, board: List[List[str]]) -> None:if not board:returnn, m len(board), len(board[0])que collections.deque()for i in range(n):if board[i][0] "O":que.append((i, 0))board[i][0] &q…

github有趣项目:Verilog在线仿真( DigitalJS+edaplayground)

DigitalJS https://github.com/tilk/digitaljs这个项目是一个用Javascript实现的数字电路模拟器。 它旨在模拟由硬件设计工具合成的电路 像 Yosys&#xff08;这里是 Github 存储库&#xff09;&#xff0c;它有一个配套项目 yosys2digitaljs&#xff0c;它可以转换 Yosys 将文…

前端学习日记Vue3---Day1

声明式渲染 使用简洁的模板语法&#xff0c;将数据与 DOM&#xff08;文档对象模型&#xff09;关联起来。通过这种方式&#xff0c;可以实现数据驱动的界面更新&#xff0c;简化开发流程。 示例 <!DOCTYPE html> <html lang"en"> <head><me…

awk的应用

步骤一&#xff1a;awk的基本用法 1&#xff09;基本操作方法 格式1&#xff1a;awk [选项] [条件]{指令} 文件 格式2&#xff1a;前置指令 | awk [选项] [条件]{指令} 其中&#xff0c;print 是最常用的编辑指令&#xff1b;若有多条编辑指令&#xff0c;可用分号分隔。 …