Pong - The Game Loop
Sat, May 14, 2011- Introduction
- The Game Runner
- Bouncing Balls
- The Game Loop
- Collision Detection
- Computer AI
The Game.Runner provides the raw 60fps frame loop of update()
+ draw()
. Within that
process the game itself (in this case Pong) needs to provide the game state machine that
starts with a basic menu, waits for user input to start a game, run the game until there
is a winner, or the user abandons it, and then go back to the menu and repeat.
Initialization
For the Pong game, we are going to use some images to display the ‘menu’ that tells the user to:
- press ‘1’ for a single player game
- press ‘2’ for a double player game
This introduces a subtle twist into the GameRunner and Pong relationship. Loading images is an asynchronous process and we can’t display the images until they are loaded, so we dont want the GameRunner to go into its loop until the images are fully loaded.
In order to resolve this issue, the Pong initialize method uses a callback pattern to
know when the images are finished loaded and doesn’t tell the GameRunner to start()
until that process is complete:
initialize: function(runner, cfg) {
Game.loadImages(Pong.Images, function(images) {
this.cfg = cfg;
this.runner = runner;
this.width = runner.width;
this.height = runner.height;
this.images = images;
this.playing = false;
this.scores = [0, 0];
this.menu = Object.construct(Pong.Menu, this);
this.court = Object.construct(Pong.Court, this);
this.leftPaddle = Object.construct(Pong.Paddle, this);
this.rightPaddle = Object.construct(Pong.Paddle, this, true);
this.ball = Object.construct(Pong.Ball, this);
this.runner.start();
}.bind(this));
},
Keyboard Input
When a keyboard event occurs, the GameRunner automatically calls any
onkeydown()
or onkeyup()
methods in the game (if they exist), so the
Pong game can detect appropriate keys and start or stop games appropriately:
onkeydown: function(keyCode) {
switch(keyCode) {
case Game.KEY.ZERO: this.startDemo(); break;
case Game.KEY.ONE: this.startSinglePlayer(); break;
case Game.KEY.TWO: this.startDoublePlayer(); break;
case Game.KEY.ESC: this.stop(true); break;
case Game.KEY.Q: this.leftPaddle.moveUp(); break;
case Game.KEY.A: this.leftPaddle.moveDown(); break;
case Game.KEY.P: this.rightPaddle.moveUp(); break;
case Game.KEY.L: this.rightPaddle.moveDown(); break;
}
},
onkeyup: function(keyCode) {
switch(keyCode) {
case Game.KEY.Q: this.leftPaddle.stopMovingUp(); break;
case Game.KEY.A: this.leftPaddle.stopMovingDown(); break;
case Game.KEY.P: this.rightPaddle.stopMovingUp(); break;
case Game.KEY.L: this.rightPaddle.stopMovingDown(); break;
}
},
This is also where we detect input from the users to move the paddles up or down.
Starting a Game
Now that we can detect keyboard input, starting a game is possible:
startDemo: function() { this.start(0); },
startSinglePlayer: function() { this.start(1); },
startDoublePlayer: function() { this.start(2); },
start: function(numPlayers) {
if (!this.playing) {
this.scores = [0, 0];
this.playing = true;
this.ball.reset();
this.runner.hideCursor();
}
},
During the Game
While the game is in progress, the update()
method needs to detect when
goals are scored and when to declare a winner and stop the game:
update: function(dt) {
this.leftPaddle.update(dt, this.ball);
this.rightPaddle.update(dt, this.ball);
if (this.playing) {
var dx = this.ball.dx;
var dy = this.ball.dy;
this.ball.update(dt, this.leftPaddle, this.rightPaddle);
if (this.ball.left > this.width)
this.goal(0);
else if (this.ball.right < 0)
this.goal(1);
}
},
goal: function(playerNo) {
this.scores[playerNo] += 1;
if (this.scores[playerNo] == 1) {
this.menu.declareWinner(playerNo);
this.stop();
}
else {
this.ball.reset(playerNo);
}
},
Stopping the Game
The game is stopped when a winner is declared, it can also be stopped in response to the user hitting the ESC key:
stop: function(ask) {
if (this.playing) {
if (!ask || this.runner.confirm('Abandon game in progress ?')) {
this.playing = false;
this.runner.showCursor();
}
}
},
You can see the game loop in progress with the demo here
More…
- Introduction
- The Game Runner
- Bouncing Balls
- The Game Loop
- Collision Detection
- Computer AI
You can find the final game here and the code is here