主站
地图测试
道具百科
触发器百科
脚本API百科
创作手册
创作功能
其他
Studio百科
制作动画
云梦 更新时间: 2024-01-31 10:22:51

我们都知道动画。那么动画的原理是什么呢?

动画其实是由连续变化的图片(或效果)合成,变化的速度通常是张/秒,如60张/秒表示每秒变换60次。它还可以用帧表示,帧同样表示张/秒,如60帧表示每秒变换60次。

而且,我们在游戏内可以看到这个:

 

它就是帧数,它越低,每秒屏幕变换的次数就越低,我们就会感觉越卡;帧数越高,动画效果就越好。

 

游戏一般会在30~60帧运行,所以我们制作的动画也要保持这个范围。

总的来说实现动画有两种方式:一是触发事件,二是全局循环。运行动画必须要有一个变量:运行次数,我们让它记录动画运行到了什么时候。本系列教程用全局变量,你可以把它换成玩家的私有变量。

 

因为有改变元件属性的动作,所以改变元件属性的动画方法基本都差不多,我们就先做一个平移动画试试。

 

触发器:

先来讲第一种方法:触发事件的方法

首先触发事件,初始化变量并运行第二个触发器

之后算好这是多少帧的动画,运行几秒,每次变化几个单位。

笔者这里是30帧,一个触发器运行1.5秒,每次变化10个单位

所以动作里的等待时间为1.5/30=0.05秒,也就是每0.05秒运行一次

到这里动画就做好了,但实际1.5秒的动画是远远不够的,所以接下来还要一段动画。那么把条件中的30改成60,让它多运行30次行不行呢?我们来做个小实验:

结果:

所以一个触发器最多这样运行50次,条件的数值不能超过50。

在第一个动画的触发器里运行下个触发器,下个触发器用来初始化

初始化之后运行下个动画,下个动画和第一个动画基本没区别,只要复制粘贴就好。当然如果想要不同的效果,也可以改

接下来就是简单的计算

最后别忘了替换触发器(反正笔者就总忘,哈哈)

第二种方法:循环播放。它适用于整个游戏都在播放的动画。

如果想要大于1.5秒,就要多设置一个变量了:

之后复制前两个触发器,稍加改动:

脚本:因为接口的限制,API里没有延迟运行的函数。所以我们只能用触发器的第二种方法的逻辑运用脚本制作动画。

local uiid = [[7032478012807019634]]--UI的ID
local image = [[7032478012807019634_4]]--要动画的元件
local button = [[7032478012807019634_5]]--点击动画的按钮
local info = 0--执行次数
ScriptSupportEvent:registerEvent([=[UI.Button.Click]=],function(event)
    if event.btnelenemt == button then
        play = true--开始播放
        info = 0--执行次数初始化
    end
end)
ScriptSupportEvent:registerEvent([=[Game.RunTime]=],function(event)
    if event.ticks%0.05 == 0 and play == true then
        info = info+1--+1
        Coustomui:setPosition(0, uiid, image, 20+info*10,20+info*5)--设置位置
        play = not(info > 30)--如果大于30就停止
    end
end)

对于脚本这种麻烦也没办法,我们只能自己找简便方法。下面是笔者的方法:

local funcs = {}--正在运行的表
function addAnimation(name,func,s,s2,is)--添加动画,name索引,func运行的函数。func有2个参数:一秒内运行的次数和当前运行第几次(总),s每几秒一次,20帧填0.05,s2是一共运行几秒。最后一个参数是否整点运行,默认false
  if type(func) == 'function'then
    funcs[name] = {func,s,0,0,s2,is,0}--前两个是数据,第三个为临时变量:一秒内运行次数,第四个是运行了几秒,第五个是数据,一共需要运行几秒,第六个是否启用,也就是说只有到整秒时才会启用,最后一个临时变量,当前运行第几次
    return name
   else
    return false
  end
end
function removeAnimation(name)
  funcs[name] = nil
end
ScriptSupportEvent:registerEvent('Game.RunTime',function(event)
  for i, f in pairs(funcs)do
    if f[6] == true then
      if event.ticks%f[2] == 0 then
        f[3] = f[3] + 1
        f[7] = f[7] + 1
        --print('f3'..f[3]..type(event.second))
        f[1](f[3],f[7])
      end
      if event.second ~= nil then
        f[3] = 0
        f[4] = f[4]+1
        --print(f[4],f[5])
        if f[4] == f[5] then
          funcs[i] = nil
        end
      end
     else
      if event.second ~= nil then
        f[6] = true
      end
    end
  end
end)

看不懂?没关系,会用就可以!下面是调用示例:

local funcs = {}--正在运行的表
function addAnimation(name,func,s,s2,is)--添加动画,name索引,func运行的函数。func有2个参数:一秒内运行的次数和当前运行第几次(总),s每几秒一次,20帧填0.05,s2是一共运行几秒。最后一个参数是否整点运行,默认false
  if type(func) == 'function'then
    funcs[name] = {func,s,0,0,s2,is,0}--前两个是数据,第三个为临时变量:一秒内运行次数,第四个是运行了几秒,第五个是数据,一共需要运行几秒,第六个是否启用,也就是说只有到整秒时才会启用,最后一个临时变量,当前运行第几次
    return name
   else
    return false
  end
end
function removeAnimation(name)
  funcs[name] = nil
end
ScriptSupportEvent:registerEvent('Game.RunTime',function(event)
  for i, f in pairs(funcs)do
    if f[6] == true then
      if event.ticks%f[2] == 0 then
        f[3] = f[3] + 1
        f[7] = f[7] + 1
        --print('f3'..f[3]..type(event.second))
        f[1](f[3],f[7])
      end
      if event.second ~= nil then
        f[3] = 0
        f[4] = f[4]+1
        --print(f[4],f[5])
        if f[4] == f[5] then
          funcs[i] = nil
        end
      end
     else
      if event.second ~= nil then
        f[6] = true
      end
    end
  end
end)
local uiid = [[7079981918763842674]]--UI的ID
local image = [[7079981918763842674_2]]--要动画的元件
local button = [[7079981918763842674_3]]--点击动画的按钮
ScriptSupportEvent:registerEvent([=[UI.Button.Click]=],function(event)
  if event.btnelenemt == button then
    addAnimation("柳仙儿动画",function(s,s2)
    Coustomui:setPosition(0, uiid, image, 20+s2*10,20+s2*5)--设置位置
    end,0.05,1,true)
  end
end)

透明动画:

local funcs = {}--正在运行的表
function addAnimation(name,func,s,s2,is)--添加动画,name索引,func运行的函数。func有2个参数:一秒内运行的次数和当前运行第几次(总),s每几秒一次,20帧填0.05,s2是一共运行几秒。最后一个参数是否整点运行,默认false
  if type(func) == 'function'then
    funcs[name] = {func,s,0,0,s2,is,0}--前两个是数据,第三个为临时变量:一秒内运行次数,第四个是运行了几秒,第五个是数据,一共需要运行几秒,第六个是否启用,也就是说只有到整秒时才会启用,最后一个临时变量,当前运行第几次
    return name
   else
    return false
  end
end
function removeAnimation(name)
  funcs[name] = nil
end
ScriptSupportEvent:registerEvent('Game.RunTime',function(event)
  for i, f in pairs(funcs)do
    if f[6] == true then
      if event.ticks%f[2] == 0 then
        f[3] = f[3] + 1
        f[7] = f[7] + 1
        --print('f3'..f[3]..type(event.second))
        f[1](f[3],f[7])
      end
      if event.second ~= nil then
        f[3] = 0
        f[4] = f[4]+1
        --print(f[4],f[5])
        if f[4] == f[5] then
          funcs[i] = nil
        end
      end
     else
      if event.second ~= nil then
        f[6] = true
      end
    end
  end
end)
local uiid = [[7079981918763842674]]--UI的ID
local image = [[7079981918763842674_2]]--要动画的元件
local button = [[7079981918763842674_3]]--点击动画的按钮
ScriptSupportEvent:registerEvent([=[UI.Button.Click]=],function(event)
  if event.btnelenemt == button then
    addAnimation("柳仙儿动画",function(s,s2)
    Coustomui:setAlpha(0,uiid,image,2.5*s2)
    end,0.05,1,true)
  end
end)

效果:

到这里你就会发现,不同动画只要更改不同的动作。那多加几个动作可不可以?

我们来试试:

local funcs = {}--正在运行的表
function addAnimation(name,func,s,s2,is)--添加动画,name索引,func运行的函数。func有2个参数:一秒内运行的次数和当前运行第几次(总),s每几秒一次,20帧填0.05,s2是一共运行几秒。最后一个参数是否整点运行,默认false
  if type(func) == 'function'then
    funcs[name] = {func,s,0,0,s2,is,0}--前两个是数据,第三个为临时变量:一秒内运行次数,第四个是运行了几秒,第五个是数据,一共需要运行几秒,第六个是否启用,也就是说只有到整秒时才会启用,最后一个临时变量,当前运行第几次
    return name
   else
    return false
  end
end
function removeAnimation(name)
  funcs[name] = nil
end
ScriptSupportEvent:registerEvent('Game.RunTime',function(event)
  for i, f in pairs(funcs)do
    if f[6] == true then
      if event.ticks%f[2] == 0 then
        f[3] = f[3] + 1
        f[7] = f[7] + 1
        --print('f3'..f[3]..type(event.second))
        f[1](f[3],f[7])
      end
      if event.second ~= nil then
        f[3] = 0
        f[4] = f[4]+1
        --print(f[4],f[5])
        if f[4] == f[5] then
          funcs[i] = nil
        end
      end
     else
      if event.second ~= nil then
        f[6] = true
      end
    end
  end
end)
local uiid = [[7079981918763842674]]--UI的ID
local image = [[7079981918763842674_2]]--要动画的元件
local button = [[7079981918763842674_3]]--点击动画的按钮
ScriptSupportEvent:registerEvent([=[UI.Button.Click]=],function(event)
  if event.btnelenemt == button then
    addAnimation("柳仙儿动画",function(s,s2)
    Coustomui:setPosition(0, uiid, image, 20+s2*10,20+s2*5)--设置位置
    Coustomui:setAlpha(0,uiid,image,2.5*s2)
    end,0.05,1,true)
  end
end)

效果:

 

进阶教程

 

我们刚刚做的平移动画,其实就是一个一次函数。如果把次数作为x,位置作为y,那么它的图像就是:

但这种效果有时候不够完美。如果我们换成二次函数呢?

函数解析式:y=-0.125(x-40)²+220

(提示:脚本直接代入解析式就可以!但是注意脚本最多20帧,必须要用相适应的解析式才可以)

local funcs = {}--正在运行的表
function addAnimation(name,func,s,s2,is)--添加动画,name索引,func运行的函数。func有2个参数:一秒内运行的次数和当前运行第几次(总),s每几秒一次,20帧填0.05,s2是一共运行几秒。最后一个参数是否整点运行,默认false
  if type(func) == 'function'then
    funcs[name] = {func,s,0,0,s2,is,0}--前两个是数据,第三个为临时变量:一秒内运行次数,第四个是运行了几秒,第五个是数据,一共需要运行几秒,第六个是否启用,也就是说只有到整秒时才会启用,最后一个临时变量,当前运行第几次
    return name
   else
    return false
  end
end
function removeAnimation(name)
  funcs[name] = nil
end
ScriptSupportEvent:registerEvent('Game.RunTime',function(event)
  for i, f in pairs(funcs)do
    if f[6] == true then
      if event.ticks%f[2] == 0 then
        f[3] = f[3] + 1
        f[7] = f[7] + 1
        --print('f3'..f[3]..type(event.second))
        f[1](f[3],f[7])
      end
      if event.second ~= nil then
        f[3] = 0
        f[4] = f[4]+1
        --print(f[4],f[5])
        if f[4] == f[5] then
          funcs[i] = nil
        end
      end
     else
      if event.second ~= nil then
        f[6] = true
      end
    end
  end
end)
local uiid = [[7079981918763842674]]--UI的ID
local image = [[7079981918763842674_2]]--要动画的元件
local button = [[7079981918763842674_3]]--点击动画的按钮
ScriptSupportEvent:registerEvent([=[UI.Button.Click]=],function(event)
  if event.btnelenemt == button then
    addAnimation("柳仙儿动画",function(s,s2)
      Coustomui:setPosition(0,uiid,image,-0.5*(s-20)^2+220,-0.5*(s-20)^2+220)
    end,0.05,1,true)
  end
end)

效果:

是不是感觉动画不再呆板了?我们再组合一下:

local funcs = {}--正在运行的表
function addAnimation(name,func,s,s2,is)--添加动画,name索引,func运行的函数。func有2个参数:一秒内运行的次数和当前运行第几次(总),s每几秒一次,20帧填0.05,s2是一共运行几秒。最后一个参数是否整点运行,默认false
  if type(func) == 'function'then
    funcs[name] = {func,s,0,0,s2,is,0}--前两个是数据,第三个为临时变量:一秒内运行次数,第四个是运行了几秒,第五个是数据,一共需要运行几秒,第六个是否启用,也就是说只有到整秒时才会启用,最后一个临时变量,当前运行第几次
    return name
   else
    return false
  end
end
function removeAnimation(name)
  funcs[name] = nil
end
ScriptSupportEvent:registerEvent('Game.RunTime',function(event)
  for i, f in pairs(funcs)do
    if f[6] == true then
      if event.ticks%f[2] == 0 then
        f[3] = f[3] + 1
        f[7] = f[7] + 1
        --print('f3'..f[3]..type(event.second))
        f[1](f[3],f[7])
      end
      if event.second ~= nil then
        f[3] = 0
        f[4] = f[4]+1
        --print(f[4],f[5])
        if f[4] == f[5] then
          funcs[i] = nil
        end
      end
     else
      if event.second ~= nil then
        f[6] = true
      end
    end
  end
end)
local uiid = [[7079981918763842674]]--UI的ID
local image = [[7079981918763842674_2]]--要动画的元件
local button = [[7079981918763842674_3]]--点击动画的按钮
ScriptSupportEvent:registerEvent([=[UI.Button.Click]=],function(event)
  if event.btnelenemt == button then
    addAnimation("柳仙儿动画",function(s,s2)
      Coustomui:setPosition(0,uiid,image,-0.5*(s-20)^2+220,-0.5*(s-20)^2+220)
      Coustomui:setAlpha(0,uiid,image,5*s2)
    end,0.05,1,true)
  end
end)

效果:

同样可以修改解析式,完成一些特殊的动画:

函数解析式:y=-0.5(x-20)²+220

local funcs = {}--正在运行的表
function addAnimation(name,func,s,s2,is)--添加动画,name索引,func运行的函数。func有2个参数:一秒内运行的次数和当前运行第几次(总),s每几秒一次,20帧填0.05,s2是一共运行几秒。最后一个参数是否整点运行,默认false
  if type(func) == 'function'then
    funcs[name] = {func,s,0,0,s2,is,0}--前两个是数据,第三个为临时变量:一秒内运行次数,第四个是运行了几秒,第五个是数据,一共需要运行几秒,第六个是否启用,也就是说只有到整秒时才会启用,最后一个临时变量,当前运行第几次
    return name
   else
    return false
  end
end
function removeAnimation(name)
  funcs[name] = nil
end
ScriptSupportEvent:registerEvent('Game.RunTime',function(event)
  for i, f in pairs(funcs)do
    if f[6] == true then
      if event.ticks%f[2] == 0 then
        f[3] = f[3] + 1
        f[7] = f[7] + 1
        --print('f3'..f[3]..type(event.second))
        f[1](f[3],f[7])
      end
      if event.second ~= nil then
        f[3] = 0
        f[4] = f[4]+1
        --print(f[4],f[5])
        if f[4] == f[5] then
          funcs[i] = nil
        end
      end
     else
      if event.second ~= nil then
        f[6] = true
      end
    end
  end
end)
local uiid = [[7079981918763842674]]--UI的ID
local image = [[7079981918763842674_2]]--要动画的元件
local button = [[7079981918763842674_3]]--点击动画的按钮
ScriptSupportEvent:registerEvent([=[UI.Button.Click]=],function(event)
  if event.btnelenemt == button then
    addAnimation("柳仙儿动画",function(s,s2)
      Coustomui:setPosition(0,uiid,image,-2*(s2-10)^2+220,-2*(s2-10)^2+220)
          end,0.05,1,true)
  end
end)

效果:

另外可以用三次函数:

函数解析式:y=0.0125(x-20)³+120

local funcs = {}--正在运行的表
function addAnimation(name,func,s,s2,is)--添加动画,name索引,func运行的函数。func有2个参数:一秒内运行的次数和当前运行第几次(总),s每几秒一次,20帧填0.05,s2是一共运行几秒。最后一个参数是否整点运行,默认false
  if type(func) == 'function'then
    funcs[name] = {func,s,0,0,s2,is,0}--前两个是数据,第三个为临时变量:一秒内运行次数,第四个是运行了几秒,第五个是数据,一共需要运行几秒,第六个是否启用,也就是说只有到整秒时才会启用,最后一个临时变量,当前运行第几次
    return name
   else
    return false
  end
end
function removeAnimation(name)
  funcs[name] = nil
end
ScriptSupportEvent:registerEvent('Game.RunTime',function(event)
  for i, f in pairs(funcs)do
    if f[6] == true then
      if event.ticks%f[2] == 0 then
        f[3] = f[3] + 1
        f[7] = f[7] + 1
        --print('f3'..f[3]..type(event.second))
        f[1](f[3],f[7])
      end
      if event.second ~= nil then
        f[3] = 0
        f[4] = f[4]+1
        --print(f[4],f[5])
        if f[4] == f[5] then
          funcs[i] = nil
        end
      end
     else
      if event.second ~= nil then
        f[6] = true
      end
    end
  end
end)
local uiid = [[7079981918763842674]]--UI的ID
local image = [[7079981918763842674_2]]--要动画的元件
local button = [[7079981918763842674_3]]--点击动画的按钮
ScriptSupportEvent:registerEvent([=[UI.Button.Click]=],function(event)
  if event.btnelenemt == button then
    addAnimation("柳仙儿动画",function(s,s2)
      Coustomui:setPosition(0,uiid,image,-0.2*(s2-10)^3+220,-0.2*(s2-10)^3+220)
    end,0.05,1,true)
  end
end)

效果:

 

最终示例:

这里有三个主要元件,分别是仙度瑞拉、按钮和完成的图标。

完成按钮是隐藏的,不隐藏的长这样:

完成的图标不隐藏,但它的透明度为0。

透明度为100的长这样:

仙度瑞拉的位置是(200,600)

完成的图标位置是(700,300),大小是(200,200)

触发器:

脚本:

local funcs = {}--正在运行的表
function addAnimation(name,func,s,s2,is)--添加动画,name索引,func运行的函数。func有2个参数:一秒内运行的次数和当前运行第几次(总),s每几秒一次,20帧填0.05,s2是一共运行几秒。最后一个参数是否整点运行,默认false
  if type(func) == 'function'then
    funcs[name] = {func,s,0,0,s2,is,0}--前两个是数据,第三个为临时变量:一秒内运行次数,第四个是运行了几秒,第五个是数据,一共需要运行几秒,第六个是否启用,也就是说只有到整秒时才会启用,最后一个临时变量,当前运行第几次
    return name
   else
    return false
  end
end
function removeAnimation(name)
  funcs[name] = nil
end
ScriptSupportEvent:registerEvent('Game.RunTime',function(event)
  for i, f in pairs(funcs)do
    if f[6] == true then
      if event.ticks%f[2] == 0 then
        f[3] = f[3] + 1
        f[7] = f[7] + 1
        --print('f3'..f[3]..type(event.second))
        f[1](f[3],f[7])
      end
      if event.second ~= nil then
        f[3] = 0
        f[4] = f[4]+1
        --print(f[4],f[5])
        if f[4] == f[5] then
          funcs[i] = nil
        end
      end
     else
      if event.second ~= nil then
        f[6] = true
      end
    end
  end
end)
local uiid = [[7079981918763842674]]--UI的ID
local image1 = [[7079981918763842674_2]]--仙度瑞拉
local image2 = [[7079981918763842674_5]]--完成图标
local button = [[7079981918763842674_3]]--完成按钮
local text = [[7079981918763842674_10]]--完成图标里的文字
ScriptSupportEvent:registerEvent([=[UI.Show]=],function(event)
    if event.CoustomUI == uiid then
      addAnimation("仙度瑞拉动画",function(s,s2)
        Coustomui:setPosition(0,uiid,image1,-0.25*(s2-20)^2+500,-0.25*(s2-20)^2+500)
    end,0.05,1,true)
    end
end)
ScriptSupportEvent:registerEvent([=[UI.Button.Click]=],function(event)
  if event.btnelenemt == button then
    addAnimation("完成任务动画动画",function(s,s2)
      Coustomui:setPosition(0,uiid,image2,-0.2*(s2-10)^3+220,-0.2*(s2-10)^3+220)
      Coustomui:setAlpha(0,uiid,image2,5*s2)
      Coustomui:setPosition(0,uiid,image2,-0.125*(s2-20)^2+750,-0.125*(s2-20)^2+750)
      Coustomui:setSize(0,uiid,image2,0.25*(s2-20)^2+100,0.25*(s2-20)^2+100)
      Coustomui:setFontSize(0,uiid,text,0.5*s2+30)
    end,0.05,1,true)
  end
end)

效果:

 

今天的内容就到这里,谢谢~

站点有内容要更新是否更新。
更新
忽略