SceneManager

Just wanted to share a little class I wrote to make things easier when juggling multiple scenes / menus / levels in my game.

The bulk of it is the SceneManager:

SceneManager = class()

-- SceneManager keeps track of multiple scenes in a game, and allows each scene
-- to perform a set of actions when it is shown or hidden

-- initialize with a set of scenes
function SceneManager:init(scenes)
    self.scenes = scenes
    if (table.maxn(self.scenes) > 0) then
        self.currentScene = scenes[1]
    end
end

function SceneManager:addScene(scene)
    table.insert(self.scenes, scene)
    
    -- if this is the only scene, then switch to it
    if (table.maxn(self.scenes) == 1) then
        self.currentScene = scenes[1]
    end
end

-- switch to another scene
function SceneManager:switchScene(newScene)
    if (self.currentScene.onExit) then 
        self.currentScene:onExit() 
    end
    
    self.currentScene = self.scenes[newScene]
    
    if (self.currentScene.onEnter) then 
        self.currentScene:onEnter() 
    end
end

-- pass on each of the main built-in functions to the current scene
function SceneManager:update()
   if (self.currentScene.update) then 
        self.currentScene:update() 
    end
end

function SceneManager:draw()
    if (self.currentScene.draw) then 
        self.currentScene:draw()
    end
end

function SceneManager:touched(touch)
    if (self.currentScene.touched) then
        self.currentScene:touched(touch)
    end
end

function SceneManager:keyboard(key)
    if (self.currentScene.keyboard) then
       self.currentScene:keyboard(key)
    end
end

You can then define as many scenes as you like, each one in its own class. A scene can implement any of the following functions, but doesn’t have to:

  • onEnter() called when the scene becomes the active scene
  • onExit() called when the scene stops being the active scene
  • update() entirely optional, but will be called before draw() - I like to split up my update and draw logic if possible
  • draw() your usual draw function
  • touched(touch) passes on touches to your scene
  • keyboard(key) passes on key presses to your scene

You’ll then need to initialize a scene manager, give it some scenes, and set up your main functions to use it:

-- I found it useful to create some variables to use to reference each scene. e.g.:
SCENE_MENU = 1
SCENE_GAME = 2
SCENE_GAMEOVER = 3
-- these are useful when switching between scenes. they refer to the order the scenes are added to the scene manager

function setup()
  sceneManager = SceneManager({ MenuScene(), GameScene(), GameoverScene()})
end

function draw()
  sceneManager:draw()
end

function touched(touch)
  sceneManager:touched(touch)
end

function keyboard(key)
  sceneManager:keyboard(key)
end

Here’s a quick example scene:

MenuScene = class()

function MenuScene:init()
  -- initialize...
end

function MenuScene:onEnter()
  -- play a sound when the menu appears
  sound(SOUND_POWERUP, 44377)
end

function MenuScene:draw()
  fill(255,255,255,255)
  noStroke()
  ellipseMode(CENTER)
  ellipse(WIDTH/2,HEIGHT/2,300,300)
end

function MenuScene:touched(touch)
  -- if the user taps, switch to the game scene
  sceneManager:switchScene(SCENE_GAME)
end

Hope this is useful to someone!

Thanks! I’ll try it when I get a chance. This will be very helpful for my game, ThingFling.

Thanks frosty this will be very handy

I like the idea. Make it modular. Thanks @frosty

Incredible, i tried to create my Own and got stuck for Weeks - thank you!!!