• QQ21031394

    工作时间

    周一至周五:9:30-18:30

    周末及节日:根据情况调休

  • 手机版二维码

    随时手机查素材

  • 扫描二维码

    加入官方QQ群

站长推荐
_何度 一级会员
  • 未知地域
  • 32发帖数
  • 4主题数
  • 1关注数
  • 0粉丝

计时器模拟

[复制链接]
_何度 发表于 2020-11-19 13:12:12 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
提莫作坊QQ群:提莫作坊www.tbwlm.cn

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 _何度 于 2020-11-19 13:30 编辑

lua实现的
计时器系统,就是通常意义的中心计时器,通过对一个 jass的Timer计时器的管理 来虚拟出任意数量的计时器。
基于以下理由,我模拟了这个模块
1.魔兽没有开源,yd源码中也没有 jass计时器的实现,这是一个黑箱。
2.jass计时器 用起来并不顺手,Timer对象占用的资源不理解为什么那么大。
3.jass计时器是多线程实现的,在我的项目中引发了异步问题。

调用接口保留了jass计时器的写法。
用法简介:
1.创建计时器
local New_Timer=CreateTimer()
2.运行计时器(可选择指定计时器 或用一个匿名计时器)
Timer(timeout 到期时间, periodic 是否循环, whichTimer 指定的计时器(可不选) )
(
     --执行函数
     function()

     end,
     --结束条件
     function()
        return 条件表达式
    end
)
用例:
Timer(0.5,true,self.LastTimer)
(
    function()
        total_past=total_past+0.5
        --单位添加引导特效
        if self.buff_factory then
            if self.auto_color then
                self.Lk_color=RandomPick(Ability_link.Colors,true)
            end
            for _,hero in ipairs(self.attach_hero) do
                local target=hero
                local last=0.6
                local compose_type='cover_time'
                local model=self.auto_color and table.concat{'abilityEffect\\LXTX\\',self.Lk_color,'.mdx'} or ''
                local buff=self.buff_factory(target,last,compose_type,model)
                Buff_add(buff)
            end
        end
        if total_past>=self.last then
            self:End_Define()
        end
    end,
    function()
        return total_past>=self.last
    end
)

实现:
--====================require==========================================
local OldCreateTimer=CJ.CreateTimer
local OldTimerStart=CJ.TimerStart
--=====================================================================

local AtomTimer={}
local mt={}
AtomTimer.__index=mt

mt.timeout=-1 --计时器周期

mt.trigleft=-1  --触发剩余时间

mt.periodic=false  --是否循环

mt.condition=nil  --循环的停止条件

mt.id=nil       --计时器标识id

mt.pause=false  --是否暂停

mt.func=nil     --执行函数

mt.removed=false  --是被移除

local TimerEventList={}         --中心计时器事件列表

local ExpiredTimer=nil          --到期的计时器【AtomTimer 类型】

local GameFrames=0.03               --游戏帧数

local GameTimePast=0            --游戏逝去时间

CenterTimer={}                      --中心计时器对象

CenterTimer.handle=OldCreateTimer() --中心计时器jass对象

CenterTimer.Frames=GameFrames       --中心计时器帧数

CenterTimer.ETimerNum=0         --当前有效计时器个数

CenterTimer.runing=false            --是否正在运行

CenterTimer.AtomId=0                --分发的AtomTimerId

CenterTimer.AllTimerList={}         --所有分发的AtomTimer记录

CenterTimer.Start=function()        --运行中心计时器
    OldTimerStart(CenterTimer.handle,CenterTimer.Frames,true,function()
        GameTimePast=GameTimePast+GameFrames
        if #TimerEventList <=0 then
           return
        else
            --print('事件列表长度',#TimerEventList,'运行计时器数目',CenterTimer.ETimerNum)
            for index=1,#TimerEventList do
                --print(index,TimerEventList[index])
                if TimerEventList[index] and not TimerEventList[index].pause then
                    TimerEventList[index].trigleft=TimerEventList[index].trigleft-GameFrames
                    if TimerEventList[index].removed then error('计时器移除异常') end
                    if TimerEventList[index].trigleft<=0 then
                        ExpiredTimer=TimerEventList[index]
                        xpcall(ExpiredTimer.func, function(e) print(debug.traceback()) print('中心计时器-执行函数异常') return e end)
                        if not ExpiredTimer.periodic then
                            ExpiredTimer.removed=true
                            CenterTimer.ETimerNum=CenterTimer.ETimerNum-1
                        else
                            ExpiredTimer.trigleft=ExpiredTimer.timeout
                            if ExpiredTimer.condition and ExpiredTimer.condition() then
                                ExpiredTimer.removed=true
                                CenterTimer.ETimerNum=CenterTimer.ETimerNum-1
                            end
                        end
                    end
                end
            end
            for index=#TimerEventList,1,-1 do
                if TimerEventList[index].removed then
                    table.remove(TimerEventList,index)
                end
            end
        end
    end)
end

function os.clock()             --获取当前游戏时间
    return GameTimePast
end
local CTlock=false          --创建计时器进程锁
function CreateTimer(provideId)        --分配一个计时器对象
    if not CTlock then CTlock=true
    else
        for i=1,8 do
            for j=1,6 do
                CJ.DisplayTimedTextToPlayer(CJ.Player(i-1),0,0,120,'|cFFF00000[错误]:创建计时器进程冲突!!')
            end
        end
        return error('创建计时器进程冲突!!')
    end
    if not provideId then
        CenterTimer.AtomId=CenterTimer.AtomId+1
        provideId=CenterTimer.AtomId
    end
    local atomtimer={id=provideId}
    setmetatable(atomtimer,AtomTimer)
    CenterTimer.ETimerNum=CenterTimer.ETimerNum+1
    CTlock=false
    return atomtimer
end
--运行计时器
---@param timeout integer  周期
---@param periodic boolean 是否循环
---@param whichtimer table 自定义计时器 AtomTimer 对象
---@return table
function Timer(timeout,periodic,whichtimer)
    return function(callback,condition)
        local timer=whichtimer or CreateTimer()
        timer.timeout=timeout
        timer.trigleft=timeout
        timer.periodic=periodic
        timer.func=callback
        timer.condition=condition
        timer.pause=false
        timer.removed=false
        for index,atomtimer in ipairs(TimerEventList) do
            if atomtimer.id==timer.id then
                TimerEventList[index]=timer
                return timer
            end
        end
        table.insert(TimerEventList,timer)
        return timer
    end
end

function DestroyTimer(timer)                --删除计时器
    if Is_intable(TimerEventList,timer) then
        timer.removed=true
        TableRemoveData(TimerEventList,timer)
        CenterTimer.ETimerNum=CenterTimer.ETimerNum-1
    end
end

function PauseTimer (timer)                 --暂停计时器
    timer.pause=true
end

function ResumeTimer (timer)                --恢复计时器
    timer.pause=false
end

function TimerGetRemaining(timer)           --获取计时器剩余时间
    if not timer.removed then
        return timer.trigleft
    else
        return -1
    end
end

function ReCreateTimer(timer)
    DestroyTimer(timer)
    timer.timeout=-1
    timer.trigleft=-1
    timer.periodic=false
    timer.func=nil
    timer.condition=nil
    timer.pause=false
    timer.removed=false
    return timer
end

function GetExpiredTimer()      --获取当前到期的计时器
    return ExpiredTimer
end

function ExtendTime(whichtimer,ExTime)           --延长计时器到期时间
    if not whichtimer.removed then
        whichtimer.trigleft=whichtimer.trigleft+ExTime
        return true
    end
    return false
end

function ReSetTime(whichtimer,time)        --重置计时器到期时间
    if not whichtimer.removed then
        whichtimer.trigleft=time or whichtimer.timeout
        return true
    end
    return false
end


CenterTimer.Start()


print 'timer.lua'


楼主热帖
免责条款:本站仅提供学习的平台,所有资料均来自于网络,版权归原创者所有!本站不提供任何保证,并不承担任何法律责任,如果对您的版权或者利益造成损害,请提供相应的资质证明,我们将于3个工作日内予以删除。

本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。本站部分作品是由网友自主投稿和发布、编辑整理上传,对此类作品本站仅提供交流平台,不为其版权负责。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。

本网站所提供的信息,只供参考之用。本网站不保证信息的准确性、有效性、及时性和完整性。本网站及其雇员一概毋须以任何方式就任何信息传递或传送的失误、不准确或错误,对用户或任何其他人士负任何直接或间接责任。在法律允许的范围内,本网站在此声明,不承担用户或任何人士就使用或未能使用本网站所提供的信息或任何链接所引致的任何直接、间接、附带、从属、特殊、惩罚性或惩戒性的损害赔偿。
对方闲得很,适合接单

精彩评论5

 楼主| _何度 发表于 2020-11-19 13:27:20 | 显示全部楼层
奈何用不来。
对方闲得很,适合接单
Oo破破oO 发表于 2020-11-19 13:53:34 | 显示全部楼层
用不来你都写出来了- -||
不知道该说你牛还是要说你笨
 楼主| _何度 发表于 2020-11-19 14:11:38 | 显示全部楼层
Oo破破oO 发表于 2020-11-19 13:53
用不来你都写出来了- -||
不知道该说你牛还是要说你笨

不会用这个网站的代码显示功能
对方闲得很,适合接单
xueyuan1996 发表于 2020-11-19 15:40:26 | 显示全部楼层
有大佬的地方就有我
Mr_小为 发表于 2021-3-10 11:20:41 | 显示全部楼层
Lua版计时器直接用英萌的就行.另外 你Lua版也是用的Jass底层计时器来实现的,无非在写法方面可以扩展一下.

你真要说好处的话,那就是Lua可以随便异步执行闭包

要是有内置的话,Jass都能够实现异步版中心计时器的

强调下版规的规定,如有恶意灌水从重处罚:
=====发表主题规则=======
1.主题内容请一定要附带预览图片,谢谢;
2.搬运来的东西请尽量不要卖钱!;
3.发帖有任何疑问请联系QQ21031394;
=====发表回复规则=======
1.禁止直接复制标题内容的;
2.禁止纯数字或者纯字母的;
3.禁止乱打一通文不对题;
4.禁止屠版和刷分行为;
第一次扣分处理,第二次扣分+警告,警告三次禁言三天,绝不手软,情况严重的直接封号,请大家珍惜自己的账号!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

猜你喜欢
天工维度唯一QQ群
786014245

欢迎进群交流,入群答案:编辑器

  • 官方在线客服

    QQ客服:小雪

    点击交谈

    QQ客服:砂糖

    点击交谈

    团队老大:荀公子

    商务合作
  • 上海市静安区共和新路4718号宏慧新汇园6号楼603室

  • 手机扫码查看手机版

    手机查找资源更方便

  • 扫一扫关注官方微信

    加入官方QQ群

Powered by 天天RPG&DZX3.4 ©2020-2021 Comsenz Inc.提百万设计( 沪ICP备18032615号-1 )营业执照