love2d教程8--动画

本来我是新把动画和角色移动写在一块的可是出现了很多问题,特别是笔误

程序调了很久,还是不稳定.后来觉得,应该把动画和角色移动分开,因为还有其它

的运动也需要动画,这样才合理.

动画(animation)实际就是快速的显示一系列连续的图片,这些图片组成完整

的动作,这样人眼看起来就动起来了.既然是连续运动,那么怎么控制时间就很重要了.一开始我看了一下dt(update里的dt)的大小,大概60-70的dt一秒,

于是就在统计update(dt)里统计其调用次数,后来写的挺好的拿到同学的机器

上一试居然不动了.立即回去修改,可是半天也没发现怎么回事,后来我输出了一

下dt,又到同学的机器上试了一下原来在他机器上dt大概只有我的一半,即他的机

器速度比我快一倍.我用dt*dx,偏移的值就很小了,让我感觉没有动.

 

后来发现直接累加dt就可以了,也是得了个教训,即

local timer=0
function love.update(dt)
    timer=timer+dt
    if(timer>1) then
        do something
    end
end

最后的效果如下

下面是完整的animation.lua的代码,注释写好了,函数名是模仿hge的.

播放模式说明,"00"逆序不循环,"01"逆序循环,"10"正序不循环,"11"正序循环

local anim = {}
anim.__index = anim
--[[
tex
    存有动画帧的纹理句柄。
nframes
    动画帧数
FPS
    动画回放速度,以帧每秒为单位。
x,y即小图在大图中的坐标
x
    动画第一帧在纹理中的X坐标,以纹理坐标为单位。
y
    动画第一帧在纹理中Y坐标,以纹理坐标为单位。
w
    动画帧的宽度。
h
    动画帧的高度。
]]
--[[
Play     开始播放动画
Stop     停止播放动画
Resume     (从暂停等状态)恢复动画。
Update     更新动画
IsPlaying     检测动画是否正在播放。

SetMode     设置回放模式。
SetSpeed     设置回放速度。
SetFrame     设置当前动画的帧。
SetFrames     设置所有的动画帧。

GetMode     获得当前的回放模式。
GetSpeed     获得当前的回放速度。
GetFrame     获得当前的动画帧。
GetFrames     获得所有的动画帧。
]]
function newAnimation( tex,nframes,FPS,x,y,w,h )
    local  a = {}
    a.img=tex
    a.fps=FPS
    a.w=w
    a.h=h
    a.posx=0
    a.posy=0
    local imgw = tex:getWidth()
    local imgh = tex:getHeight()
    --nframes=nframes or (imgw*imgh/w/h)
    a.nframes=nframes
    --quad tu kuai
    a.Frame={}
    --在整个动画中的帧位置
    a.posf=1
    a.stopFlag=false
    a.resumFlag=false
    a.stopPos=1
    a.timer=0 --计时器
    a.mode="11"
    a.debug=false
    for i=1,nframes do
        table.insert(a.Frame,love.graphics.newQuad(x+(i-1)*w,
        y,w,h,imgw,imgh))
    end

    return setmetatable(a, anim)
end

function anim:Play()
    if(self.debug==true) then
        love.graphics.print("posf  " .. self.posf,10,10)
    end
    if(self.stopFlag==true) then
        love.graphics.drawq(self.img,self.Frame[self.stopPos],self.posx,self.posy)
    else

        love.graphics.drawq(self.img,self.Frame[self.posf],self.posx,self.posy)

    end
end
function anim:Stop()
    if(self.stopFlag==false) then
        self.stopPos=self.posf
        self.stopFlag=true
    end
end
function anim:Resume()
    if(self.stopFlag==true) then
        self.posf=self.stopPos
        self.stopFlag=false
    end
end

function anim:Update(dt)
    self.timer = self.timer+dt
    if(self.timer*self.fps>1) then
        self.timer=0
        if(self.mode=="11") then
            if(self.posf>self.nframes-1) then
                self.posf=1
            else
            self.posf=self.posf+1
            end
        --逆序播放放不循环
        elseif(self.mode=="00") then
            if(self.posf<1) then
                self.posf=1
            else
                self.posf=self.posf-1
            end

        --逆序播放循环
        elseif(self.mode=="01") then
            if(self.posf<1) then
                self.posf=self.nframes
            else
                self.posf=self.posf-1
            end
        --正序播放循环
        else
            if(self.posf>self.nframes) then
                self.posf=nframes
            else
                self.posf=self.posf-1
            end
        end
    end
end

function anim:IsPlaying()
    if(self.stopFlag==true) then
        return true
    end
end

function anim:setMode(mode)
    self.mode=mode
    if(mode=="00" or mode =="01") then
        self.posf=self.nframes
    end
end

function anim:setSpeed(fps)
    self.fps=fps
end

function anim:setPos(x,y)
    self.posx=x
    self.posy=y
end

--设置要显示的帧,要继续显示使用Resume()
function anim:SetFrame(n)
    self.stopPos=n
    self.stopFlag=true
end
--设置播放的总帧数
function anim:SetFrames(n)
    sefl.nframes=n
end
function anim:GetMode ()
    return self.mode
end

function anim:GetSpeed()
    return self.speed
end
function anim:GetFrame()
    return self.posf
end
function anim:GetFrames()
    return self.nframes
end

main.lua如下

anim的使用说明,在love.load()里把载入的图片传给newAnimation(),并设置位置,

在love.draw()里调用anim的Play()函数,在love.update(dt)里调用anim的Update(dt)函数.

require('animation')
function love.load()
     font=love.graphics.newFont(16)
     love.graphics.setFont(font)
     imgW=love.graphics.newImage("assets/walk.png")
     roleW=newAnimation(imgW,8,8,0,0,84,108)
     roleW.debug=true
     roleW:setPos(400,300)
end

function love.update(dt)
    roleW:Update(dt)
end
local count=0
function love.draw()
     roleW:Play()
     count=count+1
     --简单的测试Stop和Resume函数
     love.graphics.print("count" .. count, 10,25)
     if (count>100 and count<300 ) then
         roleW:Stop()
     end

     if(count>300) then
     roleW:Resume()
     end
end

现在角色还不能行动,下一篇便是移动角色了.

最近的写作计划,移动角色,粒子效果,tile地图上的角色移动,物理效果,

金庸群侠传的素材解析(这个可能需要一些时间),之后的还没想好.

代码

git clone git://gitcafe.com/dwdcth/love2d-tutor.git

或git clone https://github.com/dwdcth/mylove2d-tutor-in-chinese.git

说明,后来我使用middleclass重写了,放到tutor08-fix里了,tutor08可以不用看了,但要看

tutor-middleclass

 2012-12-28

 

posted @ 2012-12-25 10:22  半山th  阅读(3438)  评论(11编辑  收藏  举报