> 神唱K歌 > 进入一定范围跳舞脚本

进入一定范围跳舞脚本

这是一个类似恶作剧的物品,良善者慎用。任何人只要进入该物品一定范围内,都有可能被强制跳舞!

MyTable =
{
EntryInfo = {ONLOADED, "state1"};
StateList = {"state1"};
state1 =
{
Timer = 1000,--每隔1秒扫描一次
TimeOut =-1,
NextState = "nil",
EventList = {ONSENSOR};
};

}

function MyTable.state1.OnEnter(args)
id={};--定义一个数组
end

function MyTable.state1.OnExit(args)
end

function MyTable.state1.OnTimer(args)
uScanPoint(1, "NULL",5, uGetItemId())--以物品为中心扫描5米范围内的角色,扫描到角色成功会触发OnSensor事件
local a=1
while id[a] do--while循环结构
local posplayer= uGetPlayerPos(id[a])--获得数组中用户的位置
local positem= uGetItemPos(uGetItemId())--获得物品位置
if uAbs(posplayer.x-positem.x)>5 or uAbs(posplayer.y-positem.y)>5 or uAbs(posplayer.z-positem.z)>5 then--判断用户和物品距离是否在5米范围内,uAbs()取绝对值
uRemove(id,a)--离开了这个区域,从数组中删除
a=a-1--将数组序列上移一位,保证下一条数组中的用户ID能被读到
end
a=a+1--while循环专用,没有会进入死循环
end
end

function MyTable.state1.OnSensor(args)
local flag=0--用来标记新扫描到的人是否在数组中
for a=1,uMaxn(id) do--for循环结构
if id[a]==args.guid then--用args.guid获得扫描者的ID
flag=1 --如果扫描到的用户在数组存在,flag标记为1
break --退出for循环
end
end
if flag==0 then--如果扫描到的用户不在数组中,flag标记还是0,将该用户ID加入数组,并播放一个动作
id[uMaxn(id)+1]=args.guid--uMaxn获得数组的最大索引,即数组已记录了多个用户数量
uPlayOperatorAct("dance",args.guid);--播放跳舞动作
end
end

脚本思路解释:
1.首先要每隔1秒扫描一次该物品周围。
我们有用于扫描物品周围是否有人的API: uScanPoint(1, "NULL",5, uGetItemId()) ; 但是如何让它每隔1秒执行一次呢?
uWorld脚本中有专用的结构来控制,如下:
state1 =
{
Timer = 1000,--每1秒执行一次OnTimer函数
。。。。。。
};
意思是每1秒钟执行一次后文的function MyTable.state1.OnTimer(args)函数,函数中写上我们想要做的事情,比如扫描。
2.对于已经跳过舞的人,我们不想他再浪费跳舞的机会。
建立一个数组,将跳过舞的人加入数组,每次扫描到一个人就和数组进行比较,有相同,则不给他跳舞的机会,不同,则强制他跳舞,并加入数组。
3.若这个人离开物品范围后再回来,将重新可以跳舞。
通过API得到人物的坐标,并计算他与物品坐标之间的距离,若超过距离,则将他清除出上面的数组。
4.API:uScanPoint(1, "NULL",5, uGetItemId())通常需要和ONSENSOR 函数一起使用。
state1 =
{
。。。。。。
EventList = {ONSENSOR};
};
一旦uScanPoint(1, "NULL",5, uGetItemId()) 扫描到人物,则自动执行后文的function MyTable.state1.OnSensor(args) 函数。

--while循环和for循环的区别:
--while循环是先判断条件是否满足,条件满足执行while循环内脚本,不满足自动退出循环,需要在while循环内部+1进行下一个条件判断
--for是开始循环自动+1,然后执行for循环内的脚本
--脚本基本结构讲解看这里:http://3d-ktv.com/html/shenchang/317.html