本來該早點寫完的,可是由於一些小問題,拖到現在了,不過也好,我決定以后使用middleclass來實現
面向對象.角色移動也就是對動畫的進一步加強,方便調用.
先上圖,說明代碼移植自以前學習hge時在網上下載的教程,不知原作者,如果你知道
請告知,我會補上.(數字1切換行走,2切換跑步,注意是鍵盤字母區的1,2)
對於rpg游戲,角色肯定是經常用到,因此我們需要一個角色類.
require('Anim') require('middleclass') RpgRole=class('RpgRole') --方向常數 RpgRole.static.DOWN=1 RpgRole.static.LEFT=2 RpgRole.static.RIGHT=3 RpgRole.static.UP=4 RpgRole.static.LEFTDOWN=5 RpgRole.static.RIGHTDOWN=6 RpgRole.static.LEFTUP=7 RpgRole.static.RIGHTUP=8 --tex 為Image類型,nfrmes一幅圖片中成套動作的幀數,如演示的圖片有64個動作,但一套動作里的幀數是8 --fps,每秒播放的幀數,w幀的寬,h幀的高 function RpgRole:initialize(tex,nframes,FPS,w,h) self.direction=RpgRole.DOWN self.role={} --這里的8表示八個方向,每個方向一個role,即anim for i=1,8 do self.role[i]=Anim:new(tex,nframes,FPS,0,(i-1)*h,w,h) end end --下面的-1表示改狀態和原來一樣,后面的也是 function RpgRole: update(dt,dir) dir=dir or -1 if (dir == self.direction or dir== -1) then self.role[self.direction]:update(dt) else self.setDirection(dir) end end function RpgRole: stopAll() for i=1,8 do self.role[i]:stop() end end function RpgRole: move(speed,dt) self.speed=speed --就是一個switch case語句 local dir={ [RpgRole.UP]=function() self.roleY =self.roleY - self.speed * dt end , [RpgRole.DOWN]=function() self.roleY =self.roleY + self.speed * dt end , [RpgRole.LEFT]=function() self.roleX =self.roleX - self.speed * dt end , [RpgRole.RIGHT]=function() self.roleX =self.roleX + self.speed * dt end , [RpgRole.LEFTUP]=function() self.roleX , self.roleY = (self.roleX - self.speed * dt),(self.roleY - self.speed * dt) end, [RpgRole.LEFTDOWN]=function() self.roleX , self.roleY = (self.roleX - self.speed * dt),(self.roleY + self.speed * dt) end, [RpgRole.RIGHTUP]=function() self.roleX ,self.roleY = (self.roleX + self.speed * dt),(self.roleY - self.speed * dt ) end, [RpgRole.RIGHTDOWN]=function() self.roleX,self.roleY = (self.roleX + self.speed * dt),(self.roleY + self.speed * dt) end, } --這里就是執行條件了 dir[self.direction]() end --調用anim的play方法,從第一幀開始播放,實際是設置播放起始幀為1 function RpgRole: play(dir) self.direction=dir self.role[dir]:play() end function RpgRole: render(x ,y) x=x or -1 y=y or -1 if (x == -1 or y == -1) then self.role[self.direction]:render(self.roleX, self.roleY) else self.roleX = x self.roleY = y self.role[self.direction]:render(x, y) end --調試輸出 if(self.debug==true) then love.graphics.print("x " .. self.roleX .. " y " .. self.roleY,10,10) end end --設置方向 function RpgRole:setDirection(dir) if (self.direction ~= dir) then self.role[self.direction]:stop() self.direction = dir self.role[self.direction]:play() end end --設置角色在屏幕的坐標 function RpgRole: setXY(x,y) self.roleX = x self.roleY = y end function RpgRole: getX() return self.roleX end function RpgRole: getY() return self.roleY end function RpgRole: getDirection() return self.direction end
運動時的邏輯不是很復雜,不過寫起來很長的if...else...
運動的原則是方向鍵按下,朝此方向運動;方向鍵彈起,停止運動;
若改變運動方向,先保存坐標,停止播放原方向的動畫,設置為新方向,
當然還要結合運動的狀態是行走,站立,跑步來分類處理.
main.lua
require('Anim') require('RpgRole') --角色狀態 local ROLESTATE_STAND= 0 local ROLESTATE_WALK= 1 local ROLESTATE_RUN= 2 --運動狀態 local MODE_WALK= 1 local MODE_RUN= 2 local movemode=nil local ROLESTATE=nil local currdir=RpgRole.DOWN function love.load() font=love.graphics.newFont(16) love.graphics.setFont(font) imgS=love.graphics.newImage("assets/stand.png") imgW=love.graphics.newImage("assets/walk.png") imgR=love.graphics.newImage("assets/run.png") --參數為: 圖片,一套動作的幀數,播放速度,幀寬,幀高 role_stand=RpgRole:new(imgS,8,8,84,108) role_walk=RpgRole:new(imgW,8,8,84,108) role_run=RpgRole:new(imgR,8,8,84,108) --打開輸出 role_stand.debug=true role_stand.debug=true role_stand.debug=true --注意要先設置方向,再設置位置,因為位置是綁定在方向上的 role_stand:setDirection(currdir) role_stand:setXY(400,300) role_state = ROLESTATE_STAND; movemode = MODE_WALK; end function love.update(dt) local dir=-1 --檢測鍵盤設置運動模式, if(love.keyboard.isDown("1")) then movemode=MODE_WALK end if(love.keyboard.isDown("2")) then movemode=MODE_RUN end --檢測鍵盤,設置運動方向 if(love.keyboard.isDown("left")) then if(love.keyboard.isDown("up")) then dir=RpgRole.LEFTUP elseif(love.keyboard.isDown("down")) then dir=RpgRole.LEFTDOWN else dir=RpgRole.LEFT end elseif(love.keyboard.isDown("right")) then if(love.keyboard.isDown("up")) then dir=RpgRole.RIGHTUP elseif(love.keyboard.isDown("down")) then dir=RpgRole.RIGHTDOWN else dir=RpgRole.RIGHT end elseif(love.keyboard.isDown("up")) then dir=RpgRole.UP elseif(love.keyboard.isDown("down")) then dir=RpgRole.DOWN end if (dir == -1) then --沒有方向鍵按下,變為站立狀態 if (role_state == ROLESTATE_WALK) then role_stand:setXY(role_walk:getX(), role_walk:getY()) role_stand:play(role_walk:getDirection()) role_walk:stopAll() role_state = ROLESTATE_STAND elseif (role_state == ROLESTATE_RUN) then role_stand:setXY(role_run:getX(), role_run:getY()) role_stand:play(role_run:getDirection()) role_run:stopAll() role_state = ROLESTATE_STAND else role_stand:update(dt) end --有方向鍵按下,且為行走狀態 elseif(movemode == MODE_WALK) then -- 狀態一致 if (role_state == ROLESTATE_WALK) then role_walk:setDirection(dir) role_walk:move(50, dt) role_walk:update(dt) --跑步狀態變為行走,先停止跑步,從行走的第一幀開始播放動畫,並設置行走狀態 elseif (role_state == ROLESTATE_RUN) then role_walk:setXY(role_run:getX(), role_run:getY()) role_walk:play(dir) role_run:stopAll() role_state = ROLESTATE_WALK else role_walk:setXY(role_stand:getX(), role_stand:getY()) role_walk:play(dir) role_stand:stopAll() role_state = ROLESTATE_WALK end --有方向鍵按下,且為跑步狀態 else -- 狀態一致 if (role_state == ROLESTATE_WALK) then role_run:setXY(role_walk:getX(), role_walk:getY()) role_run:play(dir) role_walk:stopAll() role_state = ROLESTATE_RUN elseif (role_state == ROLESTATE_RUN) then role_run:setDirection(dir) role_run:move(90, dt) role_run:update(dt) else role_run:setXY(role_stand:getX(), role_stand:getY()) role_run:play(dir) role_stand:stopAll() role_state = ROLESTATE_RUN end end end function love.draw() love.graphics.print("1--walk,2--run",10,25) if (role_state == ROLESTATE_STAND) then role_stand:render() elseif (role_state == ROLESTATE_WALK) then role_walk:render() else role_run:render() end end
代碼下載,已clone的直接git pull
git clone git://gitcafe.com/dwdcth/love2d-tutor.git
或git clone https://github.com/dwdcth/mylove2d-tutor-in-chinese.git