鸿蒙开发游戏(三)---大鱼吃小鱼(放置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 即可,但是项目开发完毕后要上线就需要该配 ...
随机推荐
- 12_前K个高频元素
前K个高频元素 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素.你可以按 任意顺序 返回答案.347.力扣题目链接 示例 1: 输入: nums = [1,1,1, ...
- Vue第五篇 Vue的生命周期
Vue生命周期简介 生命周期的钩子函数 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- 深入理解Kafka核心设计及原理(一):初识Kafka
转载请注明出处: 1.1 kafka简介 Kafka 起初是由 Linkedin 公司采用 Scala 语言开发的一个多分区.多副本且基于 ZooKeeper协调的分布式消息系统,现己被捐献给 Apa ...
- Redis 哨兵模式高可用
本文为博主原创,未经允许不得转载: 目录: 1. 哨兵 Sentinel 介绍 2. 哨兵架构特点及工作原理 3. redis哨兵架构搭建步骤 4. 哨兵数据丢失 5. spring boot 整合 ...
- HTTP 及 http 请求解析过程
本文为博主原创,未经允许不得转载: HTTP 全称为:超文本传输协议(HyperText Transfer Protocol,HTTP),一种无状态的,以请求/应答方式运行的协议, 它使用可扩展的语义 ...
- 如何开发一套苹果cms前端模板
本文运用了苹果cms官网的模板开发教程,开发了一套苹果cms的前端模板,感兴趣的同学可以去github下载使用. 什么是模板 模板是网站的主题外观,也被称为主题或皮肤.通过使用不同的模板,网站的前台可 ...
- [springmvc] - 配置文件 springmvc-config.xml 和 web.xml
springmvc-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...
- CoreDNS -- DNS服务与服务发现
CoreDNS -- DNS服务与服务发现 DNS服务器 手册:https://coredns.io/manual/toc/ Github:https://github.com/coredns/cor ...
- 【秘籍揭秘】如何高速下载游戏、Switch资源?省时省力一网打尽!
百度云盘SVIP合租啦亲爱的考研党和游戏玩家们,我今天要分享的是一份独家秘籍!你是不是常常为下载游戏或Switch资源而烦恼?是不是经常遇到下载速度慢.限速等问题,让你等待无尽?别担心,我有一个绝密的 ...
- Oracledb_exporter 获取表大小信息的简单方法
Oracledb_exporter 获取表大小信息的简单方法 背景 用我儿子的现状作为背景: 我爱学习, 学习让我妈快乐. 下载exporter exporter 可以在github上面下载最新版本是 ...