我只是在学习lua和love2d,我正在尝试制作一个熟悉的示例游戏。我在youtube上关注goature的教程,并使用他的状态系统来导航游戏。我完成了菜单的示例代码编写,并决定我能够从游戏中返回菜单。问题是游戏不会第二次加载游戏状态而是给我一个灰色屏幕。这应该是相关代码。
从根文件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
答案 0 :(得分:1)
您提供的代码,如书面所示,无法达到您想要的效果。
您似乎希望能够调用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。