《uni-app》一个非canvas的飞机对战小游戏实现-碰撞检测的实现

2023-05-16

在这里插入图片描述

这是一个没有套路的前端博主,热衷各种前端向的骚操作,经常想到哪就写到哪,如果有感兴趣的技术和前端效果可以留言~博主看到后会去代替大家踩坑的~接下来的几篇都是uni-app的小实战,有助于我们更好的去学习uni-app~
主页: oliver尹的主页
格言: 跌倒了爬起来就好~
准备篇:https://oliver.blog.csdn.net/article/details/127185461
启动页实现:https://oliver.blog.csdn.net/article/details/127217681
敌机模型实现:https://oliver.blog.csdn.net/article/details/127332264
requestAnimationFrame详解:https://oliver.blog.csdn.net/article/details/127377916
我方飞机实现:https://oliver.blog.csdn.net/article/details/127477230
子弹模型实现:https://oliver.blog.csdn.net/article/details/127702195

《uni-app》一个非canvas的飞机对战小游戏实现-碰撞检测的实现

  • 一. 前言
  • 二. 阅读对象与难度
  • 三. 项目地址以及最终效果
  • 四. 碰撞的实现
    • 4.1 分析分析
    • 4.2 碰撞检测
    • 4.3 爆炸动画
  • 五. 阶段性展示
  • 六. 小结

一. 前言

上一篇中主要分享的是子弹这个模型功能的实现,包括了:子弹的样式,子弹的创建坐标,子弹的位移操作等等 明显的是,到这一步我们的游戏主体还没有完成,因为子弹发射出去了,当与敌机交叉的时候子弹会穿过敌机,这不明显是不大合理的,子弹应该要摧毁敌机才行~
因此,本文将实现的是 碰撞检测 相关的内容,通过碰撞检测可以将我方飞机,子弹与敌机相互关联起来,形成一个相对完整的小游戏,耐心看完,或许你会所有收获~

二. 阅读对象与难度

本文难度属于:中级,本文中主要实现的我方飞机发射子弹后子弹与敌方飞机的碰撞检测相关内容
具体内容可以参考以下的思维导图:
在这里插入图片描述

三. 项目地址以及最终效果

文本代码已上传CSDN上的gitCode,有兴趣的小伙伴可以直接clone,项目地址:https://gitcode.net/zy21131437/planegameuni
如果有小伙伴愿意点个星,那就非常感谢了~最终效果图如下:
在这里插入图片描述

四. 碰撞的实现

4.1 分析分析

通过效果图,我们可以大致知道要实现的内容一共有两个:

  • 第一个,子弹与敌机的碰撞检测;
  • 第二个,敌机的爆炸动画被触发,包括大飞机爆炸动画和小飞机的爆炸动画;

这两个都是需要我们去实现的,只有实现了这两个后飞机大战这个小游戏才算是勉强可以正常玩耍了~

4.2 碰撞检测

在开始之前不妨思考一下,这个碰撞检测应该在什么时候执行?这明显是一个很关键的问题,不同的人有不同的解决方案,以本文为例,本文中的碰撞检测的执行时机在于敌机的每一次的 requestAnimationFrame 循环内,也就是说,每一次敌机在进行位移动画的时候都会去检测一遍有没有子弹与当前的敌机进行了碰撞,一旦进行碰撞那么,就要触发对应的后续,比如爆炸动画以及缓存中移除该飞机;
执行时机我们知道了,那么碰撞这个概念该怎么去实现呢?我们先看一段代码,代码并不复杂

export function isCollision(target, enemy) {
	return !(
		target.x + target.width < enemy.x ||
		enemy.x + enemy.width < target.x ||
		target.y + target.height < enemy.y ||
		enemy.y + enemy.height < target.y
	);
}

这一段代码就是用来做碰撞检测的,代码量上是不是非常简单,但细看一眼又觉得不大好理解,觉得很绕,其实仔细想想所谓碰撞检测不就是做了一个判断吗,判断两个DOM是否存在重叠,如果存在重叠那么就是碰撞了,需要我们后续处理,下面我们就仔细看一下这段代码,一行一行看:
首先第一行,定义了一个名为 isCollision 的函数,这个函数接收两个参数,很明显,这两个参数就是用来进行检测的两方~
第二行,第二行是返回,并且这个返回针对运算结果执行了!这个取反的操作;
从第三行开始就是两个DOM的碰撞判断了,先看第三行,第三行是一个判断

target.x + target.width < enemy.x

这段判断的意思是说,target的x轴的坐标加上target的宽度小于enemy在X轴上的坐标,什么意思呢?看个示意图:
在这里插入图片描述

简单的说,假设target的坐标加上其本身的宽度还小于enemy在X轴上的值的话,那target一定在enemy的左侧位置
再看第四行:

enemy.x + enemy.width < target.x

同理,这段判断的意思是说,enemy的x轴的坐标加上enemy的宽度小于target在X轴上的坐标,这就代表着target一定是在enemy的右侧,如果不大清楚可以继续看个示意图
在这里插入图片描述
enemy一定在target的左侧,换句话说,target一定会在enemy的右侧
第五行:

target.y + target.height < enemy.y

target的Y坐标加上target的高度小于enemy的Y坐标,直接看示意图
在这里插入图片描述
如果target的Y坐标加上高度依然小于enemy的Y坐标,这就代表target一定是在enemy的上方位置
第六行:

enemy.y + enemy.height < target.y

enemy.y的Y坐标加上enemy.y的高度小于target的Y坐标,直接看示意图
在这里插入图片描述
如果enemy的Y坐标加上高度依然小于target的Y坐标,这就代表target一定是在enemy的下方位置;

到这里我们不难发现,从第五行到第九行就是一个判断的过程,判断了两个DOM在上、下、左、右这四个方向上的是否是不重合的,最后做了个取反,如果值为true,那么就代表这两者是重合、交叉的部分,也就是发生碰撞了
因此,我们只需要在敌机执行 requestAnimationFrame 的时候做一个检测,检测是否存在敌机与子弹发生碰撞,添加一个 isCollision 方法

this.moveTimer = () => {
  //敌机移动
  this.move();

  // 碰撞检测
  this.isCollision();

  // 重绘,无限循环
  requestAnimationFrame(this.moveTimer);
};
this.moveTimer();

碰撞检测代码如下

isCollision() {
  if (this.bulletData.length === 0) return;

  this.bulletData.forEach(el => {

    const collision = isCollision(el, this.data);
    if (collision) {
      new Promise(resolve => {
        this.data.isExplosion = true;

        // 删除子弹
        this.$emit('removeBullet', el.id);

        setTimeout(() => resolve(), 450);
      }).then(res => {
        this.remove();
      });
    }
  });
}

检测到如果与任意一个子弹发生碰撞,那么立即将 isExplosion 设置为true,且将子弹的ID上传到父级,让其删除子弹~

4.3 爆炸动画

敌机的爆炸动画其实我们在之前已经分享过了,这边再简单分享一下,将其和子弹碰撞串起来,核心的点在于上一篇中的 isExplosion ,当 isExplosion 被设置成true的时候,也就是这一段

this.data.isExplosion = true;

一旦data的isExplosion为true,那么我们在computed中设置的样式会立即发生对应的变化

	computed: {
		getEnemyClass() {
			const classStyle = [`enemy_${this.data.type}`];
			const explosion = {};
			explosion[`enemy_${this.data.type}_effect`] = this.data.isExplosion;
			classStyle.push(explosion);
			return classStyle;
		}
	},

原来返回的是:

[`enemy_1`]

会变成返回

[`enemy_1`,{enemy_1_effect:true}]

这就代表enemy_1_effect这个类名上添加的animation动画会被立刻触发,其爆炸效果也就会立刻显示;
可能有小伙伴会问,这里的延迟是怎么实现的,我们知道爆炸效果是有一个延迟的,爆炸效果持续了0.45秒,0.45秒后需要将敌机移除,这里的延迟是通过 promise+setTimeout 实现的

new Promise(resolve => {
  this.data.isExplosion = true;

  // 删除子弹
  this.$emit('removeBullet', el.id);

  setTimeout(() => resolve(), 450);
}).then(res => {
  this.remove();
});

通过 setTimeout 将移除这个功能延迟到0.45秒之后执行,这样就实现了县执行爆炸动画,当爆炸动画显示了0.45秒以后,执行 remove函数,将对应敌机删除掉;

五. 阶段性展示

到这一章节,我们已经实现的效果图如下:
在这里插入图片描述

六. 小结

本文主要概述了碰撞以及爆炸效果的实现,主要包含:

  • 碰撞检测:我们在敌机每次渲染位移的时候多进行了一步碰撞检测,在检测中如果发现子弹与敌机存在DOM上的交叉,那么我们就认为两种进行碰撞了,一旦发生碰撞敌机就需要执行爆炸动画,之后移除敌机,而子弹则在一开始碰撞时就立刻进行移除~
  • 爆炸动画:爆炸动画其实在之前的对应模型实现中就已经实现了,这里只是给予其触发的一个提示,当这个提示出现时,敌机立刻执行爆炸动画~

到这里,飞机大战算是简单的,基本的能玩了,有我方飞机,有敌机,有子弹,子弹能摧毁敌机,基本上所有主要条件算是凑齐了,有兴趣的小伙伴一定要亲自试试~还是非常有趣的;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《uni-app》一个非canvas的飞机对战小游戏实现-碰撞检测的实现 的相关文章

  • C 语言使用宏自定义可打印的枚举(enum) 类型

    1 前言 xff1a 说点废话 xff0c 时间紧的请直接跳过 xff0c 看后面的实现 尽管本人很反感 C 语言中的宏定义 xff0c 特别是滥用宏定义经常会让问题变的扑朔迷离 xff0c 但是不得不承认 xff0c 在某些时候 xff0
  • Matlab GUI设计之坐标转换(附Matlab GUI设计学习手册完整版pdf)

    文章目录 如何开始 xff1f 1 界面布局2 编写回调函数 相信看这篇文章的你们大部分没有用Matlab做过界面设计 xff0c 其实不只是你们 xff0c 我也是第一次 xff08 手动滑稽 xff09 xff0c 在此将我的经验同大家
  • 【Linux】线程互斥

    目录 1 进程线程间的互斥相关背景概念 2 互斥量mutex 2 1 基本概念 2 2 售票系统举例 2 3 解释 3 互斥量的接口 3 1 初始化互斥量 3 1 1 静态分配 3 1 2 动态分配 xff08 pthread mutex
  • C语言经典算法(八)——递归实现斐波那契数列的两种方法

    后继续整理算法并写出自己的理解和备注 C 43 43 实现的 xff1a 递归实现斐波那契数列 1 递归实现斐波那契数列Fib n lt 1 gt 题目描述 输入n值 xff0c 求解第n项的斐波那契数列值 lt 2 gt 方法一 概念法
  • 使程序在Linux下后台运行 (关掉终端继续让程序运行的方法)

    你是否遇到过这样的情况 xff1a 从终端软件登录远程的Linux主机 xff0c 将一堆很大的文件压缩为一个 tar gz文件 xff0c 连续压缩了半个小时还没有完成 xff0c 这时 xff0c 突然你断网了 xff0c 你登录不上远
  • Vue+Element-UI上传图片到七牛云踩过的坑——返回 404,报错:Document not found

    文章目录 前端上传图片到七牛云的流程七牛云地址1 常见问题2 分清区别 xff1a 配置区域和访问域名 代码示例 不是进来找报错原因 xff0c 看怎么上传图片的 xff0c 先看上传流程和分清区别 xff1a 配置区域和访问域名找到域名
  • MySQL8.0.3安装过程详细

    xff08 如果以前安装过MySQL先卸载 xff09 一 MySQL卸载 1 以管理员身份打开命令提示符 2 停止MySQL后台服务 MySQL8为自己设置的MySQL服务名 D mysql 8 0 30 winx64 bin gt ne
  • 基于opencv 的人脸签到系统

    import cv2 import os import numpy as np from PIL import Image pillow import pyttsx3 import sys import json def makeDir e
  • LCA算法的实现

    include lt cstdio gt include lt string h gt include lt algorithm gt include lt set gt using namespace std const int MAXN
  • 卷积神经网络原理

    看了一篇通俗易懂的好文章 https brohrer mcknote com zh Hans how machine learning works how convolutional neural networks work html 关于
  • 括号匹配问题(并给出括号的位置)

    在纸上写了一个串 xff0c 只包含 39 39 和 39 39 一个 39 39 能唯一匹配一个 39 39 xff0c 但是一个匹配的 39 39 必须出现在 39 39 之前 请判断蒜头君写的字符串能否括号完全匹配 xff0c 如果能
  • Rust学习入门--【12】Rust 循环

    系列文章目录 Rust 语言是一种高效 可靠的通用高级语言 xff0c 效率可以媲美 C C 43 43 本系列文件记录博主自学Rust的过程 欢迎大家一同学习 Rust学习入门 1 引言 Rust学习入门 2 Rust 开发环境配置 Ru
  • 一年有多少节假日

    日历有 阳历 xff08 公历 xff09 和 阴历 xff08 农历 xff09 之分 每年都有法定节假日 xff0c 这些分成三类 双休 阳历节假日 阴历节假日 双休 1 xff09 周六和周日 2 2 天 阳历节假日 1 xff09
  • 走迷宫(bfs)

    给你一个 n 行 m 列的二维迷宫 39 S 39 表示起点 xff0c 39 T 39 表示终点 xff0c 39 39 表示墙壁 xff0c 39 39 表示平地 你需要从 39 S 39 出发走到 39 T 39 xff0c 每次只能
  • 计蒜客-蒜头君回家(bfs)

    蒜头君要回家 xff0c 但是他家的钥匙在他的朋友花椰妹手里 xff0c 他要先从花椰妹手里取得钥匙才能回到家 花椰妹告诉他 xff1a 你家的钥匙被我复制了很多个 xff0c 分别放在不同的地方 蒜头君希望能尽快回到家中 xff0c 他需
  • 互质数的个数(短除法分解质因数+欧拉函数)

    题意说明 xff1a 给出一个n xff0c 求1 n互质数的个数 include lt cstdio gt include lt cmath gt using namespace std int res 100000 int main i
  • arduino +ESP8266 网页WiFi控制

    首先几个问题 xff1a 1 xff0c 关于连线 xff0c 很简单 xff0c 直接ESP8266与arduino连接 xff0c 就五根线 如果没有弄好 xff0c 就单独调试一下 VCC xff0c CH PD连5v的 xff08
  • 蓝桥杯分考场

    历届试题 分考场 时间限制 xff1a 1 0s 内存限制 xff1a 256 0MB 问题描述 n个人参加某项特殊考试 为了公平 xff0c 要求任何两个认识的人不能分在同一个考场 求是少需要分几个考场才能满足条件 输入格式 第一行 xf
  • CCF_Markdown(正则表达式)

    试题编号 xff1a 201703 3试题名称 xff1a Markdown时间限制 xff1a 1 0s内存限制 xff1a 256 0MB问题描述 xff1a 问题描述 Markdown 是一种很流行的轻量级标记语言 xff08 lig
  • idea常用的插件

    1 lombok 省略get set方法 2 Alibaba Java Coding Guidelines 阿里的代码规范 3 Translation 谷歌中英文翻译工具 4 CodeGlance 代码迷你缩放图插件 xff0c 快速下拉拖

随机推荐

  • Hadoop windows本地环境安装

    hadoop使用java编写 xff0c 所以windows安装和java一样也需要配置环境变量 一 下载所需文件 JDK下载地址 xff0c jdk1 8下载Hadoop下载 xff0c hadoop下载 xff0c 进去后找到一个版本然
  • Gitlab的安装及使用

    1 GitLab概述 1 1 GitLab介绍 GitLab是利用Ruby on Rails一个开源的版本管理系统 xff0c 实现一个自托管的Git项目仓库 xff0c 可通过Web界面进行访问公开的或者私人项目 GitLab能够浏览源代
  • C语言例程:用二维数组实现矩阵转置

    用二维数组实现矩阵转置 本实例将输入的 3 4 矩阵转置为 4 3 矩阵 xff0c 并输出结果 通过本实例 xff0c 可以学习如何使用二 维数组 实例解析 二维数组的定义 二维数组定义的一般形式为 xff1a 第一部分 基础篇 X227
  • C++头文件的相互引用问题(#include” xxx“使用)

    188条消息 C C 43 43 头文件的引用问题 xff08 include使用 xff09 保护大苹果 CSDN博客 c 43 43 include头文件
  • 树莓派设置自动连接无线网络

    树莓派开机后自动连接无线网络方法 xff0c 亲测有效 1 在任意方法 xff08 无线或有线 xff09 已经连接树莓派的基础上 xff0c 执行该命令 xff0c 意思是编辑wpa supplicant conf这个文件 内容如下 xf
  • 常用快捷键(1)----Windows组合键

    单个的Windows键是打开和隐藏开始菜单 xff0c 功能与 Esc 43 Ctrl 组合键功能相同 下面是一些常用的Windows组合键 xff1a 1 快捷键 xff1a Windows 43 Shift 43 S 功能 xff1a
  • android 获取唯一Id,小小总结一下。仅供参考

    1 获取imei xff1a 前言 xff1a 因传统的移动终端设备标识如国际移动设备识别码 xff08 IMEI xff09 等已被部分国家认定为用户隐私的一部分 xff0c 并存在被篡改和冒用的风险 xff0c 所以在Android 1
  • xib中添加自定义可编辑属性

    IOS开发中 xff0c 有些人喜欢使用xib来进行项目的开发 xff0c 使用xib可以使界面可视化 xff0c 很多控件的属性设置都可以在 xib 中设置 xff0c 减少了代码量 xff1b 同时不用一遍遍的运行程序看效果 xff0c
  • STM32使用寄存器工程模板点亮一个LED灯

    1 环境说明 xff08 1 xff09 使用的是普中STM32F103开发板 xff08 2 xff09 keil 5软件 2 目的 点亮开发板上的LED1灯 3 步骤 xff08 1 xff09 定义一系列寄存器的宏 span clas
  • 结构体数组的使用

    测试源码 span class token macro property span class token directive keyword include span span class token string lt stdio h
  • string字符串拼接

    功能描述 实现在字符串末尾拼接字符串 函数原型 xff1a string amp operator 43 61 const char str 重载 43 61 操作符string amp operator 43 61 const char
  • 千万不要在TX2上安装Qt6

    失败 xff01 Nvidia TX2安装Qt6 和qtCreator7 手把手一步步 千万不要想在TX2上安装QT6 xff01 XCB缺失几乎无解 xff0c 如果有大佬可以指导一下 最开始准备使用交叉编译的方案给TX2写程序 因为台式
  • 最新WSL2 ubuntu环境 cuda,教程,适用于40系显卡

    实验环境 xff1a ubuntu2204 ubuntu1804 xff0c 最新4060笔记本电脑 xff0c 自我觉得是目前比较好用的搭配 xff1a wsl2 43 gnome 43 wsl中的pycharm xff0c 写的很全 x
  • 高分辨率机器安装 Ubuntu虚拟机的屏幕显示字体过小问题的解决

    在网上搜索了很多的解决方案 xff0c 有的试了没效果 xff0c 有的比较麻烦 xff0c 没尝试了 我说一下我的解决方案 问题 xff1a 首先我这个机器是2k屏的 xff0c 分辨率就是会大于 1920x1080 xff1b 然后我是
  • IDEA rebuild project idea如何重新编译项目

    idea如何重新编译项目 1 2 3 4 5 6 7 分步阅读 idea工具可以用于多种语言来开发项目 xff0c 如果是像java这样需要编译之后运行的编程语言 xff0c 每次在运行项目之前都需要对源码进行编译 一般的情况下都是idea
  • Ubuntu更新软件时报"http://cn.archive.ubuntu.com/ubuntu"相关错误的解决方案

    一 问题日志 W 仓库 http cn archive ubuntu com ubuntu xenial Release 没有 Release 文件 N 无法认证来自该源的数据 xff0c 所以使用它会带来潜在风险 N 参见 apt sec
  • 《uni-app》一个非canvas的飞机对战小游戏实现-我方飞机实现

    这是一个没有套路的前端博主 xff0c 热衷各种前端向的骚操作 xff0c 经常想到哪就写到哪 xff0c 如果有感兴趣的技术和前端效果可以留言 xff5e 博主看到后会去代替大家踩坑的 xff5e 接下来的几篇都是uni app的小实战
  • 《Vue插件》瀑布流插件vue-masonry的使用与踩坑记录

    这是一个没有套路的前端博主 xff0c 热衷各种前端向的骚操作 xff0c 经常想到哪就写到哪 xff0c 如果有感兴趣的技术和前端效果可以留言 xff5e 博主看到后会去代替大家踩坑的 xff5e 主页 oliver尹的主页 格言 跌倒了
  • 《uni-app》一个非canvas的飞机对战小游戏实现-子弹模型的实现

    这是一个没有套路的前端博主 xff0c 热衷各种前端向的骚操作 xff0c 经常想到哪就写到哪 xff0c 如果有感兴趣的技术和前端效果可以留言 xff5e 博主看到后会去代替大家踩坑的 xff5e 接下来的几篇都是uni app的小实战
  • 《uni-app》一个非canvas的飞机对战小游戏实现-碰撞检测的实现

    这是一个没有套路的前端博主 xff0c 热衷各种前端向的骚操作 xff0c 经常想到哪就写到哪 xff0c 如果有感兴趣的技术和前端效果可以留言 xff5e 博主看到后会去代替大家踩坑的 xff5e 接下来的几篇都是uni app的小实战