love2d教程9--角色移動


本來該早點寫完的,可是由於一些小問題,拖到現在了,不過也好,我決定以后使用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


免責聲明!

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



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