《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

《uni-app》一个非canvas的飞机对战小游戏实现-子弹模型的实现

  • 一. 前言
  • 二. 阅读对象与难度
  • 三. 项目地址以及最终效果
  • 四. 子弹模型的实现
    • 4.1 分析分析
    • 4.2 子弹的样式
    • 4.3 子弹创建
    • 4.4 子弹的位移
  • 五. 阶段性展示
  • 六. 小结

一. 前言

上一篇中主要分享的是我方飞机这个模型功能的实现,包括了:飞机的样式,飞机的生成,飞机的创建坐标,飞机的位移操作等等,但是,很明显我们这个飞机还是不完善的,最大的功能遗漏就是子弹了,没有子弹,怎么能被称为是飞机大战呢,对不对~
本文将实现的是
子弹模型
相关,当然,我们这个子弹还是属于简单的那一种,后续复杂子弹的实现我们后续再说,耐心看完,或许你会所有收获~

二. 阅读对象与难度

本文难度属于:中级,本文中主要实现的我方飞机发射的子弹型相关的操作,包括子弹坐标位置初始化,子弹移动,子弹样式等等,通过文本你可以大致了解到一下内容

  • Vue中的基础知识,包括v-for等常规用法;
  • 子弹的模型的样式,创建,位移等等;

具体内容可以参考以下的思维导图:
在这里插入图片描述

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

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

四. 子弹模型的实现

4.1 分析分析

根据上面的效果图,我们先分析一下要实现的功能:

  1. 首先要实现的是子弹的样式;
  2. 其次是子弹的初始化坐标,由于我方飞机的位置是不固定的,因此子弹的生成位置也将是不固定的;
  3. 最后时子弹创建后的自适应位移;

大致上这三个功能在本文这个阶段是最主要的,再来估计一下如果要实现这几个功能可能要用到什么实现逻辑
第一个,子弹样式
子弹样式这一块和我方飞机、敌机一样,都是由DOM+CSS实现的,设定好宽高以及背景图即可;
第二个,创建坐标
既然是坐标,那坐标肯定是有x和y的,从效果上看,子弹创建的位置位于飞机头部的中间处,并且由于飞机是不固定位置的,因此子弹的位置也是不固定的
第三个,子弹位移
老规矩,位移还是靠的requestAnimationFrame实现的;

4.2 子弹的样式

先来看看子弹的样式,它的的素材图如下:
在这里插入图片描述

就是一个简单的图片,我们只需要将设定其宽高,并且背景图绑定图片即可:

<template>
	<view class="bullet"></view>
</template>

<style scoped lang="less">
.bullet {
	width: 7px;
	height: 18px;
	position: fixed;
	z-index: 2;
	background: url(@/static/images/bullet.png) no-repeat left top;
}

.bullet_effect {
	display: none;
}
</style>

4.3 子弹创建

在了解子弹创建之前,我们得明白子弹的创建时机,和我方飞机与敌机不同的是,子弹并不是随时创建的,它必须在我们触发某一个按钮,比如web上的是按下空格键后触发创建,大致流程如下
在这里插入图片描述
因此首先,我们需要添加一个事件,一个按下空格键时触发的事件

initEvent() {
  document.addEventListener('keydown', e => {
    switch (e.keyCode) {
      //空格
      case 32:
        this.launchBullet();
        break;
      //up键
      case 38:
        this.keyTop = true;
        break;
      //down键
      case 40:
        this.keyBottom = true;
        break;
      //left键
      case 37:
        this.keyLeft = true;
        break;
      //right键
      case 39:
        this.keyRight = true;
        break;
      default:
        console.log('无效案件,请使用上、下、左、右控制');
    }
  });
  document.addEventListener('keyup', e => {
    switch (e.keyCode) {
      //up键
      case 38:
        this.keyTop = false;
        break;
      //down键
      case 40:
        this.keyBottom = false;
        break;
      //left键
      case 37:
        this.keyLeft = false;
        break;
      //right键
      case 39:
        this.keyRight = false;
        break;
    }
  });
},

找到plane.vue中的按键监听,在 keydown 中额外新增一项,指定值为32时触发发射子弹的函数,这个32是空格键的内部识别码

launchBullet() {
  const params = {
    width: 7,
    height: 18,
    x: this.data.x + 49,
    y: this.data.y,
    id: `bullet` + new Date().getTime()
  };
  this.$emit('addBullet', params);
}

当按下空格键后,会触发这个名为 launchBullet的子弹创建函数,这个函数包括了子弹的宽,高,X轴,Y轴的坐标,以及唯一的标识码,可能有小伙伴问,不是说子弹的坐标不固定吗,为啥这边可以直接写死,并且还是加了一个49?这里解释一下,这里的this.data.x和this.data.y是当前飞机X轴,Y轴的坐标
在这里插入图片描述

子弹虽然是不固定的,但相对我方飞机来说,确又是固定的,它生成的位置永远在我方飞机头部中间处的位置,因此,子弹的X轴坐标只需要取得飞机的X轴加上飞机一半的宽度即可,高度就是等同于我方飞机Y轴的高度~
创建完成后通过emit将参数传递到父组件中,父组件接收参数之后将其push到子弹缓存列表中

<!-- 我方飞机 -->
<template>
  <Plane @addBullet="addBullet" />
</template>

<script>
import Bullet from '../view/bullet/bullet.vue';
export default {
	data() {
		return {
			bulletData: []
		};
	},
	components: {Bullet },
	onLoad() {
		this.init();
	},
	methods: {
		addBullet(param) {
			console.log('--- 触发子弹 ---');
			this.bulletData.push(param);
		},
	}
};
</script>

当参数存入缓存数组后,通过v-for循环动态生成子弹

<!-- 子弹 -->
<template v-if="isStart">
  <Bullet v-for="bullet in bulletData" :key="bullet.id" :data="bullet"  />
</template>

并通过props将初始位置赋值给子弹模型

<template>
	<view 
    class="bullet" 
    :style="{ left: data.x + 'px', top: data.y + 'px' }"
    ></view>
</template>

<script>
export default {
	props: {
		data: {
			type: Object,
			default: () => {
				return {};
			}
		}
	},
};
</script>

这样,当我们按下空格键的时候,子弹就会被创建在飞机的头部的中间位置,虽然此时的子弹还不会位移
在这里插入图片描述

4.4 子弹的位移

子弹的位移,实现上还是非常简单的,和我方飞机与敌机是相同的实现方式,都是利用的 requestAnimationFrame 实现,先看代码吧

<script>
export default {
	methods: {
		init() {
			this.moveTimer = () => {
				// 移动
				this.move();
				// 重绘,无限循环
				requestAnimationFrame(this.moveTimer);
			};
			this.moveTimer();
		},
		move() {
			if (this.data.y > 0) {
				// 子弹的加速度
				this.data.y += -5;
			} else {
				// this.isExplosion = true;
				this.remove();
			}
		},
		remove() {
			this.$emit('removeBullet', this.data.id);
		}
	},
	mounted() {
		this.init();
	}
};
</script>

当子弹创建后,会执行 mounted 中的init方法,这个方法会通过 requestAnimationFrame 无限重绘子弹位置,重绘的依据则是在 move() 这个函数中实现的;
接着看move这个函数,分为两段:

  • 第一段当子弹在Y轴上的坐标大于0时,不断改变它在Y轴上的坐标,每次减少5个像素,或者说子弹的加速度是5;
  • 第二段是移除子弹,我们知道子弹的存在并不是无限制的,比如当子弹没有击中敌机,并且子弹在Y轴的位置小于0,这就代表其实子弹已经超出屏幕了,这种情况下那这个子弹就没有存在的意义了,完全可以在DOM中移除掉,节省性能
    在这里插入图片描述
    因此,当子弹在Y轴的坐标小于0时,触发remove函数,通过emit将子弹的ID给传递出去
this.$emit('removeBullet', this.data.id);

在父组件中接收到 removeBullet 这个事件后,遍历子弹缓存数组,移除对应id的子弹即可

	let index = 0;
	for (let i = 0; i < array.length; i++) {
		if (array[i].id === id) {
			index = i;
			break;
		}
	}
	array.splice(index, 1);

五. 阶段性展示

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

六. 小结

本文主要概述了子弹模型的实现,主要包含:

  • 子弹样式:其实就是设定好DOM,加入背景图形成了一个子弹的DOM;
  • 子弹生成:按下空格键时,创建好子弹的参数,包括生成的位置坐标,并将参数传递到子弹的模型中;
  • 子弹操作位移:位移通过requestAnimationFrame实现;

到这里,敌机,我方飞机,子弹模型都已经结束了,接下来就是碰撞检测了,这一块稍微涉及到了一些计算,当然,问题不大~

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

《uni-app》一个非canvas的飞机对战小游戏实现-子弹模型的实现 的相关文章

  • 使用matlab绘制世界地图并根据经纬度绘制点位(附m_map的下载与安装说明)

    文章目录 1 worldmap amp geoshow2 m map工具箱3 根据经纬度在世界地图上绘制点位 使用matlab绘制世界地图有两种方法 xff08 自己使用过的 xff0c 可能有别的我不了解的方法 xff09 xff1a 第
  • 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的小实战