Custom event handling in LUA and MOAI
Problem:
We want to trigger and event (or run a piece of code) when something else happens. How can we do this in LUA?
Solution:
We can store all the custom events and event handlers in a global hash table. Do a regular check running in a different thread to trigger events.
Let’s say we want to show a GameDialog
when a character finishes its walk. The implementation of the GameDialog
is ommitted here because it’s not relevant for the event handling mechanism.
Let’s define on_walk_finished
event handler
on_walk_finished = function (message)
dialog_101 = GameDialog.new()
GameDialog.run(dialog_101, "hi")
end
It’s a simple function to start a GameDialog.
Let’s define the event
walk_finished.
walk_finished = function()
x, y = Character.get_position(zeki)
return distance(-100, x) < 10
end
Here the idea is to state “how do we know when the event has happened?”. For simplicity, if the characters X
value is close to -100
, we can consider the walk is over.
How do we link those two methods?
We can define a EventManager class to check the registered events and trigger callbacks.
# event_manager.lua
EventManager = {
set_timer = function(event, callback)
game_env.events[event] = callback
end,
}
function handle_events()
for e,c in pairs(game_env.events) do
if game_env.events[e] ~= nil then
local result = e()
if result then
local callback = game_env.events[e]
callback()
game_env.events[e] = nil
end
end
end
end
return EventManager
After requiring this class, we can use the set_timer
method to link the event
and the event_handler
.
require "event_manager"
EventManager.set_timer(walk_finished, on_walk_finished)
After registring the events, we need to kick-start the event manager.
mainThread = MOAIThread.new ()
mainThread:run (
function ()
while true do
coroutine.yield ()
handle_events()
end
end
)
Please let me know if this post was useful and whether there is a better solution to the problem.