Breakout Game States

Breakout Game States
Level 3 Extended Diploma
Unit 22
Developing Computer Games
Prepare
• As always, start by making a copy and
rename the .css, and .html as BreakoutState
and edit the html file to reference:
• BreakoutState.css
• BreakoutState.js
• Create a new, empty file called
BreakoutState.js
Game states
• A state machine is a programming construct
that allows the game to be in only one state
at a time
• It can be:
• Title
the opening screen
• Play_level
the current level in play
• Game_Over the end screen
•
Changing Breakout
• We are going to refactor the code
• This is a "disciplined technique for
restructuring an existing body of code,
altering its internal structure without changing
its external behaviour
• Advantages include
• improved code readability
• reduced complexity
• Improved maintainability
Refactoring
• Make functions for:
•
•
•
Getting the canvas context
Switching game states
Each game state: start, play, game over
• Make a generic keystroke handler
• Set a frame rate interval timer for redraw
canvasApp: gets the context
canvasApp();
function canvasApp(){
var canvas=document.getElementById("canvas")
if (!canvas || !canvas.getContext){
return;
}
var ctx = canvas.getContext("2d");
if (!ctx) {
return
}
Insert this at the start of BreakoutState.js
Declare variables
//Application States
const GAME_STATE_TITLE = 0;
These are our
const GAME_STATE_NEW_LEVEL = 1;
3 states
const GAME_STATE_GAME_OVER = 2;
var currentGameState = 0;
var currentGameStateFunction = null;
//Initialise States
var titleStarted = false;
var gameStarted = false;
var gameOver = false;
var keyPressList = []; // An array for keystrokes
State Switcher
• This code will be passed a parameter for the
new state we will switch to
• A switch function will then select the required
state and call the required function:
• gameStateTitle
• gameStatePlayLevel
• gameStateGameOver
• Insert the code after the variables
State switcher code
function switchGameState(newState) {
currentGameState = newState;
switch (currentGameState) {
case GAME_STATE_TITLE:
currentGameStateFunction = gameStateTitle;
break;
case GAME_STATE_NEW_LEVEL:
currentGameStateFunction = gameStatePlayLevel;
break;
case GAME_STATE_GAME_OVER:
currentGameStateFunction = gameStateGameOver;
break;
}
}
Display title
• This code:
• Checks if it is running
• If it isn’t it displays the title screen and says it is
running
• If it is running it checks if the space bar is pressed
• When it is it calls the switcher with the parameter
GAME_STATE_NEW_LEVEL
• And says it is no longer running
• Add this code after the switcher
Display title code
function gameStateTitle(){
if (titleStarted != true){
ctx.fillStyle = '#000000';
ctx.fillRect(0,0,500,400);
ctx.fillStyle = '#ffffff';
ctx.font = '20px _sans';
ctx.textBaseline = 'top';
ctx.fillText ("Title Screen", 200,150);
ctx.fillText ("Press Space to Play", 170,200);
titleStarted = true;
}else{
if (keyPressList[32] == true){
switchGameState(GAME_STATE_NEW_LEVEL);
titleStarted = false;
}
}
}
Run the current level
• This code essentially does the same as the
title code, but with a different message
• We are just making sure we can switch states
for now
• We will add the game code in the next lesson
• This code goes after the title code
Level code
function gameStatePlayLevel(){
if (gameStarted != true){
ctx.fillStyle = '#000000';
ctx.fillRect(0,0,500,400);
ctx.fillStyle = '#ffffff';
ctx.font = '20px _sans';
ctx.textBaseline = 'top';
ctx.fillText ("Game goes here", 180,150);
ctx.fillText ("Press Space to End", 170,200);
gameStarted = true;
}else{
if (keyPressList[32] == true){
switchGameState(GAME_STATE_GAME_OVER);
gameStarted = false;
}
}
}
Game over
• This code displays the Game Over message
and allows the game to be restarted by
switching back to the title page
• It goes after the game code
Game over code
function gameStateGameOver(){
if (gameOver != true){
ctx.fillStyle = '#000000';
ctx.fillRect(0,0,500,400);
ctx.fillStyle = '#ffffff';
ctx.font = '20px _sans';
ctx.textBaseline = 'top';
ctx.fillText ("Game over", 200,150);
ctx.fillText ("Press Space to Restart", 160,200);
gameOver = true;
}else{
if (keyPressList[32] == true){
switchGameState(GAME_STATE_TITLE);
gameOver = false;
}
}
}
Run game
• This code is called by the interval timer and
runs the game at the current level
function runGame(){
currentGameStateFunction();
}
It goes after the game over code
Key handler
• This listens for a keystroke event.
• When the key is pressed the key value in
keyPressList is set to true
• When the key is released the key value in
keyPressList is set to false
• If the space bar (key value 32) is pressed then
keyPressList[32] == true
• This code goes after run game
Key handler
document.onkeydown = function(e){
e= e?e:window.event;
keyPressList[e.keyCode] = true;
}
document.onkeyup = function(e){
e= e?e:window.event;
keyPressList[e.keyCode] = false;
}
Application start
• This code
• Switches to the title state
• sets a frame rate at a constant 40 fps
• the interval timer calls runGame at the interval
time of 1000 divided by the frame rate
• This code goes at the end of the program
• Note :
• all the code is within function canvasApp()
Application start code
//Application start
switchGameState(GAME_STATE_TITLE);
const FRAME_RATE = 40;
var intervalTime = 1000/FRAME_RATE;
setInterval(runGame, intervalTime);
}
If all has gone well
• You should be able to cycle round
This seems like a lot of work
• And we can’t even play the game
• But we have
•
•
•
•
A much better structure
A framework for controlling any game
A framework for adding levels
Code that is easily understood, maintained and
extended
Next lesson
• We will put the game back in