鸿蒙开发游戏(三)---大鱼吃小鱼(放置NPC)
效果图
添加了一个NPC(小红鱼),玩家控制小黄鱼

鸿蒙开发游戏(三)---大鱼吃小鱼(放置NPC)
鸿蒙开发游戏(四)---大鱼吃小鱼(互吃升级)
鸿蒙开发游戏(五)---大鱼吃小鱼(添加音效)
鸿蒙开发游戏(六)---大鱼吃小鱼(称霸海洋)
前两篇文章我们做了摇杆控制小鱼移动,这篇将会添加一个NPC,让其自动在海洋里游荡,然后玩家控制吃掉它。在这之前我们想思考一些问题,
NPC如何生成?NPC有哪些属性?NPC是如何控制的?如何做到随机转方向?
这是该篇的难点,这里还用到了一些数学知识,包括sin,cos,弧度与角度的计算等,还是比较麻烦的,但是等你看到代码又会发现代码量很少,又会觉得如此简单,好了,看例子。
1、开始游戏
这里我们需要添加一个开始游戏按钮,因为只有玩家开始了游戏,我们启动一个计时器才会变得顺理成章,不然的话,上来就启动计时器会很好资源的。
export struct FishPage {
@State isBegin: boolean = false
}
这里我们默认是false,未启动状态
build() {
Row() {
Stack() {
// 背景
Image($r("app.media.bg_fish"))
if (this.isBegin == false) {
Button('开始游戏')
.backgroundColor('#36d')
.onClick(() => {
//这里把设置成true
this.isBegin = true
})
} else {
//渲染小鱼
}
}
}

2、添加NPC小鱼
我们在开始之前就已经开始思考了,NPC应该有什么属性,起始位置,方向,速度,等,这里暂时不需要等级,下篇互吃逻辑写。
//NPC
@State npcSpeed: number = 3
@State npcFishX: number = 300
@State npcFishY: number = 200
@State npcAngle: number = 0
@State intervalIdNPC_1: number = 1
@State npcSin: number = 1
@State npcCos: number = 1
npc显示需要写在else里面,也就是点击开始游戏后,isBegin=true时
if (this.isBegin == false) {
Button('开始游戏')
.backgroundColor('#36d')
.onClick(() => {
this.isBegin = true
})
} else {
Image($r("app.media.icon_fish_right"))
.position({ x: this.xFish - this.fishRadius, y: this.yFish - this.fishRadius })
.rotate({ angle: this.angle, centerX: '50%', centerY: '50%' })
.width(40)
.height(40)
Image($r("app.media.icon_npc_2"))
.position({ x: this.npcFishX - this.fishRadius, y: this.npcFishY - this.fishRadius })
.rotate({ angle: this.npcAngle, centerX: '50%', centerY: '50%' })
.objectFit(ImageFit.ScaleDown)
.width(40)
.height(40)
}
ok,第一个image是玩家控制的小鱼,第二个image是NPC。
3、NPC动起来
问题来了,NPC如何自己动起来了,这就又用到了计时器,这里如果有其他好的方法也评论区打出来哈。当玩家点击开始游戏按钮时启动计时器,
if (this.isBegin == false) {
Button('开始游戏')
.backgroundColor('#36d')
.onClick(() => {
this.isBegin = true
clearInterval(this.intervalIdNPC_1)
this.intervalIdNPC_1 = setInterval(() => {
//设置小鱼的移动位置,
this.npcFishX += this.npcSpeed * this.npcCos
this.npcFishY += this.npcSpeed * this.npcSin
this.npcFishX = this.getNPCBorderX(this.npcFishX)
this.npcFishY = this.getNPCBorderY(this.npcFishY)
}, 40)
})
}
这里需要说一下,启动一个计时器,内部是不断地计算npc的位置,getNPCBorderX这个是防止走出屏幕的宽度和高度设置的,当触碰到边框要改变方向。难点也在这
getNPCBorderX(x: number) {
if (x <= this.fishRadius) {
x = this.fishRadius + 10
this.getRandom()
}
if (x > this.screenWidth - this.fishRadius) {
x = this.screenWidth - this.fishRadius - 15
this.getRandom()
}
return x
}
getNPCBorderY(y: number) {
if (y <= this.fishRadius) {
y = this.fishRadius + 10
this.getRandom()
}
if (y > this.screenHeight - this.fishRadius) {
y = this.screenHeight - this.fishRadius - 10
this.getRandom()
}
return y
}
那一个x方向说吧,当x<=小鱼的半径时说明,小鱼已经贴左边了,大于屏幕宽度时贴右边了,这时我们要改变方向,getRandom()就是改变方向用的,至于x=this.fishRadius +10 这个主要是当贴边后,小鱼还在走,就会触发多次if语句,生成多次方向,也就是说会出现抖动现象,感兴趣去掉赋值可以试试。
4、NPC方向生成
这一块是最麻烦的,
弧度 = 角度 * π / 180
角度 = 弧度 * 180 / π
我们认识到的Math.sin,cos,tan等一般都是传入一个弧度,而不是角度(我传入角度老是有问题,这里传入弧度就解决了)
/*随机获取一个角度*/
getRandom() {
this.npcAngle= this.selectFrom(-179,180)
// let angle = Math.random()+Math.random()+Math.random()
// this.npcAngle = angle * 180 / Math.PI
//这是是求弧度,弧度 = 角度 * π / 180
this.npcSin = Math.sin(this.npcAngle * Math.PI /180)
this.npcCos = Math.cos(this.npcAngle * Math.PI /180)
console.log("角度"+this.npcAngle)
}
selectFrom(startNumber, endNumber) {
let choice = endNumber - startNumber + 1;
return Math.floor(Math.random() * choice + startNumber)
}
首先我们需要随机生成一个角度,比如说90度,50度,-120度等

角度是作为鱼头方向用的,我们按照speed速度去计算该方向的值

那么x轴上的值就是x = speed * cos值,如下
this.intervalIdNPC_1 = setInterval(() => {
//设置小鱼的移动位置,
this.npcFishX += this.npcSpeed * this.npcCos
this.npcFishY += this.npcSpeed * this.npcSin
this.npcFishX = this.getNPCBorderX(this.npcFishX)
this.npcFishY = this.getNPCBorderY(this.npcFishY)
}, 40)
5、关闭计时器
onPageHide() {
clearInterval(this.intervalIdNPC_1)
}
记住页面消失时,或者游戏结束时需要关闭计时器
好了,到这NPC防止就完成了。
鸿蒙开发游戏(三)---大鱼吃小鱼(放置NPC)的更多相关文章
- 【C语言探索之旅】 第三部分第二课:SDL开发游戏之创建窗口和画布
内容简介 1.第三部分第二课: SDL开发游戏之创建窗口和画布 2.第三部分第三课预告: SDL开发游戏之显示图像 第三部分第二课:SDL开发游戏之创建窗口和画布 在上一课中,我们对SDL这个开源库做 ...
- 【C语言探索之旅】 第三部分第一课:SDL开发游戏之安装SDL
内容简介 1.课程大纲 2.第三部分第一课: SDL开发游戏之安装SDL 3.第三部分第二课预告: SDL开发游戏之创建窗口和画布 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会 ...
- HTML5 Canvas游戏开发(三)lufylegend开源库件(上)
lufylegend可以解决HTML5开发游戏中会遇到的一些问题: 1.各种浏览器对于JavaScript和HTML的解析是不一致的. 2.手机浏览器和PC浏览器的区别. 3.JavaScript并非 ...
- 使用 Unity 3D 开发游戏的架构设计难点
Unity 3D 引擎对于开发者来说,入手非常快,因为它采用的是 C# 作为开发语言,这也大大降低了开发者的门槛.但凡只要懂一门编程语言的人都能使用 Unity 3D 引擎开发,另外 Unity 3D ...
- GJM : 各大开发游戏引擎
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
- MS CRM 2011的自定义和开发(11)——插件(plugin)开发(三)
http://www.cnblogs.com/StoneGarden/archive/2012/02/06/2340661.html MS CRM 2011的自定义和开发(11)——插件(plugin ...
- Qt移动应用开发(三):使用精灵图片实现帧动画
Qt移动应用开发(三):使用精灵图片实现帧动画 上一篇博文讲到了Qt Quick对于动画的一般支持.动画的形式多样,配合不同的插值函数,能够差点儿实现全部想要的动画效果,而对于游戏的一些特殊的效果比方 ...
- 使用Photon引擎进行unity网络游戏开发(三)——网络游戏大厅及房间
使用Photon引擎进行unity网络游戏开发(三)--网络游戏大厅及房间 Photon PUN Unity 网络游戏开发 连接到Photon ConnectUsingSettings 设置你的客户端 ...
- Kinect for Windows SDK开发入门(三):基础知识 下
原文来自:http://www.cnblogs.com/yangecnu/archive/2012/04/02/KinectSDK_Application_Fundamentals_Part2.htm ...
- Java开发学习(三十七)----SpringBoot多环境配置及配置文件分类
一.多环境配置 在工作中,对于开发环境.测试环境.生产环境的配置肯定都不相同,比如我们开发阶段会在自己的电脑上安装 mysql ,连接自己电脑上的 mysql 即可,但是项目开发完毕后要上线就需要该配 ...
随机推荐
- IDEA插件Material Theme UI 激活
介绍 "Material Theme UI" 是一款为 IntelliJ IDEA 提供现代化材料设计主题的插件,通过重新设计IDE的外观,为开发人员带来更加美观.富有活力的用户体 ...
- java垮平台的原理-垃圾回收-day1
目录 1. 跨平台原理 2. 垃圾回收 3. DOS的几个基本命令 4. PATH环境变量的作用 5 java的安装 6. 第一个java程序 6. 另外两个环境变量CLASS_PATH 与JAVA_ ...
- Vue2 - 配置跨域
在根目录下创建 vue.config.js 文件 . 即可 vue.config.js : // vue.config.js 配置说明 //官方vue.config.js 参考文档 https://c ...
- Python Code_02
author : 写bug的盼盼 development time : 2021/8/27 19:59 变量定义 name = '阿哈' print(name) print('标识',id(name) ...
- Python注释是什么东东
注释 标注解释,目的是帮助读者理解的文本 也就是说,注释首先是文本,其二是说明,其三是思路,其四是例子注释有两种形式 1. # ... 单行注释 用于对某句语句或语句块进行解释 放在语句块的头行或一个 ...
- [转帖]Python执行Linux系统命令的4种方法
https://www.cnblogs.com/pennyy/p/4248934.html (1) os.system 仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 代码如下: sys ...
- [转帖]Debian开启SSH
一.Debian开启SSH 参考链接: https://blog.csdn.net/zzpzheng/article/details/71170572 https://help.aliyun.com/ ...
- [转帖]Jmeter压力测试工具安装及使用教程
https://www.cnblogs.com/monjeo/p/9330464.html 一.Jmeter下载 进入官网:http://jmeter.apache.org/ 1.第一步进入官网如下图 ...
- [转帖]三星研发出首个基于存算一体技术的GPU大型计算系统 (收录于存算一体芯片赛道投资融资分析)
https://zhuanlan.zhihu.com/p/591850021 陈巍谈芯:产业巨头已经打通存算一体技术的落地通道,存算一体技术加快应用部署.与未使用HBM-PIM(HBM-PIM GPU ...
- Linux KVM网络处理过程
Linux KVM网络处理过程 总体解决方法 本次遇到的问题是KVM的网桥处理不小心导致系统无法连接.处理简要总结: 进入机房,给IPMI插上网线, 开机点 Del 进入bios 设置IMPI的地址 ...