Skip to content

47. Game template

May 4, 2013

When your screen is redrawing 60 times a second, and what you are drawing depends on where you are in the (we’ll assume) game, you need a “finite state machine”. This is a fancy term for a game which can be in only one of several different states at any time, and it will need

  • a variable that holds the state of the game, and
  • code that uses that variable to draw, do stuff, etc.
  • .
    A nice example was just posted in the forum by Zoyt, something he calls his Scene Manager. I’m going to look at it piece by piece. As usual, we can learn quite a lot from the detail.

     --# Main
    function setup()
        parameter.integer('Current scene',1,3,1,function(s)
                if s == 1 then
                    changeScene('start')
                elseif s == 2 then
                    changeScene('game')
                elseif s == 3 then
                    changeScene('gameover')
                end
            end)
    end
    

    The setup function uses a parameter to view the current state and allow the user to change between them. Note how it includes a “callback” function that will run whenever the parameter changes (callback means it doesn’t run now, but only when it is called on demand, later).

    Note too, how the function has one parameter (s) which is the user selection. It doesn’t have to be called s, but if you want to know what the user selected, then put a variable name in the function brackets and Codea will fill it with the number selecred by the user.

    This type of function is also known as “anonymous” because it doesn’t have a name, and it doesn’t need a name because it will never be called by any other function, being buried inside a parameter.

    If you are designing a game with a start button, you will want to put that button on the screen at some point, but while you are developing, a parameter is a nice and easy way to provide that functionality while you are trying to get everything else working.

    Getting back to the “state machine”, this function sets up three simple states – ready to go, game in progress, and game over, and the variable “s” stores a number to tell Codea which one applies. The function inside the parameter runs a function to change the state, if s changes in value.

    Next we have a function that changes between states, doing anything you need to do.

     
    function changeScene(s)
        if scene ~= nil then
            scene:exit()
        end
        if s == 'start' then
            scene = Start()
            sID = s
        elseif s == 'game' then
            scene = Game()
            sID = s
        elseif s == 'gameover' then
            scene = GameOver()
            sID = s
        else
            print('Invalid scene name')
        end
    end
    

    This is only a template, so it doesn’t have much code. In fact, all it really does is define scene as one of three classes. Each of these will have their own draw functions, so all draw needs to do is this:

     
    function draw()
        background(40, 40, 50)
        scene:draw()
    end
    

    Neat, huh? If you want to do anything in Main, you can just call a scene function without worrying which state the game is in, and (as long as the three classes all have that function), the right one will run, because “scene” is pointing at the class for the current state.

    Now we have the three state classes. Again, there isn’t much code, as this is a template. But you can build just about any game using this framework. What is nice is how it keeps the three game states completely separate, with all the detail happening inside separate classes. When you start building any sort of complex game, you will be grateful for this separation, because it is simpler to build, check and debug.

     
    --# Start
    Start = class()
     
    function Start:init()
        print('start')
    end
     
    function Start:draw()
        text('Start screen',WIDTH/2,HEIGHT/2)
    end
     
    function Start:exit()
        print('exit')
    end
     
    --# Game
    Game = class()
     
    function Game:init()
        print('start')
    end
     
    function Game:draw()
        text('Game screen',WIDTH/2,HEIGHT/2)
    end
     
    function Game:exit()
        print('exit')
    end
     
    --# GameOver
    GameOver = class()
     
    function GameOver:init()
        print('start')
    end
     
    function GameOver:draw()
        text('Game over screen',WIDTH/2,HEIGHT/2)
    end
     
    function GameOver:exit()
        print('exit')
    end
    

    The full code is here. Copy this if you want to run it

    Advertisements

    From → Games, Programming

    3 Comments
    1. Briarfox permalink

      This is an example of the state machine I’ve been using. Its from aciolino on the codea forums. It gets rid of all the if statments. I really likes your idea of using a parameter. I had been just typing the state into the command console.

      –# Main
      function setup()

      APP_MENU = 1
      APP_Play = 2

      APPSTATES = {menu,play}
      APPSTATE = APP_MENU
      parameter.integer(“GameMode”,1,2,1,callback)
      end

      function draw()
      APPSTATES[APPSTATE]:draw()
      end

      function touched(touch)
      APPSTATES[APPSTATE]:touched(touch)
      end

      function callback(state)
      APPSTATE = state
      APPSTATES[APPSTATE]:load()
      end
      –# menu
      menu = class()

      function menu:load()
      — you can accept and set parameters here

      self.doSomething = “Menu Loaded”
      end

      function menu:draw()
      — Codea does not automatically call this method
      print(self.doSomething)
      end

      function menu:touched(touch)
      — Codea does not automatically call this method
      if touch.state == BEGAN then self.doSomething = “This is a Menu” end
      end

      –# play
      play = class()

      function play:load()
      — you can accept and set parameters here

      self.doSomething = “Loading Game Play”
      end

      function play:draw()
      — Codea does not automatically call this method
      print(self.doSomething)
      end

      function play:touched(touch)
      — Codea does not automatically call this method
      if touch.state == BEGAN then self.doSomething = “Playing the game” end
      end

    2. Saurabh permalink

      If you call the draw function of a class then is the init function called before it??

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out /  Change )

    Google photo

    You are commenting using your Google account. Log Out /  Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out /  Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out /  Change )

    Connecting to %s

    %d bloggers like this: