The reason is that when you call require multiple times it only runs the file once (the first time) and just uses the cached result after that.
As a result all your function love.update(dt), love.draw() declarations etc are only done the first time, and when you try to loadState() back into the menu you clear the callbacks but require()-ing menu again doesn't actually do anything.
I propose two solutions:
1.) a cheap way of making it work with minimal changes:
wrap every complete state file in a single function and return it from the module. For example:
Code: Select all
return function ()
function load()
love.graphics.clear()
require "scripts"
love.graphics.setBackgroundColor(60, 60, 60, 255 )
play = love.graphics.newImage("assets/play.png")
....
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 )
if ins then
if v.action == "play" then
loadState("Level1")
elseif v.action == "exit" then
love.event.quit()
end
end
end
end
end
end
and then slightly change loadState():
Code: Select all
state = {}
function loadState(name)
states = {}
clearLoveCallbacks()
local path = "states/" .. name
require(path .. "/main")() -- TWO EXTRA PARENTHESIS - CALL THE FUNCTION THE MODULE RETURNS
load()
end
Also instead of making a global load() which is pretty ugly you can use the function the module returns to do that.
however I would advise you start using a "table based" state concept, because it is more flexible, easier to debug and doesn't rely on all the globals which can easily sneak in hard to find bugs:
- make each gamestate module return a table
- the table contains all the callbacks like .update, .draw etc.
- to load a state just require that module and assign the table to a global variable (current_state)
- love.update, love.draw etc call current_state.update, current_state.draw etc.
- add a .load to the table that resets the state every time instead of relying on the default values so the game restarts when you switch back to it from the menu a second time
for example:
Code: Select all
state = {}
function loadState(name)
local module = "states." .. name
state = require(module)
state.load()
end
function love.draw(...)
if state.draw then state.draw(...) end
end
function love.update(...)
if state.update then state.update(...) end -- only call if it exists
end
function love.keypressed(...)
if state.keypressed then state.keypressed(...) end -- only call if it exists
end
-- etc.
and the file states/menu/init.lua:
Code: Select all
local Menu = {}
local buttons
function Menu.load()
buttons = ... -- reset buttons
end
function Menu.draw()
-- draw buttons etc.
end
return Menu
Note that everything is local, there is no reason to make "Menu" or "buttons" global.
also a few other unrelated notes:
- with require() do not use slashes, use dots (states.Menu.main)
- if you name your states/Menu/main.lua as init.lua instead, you can require("states/Menu") (like in my code example above); if the given module is a directory it will automatically try /init.lua and you can still have each as it's own folder.