var ctx = null;
var gameTime = 0, lastFrameTime = 0;
var currentSecond = 0, frameCount = 0, framesLastSecond = 0;
var showFramerate = false;
var offsetX = 0;
var offsetY = 0;
var mouseState = {
x : 0,
y : 0,
click : null
};
var gameState = {
screen : 'menu',
dir : 0,
moveDelay : 300,
lastMove : 0,
snake : [],
newBlock : null,
mapW : 14,
mapH : 14,
tileW : 20,
tileH : 20,
score : 0,
newBest : false,
bestScore : 0
};
function startGame()
{
gameTime = 0;
lastFrameTime = 0;
gameState.snake.length = 0;
gameState.dir = 0;
gameState.score = 0;
gameState.lastMove = 0;
gameState.screen = 'playing';
gameState.newBest = false;
gameState.snake.push([
Math.floor(gameState.mapW / 2),
Math.floor(gameState.mapH / 2)
]);
placeNewBlock();
}
function placeNewBlock()
{
do {
var x = Math.floor(Math.random() * gameState.mapW);
var y = Math.floor(Math.random() * gameState.mapH);
var onSnake = false;
for(var s in gameState.snake)
{
if(gameState.snake[s][0]==x &&
gameState.snake[s][1]==y)
{
onSnake = true;
break;
}
}
if(!onSnake)
{
gameState.newBlock = [x, y];
break;
}
} while(true);
}
function updateGame()
{
if(gameState.screen=='menu')
{
if(mouseState.click!=null)
{
if(mouseState.click[1] >= 150 &&
mouseState.click[1]<= 220)
{
startGame();
}
}
mouseState.click = null;
}
else if(gameState.screen=='playing')
{
if((gameTime - gameState.lastMove) < gameState.moveDelay)
{
return;
}
var tmp = gameState.snake[0];
var head = [tmp[0], tmp[1]];
var dir = gameState.dir;
if(dir==0 && head[1]==0) { gameOver(); }
else if(dir==2 && head[1]==(gameState.mapH-1)) { gameOver(); }
else if(dir==3 && head[0]==0) { gameOver(); }
else if(dir==1 && head[0]==(gameState.mapW-1)) { gameOver(); }
if(dir==0) { head[1]-= 1; }
else if(dir==2) { head[1]+= 1; }
else if(dir==1) { head[0]+= 1; }
else if(dir==3) { head[0]-= 1; }
for(var s in gameState.snake)
{
if(s==(gameState.snake.length-1)) { break; }
if(gameState.snake[s][0]==head[0] &&
gameState.snake[s][1]==head[1])
{
gameOver();
break;
}
}
if(gameState.screen=='menu') { return; }
gameState.snake.unshift(head);
gameState.lastMove = gameTime;
if(gameState.newBlock[0]==head[0] &&
gameState.newBlock[1]==head[1])
{
gameState.score+= 1;
placeNewBlock();
}
else { gameState.snake.pop(); }
}
}
function gameOver()
{
gameState.screen = 'menu';
if(gameState.score > gameState.bestScore)
{
gameState.bestScore
= gameState.score;
gameState.newBest = true;
}
}
window.onload = function()
{
ctx = document.getElementById('game').getContext('2d');
offsetX = Math.floor((document.getElementById('game').width -
(gameState.mapW * gameState.tileW)) / 2);
offsetY = Math.floor((document.getElementById('game').height -
(gameState.mapH * gameState.tileH)) / 2);
document.getElementById('game').addEventListener('click', function(e) {
var pos = realPos(e.pageX, e.pageY);
mouseState.click = pos;
});
document.getElementById('game').addEventListener('mousemove',
function(e) {
var pos = realPos(e.pageX, e.pageY);
mouseState.x = pos[0];
mouseState.y = pos[1];
});
window.addEventListener('keydown', function(e) {
if(e.keyCode==38) { gameState.dir = 0; }
else if(e.keyCode==39) { gameState.dir = 1; }
else if(e.keyCode==40) { gameState.dir = 2; }
else if(e.keyCode==37) { gameState.dir = 3; }
else if(e.keyCode==70) { showFramerate = !showFramerate; }
});
requestAnimationFrame(drawGame);
};
function drawMenu()
{
ctx.textAlign = "center";
ctx.font = "bold italic 20pt sans-serif";
ctx.fillStyle = ((mouseState.y>=150 && mouseState.y<=220) ?
"#0000aa" : "#000000");
ctx.fillText("Nowa Gra", 150, 180);
ctx.font = "italic 12pt sans-serif";
ctx.fillText("Najlepszy wynik: " + gameState.bestScore, 150, 210);
if(gameState.newBest)
{
ctx.fillText("Najlepszy wynik!", 150, 240);
}
if(gameState.score>0)
{
ctx.fillText("Wynik: " + gameState.score, 150, 260);
}
}
function drawPlaying()
{
ctx.strokeStyle = "#2c6b00";
ctx.fillStyle = "#2c6b00";
ctx.strokeRect(offsetX, offsetY,
(gameState.mapW * gameState.tileW),
(gameState.mapH * gameState.tileH));
for(var s in gameState.snake)
{
ctx.fillRect(offsetX + (gameState.snake[s][0] * gameState.tileW),
offsetY + (gameState.snake[s][1] * gameState.tileH),
gameState.tileW, gameState.tileH);
}
ctx.font = "12pt sans-serif";
ctx.textAlign = "right";
ctx.fillText("Wynik: " + gameState.score, 290, 20);
ctx.fillStyle = "#e00b00";
ctx.fillRect(offsetX + (gameState.newBlock[0] * gameState.tileW),
offsetY + (gameState.newBlock[1] * gameState.tileH),
gameState.tileW, gameState.tileH);
}
function drawGame()
{
if(ctx==null) { return; }
var currentFrameTime = Date.now();
var timeElapsed = currentFrameTime - lastFrameTime;
gameTime+= timeElapsed;
updateGame();
var sec = Math.floor(Date.now()/1000);
if(sec!=currentSecond)
{
currentSecond = sec;
framesLastSecond = frameCount;
frameCount = 1;
}
else { frameCount++; }
ctx.fillStyle = "#ddddee";
ctx.fillRect(0, 0, 300, 400);
if(showFramerate)
{
ctx.textAlign = "left";
ctx.font = "10pt sans-serif";
ctx.fillStyle = "#000000";
ctx.fillText("Frames: " + framesLastSecond, 5, 15);
}
if(gameState.screen=='menu') { drawMenu(); }
else if(gameState.screen=='playing') { drawPlaying(); }
lastFrameTime = currentFrameTime;
requestAnimationFrame(drawGame);
}
function realPos(x, y)
{
var p = document.getElementById('game');
do {
x-= p.offsetLeft;
y-= p.offsetTop;
p = p.offsetParent;
} while(p!=null);
return [x, y];
}