场景脚本编写教程——“训练-前进”任务
任务要求
目的:要求机器人从起点出发,在任务限时内前进到前方的终点区域;
成功条件:在任务限时内前进到终点区域;
失败条件:在任务限时内未前进到终点区域;
评分方式:任务成功得100分,否则0分;
构建场景
进入“构建场景”,启动场景编辑器,场景编辑器自动新建了一个空场景,场景中已经添加了几个必须的模型,其作用如下:
相机限制:限制机器人的活动范围,机器人只能在相机限制设定的“球”范围内活动,当机器人碰到相机限制的边缘时,会被阻挡;保存场景时,系统以“相机限制”为范围拍摄一张图片,作为仿真时的小地图;其默认的半径为“50”,可根据场景需要修改此数值;
任务配置:是场景的重要设置模型,可设置任务相关的模式、时间、机器人限制等,其设置项很多,在需要时再详细说明各项设置目的;
起始点:每个场景中至少且必须有一个“起始点”,开始仿真时机器人从起始点开始运行;进入仿真或复位后,系统将机器人放置到其下底面与起始点平面齐平、朝向与起始点箭头一致的位置上;场景中最多可以放置4个起始点;
物理设置:(无名称,法码外观)设置仿真时的重力和碰撞 精度,此任务无须关注;
添加模型
添加以下2个模型:
    1. 将“模型”列表切换到“自然”类,单击第2行第3个“地图_7”模型,将其添加到场景中;
    2. 将“触发”类中的第1行第1个“触发方块”模型添加场景,放置到“地图_7”上;
设置模型位置与属性
按下表设置场景中模型的参数(方法参考“萝卜圈仿真-构建场景用户手册”):
图标 | 名称 | 位置 | 缩放 | 作用 |
---|---|---|---|---|
地图_7 | 0,0,0 | 机器人运行的地面 | ||
触发方块 | 0,2,50 | 100,4,20 | 检测机器人是否到达终点 | |
起始点 | 0,0,0 | 机器人起始位置 |
按下表设置相关模型的属性。
图标 | 名称 | 位置 | 缩放 | 作用 |
---|---|---|---|---|
地图_7 | 0,0,0 | 机器人运行的地面 | ||
触发方块 | 0,2,50 | 100,4,20 | 检测机器人是否到达终点 |
提示:
修改“起始点”的位置会与“相机限制”重合,这种情况不会对机器人有影响,“相机限制”模型在仿真时不可见,且没有阻挡效果;
编写规则
单击“功能”>“编写脚本”,弹出“脚本逻辑”窗口,开始编写此任务的规则。场景的脚本在第一次打开时,会自动添加必要的函数,可以在这些函数构成的框架上完成此任务规则。去除掉函数的注释后其内容如下:
起止行号 | 函数或语句 | 规则作用 |
---|---|---|
1-1 | Game = Game or {} | 无用 |
10-12 | 游戏信息 = { 总耗时 = 0, } |
用于存储在算分函数中需要记录的任务数据,如任务时间、得分等 |
19-20 | 显示信息 = { } |
暂时不关注 |
26-28 | Game.ComputeResult = function(self) return 1,0 end |
算分函数,任务结束后根据“游戏信息”表中的数据计算任务成功与得分 |
34-36 | Game.IsGameOver = function(self) - - end |
暂时不关注 |
41-43 | Game.GameReset = function(self) end |
暂时不关注 仿真复位时执行一次 |
48-50 | Game.GameInit = function(self) end |
暂时不关注 仿真开始时执行一次 |
56-58 | Game.Update = function(self, fDelta) end |
仿真运行时需要执行的功能 仿真运行重复执行 |
规则代码
编写“训练-前进”任务规则时目前关注以下几点:
1. 检测机器人是否到达设定的终点,即机器人是否接触到触发器“触发方块”;
2. 任务的算分,判断任务是否成功;
在规则的“游戏信息”表中加入以下语句
游戏信息 = { 总耗时 = 0, -- 任务总时间 任务成功 = 0, -- 标识任务是否成功 }
语句作用:
用于标识机器人是否完成任务,其初始值为0,当机器人完成任务时,脚本将其改为1。依据这个变量判断机器人是否完成任务。
提示:
为了排版需要求,可能会修改格式(如使用中文逗号,增加换行,--中插入空格等)。在此文档中复制代码到“脚本逻辑”中,可能会有语法错误!
代码示例中,灰色文字是原有语句,无需改动,用于参考在何处添加语句;黑色加粗文字是需要键入的代码语句;
代码中任何符号(字符串中除外)均是英文半角符号,特别是“,”不要写成中文的“,”,否则脚本会提示错误;
“--”为Lua语言中注释符号,相当于C语言中“//”;
继续在规则中添加代码
Game.Update = function(self, fDelta) if Event.IsTouch("起始点", "触发方块") then 游戏信息.任务成功 = 1 Execution.OverGame() end end
语句作用:
用于检测机器人是否与终点区域的“触发方块”接触,当其接触时标记任务成功,并将仿真结束。
语句解释
●    Lua判断语句
if (条件)then
(执行语句)
end
Lua的if判断语句,当“条件”成立时(条件的结果为true),执行“执行语句”。
●    触发器接触事件
其判断条件为
Event.IsTouch("起始点", "触发方块")
这是萝卜圈仿真提供的系统事件接口,其作用是检测某物体是否与指定的触发器接触,当指定物体与指定触发器接触时此函数返回true,否则返回false。这里用来检测机器人与否与“触发方块”接触。
事件中用于检测的事件接口函数需要用到模型的名称,如“触发方块”,而机器人是没有名称,在仿真时,需要在事件等接口中检测机器人时,需要使用机器人出发时的“起始点”的名称。
场景模型的名称总是唯一的,且不可更改。
●    Lua赋值
当判断到任务成功时,将“游戏信息.任务成功”的值由0改为1,使用以下语句:
游戏信息.任务成功 = 1
●    结束仿真
当规则判断任务完成、任务失败、机器人犯规等情况出现时,需要结束仿真,使用以下语句:
Execution.OverGame()
仿真结束后,系统会停止执行脚本的Game.Update()函数,并将“游戏信息”表中的所有变量提交到服务器,供算分函数“Game.ComputeResult()”使用;
●    超时自动结束
仿真开始后,当任务时间超出“任务配置”中的“一次任务限时”中设定的时间后,系统会自动结束仿真;这种结束方式发生时,没有发生机器人接触到“触发方块”事件,不会更改“游戏信息.任务成功”变量的值,仍为0,所以在算分阶段可以判断出机器人没有完成任务。
继续在代码中添加语句
Game.ComputeResult = function(self) if 游戏信息.任务成功 == 1 then return 0, 100 else return 1, 0 end -- return 1, 0 end
在任务的算法阶段,首先需要判断任务是否成功。任务成功和不成功需要不同的得分。
系统要求Game.ComputeResult()返回2个值,第1个值表示机器人是否完成任务,这个值有2个选项,0:任务成功,1:任务失败;
第2个值代表机器人的得分,与任务是否成功无关,完全由任务规则决定,任务失败时也可以有得分。
在算分阶段需要的任何数据只能从“游戏信息”表中获取,不在此表中的数据获取不到。
因为训练任务的规则要求,任务成功即得100分,不成功为0分。所以当判断“游戏信息.任务成功 == 1”时,返回“0,100”,否则返回“1,0”
保存脚本
脚本编写完毕后,需要单独保存。单击“脚本逻辑”窗口工具栏的“保存”图标,以保存脚本的更改。
注意:如果不在“脚本逻辑”窗口单击“保存”按钮,关闭“脚本逻辑”窗口后,更改将丢失!
保存场景
以“我的训练-前进”为名称(或其它名称,但不要与官方离线场景同名)保存场景。
调试与排错
调试场景时需要事先搭建好完成此场景任务的机器人,并为其编写好控制程序。
在离线模式中新建仿真包,使用“我的训练-前进”场景、相关的机器人及其控制程序,进入仿真,单击仿真窗口的“开始”按钮,开始仿真,当机器人前进到终点区域时弹出“恭喜”的结果画面,并显示得分为100分时,表示场景及脚本可以正常工作。
编写程序难免会出现错误,知道出错时如何排除错误是编程的重要知识。
语法错误
常见是拼写错误,如将英文的“,”拼写为中文“,”。另一个错误是关键字丢失,如习惯C语言的用户可能会丢失if判断的“then”关键字,丢失判断、函数等的“end”关键字。
在保存时系统会检查语法错误,并提示错误信息(信息内容为英文),信息中包括错误发生的行号,及错误类型,根据提示进行排除错误。
运行时错误
这些错误在保存时无法检查,只有在运行到错误的语句时,由于无法正确执行,系统会提示执行错误,并显示错误信息或记录在软件日志文件中。
有2处可以查看错误信息,大部分错误信息直接在系统的“调试”窗口中出现,可以直接查看(此窗口无法关闭,只在关闭软件时自动关闭),一部分错误信息在软件安装目录中的“IRQ_SoftLog.log”文件中记录,使用“写字板”(不是记事本,或其它文本编辑软件,如UltraEdit)软件打开此文件,直接查看最后部分的内容。
重要提示:
在仿真中进入场景编辑器修改场景的脚本后,必须要完全退出仿真(回到离线模式主界面),再重新进入仿真后脚本更改才能生效!
完善
之前做的一些工作使场景可以使用了,当机器人完成任务时可以正确处理,显示正确的得分,任务超时时系统会自动结束,也会显示得分。
我们继续完善场景,使用户在玩此任务时,场景更美观,加入一些提示等,以增加互动性。
场景美化
●    隐藏模型
像触发器这类模型在仿真时应当被隐藏,有2种方法:
方法1:属性设置
进入场景编辑器,选择“触发方块”,修改以下属性:
通过设置模型属性的方式来隐藏模型的方法同样适用手其它有此属性的模型。
图标 | 名称 | 属性 | 新值 | 作用 |
---|---|---|---|---|
触发方块 | 运行时可见 | 取消勾选 | 仿真时隐藏 |
方法2:代码设置
Game.GameReset = function(self) SDK.SetVisible("触发方块", false) end
SDK.SetVisible() 是系统API,用于设置某个物体是否可见,接受2个参数,第1个为要设置的物体名称,是第2个参数是否可见(true:可见,false:不可见);
隐藏模型的代码可以放置在规则代码下面的几个函数中,不同的函数具有不同的效果:
放置在Game.GameInit() 时,仿真复位后,触发器是可见,当用户单击“开始”仿真按钮后,触发器变为不可见;
放置在Game.GameReset() 时,仿真复位后,触发器即不可见;
如有需要,可以同样的方法隐藏“起始点”。
提示:
模型被隐藏后,其各种作用(如触发器的触发功能,物体的碰撞效果等)仍有效。
●    添加装饰模型
可以添加一些模型使场景更生动,以免显得枯燥。在除了机器人行进的区域外,可以添加一些建筑、树木、花草等。
请根据个人喜好自由添加。
●    美丽的天空
默认情况下,场景四周是漆黑一片,可以添加“特殊”>“天空设置”模型,修改场景的天空,按下表设置:
图标 | 名称 | 属性 | 新值 | 作用 |
---|---|---|---|---|
天空设置 | 天空 | 海洋1 | 设置天空效果 |
提示信息
用户在进行任务时,规则将任务的一些情况反馈给用户,是比较好的做法。
任务开始时提示任务消息,编写以下代码:
Game.GameReset = function(self) SDK.SetVisible("触发方块", false) ShowMsg("我的训练-前进任务开始,前进吧!") end
ShowMsg() 函数是系统函数,作用是在仿真窗口显示大约5秒钟的信息;其接受2个参数,第1个参数为显示的内容,字符串类型,第2个参数可选,显示信息的字体颜色,共有3个选项(blue:蓝色(默认);yellow:黄色;red:红色);
提示:
字符串中可以使用Lua符号“..”进行连接,示例:
ShowMsg("我的训练-前进任务开始," .. "前进吧!")
字符串是由一对英文引号包括的字符串,字符串中可以使用中文标点(包括中文双引号);
字符串中可连接显示变量的值,示例:
ShowMsg("当前任务得分:" .. 游戏信息.任务得分)