Play - 状态跳转函数

Play - 让机器人动起来一节中,我们通过简单的脚本演示了如何实现两点间的运动。在脚本中,有一个switch函数,用于切换不同的状态。在本节中,我们将详细介绍switch函数的使用方法。

switch函数的运行

switch函数是Play中的一个重要组成部分,用于判断当前状态是否需要切换到下一个状态。在Play的执行过程中,每一帧开始当前状态的switch函数会被立刻调用,以判断是否需要切换状态。下面是一个简单的例子:

gPlayTable.CreatePlay{
    firstState = 'run1', -- 初始状态

    ['run1'] = {
        switch = function() -- 判断如果到达目标点则结束脚本
            if player.toTargetDist('Leader') < 100 then
                return 'finish'
            end
        end,
        Leader = task.goto(Pos(0,0)), -- 设置任务:移动到(0,0)
        match = '(L)' -- 用于Leader角色的单次匹配
    },

    name = "TestRun", -- Play的名称
}

在上面的代码中,switch函数判断了Leader角色是否到达目标点,如果到达则返回finish状态,Play结束。在实际的开发中,switch函数可以根据不同的需求进行自定义,例如判断是否到达目标点、是否有敌方机器人等。其返回值的类型为string,表示下一个状态的名称,如果返回nil则表示不切换状态,继续执行当前状态。其返回值的类型以及含义具体如下:

  • nilreturn nil或无return):不切换状态,继续执行当前状态。

  • exit或者finish:结束Play的执行(一般用于定位球等脚本执行完跳转到一般脚本)。

  • 其他string:下一个状态的名称,表示切换到下一个状态。

switch函数的一般使用

在实际的开发中,switch函数的使用可以大致归类为以下几种情况:

  • 基于几何信息

    • 距离(到点/到球/到某个机器人/禁区/球门/边界)

    • 角度(朝向/角度差)

    • 速度(机器人速度/球速)

    • 位置(在某个区域/在某个角色附近)

  • 基于事件

    • 某个机器人是否持球

    • 某个机器人是否踢球

    • 红外传感器信息

    • 球出界

    • 球消失

    • 机器人数量变化

  • 基于裁判盒信息

    • 比赛状态(Normal Start指令)

  • 基于时间

    • 固定时间

    • 满足某条件后的持续时间(bufcnt函数)

  • 其他

    • 自动裁判机状态等

上述的所列举的判断有部分已经封装成更容易使用的接口,分布在player.lua/enemy.lua/ball.lua/cond.lua这几个模块中。

小trick

由于当前play框架中,并没有设计除了switch以外的每帧调用的代码段,所以有时也会将需要在当前帧调用的任务放在switch里面,例如:

  • 多机器人协同的策略模块(c++)层的调用

  • 希望在play层临时绘制的debug可视化信息

  • 特殊的,如果你遇到了需要在第一次进入play时初始化的情况,可以将fristState设置成init,并将init状态的switch作为你的初始化函数使用

总结

依据上述介绍,我们可以看到switch函数在Play中的重要性。通过switch函数,我们可以根据不同的需求切换状态,实现复杂的策略逻辑。在实际的开发中,我们可以根据不同的需求自定义switch函数,实现更加灵活的策略逻辑。