Designing the main application loop with LuaSDL
LuaSDL offers an event-based application design. LibSDL uses a window to capture input events. Without it, you wouldn't be able to detect key strokes, mouse movement and, of course, you will be without any graphical output.
Getting ready
Before running your Lua script with LuaSDL, make sure you've got the LuaSDL module with all the dependencies in the same directory. However, you can always override the PATH environmental variable so that your application can find the necessary libraries. Note that the path environment variable is managed in the operating system and it's not for the Lua module location!
How to do it…
First, you must load the LuaSDL module file. If this step fails, you are either missing the correct libSDL library or one of the dependencies:
require 'LuaSDL'
You can define your own assertion check function with the optional SDL error reporting:
function SDL_assert(condition, msg) local msg = (msg and msg .. ": " .. SDL.SDL_GetError()) return assert(condition, msg) end
You have to set up the default window parameters as follows:
local window_x_pos = 128 local window_y_pos = 128 local window_width = 640 local window_height = 480 local window_bpp = 0 local window_flags = 0
LuaSDL must be initialized with SDL.SDL_Init
before any use:
SDL_assert(SDL.SDL_Init(SDL.SDL_INIT_EVERYTHING) >= 0, "Couldn't initialize SDL")
LuaSDL places the window randomly upon creation. You can override this by setting the environmental variable SDL_VIDEO_WINDOW_POS
:
SDL.SDL_putenv(string.format("SDL_VIDEO_WINDOW_POS=%d,%d",window_x_pos, window_y_pos))
To set a window caption, you have to call the SDL.SDL_WM_SetCaption
function:
SDL.SDL_WM_SetCaption("LuaSDL Example", "Example")
Now, you can create a window with the SDL.SDL_SetVideoMode
function, which returns the SDL_Surface
object as a userdata:
local screen = SDL_assert(SDL.SDL_SetVideoMode(window_width, window_height, window_bpp, window_flags))
You can use the event loop invariant or just use a break
statement on the application exit:
local running = true
It's more efficient to use the table of event functions than the usual approach with the if
, elseif
, and else
statements. Each table key is an integer constant in this case:
local events = { [SDL.SDL_MOUSEMOTION] = function(event_struct) local event_struct = event_struct.motion -- do something when this event occurs end, [SDL.SDL_MOUSEBUTTONDOWN] = function(event_struct) local event = event_struct.button end, [SDL.SDL_MOUSEBUTTONUP] = function(event_struct) local event = event_struct.button end, [SDL.SDL_KEYDOWN] = function(event_struct) local event = event_struct.key local key = event_struct.keysym.sym end, [SDL.SDL_KEYUP] = function(event_struct) local event = event_struct.key local key = event_struct.keysym.sym end, [SDL.SDL_VIDEORESIZE] = function(event_struct) local event = event_struct.resize end, [SDL.SDL_QUIT] = function(event_struct) running = false end, } -- prepare local instance of SDL_Event object local local_event = SDL.SDL_Event_local() while (running) do -- check for events in the poll if (SDL.SDL_PollEvent(local_event)~=0) then local event_fn = events[local_event.type] if type(event_fn)=='function' then event_fn(local_event) end end end
The SDL.SDL_Quit
function ensures that all the temporary objects are freed upon application exit:
SDL.SDL_Quit()
How it works…
Using the LuaSDL library must follow a certain pattern to ensure correct management of resources and events. Events are used as a primary source of information about user interaction with your application. The LuaSDL library can detect mouse movement, keyboard input, change of application window size, and a request to close your application.
The whole process of event processing uses event polling where you use the SDL.SDL_PollEvent
function in each step of the main application loop to obtain information about the event that has occurred. This function may return a value 0 if there are no events to process. In this case, you can use this free time to process game logic. This recipe uses a skeleton table for event processing functions called events
.
The most important event, SDL.SDL_QUIT
, is received when the user closes the application window. You should clean up all the resources and LuaSDL state as well. Don't forget to use the SDL.SDL_Quit
function before exiting your application to ensure all the previously used memory is freed.