require "XLuaBase"

--{{XFUN EVENT
    --在此处添加事件
X_ON_LUAINIT(OnItemInit)  
X_ONSPRITECLOSETO(OnSpriteCloseTo)
X_ON_TIMER(OnItemTimer)  
--}}XFUN EVENT

--范围半径
#define NRADIUS 1000

--精灵移动时两个节点之间的最短距离
#define NMOVE_MINDISTANCE              100

--人物靠近的触发距离
#define NPERSON_CLOSEDISTANCE          5

--检查是否主控
#define NTIMER_MAINCTRL_ID 1000
#define NTIMER_MAINCTRL_TIME 10000

--检查命令是否快结束了
#define NTIMER_CMDEND_ID    1001

---------------------------------------------
--事件处理函数
---------------------------------------------

LXRandomMove = {}
LXRandomMove.__index = LXRandomMove

objRandomMove = {}
setmetatable(objRandomMove,LXRandomMove)                    ---设置元表数据
---------------------------------------------
--类实现函数
---------------------------------------------
--物体初始化
function LXRandomMove:OnItemInit(objSprite)
    math.randomseed(os.time())    
    
    --初始化
    self:Init(objSprite, NRADIUS)

--精灵靠近
    objSprite.EnableClosetoEvent(NPERSON_CLOSEDISTANCE)

--设置定时器
    objSprite.SetTimer(NTIMER_MAINCTRL_ID, NTIMER_MAINCTRL_TIME)
end

--初始化数据
function    LXRandomMove:Init(objSprite, fRadius)
    self.objSprite = objSprite                    --精灵对象

local objTrans = objSprite.GetTranslate()    --中心点位置
    self.ptCenter = objTrans.GetPosition()
 
    --todo
    objTrans.SetScale(1.2)
    objSprite.ApplyTranslate(objTrans)

self.fRadius = fRadius                        --范围半径
 
    self.Nodes = {}                                --当前路径的节点    
    self.nNodeMoveCount = 10                    --当前移动次数
    self.nNodeAnimateCount = 10                    --当前动作次数
    if self.Nodes then
         for i = 1, self.nNodeMoveCount + self.nNodeAnimateCount, 1 do    --节点数据
            self.Nodes[i] = {}
            self.Nodes[i].ptStart = X3DPoint.CreateObject()     --起始移动位置
            self.Nodes[i].ptEnd = X3DPoint.CreateObject()     --目标移动位置
            self.Nodes[i].ptDir = X3DPoint.CreateObject()     --移动方向
            self.Nodes[i].vMove = math.random(1.2*10, 1.6*10) /10      --移动速度
            self.Nodes[i].fTime = 0                             --时间
            self.Nodes[i].fStartTime = 0                     --多长时间开始
            self.Nodes[i].bMoveByTerrain = true                 --是否沿着地表移动
            self.Nodes[i].bActionLoop = true                 --动作循环
            self.Nodes[i].nAction = NANIMATEID_MOVE             --动作索引
            self.Nodes[i].strMove = "Move"                     --是否要移动位置
        end
    end

self.bMainCtrl = false                                    --是否主控
    self.fStartTime = 0                                        --当前动画总共时间
    self.nNotifySvrDelayTime = 200                            --发送消息到服务器的延迟时间

self.Animate = {}                                        --动作
    if self.Animate then
        self.Animate.nStay = 2                                --待机动作索引
        self.Animate.nMove = 1                                --移动动作索引
        self.Animate.nCount = 3                                --动作总数

self.Animate.Length = {}                            --动作长度
        for i = 0, self.Animate.nCount - 1, 1 do
            self.Animate.Length[i] = self.objSprite.GetAnimateLength(i)
        end
    end

self.cache = {}
    if self.cache then
        self.cache.nMoveCount = 4
        self.cache.nMove = {}                                --随机速度
        for i = 1, self.cache.nMoveCount, 1 do
            self.cache.nMove[i] = math.random(1.2*10, 1.6*10) /10  
        end

self.cache.Cmd = {}                                    --一系列命令, 每个子命令的个数,命令格式为:移动->待机->随机->待机->移动
        self.cache.nCmdCount = 10             
        for i = 1, self.cache.nCmdCount, 1 do
            self.cache.Cmd[i] = {}
            self.cache.Cmd[i].nMove = math.random(1, 2)        --移动个数
            self.cache.Cmd[i].nStayBegin = math.random(3, 5)    --开始待机个数
            self.cache.Cmd[i].nRandom = math.random(0, 4)    --随机个数
            self.cache.Cmd[i].nRandomValue = {}                --随机索引
            for j = 1, self.cache.Cmd[i].nRandom, 1 do                
                self.cache.Cmd[i].nRandomValue[j] = self:RandomAnimateIndex()  
            end
 
            self.cache.Cmd[i].nStayEnd = math.random(2, 4)    --结束待机个数
        end
    end
end  
        
--随机移动路径
function    LXRandomMove:RandomMoveData(nBegin, nCount)      
    for i = nBegin, nBegin + nCount - 1, 1 do         
        if i == 1 then
            --得到自身位置
            local objSelfTrans = self.objSprite.GetTranslate()         
            local ptSelf = objSelfTrans.GetPosition()    
            CopyPosition(self.Nodes[i].ptStart, ptSelf)
        else
            CopyPosition(self.Nodes[i].ptStart, self.Nodes[i - 1].ptEnd)  
        end
        self:RandomPath(self.Nodes[i].ptStart, self.Nodes[i].ptEnd)         
            
        self.Nodes[i].vMove = self.cache.nMove[math.mod(i, self.cache.nMoveCount) + 1]    
        
        self.Nodes[i].nAction = self.Animate.nMove  
                    
        local fDistance = self.Nodes[i].ptStart.Distance(self.Nodes[i].ptEnd)   
        self.Nodes[i].fTime = (fDistance/100) / self.Nodes[i].vMove *1000        --100是将单位从cm换算成m, 1000是将秒换算为毫秒
      
          self.Nodes[i].ptDir.x = self.Nodes[i].ptEnd.x - self.Nodes[i].ptStart.x
        self.Nodes[i].ptDir.z = self.Nodes[i].ptEnd.z - self.Nodes[i].ptStart.z
        self.Nodes[i].ptDir.y = 0    
 
        self.Nodes[i].bMoveByTerrain = true
        self.Nodes[i].bActionLoop = true
        self.Nodes[i].strMove = "Move"

self.Nodes[i].fStartTime = self.fStartTime    
        self.fStartTime = self.Nodes[i].fStartTime + self.Nodes[i].fTime    
    end            
end

--随机动作
function    LXRandomMove:RandomAnimateData(nIndex, nAnimateIndex)        
    local ptDir = self.Nodes[self.nNodeMoveCount].ptDir
    local ptEnd = self.Nodes[self.nNodeMoveCount].ptEnd
 
    CopyPosition(self.Nodes[nIndex].ptStart, ptEnd)
    CopyPosition(self.Nodes[nIndex].ptEnd, self.Nodes[nIndex].ptStart)

self.Nodes[nIndex].vMove = 0

self.Nodes[nIndex].nAction = nAnimateIndex      
    self.Nodes[nIndex].fTime = self.Animate.Length[nAnimateIndex]
        
    CopyPosition(self.Nodes[nIndex].ptDir, ptDir)

self.Nodes[nIndex].bMoveByTerrain = true    
    self.Nodes[nIndex].bActionLoop = true    
    self.Nodes[nIndex].strMove = "DoAction"

self.Nodes[nIndex].fStartTime = self.fStartTime        
    self.fStartTime = self.fStartTime + self.Nodes[nIndex].fTime    
end

--随机一个数据
function    LXRandomMove:RandomPath(ptLast, ptNew)    
      local fDistance    
    repeat        
        self:RandomOneData(ptNew)    
        fDistance = ptLast.Distance(ptNew)
    until fDistance > NMOVE_MINDISTANCE    --两个节点之间保持固定距离  
    
    --调整位置的高度
    self:AdjustPosHeight(ptNew)  
end

--随机一个数据
function    LXRandomMove:RandomOneData(pt)     
    --随机半径和角度
    local nAngle = math.random(0, 360)
    local fAnale = math.rad(nAngle)
    local nRadius = math.random(0, self.fRadius)     
   
    pt.x = self.ptCenter.x + nRadius*math.cos(fAnale)        
    pt.z = self.ptCenter.z + nRadius*math.sin(fAnale)    
    pt.y = self.ptCenter.y   
end

--调整位置的高度
function    LXRandomMove:AdjustPosHeight(ptNode)
    --得到地表高度
    ptNode.y = theSpace.GetTerrainHeight(ptNode)   
end

--随机动画索引
function    LXRandomMove:RandomAnimateIndex()
    local nAnimate
    repeat
        nAnimate = math.random(0, self.Animate.nCount - 1)    
    until nAnimate ~= self.Animate.nMove
    return nAnimate       
end

--移动物体
function LXRandomMove:Go()        
    local nCmd = math.random(1, self.cache.nCmdCount)

--随机移动路径   
    self.nNodeMoveCount = self.cache.Cmd[nCmd].nMove    
    self:RandomMoveData(1, self.nNodeMoveCount)

--随机动画路径  
    local nStayBegin = self.cache.Cmd[nCmd].nStayBegin
    local nRandom = self.cache.Cmd[nCmd].nRandom
    local nRandomValue = self.cache.Cmd[nCmd].nRandomValue
    local nStayEnd = self.cache.Cmd[nCmd].nStayEnd
      self:RandomAllAnimate(nStayBegin, nRandom, nStayEnd, nRandomValue)

--开始发送服务器消息  
    self:SendServerMsg()    
end

--开始发送服务器消息   
function LXRandomMove:RandomAllAnimate(nStayBegin, nRandom, nStayEnd, nRandomValue)
    local nBegin = 1 + self.nNodeMoveCount

--待机动作      
    for i = nBegin, nBegin + nStayBegin - 1, 1 do
        self:RandomAnimateData(i, self.Animate.nStay)
    end

--随机动作
    nBegin = nBegin + nStayBegin
    for i = nBegin, nBegin + nRandom - 1, 1 do
        self:RandomAnimateData(i, nRandomValue[i - nBegin + 1])
    end  
            
    --待机动作
    nBegin = nBegin + nRandom      
    for i = nBegin, nBegin + nStayEnd - 1, 1 do
        self:RandomAnimateData(i, self.Animate.nStay)
    end
    
    self.nNodeAnimateCount = nStayBegin + nRandom + nStayEnd
end

--开始发送服务器消息   
function LXRandomMove:SendServerMsg()
    local nCount = self.nNodeMoveCount + self.nNodeAnimateCount
    for i = 1, nCount, 1 do        
        --物体移动
        self.objSprite.MoveTo(self.Nodes[i].ptStart, self.Nodes[i].ptEnd, self.Nodes[i].ptDir,
        self.Nodes[i].vMove, self.Nodes[i].nAction, self.Nodes[i].fStartTime,
        self.Nodes[i].bMoveByTerrain, self.Nodes[i].bActionLoop, self.Nodes[i].strMove)
    end    
end        
 
--人物靠近
function    LXRandomMove:OnSpriteCloseTo(objSprite)    
     if not objSprite then
        return
    end

--判断主控
    self.bMainCtrl = theSpace.IsMainControl()
    if self.bMainCtrl == false then
        return
    end

self.fStartTime = 0

--得到移动路径      
    self.nNodeMoveCount = 1
    self:GetSpriteCloseData(objSprite, self.Nodes[1])

--随机动画路径  
    local nStayBegin = math.random(1, 2)
    local nRandom = math.random(0, 2)
    local nRandomValue = {}
    for i = 1, nRandom, 1 do
        nRandomValue[i] = self:RandomAnimateIndex()
    end
    local nStayEnd = math.random(1, 2)
    self:RandomAllAnimate(nStayBegin, nRandom, nStayEnd, nRandomValue)

--发生服务器消息
    self:SendServerMsg()

self.objSprite.KillTimer(NTIMER_CMDEND_ID)
    self.objSprite.SetTimer(NTIMER_CMDEND_ID, self.fStartTime - self.nNotifySvrDelayTime)
end

--定时器
function    LXRandomMove:GetSpriteCloseData(objSprite, objNode)
    --得到自身位置
    local objSelfTrans = self.objSprite.GetTranslate()         
    local ptSelf = objSelfTrans.GetPosition()    
    CopyPosition(objNode.ptStart, ptSelf)
        
    --得到人物位置
    local objSpriteTrans = objSprite.GetTranslate()         
    local ptDes = objSpriteTrans.GetPosition()

--向人物走出一步                 
    objNode.ptDir.x = ptDes.x - ptSelf.x        
    objNode.ptDir.y = ptDes.y - ptSelf.y
    objNode.ptDir.z = ptDes.z - ptSelf.z  
    objNode.ptDir.Normalize()

objNode.ptEnd.x = ptSelf.x + objNode.ptDir.x*NMOVE_MINDISTANCE
    objNode.ptEnd.y = ptSelf.y + objNode.ptDir.y*NMOVE_MINDISTANCE
    objNode.ptEnd.z = ptSelf.z + objNode.ptDir.z*NMOVE_MINDISTANCE

self:AdjustPosHeight(objNode.ptEnd)     
    objNode.ptDir.y = 0    
    
    objNode.vMove = math.random(1.2*10, 1.6*10) /10
    objNode.nAction = self.Animate.nMove     
    
    local fDistance = objNode.ptStart.Distance(objNode.ptEnd)  
    objNode.fTime = (fDistance/100) / objNode.vMove *1000        --100是将单位从cm换算成m, 1000是将秒换算为毫秒

objNode.bMoveByTerrain = true
    objNode.bActionLoop = true
    objNode.strMove = "Move"

objNode.fStartTime = self.fStartTime    
    self.fStartTime = objNode.fStartTime + objNode.fTime    
end
    
--定时器
function    LXRandomMove:OnItemTimer(param)
    if param == NTIMER_MAINCTRL_ID then --检查主控
        local bMainCtrl = theSpace.IsMainControl()
        if bMainCtrl ~= self.bMainCtrl then
            self.bMainCtrl = bMainCtrl
    
            --开始移动物体      
            if self.bMainCtrl then
                self.fStartTime = 0
                self:Go()
                self.objSprite.SetTimer(NTIMER_CMDEND_ID, self.fStartTime - self.nNotifySvrDelayTime)
            end
        end
    elseif param == NTIMER_CMDEND_ID then --检查命令是否快结束了
        self.bMainCtrl = theSpace.IsMainControl()
        if self.bMainCtrl then
            self.fStartTime = 0
            self:Go()
            self.objSprite.KillTimer(NTIMER_CMDEND_ID)
            self.objSprite.SetTimer(NTIMER_CMDEND_ID, self.fStartTime - self.nNotifySvrDelayTime)
        end
    end
end

--设置值
function    CopyPosition(ptSrc, ptDes)
    ptSrc.x = ptDes.x
    ptSrc.y = ptDes.y
    ptSrc.z = ptDes.z
end

---------------------------------------------
--事件处理函数
---------------------------------------------
--初始化
function OnItemInit(this,nEventID,SendName,param)
    --初始化数据
    objRandomMove:OnItemInit(this)        
end

--动画结束
function OnItemCurAnimateEnd(this,nEventID,SendName,param)
    objRandomMove:OnItemCurAnimateEnd(param)    
end

--人物靠近
function OnSpriteCloseTo(this,nEventID,SendName,param)
    if param.bEnter == 1 then               --靠近
        local objSprite = param.ItemObject
        objRandomMove:OnSpriteCloseTo(objSprite)        
    end
end

--定时器
function OnItemTimer(this,nEventID,SendName,param)
    objRandomMove:OnItemTimer(param)
end

3D游戏精灵-兔子脚本 (lua语言开发,xfun平台)最新版相关推荐

  1. 3D游戏精灵-蝴蝶脚本 (lua语言开发,xfun平台)

    require "XLuaBase" --{{XFUN EVENT     --在此处添加事件 X_ON_LUAINIT(OnItemInit) X_ONCURANIMATEEND ...

  2. lua语言开发esp8266接入巴法云,mqtt和tcp协议

    第一步,lua语言开发环境配置 下载安装java环境,下载地址:点击下载 选择windows版本下载安装即可,如图所示: 下载开发环境包: 下载地址:点击下载 esp8266串口驱动:点击下载 下载后 ...

  3. lua 给userdata设置元表_提高Lua语言开发效率的简单方法

    概述 首先,lua是一门高效的(efficient).轻量级(lightweight)的嵌入式脚本语言(embeddable scripting language),这是它的官方网站的标语. 其次,l ...

  4. android lua 开发环境搭建,使用 lua 语言开发Android应用

    做移动端开发,做蛋疼的就是不能动态发版,不能像 web 那样发版立即全部用户生效,然而 lua语言 为其提供了可能性.使用 lua 来构建跨平台原生应用有许多好处,比如 lua 语言简洁高效,可移植性 ...

  5. CF-IOT之LUA语言开发

    概述 CFIOT内置了丰富的API接口,以模块的形式类聚这些API接口,并导入到内置的LUA虚拟机,供用户的LUA脚本调用,用户可使用CFIOT云端通讯协议远程更新LUA脚本和管理虚拟机,如关闭.启动 ...

  6. python可以开发3d游戏吗_用python3从零开始开发一款烧脑射击游戏#3

    上回说到我们已经可以控制小方块的移动了,现在我们要把这个小方块放置到游戏场景里 剥去美术的外壳,游戏场景其实就是一个标记了玩家可行走与不可行走的空间 对于2D游戏,它是一个平面网格,3D游戏就是一个3 ...

  7. 汇编x86x64游戏内存封包实战注入脚本lua辅助开发反调试过检测

  8. CoppeliaSim(原Vrep)中实现多关节机械臂的正运动学仿真【CoppeliaSim内嵌脚本lua语言实现】

    lua实现 文章目录 lua实现 `本章在动力学建模完成的前提下进行` 1)创建脚本 2)代码实现 3)以上代码的运行结果 4)代码中用到函数的help文档 本章在动力学建模完成的前提下进行 传送门: ...

  9. 基于C语言开发Linux平台的协议分析软件

    资源下载地址:https://download.csdn.net/download/sheziqiong/85946240 资源下载地址:https://download.csdn.net/downl ...

最新文章

  1. Dalvik中类的加载
  2. Docker数据卷管理
  3. 我在谷歌实习时发现了一个模型 bug,于是有了这篇 ACL
  4. STM32通过串口如何接收服务器发来的数据
  5. 直播预告丨爆款独立站如何利用数据提升经营效率?
  6. mac下antlr4命令使用
  7. android 透明度_Android智能视图翻转器
  8. Bat批处理命令执行中文路径解决方法
  9. 线性判别分析LDA算法与python实现
  10. 面试官教你写简历之『实习/应届生简历指南』(收藏)
  11. 深入理解Nginx负载均衡和反向代理_学习笔记
  12. 怎么用diskgenius扩大c盘,超简单。
  13. 麻将胡牌递归算法(lua)
  14. Spark 第三讲 Scala数组与函数基础
  15. CUDA+pytorch+DGL安装
  16. 如何用python解方程组_python如何解方程组
  17. 计组_定点数一位乘_布斯公式
  18. 直播技术总结(四)音视频数据压缩及编解码基础
  19. Vue轮子-Lottie-动画实现
  20. 2021.7 纪中快乐游记(上)

热门文章

  1. Qcom Sensor调试
  2. 4-1、matplotlib绘制两个系列的簇状柱形图(参数详解)
  3. 基于自适应图正则化的低秩表示
  4. pythonpil库过滤图像contour_Python随记【三】
  5. Cordova高德地图定位、ionic2/3/4高德地图定位(解决部分国产手机无法定位的情况)
  6. 工具猿之Linux运维命令总结以及场景运用
  7. 支撑掩护式液压支架设计(论文+CAD图纸+翻译)
  8. 监控摄像头个人购买零门槛真的没问题吗?
  9. 计算机上全部是应用程序,电脑桌面的所有应用程序.exe名称后缀都变成.lnk的解决方法...
  10. 助力企业加快攻破数字化“壁垒”,得帆信息的PaaS“组合拳”