Skip to content

Straightforward Gamestates

noooway edited this page Jan 18, 2017 · 20 revisions

A typical game has a menu screen, a congratulations screen and some kind of a pause regime. These different game modes are called gamestates. In this part, a simple implementation for such functionality is shown.

I'm going to define 4 gamestates: "menu", "game", "gamepaused" and "gamefinished". In the straightforward implementation it is enough to maintain a simple variable gamestate to switch between them. It is declared in the main.lua and initialized to the first game state - "menu".

 local gamestate = "menu"

In each love callback we need if-else structure:

function love.update( dt )
   if gamestate == "menu" then
   .....
   elseif gamestate == "game" then
   .....
   elseif gamestate == "gamepaused" then
   .....
   elseif gamestate == "gamefinished" then
   .....
   end
end

In the "menu" the message is shown.

function love.draw()
   if gamestate == "menu" then
      love.graphics.print("Menu gamestate. Press Enter to continue.",
			  280, 250)
   elseif gamestate == "game" then
   .....

When Enter is pressed, the game starts, i.e. the state changes to the "game". On Esc the game is exited.

function love.keyreleased( key, code )
   if gamestate == "menu" then
      if key == "return" then
	 gamestate = "game"
      elseif key == 'escape' then
	 love.event.quit()
      end    
   elseif gamestate == "game" then
   .....

There is nothing to update update in this state, so the corresponding section of love.update is empty:

function love.update( dt )
   if gamestate == "menu" then
   elseif gamestate == "game" then
   .....

For the "game" gamestate, we simply transfer contents of love.draw, love.update and from the previous part. In love.keyreleased there is a minor difference: on Esc instead of quitting, the game switches to "gamepaused" state.

In the "gamepaused" state I want to freeze the ball and platform and display a message. This can be implemented if we draw the game objects but don't update them.

function love.draw()
   .....
   elseif gamestate == "gamepaused" then
      ball.draw()
      platform.draw()
      bricks.draw()
      walls.draw()
      love.graphics.print(
	 "Game is paused. Press Enter to continue or Esc to quit",
	 50, 50)
   elseif gamestate == "gamefinished" then
   .....

The update-part is empty. The keyreleased is similar to "menu".

The "gamefinished" state is entered when there are no more levels.

function switch_to_next_level( bricks, ball, levels )  --(\*1)
   if bricks.no_more_bricks then
      ..... 
      elseif levels.current_level >= #levels.sequence then
	 gamestate = "gamefinished"
      end
   end
end

(*1): This function is moved from levels table. An explanation is below.

It is similar to "menu" except that on Enter it resets the level counter and restarts the game from the first level.

function love.keyreleased( key, code )
   .....
   elseif gamestate == "gamefinished" then
      if key == "return" then
	 levels.current_level = 1
	 level = levels.require_current_level()
	 bricks.construct_level( level )
	 ball.reposition()	 	 
	 gamestate = "game"
      elseif key == 'escape' then
	 love.event.quit()
      end    
   end
end

There is also one minor catch with levels.switch_to_next_level. The gamestate variable is defined in the scope of main.lua. If we simply pass it into this function, it will be passed by value and we won't be able to change from "game" to "gamefinished". There are several solutions to this problem; I simply move this function from levels table to main.lua.

function switch_to_next_level( bricks, ball, levels )
   if bricks.no_more_bricks then
      if levels.current_level < #levels.sequence then
	 levels.current_level = levels.current_level + 1
	 level = levels.require_current_level()
	 bricks.construct_level( level )
	 ball.reposition()	 	 
      elseif levels.current_level >= #levels.sequence then
	 gamestate = "gamefinished"
      end
   end
end

    Home
    Acknowledgements
    Todo

Chapter 1: Prototype

  1. The Ball, The Brick, The Platform
  2. Game Objects as Lua Tables
  3. Bricks and Walls
  4. Detecting Collisions
  5. Resolving Collisions
  6. Levels

    Appendix A: Storing Levels as Strings
    Appendix B: Optimized Collision Detection (draft)

Chapter 2: General Code Structure

  1. Splitting Code into Several Files
  2. Loading Levels from Files
  3. Straightforward Gamestates
  4. Advanced Gamestates
  5. Basic Tiles
  6. Different Brick Types
  7. Basic Sound
  8. Game Over

    Appendix C: Stricter Modules (draft)
    Appendix D-1: Intro to Classes (draft)
    Appendix D-2: Chapter 2 Using Classes.

Chapter 3 (deprecated): Details

  1. Improved Ball Rebounds
  2. Ball Launch From Platform (Two Objects Moving Together)
  3. Mouse Controls
  4. Spawning Bonuses
  5. Bonus Effects
  6. Glue Bonus
  7. Add New Ball Bonus
  8. Life and Next Level Bonuses
  9. Random Bonuses
  10. Menu Buttons
  11. Wall Tiles
  12. Side Panel
  13. Score
  14. Fonts
  15. More Sounds
  16. Final Screen
  17. Packaging

    Appendix D: GUI Layouts
    Appendix E: Love-release and Love.js

Beyond Programming:

  1. Game Design
  2. Minimal Marketing (draft)
  3. Finding a Team (draft)

Archive

Clone this wiki locally