#MonthOfCode - Day 28: race

My entry for the 28th day of the month of code. The theme for today is: race.

You are the red player, can you beat the computer? Click to start the game, then click like crazy to win the race!

Code after the break.

race.jsview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
document.addEventListener('DOMContentLoaded', function() {
var requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000/60);
};
})();

var $canvas = $('#moc-28');
var ctx = $canvas[0].getContext('2d');
var lastTime;
var started;
var gameover;
var players;


$canvas.on('click', function () {
// first click is to start the game
if (!started) {
started = true;
lastTime = Date.now();
// start the game
run();
} else {
forward();
}

if (gameover) {
reset();
}
});

function reset() {
gameover = false;
started = false;
players = [{
x : 0,
y : 50,
fillStyle : 'red'
}, {
x : 0,
y : 100,
fillStyle : 'green',
speed : 0.8 + 0.4 * Math.random()
}, {
x : 0,
y : 150,
fillStyle : 'blue',
speed : 0.8 + 0.4 * Math.random()
}, {
x : 0,
y : 200,
fillStyle : 'gray',
speed : 0.8 + 0.4 * Math.random()
}, {
x : 0,
y : 250,
fillStyle : 'orange',
speed : 0.8 + 0.4 * Math.random()
}];

draw(); // first frame
}

function forward() {
players[0].x += 2;
}

function update(dt) {

players.forEach(function (p, i) {
if (i !== 0) {
p.x += (p.speed + Math.random()) * 0.01 * dt;
}
if (p.x > 490) {
gameover = true;
alert('The ' + p.fillStyle + ' player wins!');
}
});
}

function draw() {
ctx.clearRect(0,0, 500, 300);
ctx.strokeStyle = '#333';
ctx.lineWidth = 2;
players.forEach(function (p) {
ctx.beginPath();
ctx.moveTo(0, p.y);
ctx.lineTo(500, p.y);
ctx.stroke();
ctx.fillStyle = p.fillStyle;
ctx.fillRect(p.x, p.y - 5, 10, 10);
});
}

function run() {
update(Date.now() - lastTime);
draw();
lastTime = Date.now();
if (!gameover) {
requestAnimFrame(run);
}
}

reset();

});