任务要求

目的:要求机器人从起点出发,沿跑道行进到终点;

任务限时:180秒

成功条件:在任务限时内行进到终点;

失败条件:

    1. 在任务限时内未行进行到终点;

    2. 机器人从跑道上掉落;

    3. 机器人未完整走完个跑道(中途从高处跑道掉到低处跑道平继续行进行到终点);

    4. 未从起始点出发走到终点;

评分方式:采用时间奖励分方式(任务限时-任务用时)

构建场景

进入“构建场景”,启动场景编辑器,使用“模型”>“场景”类中的“跑道_1”到“跑道_21”按下图或自由设计构建场景。

构建要求

无论什么样式的场景都需要包括以下内容:

    1. 添加一个“模型”>“自然”>“地图_7”作为地面,在其平面上构建跑道;

    2. 按图示或自由设计一条跑道;

    3. 跑道上有一个“起始点”在其上放置一个触发方块;

    4. 跑道上有一个终点,放置一个触发方块;

    5. 在跑道的必经“关键点”上放置触发方块;

拼接跑道

按照“构建场景用户册”中“修改模型位置”章节关于“可拼接模型”的说明,构建“跑道竞速场景”。

典型的跑道竞速场景如下图:

拼接跑道

放置“起始点”

此任务中要求机器人从跑道上开始,因此“起始点”要放置在跑道上,有2个方法实现:

●    将场景中原有起始点移动到需要的位置和高度,需要调整X、Y、Z轴,注意要求“起始点”比跑道面略高;

●    将原有“起始点”删除,重新在需要的位置添加一个“起始点”,添加时“起始点”自动放置到跑道上,且比跑道略高,只需调整X、Y轴到需要的位置。

添加触发方块

添加起点触发方块,在“起始点”上添加一个触发方块;

添加终点触发方块,在跑道终点上添加一个触发方块;

添加若干(至少5个)关键点触发器,在跑道上添加触发方块

触发方块
图标 名称 缩放 旋转 作用
起始点触发方块 4,1,4 按需要 检测机器人是否从起始点出发
终点触发方块 4,1,4 按需要 检测机器人是否到达终点
路径关键点触发方块 4,1,4 按跑道需要 检测机器人是否经过此处,横置在跑道上

按下表设置相关模型的属性。

相关模型的属性
图标 名称 属性 新值 作用
相机限制 设定半径 100 放置整个跑道的中心位置,半径根据需要设定
任务配置 一次任务限时(单位:秒) 180(默认值) 关注此值,设置任务限时

编写规则

单击“功能”>“编写脚本”,弹出“脚本逻辑”窗口,开始编写此任务的规则。

模型名称变量

在场景稍复杂,且可能会反复修改的场景中,为事件中使用的模型名称定义变量是比较好的做法。在修改场景、更新模型等之后,模型的名称发生变化后,在脚本中修改对应的名称变量,即可使原来的脚本正常工作,而不必找到脚本中所有使用此名称的位置逐个修改;

在规则文件的最后添加一个表,记录场景中的所有物体的名称等。此段代码要完整的添加到脚本文件最后。

Rule = {
	MissionState = "Running",-- 任务状态, Running:进行中 Failure:任务失败
	RobotName = "起始点",			-- 场景中"起始点"名称
	TrigStart = "触发方块",			-- 起始点触发方块名称
	TrigEnd = "触发方块_15",		-- 终点触发方块名称
	Ground = "大地形",				-- 地面模型名称
	KeyPoint = {					-- 所有关键点触发器名称,及是否接触列表
		-- 1.名称	 2.是否接触
		{"触发方块_2",	false},		-- 注意格式,
		{"触发方块_3",	false},
		{"触发方块_4",	false},
		{"触发方块_5",	false},
		{"触发方块_6",	false},
		{"触发方块_7",	false},
		{"触发方块_8",	false},
		{"触发方块_9",	false},
		{"触发方块_10",	false},
		{"触发方块_11",	false},
		{"触发方块_12",	false},
		{"触发方块_13",	false},
		{"触发方块_14",	false},
	},
	BeginStart = false,				-- 记录机器人是否从起始点出发
}

仿真复位时处理

在Game.GameReset () 函数中添加以下代码,这里主要作用是隐藏触发器和读取任务限时,在调试阶段,如要显示触发器,可以将隐藏触发器代码每行用“- -”注释;

Game.GameReset = function(self)
	SDK.SetVisible(Rule.TrigStart, false)	-- 设置起始区触发方块不可见
	SDK.SetVisible(Rule.TrigEnd, false)		-- 设置终点区触发方块不可见
	for k,v in pairs(Rule.KeyPoint) do	-- 设置所有关键点触发方块不可见
	    SDK.SetVisible(v[1], false)
	end
	游戏信息.任务限时 = IRQ_MissionConfig.任务限时	-- 读取"一次任务限时"
end

仿真开始时处理

在Game.GameInit()函数中添加以下代码,使得在开始仿真时显示一条消息;

Game. GameInit = function(self)
	ShowMsg("跑道竞速任务开始!")				-- 任务开始显示任务信息
end

“游戏信息”表添加记录

在“游戏信息”表中加入一个变量,记录任务是否完成;

游戏信息 = {
	总耗时 = 0,		-- 任务总时间
	任务完成 = 0,	-- 完成为1, 未从起始点开始,未成功,未完整走完等都为0
}

计算分数方法

在Game.ComputeResult() 函数中加入以下代码,用于计算分数。“游戏信息.任务限时”从场景的“任务配置”中读取,单位为“秒”,“游戏信息.任务时间”在仿真时由系统写入,单位为“毫秒”,算分时注意单位,Round()函数为四舍五入函数。

Game.ComputeResult = function(self)
	-- 任务完成时, 采用成功的算分方法
	if 游戏信息.任务完成 == 1 then
		return 0, Round(游戏信息.任务限时 - 游戏信息.任务时间/1000,2)
	-- 否则采用失败的算法方法
	else
		return 1,0
	end
end

运行时处理结构

在Game.Update = function(self, fdelta)函数中加入以下结构代码

Game.Update=function(self,fDelta)
	-- 任务运行中处理
	if Rule.MissionState == "Running" then
		-- 接下来会添加任务进行时处理代码
	-- 任务失败时处理
	elseif Rule.MissionState == "Failure" then
		-- 接下来会添加任务失败时处理代码
	end
end

在“任务运行中处理”部分中添加代码,检测机器人是否从起始点出发,当机器人整体离开起始点的触发器时认为是从起始点出发;

Game.Update=function(self,fDelta)
	-- 任务运行中处理
	if Rule.MissionState == "Running" then
		-- 检测机器人是否从起始点出发
		-- 当标记为 false 时一直检测"机器人是否整体离开起始点触发器"
		if Rule.BeginStart == false
			and Event.IsAllOut(Rule.RobotName, Rule.TrigStart) then
			Rule.BeginStart = true		-- 离开后标记为 true
		end

	-- 任务失败时处理
	elseif Rule.MissionState == "Failure" then
		-- 接下来会添加任务失败时处理代码
	end
end

继续在“任务运行中处理”部分添加代码,检测机器人是否经过所有关键点。机器人每经过(接触到时)一个关键点触发器,将这个触发器的标记为true,由于有多个触发器,可以用遍历(类似循环)方法来对每个进行检测。

Game.Update=function(self,fDelta)
	-- 任务运行中处理
	if Rule.MissionState == "Running" then
		--(检测从起始点出发)
		......
		-- 检测机器人是否经过所有关键点
		for k,v in pairs(Rule.KeyPoint) do
			-- k 为记录序号, 此处无用
			-- v[1] 为触发器名称, 用于接触事件检测
			-- v[2] 为检测结果
			-- 没检测到(false)时始终检测, 检测到之后(修改为true)不再检测		    	if v[2] == false and Event.IsTouch(Rule.RobotName, v[1]) then
				v[2] = true				-- 检测到接触时标记为 true
			end
		end

	-- 任务失败时处理
	elseif Rule.MissionState == "Failure" then
		-- 接下来会添加任务失败时处理代码
	end
end

续在“任务运行中处理”部分添加代码,以处理当机器人到达终点时的情况。首先判断机器人是否从起始点出发,如果是从起始点出发时,再判断机器人是否经过了所有触发器。

Game.Update=function(self,fDelta)
	-- 任务运行中处理
	if Rule.MissionState == "Running" then
		--(检测从起始点出发)
		--(检测机器人是否经过所有关键点)
		......
		-- 机器人到达终点后处理
		if Event.IsTouch(Rule.RobotName, Rule.TrigEnd) then
			-- 判断机器人是否从起始点出发
			if Rule.BeginStart == false then
				-- 未从起始点出发时, 显示错误消息, 将任务状态转到失败
				ShowMsg("机器人未从起始点出发,任务失败!\n5 秒钟后结束任务,请复位后重新开始。", "red")
				Rule.MissionState = "Failure"
			-- 判断机器人是否经过所有关键点
			else
				-- 先假设经过了所有关键点
				local isTrigAll = true
				-- 无序遍历所有关键点触发器的记录
				for k,v in pairs(Rule.KeyPoint) do
					-- k为记录序号, 此处无用
					-- v[1] 为触发器名称, 此处无用
					-- v[2] 为机器人是否经过此处
					if v[2] == false then
						-- 有一个标记为 false时, 即表示未经过所有关键点, 不用再继续检测了,结束遍历
						isTrigAll = false
						break
					end
				end
				-- 判断是否经过所有关键点
				-- 经过所有关键点
				if isTrigAll == true then
					游戏信息.任务完成 = 1		-- 在 "游戏信息" 标记任务已完成
					Execution.OverGame()		-- 结束仿真
				else
					-- 未经过所有关键点, 显示错误消息, 将任务状态转到失败
					ShowMsg("机器人虽然到达终点,但未完整走完整个跑道,任务失败!\n5 秒钟后结束任务,请复位后重新开始。", "red")
					Rule.MissionState = "Failure"
				end
			end
		end

	-- 任务失败时处理
	elseif Rule.MissionState == "Failure" then
		-- 接下来会添加任务失败时处理代码
	end
end

继续在“任务运行中处理”部分添加代码,检测机器人是否掉落到地面;

Game.Update=function(self,fDelta)
	-- 任务运行中处理
	if Rule.MissionState == "Running" then
		--(检测从起始点出发)
		--(检测机器人是否经过所有关键点)
		--(机器人到达终点后处理)
		......
		-- 检测机器人是否掉落到地面
		if Event.IsCollide(Rule.RobotName, Rule.Ground) then
			-- 未经过所有关键点, 显示错误消息, 将任务状态转到失败
			ShowMsg("机器人掉落到地面,任务失败!\n5 秒钟后结束任务,请复位后重新开始。", "red")
			Rule.MissionState = "Failure"
		end

	-- 任务失败时处理
	elseif Rule.MissionState == "Failure" then
		-- 接下来会添加任务失败时处理代码
	end
end

任务失败时处理

继续在“任务失败时处理”部分添加代码,使得失败后,显示过失败提示后5秒后结束仿真;

Game.Update=function(self,fDelta)
	-- 任务运行中处理
	if Rule.MissionState == "Running" then
		......
	-- 任务失败时处理
	elseif Rule.MissionState == "Failure" then
			-- 失败后一直在此执行, 不再做任何检测
		-- 经过 5 秒钟后结束仿真
		if Event.IsContinue("失败", 5.0*1000, true) then
			Execution.OverGame()
		end
	end
end

调试

“跑道竞速”任务的规则要求比较多,在规则编写完之后,每个成功和失败的情况都要测试到,调试规则有以下几个方法可以参考。

●    机器人掉落到地面:编写使机器人一直前进的控制程序,模拟这种情况;

●    机器人未从起始点出发:在仿真开始之前,单击仿真控制栏的“手动设置方位”按钮,将机器人向前移动,使其离开起始点触发器,再开始仿真;

●    机器人是否经过所有关键点:可以编辑场景,将其中的一个或多个触发器的高度改变,使机器人正常经过时,不能接触到此触发器;

●    任务超时:修改程序,使机器人不动,仿真开始后,等待“任务配置”中的“一次任务限时”时间;

完善

在不影响机器人运动的前提下,跑道周围或远或近放置一些建筑、树木等模型,增加场景的非富性;

可以放置“天空”模型,修改场景的天空样式和环境光;