本来该早点写完的,可是由于一些小问题,拖到现在了,不过也好,我决定以后使用middleclass来实现
面向对象.角色移动也就是对动画的进一步加强,方便调用.
先上图,说明代码移植自以前学习hge时在网上下载的教程,不知原作者,如果你知道
请告知,我会补上.(数字1切换行走,2切换跑步,注意是键盘字母区的1,2)
对于rpg游戏,角色肯定是经常用到,因此我们需要一个角色类.
require('Anim')require('middleclass')RpgRole=class('RpgRole')--方向常数RpgRole.static.DOWN=1RpgRole.static.LEFT=2RpgRole.static.RIGHT=3RpgRole.static.UP=4RpgRole.static.LEFTDOWN=5RpgRole.static.RIGHTDOWN=6RpgRole.static.LEFTUP=7RpgRole.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) endend--下面的-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) endendfunction RpgRole: stopAll() for i=1,8 do self.role[i]:stop() endendfunction 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方法,从第一帧开始播放,实际是设置播放起始帧为1function RpgRole: play(dir) self.direction=dir self.role[dir]:play()endfunction 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) endend--设置方向function RpgRole:setDirection(dir) if (self.direction ~= dir) then self.role[self.direction]:stop() self.direction = dir self.role[self.direction]:play() endend--设置角色在屏幕的坐标function RpgRole: setXY(x,y) self.roleX = x self.roleY = yendfunction RpgRole: getX() return self.roleXendfunction RpgRole: getY() return self.roleYendfunction RpgRole: getDirection() return self.directionend
运动时的逻辑不是很复杂,不过写起来很长的if...else...
运动的原则是方向键按下,朝此方向运动;方向键弹起,停止运动;
若改变运动方向,先保存坐标,停止播放原方向的动画,设置为新方向,
当然还要结合运动的状态是行走,站立,跑步来分类处理.
main.lua
require('Anim')require('RpgRole')--角色状态local ROLESTATE_STAND= 0local ROLESTATE_WALK= 1local ROLESTATE_RUN= 2--运动状态local MODE_WALK= 1local MODE_RUN= 2local movemode=nillocal ROLESTATE=nillocal currdir=RpgRole.DOWNfunction 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;endfunction 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 endfunction 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() endend
代码下载,已clone的直接git pull
git clone git://gitcafe.com/dwdcth/love2d-tutor.git或git clone https://github.com/dwdcth/mylove2d-tutor-in-chinese.git