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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM