博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
love2d教程9--角色移动
阅读量:5079 次
发布时间:2019-06-12

本文共 7077 字,大约阅读时间需要 23 分钟。

本来该早点写完的,可是由于一些小问题,拖到现在了,不过也好,我决定以后使用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

转载于:https://www.cnblogs.com/xdao/archive/2012/12/28/love2d-tutor09.html

你可能感兴趣的文章
中文脏话识别的解决方案
查看>>
CSS之不常用但重要的样式总结
查看>>
Python编译错误总结
查看>>
URL编码与解码
查看>>
日常开发时遇到的一些坑(三)
查看>>
Eclipse 安装SVN插件
查看>>
深度学习
查看>>
TCP粘包问题及解决方案
查看>>
构建之法阅读笔记02
查看>>
添加按钮
查看>>
移动端页面开发适配 rem布局原理
查看>>
Ajax中文乱码问题解决方法(服务器端用servlet)
查看>>
会计电算化常考题目一
查看>>
阿里云服务器CentOS6.9安装Mysql
查看>>
剑指offer系列6:数值的整数次方
查看>>
js 过滤敏感词
查看>>
poj2752 Seek the Name, Seek the Fame
查看>>
软件开发和软件测试,我该如何选择?(蜗牛学院)
查看>>
基本封装方法
查看>>
bcb ole拖拽功能的实现
查看>>