cocos creator中使用行为树(BehaviorTree) 三

cocos creator中使用行为树(BehaviorTree) 三

这一节我们不对AI添加新的功能, 而是修改一下以前的代码.

因为本节修改了上两节的代码, 也为了后面的内容大家方便, 我把这个项目上传到了github上

https://github.com/kirikayakazuto/BehaviorTreeGame

  1. 添加思考时间间隔参数, 表示没过多少时间思考一次
  2. 在tick上添加参数(dt: number), 表示距离上一次调用的时间, 用来做平滑处理, 方便帧同步

在第一节上, 我们设置的思考时间是每一帧思考一次, 如果1s内跑了60帧的话, 那么就是思考60次, 然而大部分时间我们并不需要如此频繁的思考调用, 所有我们添加一个思考时间间隔

打开GameScene脚本, 添加

一个属性stepInterval = 60; 单位ms 每过60ms思考一次

import PlayerCtl from "./PlayerCtl";
import { PlayerDir } from "./GameInterface";
const {ccclass, property} = cc._decorator;

/**
 * 一个简单的样例, 用于学习行为树AI
 * 怪物1, 默认在一段位置内巡逻, 一旦发现目标(玩家), 则发动攻击
 */
@ccclass
export default class GameScene extends cc.Component {

    @property(PlayerCtl)
    playerCtl: PlayerCtl = null;

    @property(cc.Node)
    master: cc.Node = null;

    stepInterval = 60;            // 思考间隔 单位ms
    restRunningSecond = 0;        // 当前执行的时间
    isRunning = false;            // 是否正在执行


    onLoad() {
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
    }


    start () {
        this.playerCtl.init(this);
    }

    onKeyDown(event: any) {
        switch(event.keyCode) {
            case cc.KEY.left:
            case cc.KEY.a:
                this.playerCtl.setDirection(PlayerDir.left);
            break;
            case cc.KEY.right:
            case cc.KEY.d:
                this.playerCtl.setDirection(PlayerDir.right);
            break;
        }
    }
    onKeyUp(event: any) {
        switch(event.keyCode) {
            case cc.KEY.left:
            case cc.KEY.a:
            case cc.KEY.right:
            case cc.KEY.d:
                this.playerCtl.setDirection(PlayerDir.stop);
            break;
            
        }
    }

    onDestroy() {
        cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
    }

    

    update(dt: number) {   
        let ms = dt;
        this.playerCtl.playerUpdate(ms);

        if(!this.isRunning) {
            this.restRunningSecond = this.stepInterval / 1000;    
            this.isRunning = true;
        }
        this.restRunningSecond -= ms;
        if(this.restRunningSecond <= 0) {
            this.isRunning = false;
            this.runBehaviorTree(); 
        }
    }

    runBehaviorTree() {
        this.master.getComponent("BehaviorTree").tick();
    }


}

这样, 就降低了思考次数. 接下来, 我们实现功能二

首先我们看到runBeHaviorTree方法, 添加参数ms: number

runBehaviorTree(ms: number) {
        this.master.getComponent("BehaviorTree").tick();
    }

接下来就是怎么将ms通过BehaviorTree脚本的tick方法传到Attck脚本的tick方法中

打开BehaviorTree脚本, 进行一波源码分析, 找到tick方法

tick: function(target){
let t = {};
if(target != undefined){t = target;}
this.tree.tick(t,this.blackboard)
}

tick方法接收一个参数target对象, 不传就是一个空对象{}, 暂时不知道t有什么用, 

方法内部是调用了 this.tree.tick(t. this.blackboard);

又看到 this.tree = new b3.BehaviorTree(); 打开b3, 找到BehaviorTree方法

可以看到BehaviorTree = new b3.Class();

在找到b3.Class方法, 返回的是一个cls方法, 即BehaviorTree是一个有cls为构造函数实例化的对象

在回到BehaviorTree对象的tick方法, 有两个参数target, blackboard, 和我们在this.tree.tick(t,this.blackboard)这里传入的参数对应

我们在看看BehaviorTree的tick方法是怎么实现的

重点代码, 先是创建一个tick对象, 在execute执行这个tick

找到_execute方法

挨个调用, 重点是_tick方法, 在找到tick方法

到这里就全部结束了

我们可以看到, 最终是将tick传出, 所以我门只要把dt属性添加到tick中就好了, 

找到tick对象, 添加dt属性

/**
     * Initialization method.
     *
     * @method initialize
     * @constructor
    **/
    p.initialize = function() {
        // set by BehaviorTree
        this.tree       = null;
        this.debug      = null;
        this.target     = null;
        this.blackboard = null;

        // updated during the tick signal
        this._openNodes  = [];
        this._nodeCount  = 0;
        this.dt = 0;
    }

那么在BehaviorTree的tick方法中

添加好dt

在到BehaviorTree脚本中, 添加上dt

在到GameScene中的runBehaviorTree方法中

测试一下

成功在attack脚本中获得到了dt

把dt加上, 恩  大功告成!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值