Love2d。状态系统无法第二次加载游戏状态。

我正在学习lua和love2d,尝试制作一个示例游戏以熟悉它们。我正在遵循goature在YouTube上的教程,并使用他的状态系统来导航游戏。我完成了菜单的示例代码,决定我想从游戏返回菜单。问题是游戏不会第二次加载游戏状态,而是给我一个灰色的屏幕。这应该是相关的代码。

从根文件main.lua

function clearLoveCallbacks()
    love.draw = nil
    love.joystickpressed = nil
    love.joystickreleased = nil
    love.keypressed = nil
    love.keyrelease = nil
    love.load = nil
    love.mousepressed = nil
    love.mousereleased = nil
    love.update = nil
end

states = {}
function loadState(name)
    states = {}
    clearLoveCallbacks()
    local path = "states/" .. name
    require(path .. "/main")
    load()
end

function load()
end

function love.load()
    loadState("menu")

end

从菜单main.lua

function load()

    love.graphics.setBackgroundColor(190, 190, 190, 255)

    imgPlay = love.graphics.newImage("Textures/start.png")
    imgPlayOn = love.graphics.newImage("Textures/start_on.png")
    imgexit = love.graphics.newImage("Textures/exit.png")
    imgexitOn = love.graphics.newImage("Textures/exit_on.png")

    buttons = {
              {imgOff = imgPlay, imgOn = imgPlayOn, x = 400, y = 300 - 64, w = 256, h = 64, action = "play"},
              {imgOff = imgexit, imgOn = imgexitOn, x = 400, y = 300 + 64, w = 256, h = 64, action ="exit"}
              }
end
function love.mousepressed(x, y, button)
    if button == 1 then
        for k,v in pairs(buttons) do
            local ins = insideBox(x, y, v.x - (v.w/2), v.y - (v.h/2), v.w, v.h) -- must use v. for the rest of the arguments except the first 2 because that x and y defined in arguments of the function

            if ins then
                if v.action == "play" then
                    loadState("New_Game") -- loads new game for some reason if i load the menu state from game it won't load the game a secound time
                elseif v.action == "exit" then
                    love.event.quit() -- love2d function to quit
                end
            end
        end
    end
end

和从New_Game main.lua

function load()
    require("States/New_Game/entities")
    love.graphics.setBackgroundColor(255,255,255,255)
    ents.startup()
    --local newEnt= ents.Create("new_ent", 128, 128)
    ents.Create("enemy_base", -math.random(128, 256), 128)
end
function love.keypressed(key, unicode)
    if love.keyboard.isDown("escape") then
        loadState("Menu")
    end
end
点赞
用户734069
用户734069

你提供的代码,按照它现在的写法,不能做你所想要的事情。

你似乎想要能够调用 loadState,并且你希望这个函数将一些内容加载到全局变量中,这样就相当于设置了一个新的“状态”。

这样也许没问题......除非你使用了 require 来进行加载。而且,除非 Love2D 改变了这个函数的工作方式,否则 require 只会加载一个特定的脚本 _一次_。

你知道,执行脚本本身才会改变状态。它定义了一个全局的 load 函数,你调用了它。它在 love 表中定义了一些其他的函数。等等等等。

但这只会发生在脚本被加载和执行时。正如之前所说,require 只会在你第一次要求一个新模块时执行这个操作。

也许,你真正需要的是 dofile,而不是 require。但是,老实说,我建议重新架构你的系统,不要依赖全局变量。预先注册你想要的状态,但不要将它们设置为全局值。相反,每个状态应该定义一个包含它的 load 函数的表。而 load 函数应该注册它的 Love2D 回调。

你的“状态”应该长这样:

local ret = {}

--Executed only once.
local imgPlay = love.graphics.newImage("Textures/start.png")
local imgPlayOn = love.graphics.newImage("Textures/start_on.png")
local imgexit = love.graphics.newImage("Textures/exit.png")
local imgexitOn = love.graphics.newImage("Textures/exit_on.png")

local buttons =
{
    {imgOff = imgPlay, imgOn = imgPlayOn, x = 400, y = 300 - 64, w = 256, h = 64, action = "play"},
    {imgOff = imgexit, imgOn = imgexitOn, x = 400, y = 300 + 64, w = 256, h = 64, action ="exit"}
}

local function mousepressed(x, y, button)
    if button == 1 then
        for k,v in pairs(buttons) do
            local ins = insideBox(x, y, v.x - (v.w/2), v.y - (v.h/2), v.w, v.h) -- must use v. for the rest of the arguments except the first 2 because that x and y defined in arguments of the function

            if ins then
                if v.action == "play" then
                    loadState("New_Game") -- loads new game for some reason if i load the menu state from game it won't load the game a secound time
                elseif v.action == "exit" then
                    love.event.quit() -- love2d function to quit
                end
            end
        end
    end
end

function ret.load()
    --Actual state setup.
    love.mousepressed = mousepressed

    love.graphics.setBackgroundColor(190, 190, 190, 255)
end

return ret

你的 loadState 函数也需要更改:

function loadState(name)
    states = {}
    clearLoveCallbacks()
    local path = "states/" .. name
    local state = require(path .. "/main")
    state.load()
end

哦,我建议你放弃你正在“学习”的任何教程。它教你糟糕的东西。它涉及到太多的全局使用,这就是导致这个问题的原因。如果你只是在学 Lua,那么你正在糟糕地使用 Lua。

2016-01-23 18:58:47