/**
* Super Tapper JavaScript
*
* @author David Miles
* @created 11/27/2010
* @revised 11/28/2010
*/
/**
* Console fix
*/
if(console === undefined){
var console = {log: function(msg){ alert("Console: " + msg); }};
}
/**
* Page load event
*/
window.onload = function(){
document.getElementById("game").appendChild(new SuperTapper.Game());
};
// Namespace SuperTapper {{{
var SuperTapper = {};
/**
* SuperTapper Game class
*/
SuperTapper.Game = function(){
// Difficulties
this.difficulty = null;
this.difficulties = ["Easy", "Hard", "Disco"];
// Screens
this.title = null;
this.game = null;
// Game variables
this.gameTimer = null;
this.gameInterval = null;
this.gameEnemy = null;
this.gamePlayer = null;
this.gameScore = null;
this.score = null;
// Disco moe
this.discoTImer = null;
// Initialize title screen
this.initTitle();
this.screen = document.createElement("div");
this.screen.appendChild(this.title);
return this.screen;
};
SuperTapper.Game.prototype.initTitle = function(){
// Keep a self reference for closures
var self = this;
// Title container
this.title = document.createElement("div");
this.title.setAttribute("id", "gameTitle");
this.title.setAttribute("class", "round");
// Header
var header = document.createElement("h1");
// @TODO: Add player name for high scores
// Difficulties
var difficulty = document.createElement("div");
difficulty.setAttribute("id", "gameDifficulty");
for(var i in this.difficulties){
// Container
var div = document.createElement("div");
div.setAttribute("class", "difficulty");
// Radio button
var radio = document.createElement("input");
radio.setAttribute("id", "difficulty" + this.difficulties[i]);
radio.setAttribute("type", "radio");
radio.setAttribute("name", "difficulty");
radio.setAttribute("value", i);
radio.onclick = function(){
self.difficulty = parseInt(this.value);
};
// Label
var label = document.createElement("label");
label.setAttribute("for", "difficulty" + this.difficulties[i]);
label.innerText = this.difficulties[i];
// Append
div.appendChild(radio);
div.appendChild(label);
difficulty.appendChild(div);
}
// Start button
var start = document.createElement("a");
start.setAttribute("id", "startGame");
start.setAttribute("href", "#");
// Start button onClick event
start.onclick = function(){
if(self.difficulty !== null){
self.start();
}else{
alert("You must select a difficulty!");
}
return false;
};
// Append all children to the title
this.title.appendChild(header);
this.title.appendChild(difficulty);
this.title.appendChild(start);
};
SuperTapper.Game.prototype.initGame = function(){
// Keep a self reference for closures
var self = this;
// Game container
this.game = document.createElement("div");
this.game.setAttribute("id", "gamePlaying");
this.game.setAttribute("class", "round");
// Game objects
this.gamePlayer = new SuperTapper.Player();
this.gameEnemy = new SuperTapper.Enemy();
this.gameScore = document.createElement("div");
this.gameScore.setAttribute("id", "score");
this.score = new SuperTapper.Score(this.difficulty);
// Game events
this.game.onclick = function(){
self.score.miss();
// We have this call in only this.game.onclick because this event will always
// fire when clicking on any game objects.
self.move();
}
this.gamePlayer.onclick = function(){
// Force focus onto the game board (otherwise cheating is possible in IE)
self.game.focus();
// Register a hit
self.score.hit(this);
// Compensate for score loss
self.score.compensate();
return false;
}
this.gameEnemy.onclick = function(){
// Force focus onto the game board (otherwise cheating is possible in IE)
self.game.focus();
// Register a hit
self.score.hit(this);
// Compensate for score loss
self.score.compensate();
return false;
}
// Stop button
var stop = document.createElement("a");
stop.setAttribute("id", "stopButton");
stop.setAttribute("href", "#");
stop.onclick = function(){
self.stop();
};
// Append all elements
this.game.appendChild(this.gameScore);
this.game.appendChild(this.gamePlayer);
this.game.appendChild(this.gameEnemy);
this.game.appendChild(stop);
// Game movement interval
switch(this.difficulty){
case 0:
this.gameInterval = 1500;
break;
case 1:
this.gameInterval = 1000;
break;
case 2:
this.gameInterval = 750;
// Start disco mode timer
this.discoTimer = setInterval(function(){
self.game.style.backgroundColor = "rgb(" + Math.rand(255) + ", " + Math.rand(255) + ", " + Math.rand(255) + ")";
}, 150);
break;
}
// We have to use a separate event handler because self.move() loses the reference
// to the score object for some reason. So, in this event handler we just call
// self.move() to move the pieces and then update the score ourself
var gameTimerTick = function(){
self.move();
clearTimeout(self.gameTimer);
self.gameTimer = setTimeout(arguments.callee, self.gameInterval);
};
// Start game timer
this.gameTimer = setTimeout(gameTimerTick, this.gameInterval);
};
SuperTapper.Game.prototype.move = function(){
var g = this.game;
var p = this.gamePlayer;
var e = this.gameEnemy;
// Move player
p.style.top = Math.rand(g.offsetHeight - p.offsetHeight) + "px";
p.style.left = Math.rand(g.offsetWidth - p.offsetWidth) + "px";
// Move enemy
e.style.top = Math.rand(g.offsetHeight - e.offsetHeight) + "px";
e.style.left = Math.rand(g.offsetWidth - e.offsetWidth) + "px";
// Update score
this.updateScore();
};
SuperTapper.Game.prototype.updateScore = function(){
this.gameScore.innerText = this.score.getScore();
};
SuperTapper.Game.prototype.start = function(){
this.initGame();
this.screen.removeChild(this.title);
this.screen.appendChild(this.game);
this.move();
};
SuperTapper.Game.prototype.stop = function(){
// Make sure they want to end the game
if(!confirm("Are you sure you want to end the game?")){
// Compensate for score loss
this.score.compensate();
return false;
}
clearTimeout(this.gameTimer);
if(this.discoTimer !== null){
clearInterval(this.discoTimer);
}
this.screen.removeChild(this.game);
this.screen.appendChild(this.title);
alert("You finished with a score of " + this.score.getScore() + "!");
};
/**
* SuperTapper Score class
*/
SuperTapper.Score = function(difficulty){
this.difficulty = difficulty;
this.enemyHits = 0;
this.playerHits = 0;
this.misses = 0;
};
SuperTapper.Score.prototype.hit = function(e){
switch(e.id){
case "gameEnemy":
this.enemyHits++;
break;
case "gamePlayer":
this.playerHits++;
break;
}
};
SuperTapper.Score.prototype.miss = function(){
this.misses++;
};
SuperTapper.Score.prototype.compensate = function(){
this.misses--;
};
SuperTapper.Score.prototype.getScore = function(){
var d = this.difficulty + 1
, e = this.enemyHits
, p = this.playerHits
, m = this.misses;
return ((e * d) - (p * d) - m) * (10 * d);
}
/**
* SuperTapper Enemy class
*/
SuperTapper.Enemy = function(){
var enemy = document.createElement("a");
enemy.setAttribute("id", "gameEnemy");
enemy.setAttribute("class", "gameObject");
enemy.setAttribute("href", "#");
return enemy;
};
/**
* SuperTapper Player class
*/
SuperTapper.Player = function(){
var player = document.createElement("a");
player.setAttribute("id", "gamePlayer");
player.setAttribute("class", "gameObject");
player.setAttribute("href", "#");
return player;
};
// }}}
/**
* Generate a random number in a maximum range
*
* @param int max Maximum number to be returned
* @return int
*/
Math.rand = function(max){
return Math.floor(Math.random() * max);
}