前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >鸿蒙开发游戏(三)---大鱼吃小鱼(放置NPC)

鸿蒙开发游戏(三)---大鱼吃小鱼(放置NPC)

作者头像
cMusketeer
发布2024-02-17 09:18:14
1650
发布2024-02-17 09:18:14
举报
文章被收录于专栏:Android机器圈

效果图

添加了一个NPC(小红鱼),玩家控制小黄鱼

鸿蒙开发游戏(一)---大鱼吃小鱼(界面部署

鸿蒙开发游戏(二)---大鱼吃小鱼(摇杆控制)

鸿蒙开发游戏(三)---大鱼吃小鱼(放置NPC)

鸿蒙开发游戏(四)---大鱼吃小鱼(互吃升级)

鸿蒙开发游戏(五)---大鱼吃小鱼(添加音效)

鸿蒙开发游戏(六)---大鱼吃小鱼(称霸海洋)

前两篇文章我们做了摇杆控制小鱼移动,这篇将会添加一个NPC,让其自动在海洋里游荡,然后玩家控制吃掉它。在这之前我们想思考一些问题,

NPC如何生成?NPC有哪些属性?NPC是如何控制的?如何做到随机转方向?

这是该篇的难点,这里还用到了一些数学知识,包括sin,cos,弧度与角度的计算等,还是比较麻烦的,但是等你看到代码又会发现代码量很少,又会觉得如此简单,好了,看例子。

1、开始游戏

这里我们需要添加一个开始游戏按钮,因为只有玩家开始了游戏,我们启动一个计时器才会变得顺理成章,不然的话,上来就启动计时器会很好资源的。

代码语言:javascript
复制
export struct FishPage {
    @State isBegin: boolean = false
}

这里我们默认是false,未启动状态

代码语言:javascript
复制
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应该有什么属性,起始位置,方向,速度,等,这里暂时不需要等级,下篇互吃逻辑写。

代码语言:javascript
复制
//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时

代码语言:javascript
复制
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如何自己动起来了,这就又用到了计时器,这里如果有其他好的方法也评论区打出来哈。当玩家点击开始游戏按钮时启动计时器,

代码语言:javascript
复制
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这个是防止走出屏幕的宽度和高度设置的,当触碰到边框要改变方向。难点也在这

代码语言:javascript
复制
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方向生成

这一块是最麻烦的,

代码语言:javascript
复制
弧度 = 角度 * π / 180
角度 = 弧度 * 180 / π

我们认识到的Math.sin,cos,tan等一般都是传入一个弧度,而不是角度(我传入角度老是有问题,这里传入弧度就解决了)

代码语言:javascript
复制
/*随机获取一个角度*/
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值,如下

代码语言:javascript
复制
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、关闭计时器

代码语言:javascript
复制
onPageHide() {
  clearInterval(this.intervalIdNPC_1)
}

记住页面消失时,或者游戏结束时需要关闭计时器

好了,到这NPC防止就完成了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-02-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、开始游戏
  • 2、添加NPC小鱼
  • 3、NPC动起来
  • 4、NPC方向生成
  • 5、关闭计时器
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档