require "XLuaBase"
--{{XFUN EVENT
--在此处添加事件
X_ON_LUAINIT(OnItemInit)
X_ONCURANIMATEEND(OnItemCurAnimateEnd)
X_ONSPRITECLOSETO(OnSpriteCloseTo)
ON_XEVENT(412,"*","OnSpriteMoveTo")
--}}XFUN EVENT
--范围半径
#define NRADIUS 1000
--动画总数
#define NANIMATECOUNT 2
--当前行走动画索引
#define NANIMATEID_MOVE 0
--运行一圈的时间(s)
#define NRUNANIMATE_TIME 4
---------------------------------------------
--事件处理函数
---------------------------------------------
LXRandomMove = {}
LXRandomMove.__index = LXRandomMove
objRandomMove = {}
setmetatable(objRandomMove,LXRandomMove)---设置元表数据
---------------------------------------------
--类实现函数
---------------------------------------------
--物体初始化
function LXRandomMove:OnItemInit(objSprite, fRadius)
math.randomseed(os.time())
self:Init(objSprite, fRadius)
--开始移动物体
self:MoveNext()
end
--初始化数据
function LXRandomMove:Init(objSprite, fRadius)
self.objSprite = objSprite--精灵对象
local objTrans = objSprite.GetTranslate() --中心点位置
self.ptCenter = objTrans.GetPosition()
self.fRadius = fRadius--范围半径
self.tMove = {} --移动速度
if self.tMove then
self.tMove.nMaxMove = 1.4 --最大移动速度(m/s)
self.tMove.nMinMove = 1.0 --最小移动速度(m/s)
end
self.nPlayAnimateCount = 1--待机时动画总数
self.nCurAnimate = -1--当前动画索引
self:InitPath(self.ptCenter) --路径节点
end
--初始化路径数据
function LXRandomMove:InitPath(ptLast)
--随机路线
self.Nodes = {} --当前路径的节点
self.nNodeCount = 10--当前节点总数
self.nNodeIndex = 1 --当前节点索引
local ptNode
local ptPrevious = ptLast
local nMove
local fDistance
for i = 1, self.nNodeCount, 1 do
self.Nodes[i] = X3DPoint.CreateObject() --节点数据
repeat
if i > 1 then
ptPrevious = self.Nodes[i - 1]
end
nMove = self:RandomOneData(ptPrevious, self.Nodes[i])
fDistance = self.ptCenter.Distance(self.Nodes[i])
until fDistance < self.fRadius --在范围内
--根据地表高度往上面偏移
self.Nodes[i].y = theSpace.GetTerrainHeight(self.Nodes[i]) + 150 + math.random(100, 200)
--保存速度
self.tMove[i] = nMove
end
end
--随机一个数据
function LXRandomMove:RandomOneData(ptLast, ptNode)
--蝴蝶转一圈需要4s, 在此设置每4s移动一次
--随机速度
local nMove = math.random(self.tMove.nMinMove*10, self.tMove.nMaxMove*10) /10
--随机角度, 得到圆上面一个点
local nAngle = math.random(0, 360)
local fAnale = math.rad(nAngle)
local nDistance = nMove*NRUNANIMATE_TIME*100 --移动距离(cm)
ptNode.x = ptLast.x + nDistance*math.cos(fAnale)
ptNode.z = ptLast.z + nDistance*math.sin(fAnale)
ptNode.y = self.ptCenter.y
return nMove
end
--当前路径结束
function LXRandomMove:OnCurPathEnd(ptLast)
self:InitPath(ptLast)
end
--当前动画结束
function LXRandomMove:OnItemCurAnimateEnd(param)
print("OnItemCurAnimateEnd .."..param)
if param == self.nCurAnimate then
self.nPlayAnimateCount = self.nPlayAnimateCount - 1
if self.nPlayAnimateCount > 0 then
self:PlayAnimate(this)
else
self:MoveNext()
end
end
end
--移动到下一个路径
function LXRandomMove:MoveNext()
--当前位置
local objTrans = self.objSprite.GetTranslate()
local ptCur = objTrans.GetPosition()
--下一个位置
self.nNodeIndex = self.nNodeIndex + 1
if self.nNodeIndex > self.nNodeCount then
self:OnCurPathEnd(ptCur)
self.nNodeIndex = 1
end
local ptNext = self.Nodes[self.nNodeIndex]
--移动物体
self:MoveTo(ptCur,ptNext)
end
--从一个位置移动到另外一个位置
function LXRandomMove:MoveTo(ptCur,ptNext)
local ptDirection = ptNext - ptCur
ptDirection.y = 0
local fDistance = ptNext.Distance(ptCur)
local fTime = (fDistance/100) / self.tMove[self.nNodeIndex] *1000 --100是将单位从cm换算成m, 1000是将秒换算为毫秒
--物体移动
self.objSprite.MoveTo(ptNext, ptDirection, 0, NANIMATEID_MOVE, fTime, 0, false)
end
--移动到目标位置
function LXRandomMove:OnSpriteMoveTo(param)
--随机判断做动画还是移动
--self.nPlayAnimateCount = math.random(0, self.nPlayAnimateCount)
self.nPlayAnimateCount = 1
if self.nPlayAnimateCount > 0 then
self:PlayAnimate()
else
self:MoveNext()
end
end
--做动画
function LXRandomMove:PlayAnimate()
repeat
self.nCurAnimate = math.random(0, NANIMATECOUNT - 1)
until self.nCurAnimate ~= NANIMATEID_MOVE
self.objSprite.PlayAnimate(self.nCurAnimate, false)
print("PlayAnimate .."..self.nCurAnimate)
end
--人物靠近
function LXRandomMove:OnSpriteCloseTo(objSprite)
if not objSprite then
return
end
--得到自身位置
local objSelfTrans = self.objSprite.GetTranslate()
local ptSelf = objSelfTrans.GetPosition()
--得到人物位置
local objSpriteTrans = objSprite.GetTranslate()
local ptDes = objSpriteTrans.GetPosition()
--向人物走出一步
local vecDir = ptDes - ptSelf
vecDir.Normalize()
local nDistance = self.tMove[self.nNodeIndex]*NRUNANIMATE_TIME*100 --距离单位cm
ptDes.x = ptSelf.x + vecDir.x*nDistance
ptDes.y = ptSelf.y + vecDir.y*nDistance
ptDes.z = ptSelf.z + vecDir.z*nDistance
self:MoveTo(ptSelf, ptDes)
end
--开始显示人物移动范围
function ShowRangeImageOnTerrain(fRange)
local RangeImage = XImage.CreateObject()
RangeImage.Load("range.xmp")
if RangeImage then
theSpace.ShowImageOnTerrain(RangeImage, objRandomMove.ptCenter,fRange,fRange,1)
end
end
---------------------------------------------
--事件处理函数
---------------------------------------------
--初始化
function OnItemInit(this,nEventID,SendName,param)
--初始化数据
objRandomMove:OnItemInit(this, NRADIUS)
--精灵靠近
this.EnableClosetoEvent(5)
ShowRangeImageOnTerrain(NRADIUS)
end
--动画结束
function OnItemCurAnimateEnd(this,nEventID,SendName,param)
objRandomMove:OnItemCurAnimateEnd(param)
end
--移动到目标位置
function OnSpriteMoveTo(this,nEventID,SendName,param)
objRandomMove:OnSpriteMoveTo(param)
end
--人物靠近
function OnSpriteCloseTo(this,nEventID,SendName,param)
if param.bEnter == 1 then --靠近
local objSprite = param.ItemObject
objRandomMove:OnSpriteCloseTo(objSprite)
end
end