如何编程玩家在Lua中以平滑和标准的方式跳跃?

问题描述 投票:0回答:1

我已经学习编程游戏四年了,但是我仍然不知道玩家如何正确跳跃(我只需要平台游戏的基本跳跃方法,但我仍然不能做到)。我在线搜索了很多教程,但很少或是,那些语言与Lua不同。

在过去的四年中,当我制作平台游戏时,为了使角色跳跃,我尝试了许多方法,每种方法都不完整,并且存在错误(例如玩家穿过墙壁时卡住了,跳跃时卡住了)在玩家头部的墙上以及其他许多怪异的东西。

现在,我将介绍我尝试过的最新方法。这是我的播放器文件:我正在使用bump.lua库的支持。在此处访问图书馆:https://github.com/kikito/bump.lua

这是我的文件:

Knight = Object:extend()

function Knight:new(x, y)
    --- properties
    self.x = x
    self.y = y
    self.width = 36
    self.height = 48
    -----
    self.scaleX = 1
    ---- art 
    self.sprite = love.graphics.newImage("sources/art/player/knight/knight.png")
    self.grid = anim8.newGrid(48, 81, self.sprite:getWidth(), self.sprite:getHeight())
    self.animations = {}
    self.animations.idle = anim8.newAnimation(self.grid(1, 1, 2, 1, 3, 1, 2, 1), 0.1)
    self.animations.walk = anim8.newAnimation(self.grid(4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 4, 1), 0.05)
    self.animations.jump = anim8.newAnimation(self.grid(9, 1), 0.1)
    self.anim = self.animations.idle
    ----- 
    ----- physics value
    self.xVelocity = 0
    self.yVelocity = 0
    self.onGround = false
    self.gravity = 10
    --- add to bump world 
    world:add(self, self.x, self.y, self.width, self.height)
end

local knightFilter = function(item, other)
  if     other.isCoin   then return 'cross'
  elseif other.isBlock   then return 'slide'
  elseif other.isExit   then return 'touch'
  elseif other.isSpring then return 'bounce'
  end
  -- else return nil
end

function Knight:update(dt)
    if love.keyboard.isDown('a') then 
        self.xVelocity = -200
        self.scaleX = -1
    elseif love.keyboard.isDown('d') then
        self.xVelocity = 200
        self.scaleX = 1
    else
        self.xVelocity = 0
    end

    if self.onGround == false then self.yVelocity = self.yVelocity + self.gravity end

    local goalX, goalY = self.x + self.xVelocity * dt, self.y + self.yVelocity * dt
    local actualX, actualY, cols, len = world:move(self, goalX, goalY, knightFilter)
    self.x, self.y = actualX, actualY
    self.onGround = false
    for i = 1, len do
        local other = cols[i].other
        if other.isBlock then
            self.onGround = true
        else
            self.onGround = false
        end
    end

    self.anim:update(dt)
end

function Knight:draw()
    love.graphics.setColor(1, 1, 1)
    self.anim:draw(self.sprite, math.floor(self.x) + 18, math.floor(self.y) + 4, nil, self.scaleX, 1, 24, 36)
    love.graphics.rectangle("line", self.x, self.y, self.width, self.height)
end

这是main.lua(您只需要注意函数love.keypressed ()love.keyreleased ()):

Object = require "libs/classic"
bump = require "libs/bump"
anim8 = require "libs/anim8"

function love.load()
    world = bump.newWorld()
    addPlayer("knight")
    variableandrequire()
    --- gameplay level1
    loadDataLevel1()
    buildMap()
    -------
end

function variableandrequire()
    listOfBlocks = {}
    -----
    require "entities/blocks/block"
end

function love.update(dt)
    dt = math.min(dt, 0.025)
    player:update(dt)
end

function love.draw()
    player:draw()
    drawBlocks()
end

function drawBlocks()
    for i, v in ipairs(listOfBlocks) do
        v:draw()
    end
end

function addPlayer(name)
    local character = name
    if character == "knight" then
        require "entities/characters/knight"
        player = Knight (100, 100)
    end
end

function loadDataLevel1()
    map = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
           {0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
           {0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
           {0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
           {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},}

end

function buildMap()
    --id : 1.grass 2.dirt
    for y = 1, 10 do
        for x = 1, 15 do
            if map[y][x] == 1 then
                table.insert(listOfBlocks, Block((x - 1) * 64, (y - 1) * 64, 1))
            elseif map[y][x] == 2 then
                table.insert(listOfBlocks, Block((x - 1) * 64, (y - 1) * 64, 2))
            end
        end
    end
end

function love.keypressed(key) 
    if key == 'w' then
        if player.onGround then
            player.yVelocity = -350
            player.onGround = false
        end
    end
end

function love.keyreleased(key)
    if key == 'w' then
        if player.yVelocity < -60 then player.yVelocity = -60 end
    end
end 

我遇到了以下错误:玩家自由落体时,跌落的速度很好,但是如果玩家站在一个障碍物上,则缓慢地按向左或向右按​​钮直到它跌落(然后玩家触摸关闭在墙壁的侧面),坠落的速度非常快,当玩家靠近墙壁站立​​并跳跃时,尽管墙壁远高于跳跃高度,但玩家似乎紧贴墙壁并缓慢爬升。

而且我认为这是我的转储方法。因为它会产生许多错误,所以会一个接一个地出现。当然,我的工作方式从来都不是完美的。如果没有人教,我一生都不会知道一种标准方法。

我很高兴为您提供一种标准且基本的跳转方法(我不需要太高),就像今天大多数平台游戏一样,跳转看起来都很流畅(我很欣赏这种方式)。同样重要的是,它在Lua中执行。

lua love2d
1个回答
1
投票

您尝试过YouTube吗?关于您的所有问题,有一些不错的教程。

[我可以建议这段关于玩家跌落太快的视频:https://www.youtube.com/watch?v=9130QVnn7VU

和跳跃技师:https://www.youtube.com/watch?v=zDVZchjddbQ

[您可以按照整个系列看他如何做。他也在使用凹凸。

© www.soinside.com 2019 - 2024. All rights reserved.