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]; }