本來我是新把動畫和角色移動寫在一塊的可是出現了很多問題,特別是筆誤
程序調了很久,還是不穩定.后來覺得,應該把動畫和角色移動分開,因為還有其它
的運動也需要動畫,這樣才合理.
動畫(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