4. Tron Game

The game below is based on the movie Tron:

or here’s the newer version of the movie:

Here’s code for making a Tron game:

<!DOCTYPE html>
<html lang="en">
 <head>
 <style>
 html,body { height: 100%; margin: 0px; padding: 0px; }
 #full { height: 90%} 
 canvas { border: none; } 
 </style>
 <script>
 var blockWidth,
 gameStarted,
 bikes,
 stopGame,
 stopStartScreen,
 deadBikes,
 winner,
 blueScore,
 orangeScore,
 canvas,
 ctx; 
 
 function load(){
 init();
 initScores();
 fitToContainer();
 addBikes();
 window.addEventListener('keydown',keyPress,false);
 canvas.focus(); 
 stopStartScreen = setInterval(startScreen,100);
 }
 
 function initScores(){
 redScore = greenScore = blueScore = orangeScore = 0;
 }
 
 function startScreen(){
 if(!gameStarted) {
 clearCanvas();
 drawFirstBlock();
 drawPressStart();
 drawControls();
 }
 else {
 clearInterval(stopStartScreen);
 clearCanvas();
 stopGame = setInterval(game,100);
 }
 }
 
 function drawPressStart(){
 ctx.fillStyle = "black";
 ctx.font = "30px Arial";
 var startMessage = "Press any key to start";
 ctx.fillText(startMessage,Math.floor(canvas.width/2-ctx.measureText(startMessage).width/2),canvas.height/2 - 15);
 }
 
 function drawControls(){
 drawControl(bikes[0],10,bikes[0].y - 70);
 drawControl(bikes[1],10,bikes[1].y + 40);
 drawControl(bikes[2],canvas.width - 130,bikes[2].y - 70);
 drawControl(bikes[3],canvas.width - 130,bikes[3].y + 40);
 }
 
 function drawControl(aBike,x,y){
 ctx.font = "10px Arial";
 var buttons = aBike.buttons;
 for(var i=0;i<buttons.length;i++){
 ctx.fillText(buttons[i].direction+": "+buttons[i].button,x,y);
 y+=15;
 }
 }
 
 function scoreScreen(){
 if(!gameStarted) {
 clearCanvas();
 drawFirstBlock();
 drawScores();
 drawReset();
 }
 else {
 clearInterval(stopScoreScreen);
 clearCanvas();
 stopGame = setInterval(game,100);
 }
 }
 
 function drawReset(){
 var resetMessage = "Press R to restart game";
 ctx.font = "10px Arial";
 ctx.fillText(resetMessage,Math.floor(canvas.width/2-ctx.measureText(resetMessage).width/2),canvas.height/2 + 60);
 }
 
 function drawScores(){
 ctx.fillStyle = "black";
 ctx.font = "30px Arial";
 var winnerMessage = winner+" wins!";
 var scoreMessage = "Blue "+blueScore+" Orange "+orangeScore;
 ctx.fillText(winnerMessage,Math.floor(canvas.width/2-ctx.measureText(winnerMessage).width/2),canvas.height/2 - 30);
 ctx.fillText(scoreMessage,Math.floor(canvas.width/2-ctx.measureText(scoreMessage).width/2),canvas.height/2 + 30);
 }
 
 function init(){
 blockWidth = 10;
 bikes = [];
 deadBikes = 0;
 canvas = document.querySelector('canvas');
 ctx = canvas.getContext('2d');
 gameStarted = false;
 }
 
 function keyPress(e) { 
 e.preventDefault();
 gameStarted = true;
 var key = getKey(e);
 
 if(key == 'R') {
 clearInterval(stopScoreScreen);
 clearCanvas();
 load();
 return;
 }
 
 for(var i=0;i<bikes.length;i++){
 var aBike = bikes[i];
 var aBikeButtons = aBike.buttons;
 for(var j=0;j<aBikeButtons.length;j++){
 if(key==aBikeButtons[j].button){
 aBike.direction = aBikeButtons[j].direction;
 }
 }
 }
 }
 
 function getKey(e){
 switch (event.keyCode) {
 case 37:
 return "LEFT_ARROW";
 break;
 case 38:
 return "UP_ARROW";
 break;
 case 39:
 return "RIGHT_ARROW";
 break;
 case 40:
 return "DOWN_ARROW";
 break;
 default:
 return String.fromCharCode(e.which); 
 }
 }
 
 function fitToContainer(){
 canvas.style.width='100%';
 canvas.style.height='100%';
 canvas.width = canvas.offsetWidth;
 canvas.height = canvas.offsetHeight;
 }
 
 function addBikes(){
 var midHeightRoundTen = Math.floor(canvas.height/2) - (Math.floor(canvas.height/2)%10);
 var widthRoundTen = canvas.width - (canvas.width%10);
 
 var orangeA = new bike(0,midHeightRoundTen-10,"ORANGE",'W','S','D','A',"RIGHT");
 var orangeB = new bike(0,midHeightRoundTen+10,"ORANGE",'I','K','L','J',"RIGHT");
 var blueA = new bike(widthRoundTen-10,midHeightRoundTen-10,"BLUE",'G','B','N','V',"LEFT");
 var blueB = new bike(widthRoundTen-10,midHeightRoundTen+10,"BLUE",'UP_ARROW','DOWN_ARROW','RIGHT_ARROW','LEFT_ARROW',"LEFT");
 
 bikes.push(orangeA);
 bikes.push(orangeB);
 bikes.push(blueA);
 bikes.push(blueB);
 }
 
 function game(){ 
 if(deadBikes<3) {
 for(var i=0;i<bikes.length;i++){
 var aBike = bikes[i];
 if(aBike.alive){
 drawBlock(aBike);
 moveBlock(aBike);
 if(touchingBike(aBike) || touchingEdge(aBike)) killBike(aBike);
 }
 } 
 }
 else {
 clearInterval(stopGame);
 winner = getLivingBike();
 init();
 updateScores();
 addBikes();
 stopScoreScreen = setInterval(scoreScreen,100);
 }
 }
 
 function updateScores(){
 if(winner == "RED") redScore++;
 if(winner == "GREEN") greenScore++;
 if(winner == "BLUE") blueScore++;
 if(winner == "ORANGE") orangeScore++;
 }
 
 function getLivingBike(){
 for(var i=0;i<bikes.length;i++){
 var aBike = bikes[i];
 if(aBike.alive) return aBike.color;
 }
 }
 
 function drawFirstBlock(){
 for(var i=0;i<bikes.length;i++){
 var aBike = bikes[i];
 drawBlock(aBike);
 }
 }
 
 function killBike(aBike){
 aBike.alive = false;
 deadBikes++;
 }
 
 function touchingBike(aBike){
 var pos = aBike.positions.pop();
 for(var i=0;i<bikes.length;i++){
 var anotherBike = bikes[i];
 for(var j=0; j<anotherBike.positions.length; j++){
 if(pos.x==anotherBike.positions[j].x && pos.y==anotherBike.positions[j].y) return true;
 }
 }
 aBike.positions.push(pos);
 return false;
 }
 
 function touchingEdge(aBike){
 return (aBike.x+blockWidth > canvas.width || aBike.x < 0 || aBike.y+blockWidth > canvas.height || aBike.y < 0);
 }
 
 function moveBlock(aBike){
 if(aBike.direction=="DOWN") aBike.y+= blockWidth; 
 else if(aBike.direction=="UP") aBike.y-= blockWidth;
 else if(aBike.direction=="LEFT") aBike.x-= blockWidth; 
 else if(aBike.direction=="RIGHT") aBike.x+= blockWidth; 
 else alert("No direction");
 aBike.positions.push({x:aBike.x,y:aBike.y});
 }
 
 function drawBlock(aBike){
 ctx.fillStyle = aBike.color;
 ctx.fillRect(aBike.x,aBike.y,blockWidth,blockWidth); 
 }
 
 function clearCanvas(){
 ctx.clearRect(0,0,canvas.width,canvas.height);
 }
 
 function bike(x,y,color,up,down,right,left,direction) {
 this.x = x;
 this.y = y;
 this.color = color;
 this.positions = [];
 this.buttons = [{button:up,direction:"UP"},{button:down,direction:"DOWN"},{button:right,direction:"RIGHT"},{button:left,direction:"LEFT"}];
 this.direction = direction;
 this.alive = true;
 }
 </script>
 </head>
 <body onload="load()">
 <div id="full">
 <canvas tabindex="0"></canvas>
 </div>
 </body>
</html>

You can copy/paste the above code into Thimble to see the basic game working or click on the link below to play an improved version of the game.