This is a crude example of a playable game that can be expressed in less than 250 lines of code!
Demo
Code
1<!DOCTYPE html>
2<html>
3<body>
4 <canvas id="game"> </canvas>
5 <script type="text/javascript">
6 var game = (function() {
7 var Width = 800, Height = 450;
8 var canvas = document.getElementById("game");
9 var FPS = 1000 / 60;
10 canvas.width = Width;
11 canvas.height = Height;
12 canvas.setAttribute('tabindex', 1);
13 var ctx = canvas.getContext("2d");
14
15 var BG = {
16 Color: '#333',
17 Paint: function() {
18 ctx.fillStyle = this.Color;
19 ctx.fillRect(0, 0, Width, Height);
20 }
21 };
22
23 var Ball = { Radius: 5, Color: '#999', X: 0, Y: 0, VelX: 0, VelY: 0 };
24 Ball.Paint = function() {
25 ctx.beginPath();
26 ctx.fillStyle = this.Color;
27 ctx.arc(this.X, this.Y, this.Radius, 0, Math.PI * 2, false);
28 ctx.fill();
29 this.Update();
30 };
31 Ball.Update = function() {
32 this.X += this.VelX;
33 this.Y += this.VelY;
34 };
35 Ball.Reset = function() {
36 this.X = Width / 2;
37 this.Y = Height / 2;
38 this.VelX = (!!Math.round(Math.random() * 1) ? 1.5 : -1.5);
39 this.VelY = (!!Math.round(Math.random() * 1) ? 1.5 : -1.5);
40 };
41
42 function Paddle(position) {
43 this.Color = '#999';
44 this.Width = 5;
45 this.Height = 100;
46 this.X = 0;
47 this.Y = Height / 2 - this.Height / 2;
48 this.Score = 0;
49 if (position == 'left')
50 this.X = 0;
51 else this.X = Width - this.Width;
52 this.Paint = function() {
53 ctx.fillStyle = this.Color;
54 ctx.fillRect(this.X, this.Y, this.Width, this.Height);
55 ctx.fillStyle = this.Color;
56 ctx.font = "normal 10pt Calibri";
57 if (position == 'left') {
58 ctx.textAlign = "left";
59 ctx.fillText("score: " + Player.Score, 10, 10);
60 } else {
61 ctx.textAlign = "right";
62 ctx.fillText("score: " + Computer.Score, Width - 10, 10);
63 }
64 };
65 this.IsCollision = function() {
66 if (Ball.X - Ball.Radius > this.Width + this.X || this.X > Ball.Radius * 2 + Ball.X - Ball.Radius)
67 return false;
68 if (Ball.Y - Ball.Radius > this.Height + this.Y || this.Y > Ball.Radius * 2 + Ball.Y - Ball.Radius)
69 return false;
70 return true;
71 };
72 };
73
74 window.requestAnimFrame = (function() {
75 return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
76 return window.setTimeout(callback, FPS);
77 };
78 })();
79 window.cancelRequestAnimFrame = (function() {
80 return window.cancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.mozCancelRequestAnimationFrame || window.oCancelRequestAnimationFrame || window.msCancelRequestAnimationFrame || clearTimeout
81 })();
82
83 var Computer = new Paddle();
84 var Player = new Paddle('left');
85
86 function Paint() {
87 ctx.beginPath();
88 BG.Paint();
89 Computer.Paint();
90 Player.Paint();
91 Ball.Paint();
92 }
93
94 function MouseMove(e) {
95 Player.Y = e.pageY - Player.Height / 2;
96 }
97 canvas.addEventListener("mousemove", MouseMove, true);
98
99 function Loop() {
100 init = requestAnimFrame(Loop);
101 Paint();
102 if (Player.IsCollision() || Computer.IsCollision()) {
103 Ball.VelX = Ball.VelX * -1;
104 Ball.VelX += (Ball.VelX > 0 ? 0.5 : -0.5);
105 if (Math.abs(Ball.VelX) > Ball.Radius * 1.5)
106 Ball.VelX = (Ball.VelX > 0 ? Ball.Radius * 1.5 : Ball.Radius * -1.5);
107 }
108 if (Ball.Y - Ball.Radius < 0 || Ball.Y + Ball.Radius > Height)
109 Ball.VelY = Ball.VelY * -1;
110 if (Ball.X - Ball.Radius <= 0) {
111 Computer.Score++;
112 Ball.Reset();
113 } else if (Ball.X + Ball.Radius > Width) {
114 Player.Score++;
115 Ball.Reset();
116 }
117 if (Computer.Score === 10)
118 GameOver(false);
119 else if (Player.Score === 10)
120 GameOver(true);
121 Computer.Y = (Computer.Y + Computer.Height / 2 < Ball.Y ? Computer.Y + Computer.Vel : Computer.Y - Computer.Vel);
122 };
123
124 function GameOver(win) {
125 cancelRequestAnimFrame(init);
126 BG.Paint();
127 ctx.fillStyle = "#999";
128 ctx.font = "bold 40px Calibri";
129 ctx.textAlign = "center";
130 ctx.fillText((win ? "YOU WON!" : "GAME OVER"), Width / 2, Height / 2);
131 ctx.font = "normal 16px Calibri";
132 ctx.fillText("refresh to replay", Width / 2, Height / 2 + 20);
133 }
134 return {
135 Start: function() {
136 Ball.Reset();
137 Player.Score = 0;
138 Computer.Score = 0;
139 Computer.Vel = 1.25;
140 Loop();
141 }
142 };
143 })();
144 game.Start();
145 </script>
146</body>
147</html>