Added difficulty option, score-keeping, and better levels.

This commit is contained in:
Jonathan Bernard 2014-12-14 08:51:19 -06:00
parent cb1db47704
commit 218e866079
4 changed files with 365 additions and 163 deletions

278
snake/snake-levels.js Normal file
View File

@ -0,0 +1,278 @@
(function(){
var small = { "boardSize": "standard", levels: [] };
var mazes = { "boardSize": "standard", levels: [] };
var large = { "boardSize": "large", levels: [] };
var nibbles = { "boardSize": "large", levels: [] };
// Level 1: Hello Snake!
small.push({
"name": "Hello Snake!", "rows":10, "cols":10,
"easy": { "fps": 2, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps": 4, "targetScore": 7, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps": 8, "targetScore": 8, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps": 12, "targetScore": 10, "growthFactor": 2, "growthFactorIncrease": 1},
"board":[
1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,2,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1]});
// Level 2: Room to Grow
small.push({
"name": "Room to Grow", "rows":16, "cols":16,
"easy": { "fps":3, "targetScore": 7, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps":3, "targetScore": 7, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps":3, "targetScore": 7, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps":3, "targetScore": 7, "growthFactor": 2, "growthFactorIncrease": 1},
"board":[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]});
// Level 3: North and South
small.push({
"name": "North and South", "rows":15, "cols":15,
"easy": { "fps":3, "targetScore": 6, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps":3, "targetScore": 6, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps":3, "targetScore": 6, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps":3, "targetScore": 6, "growthFactor": 2, "growthFactorIncrease": 1},
"board":[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,2,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,1,1,1,1,1,1,1,1,1,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]});
// Level 4: Four Small Rooms
small.push({
"name": "Four Small Rooms","rows":15,"cols":15,
"easy": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"board": [
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,2,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]});
// Level 5: Polka Dots
small.push({
"name": "Polka Dots" ,"rows":15,"cols":15,
"easy": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"board":[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,1,0,0,0,1,0,0,0,1,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,
1,0,0,0,0,2,0,0,0,0,0,0,0,0,1,
1,0,0,1,0,0,0,1,0,0,0,1,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,1,0,3,0,1,0,0,0,1,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]});
// Level 6: Toaster Face
small.push({
"name": "Toaster Face","rows":15,"cols":15,
"easy": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"board":[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,0,0,0,0,0,1,0,0,0,0,0,1,1,
1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,1,0,0,1,0,0,0,0,0,1,0,0,1,1,
1,0,0,1,1,1,1,1,1,1,1,1,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,1,0,0,1,2,0,0,0,0,1,0,0,1,1,
1,0,0,1,1,1,0,0,0,1,1,1,0,0,1,
1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,
1,1,0,0,0,0,0,1,0,0,0,0,0,1,1,
1,0,0,1,0,1,1,1,1,1,0,1,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]});
// Level 7: Wierd Walls
small.push({
"name": "Wierd Walls","rows":15,"cols":15,
"easy": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"board":[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,2,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,1,0,0,0,1,1,1,1,1,1,1,0,1,
1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,
1,0,1,0,1,0,1,0,0,0,1,1,1,0,1,
1,0,1,0,1,0,1,0,1,0,0,0,0,0,1,
1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,
1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,
1,0,0,0,0,0,1,0,1,0,1,0,1,0,1,
1,0,1,1,1,0,0,0,1,0,1,0,1,0,1,
1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,
1,0,1,1,1,1,1,1,1,0,0,0,1,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]});
// Level 8: Feast and Famine
small.push({
"name": "Feast and Famine","rows":15,"cols":15,
"easy": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"board":[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,2,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,0,3,0,3,0,3,1,
1,0,0,0,0,0,0,1,0,0,3,0,3,0,1,
1,0,0,0,0,0,0,1,0,3,0,3,0,3,1,
1,0,0,0,0,0,0,1,0,0,3,0,3,0,1,
1,0,0,0,0,0,0,0,0,3,0,3,0,3,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]});
// Level 1: Maze 1
mazes.push({
"name": "Maze 1","rows":15,"cols":15,
"easy": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"board":[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,
1,0,1,1,1,1,0,1,0,1,1,0,1,0,1,
1,0,0,0,0,0,0,1,0,0,0,0,1,0,1,
1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,
1,0,1,2,0,0,0,0,0,0,0,0,1,0,1,
1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,
1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,
1,0,1,1,0,1,0,1,1,0,0,0,1,0,1,
1,0,0,0,0,0,0,1,1,0,1,0,0,0,1,
1,0,1,1,1,1,0,0,0,0,0,0,0,1,1,
1,0,0,0,0,0,0,1,1,1,1,1,0,0,1,
1,0,1,1,1,0,1,1,0,0,0,1,1,0,1,
1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]});
// Level 2: Spiral
mazes.push({
"name": "Spiral","rows":15,"cols":15,
"easy": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"board":[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,
1,0,1,1,1,1,1,1,1,1,0,1,0,0,1,
1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,
1,0,1,0,1,1,1,1,0,1,0,1,0,0,1,
1,0,1,0,1,3,0,1,0,1,0,1,0,0,1,
1,0,1,0,1,0,0,0,0,1,0,1,0,0,1,
1,0,1,0,1,0,0,0,0,0,0,1,0,0,1,
1,0,1,0,1,1,1,1,1,1,1,1,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]});
// Level 3: Maze 2
mazes.push({
"name": "Maze 2","rows":17,"cols":17,
"easy": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"medium": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"hard": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"insane": { "fps":3, "targetScore": 5, "growthFactor": 2, "growthFactorIncrease": 1},
"board":[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,
1,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,
1,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,
1,0,1,0,0,1,1,0,1,1,1,0,1,1,1,0,1,
1,0,1,1,0,1,1,0,0,0,1,0,0,1,0,0,1,
1,0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,1,
1,0,0,0,1,0,0,1,1,1,0,0,0,1,0,0,1,
1,0,1,0,0,1,0,0,0,0,1,1,1,1,1,0,1,
1,0,0,1,0,0,0,1,1,0,1,0,0,0,0,0,1,
1,1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,
1,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,1,
1,0,1,1,1,1,0,0,0,0,1,1,1,1,1,0,1,
1,0,1,0,0,0,1,1,1,1,0,0,0,1,0,0,1,
1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]}
]);
window.SnakeLevels = {
"Small Rooms": small,
"Large Rooms": large,
"Classic Nibbles": nibbles,
"Mazes": mazes }
})();

View File

@ -2,9 +2,10 @@
<html>
<head>
<meta charset=utf-8>
<link href='http://fonts.googleapis.com/css?family=Press+Start+2P' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Press+Start+2P|PT+Mono' rel='stylesheet' type='text/css'>
<link href="snake.css" type="text/css" rel="stylesheet">
<script src="snake.js" type="application/javascript"></script>
<script src="snake-levels.js" type="application/javascript"></script>
</head>
<body>
<div class=corner></div><div class=corner></div><div class=corner></div><div class=corner></div>
@ -70,6 +71,10 @@
<label>Growth</label><input type=text id=growthFactor>
<label>Growth Increase</label><!--
--><input type=text id=growthFactorIncrease>
</section><!--
--><section id=score>
<h4>Score</h4>
</section>
</div>
<div class=debug-aspect>
@ -88,39 +93,31 @@
<script type="application/javascript">
var canvas = document.getElementById("snakeCanvas");
var scoreValue = document.querySelector("#score span.value");
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
var loadLevel = function(event) {
var levelEl = event.target;
var loadLevel = function(ev) {
var levelEl = ev.target;
document.querySelector("#levelSelect li.selected").className = "";
levelEl.className = "selected";
var levelNum = parseInt(levelEl.getAttribute("levelNum"));
Snake.initialize(levelData[levelNum]); };
var levelData = [
// Level 1: Hello Snake!
{"board":[1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,2,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1],"rows":10,"cols":10,"fps":2},
// Level 2: Room to Grow
{"board":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"rows":16,"cols":16,"fps":3},
// Level 3: North and South
{"board":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"rows":15,"cols":15,"fps":3},
// Level 4: Four Small Rooms
{"board":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"rows":15,"cols":15,"fps":3},
// Level 5: Polka Dots
{"board":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,3,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"rows":15,"cols":15,"fps":3},
// Level 6: Toaster Face
{"board":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,0,1,0,0,0,1,0,1,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,1,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,0,0,1,2,0,0,0,0,1,0,0,1,1,1,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,0,1,1,1,1,1,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"rows":15,"cols":15,"fps":3},
// Level 7: Wierd Walls
{"board":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,0,0,0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1,0,0,0,1,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1,0,1,1,1,1,1,1,1,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"rows":15,"cols":15,"fps":3},
// Level 8: Maze 1
{"board":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,0,0,0,0,1,0,0,0,0,1,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1,2,0,0,0,0,0,0,0,0,1,0,1,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,1,0,1,1,0,1,0,1,1,0,0,0,1,0,1,1,0,0,0,0,0,0,1,1,0,1,0,0,0,1,1,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"rows":15,"cols":15,"fps":3},
// Level 9: Spiral
{"board":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,0,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,0,1,1,1,1,0,1,0,1,0,0,1,1,0,1,0,1,3,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,0,0,0,1,0,1,0,0,1,1,0,1,0,1,0,0,0,0,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"rows":15,"cols":15,"fps":3},
// Level 10: Feast and Famine
{"board":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,2,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,3,0,3,0,3,1,1,0,0,0,0,0,0,1,0,0,3,0,3,0,1,1,0,0,0,0,0,0,1,0,3,0,3,0,3,1,1,0,0,0,0,0,0,1,0,0,3,0,3,0,1,1,0,0,0,0,0,0,0,0,3,0,3,0,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"rows":15,"cols":15,"fps":3},
// Level 11: Maze 2
{"board":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,1,0,1,0,0,1,1,0,1,1,1,0,1,1,1,0,1,1,0,1,1,0,1,1,0,0,0,1,0,0,1,0,0,1,1,0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,1,1,0,0,0,1,0,0,1,1,1,0,0,0,1,0,0,1,1,0,1,0,0,1,0,0,0,0,1,1,1,1,1,0,1,1,0,0,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,1,1,1,0,0,0,0,1,1,1,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,0,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"rows":17,"cols":17,"fps":3}];
var nextLevel = function() {
};
var updateScore = function(ev) {
var curScore = parseInt(scoreValue.textContent);
curScore += ev.detail.bodyLength;
curScore.textContent = curScore;
if (evDetail.score == Snake.currentLevel.targetScore)
nextLevel(); };
canvas.addEventListener('score', updateScore);
// Add listeners for each of the level list items.
var levelLis = document.querySelectorAll("#levelSelect li");

View File

@ -18,7 +18,6 @@
var startBoard;
var startGrowthFactor = 2; // When we eat food, how many turns do we grow?
var startGFIncrease=0; // When we eat, how much should the GF increase?
var targetScore = 0; // How many pieces of food must we eat to win?
var body = new Array(); // Queue of body indices.
var headCur; // Index of the head's current position.
@ -26,6 +25,7 @@
var foodEaten = false; // Did we eat food this turn?
var growthFactor // When we eat food, how many turns do we grow?
var growthCounter; // How many remaining turns should we grow?
var fps; // How fast should the game run (frames/sec)?
var score = 0; // How many pieces of food have we eaten?
// HTML Elements
@ -57,6 +57,8 @@
if (!options) options = {};
S.currentLevel = options;
// Store our own copy of the canvas and get a 2D graphics context.
if (options.canvas) canvas = options.canvas;
else canvas = document.getElementsByTagName("canvas")[0];
@ -85,37 +87,30 @@
// Figure out how big each game tile is.
tileWidth = Math.ceil(canvas.width / COLS);
tileHeight = Math.ceil(canvas.height / ROWS);
console.log("canvas.width: " + canvas.width);
console.log("canvas.height: " + canvas.height);
console.log("ROWS: " + ROWS);
console.log("COLS: " + COLS);
console.log("Tile Width: " + tileWidth);
console.log("Tile Height: " + tileHeight);
// Mark the player as dead. This is primarily for the case where a
// player re-initializes the board during a game in progress. It
// causes any scheduled logic to quit without affecting out game state.
// causes any scheduled logic to quit without affecting out game state.
dead = true;
// Read in the growth factor and increase.
if (options.growthFactor) startGrowthFactor = options.growthFactor;
else startGrowthFactor = 2;
// Read in the difficulty and difficulty-related data.
if (!options.difficulty) options.difficulty = "easy";
var difVals = (options[difficulty] ? options[difficulty] : {});
if (options.growthFactorIncrease)
startGFIncrease = options.growthFactorIncrease;
else startGFIncrease = 1;
startGrowthFactor = difVals.growthFactor ? difVals.growthFactor : 2;
startGFIncrease = difVals.growthFactorIncrease ?
difVals.growthFactorIncrease : 1;
fps = difVals.fps ? difVals.fps : 3;
// Check for a target score to consider this level "won."
if (options.targetScore) targetScore = option.targetScore;
else options.targetScore = 0; // 0 = no target, play indefinitely.
// Check to see if they want to use the editor or the game.
editor = Boolean(options.editor);
// Clear the canvas.
g.fillStyle = "white";
g.fillRect(0, 0, canvas.width, canvas.height);
// They want the game
if (!editor) {
canvas.addEventListener('keydown', handleGameKey);
@ -124,7 +119,7 @@
g.fillStyle = "black";
g.fillText("Press Space to begin.", 50, Math.floor(canvas.height/2), canvas.width - 100);
if (options.fps) skipTicks = Math.ceil(1000 / options.fps);
skipTicks = Math.ceil(1000 / fps);
else skipTicks = 150; }
// They want the editor
@ -134,9 +129,9 @@
editorControls = document.getElementById("editorControls")
editorDataTextarea = document.querySelector("#editorControls textarea");
startEditor(); }
canvas.focus(); }
function startGame() {
@ -167,7 +162,7 @@
// Draw the board
paintBoard();
gameLoop(); }
function startEditor() {
@ -227,15 +222,22 @@
// happens via not moving the tail.
if (board[headCur] == FOOD) {
foodEaten = true;
score+=1;
growthCounter += growthFactor;
growthFactor += growthFactorIncrease; }
growthFactor += growthFactorIncrease;
// Alert anyone listening to us.
var scoreEvent = new CustomEvent('score',
{detail: {'score': score, 'bodyLength': body.length}});
canvas.dispatchEvent(scoreEvent); }
// 4. Remove the tail.
if (growthCounter == 0) {
var tailIdx = body.shift();
board[tailIdx] = SPACE
paintIdx(tailIdx); }
else growthCounter -= 1;
else growthCounter -= 1;
// 5. Detect wall and snake collisions
if (board[headCur] == WALL || board[headCur] == SNAKE) {
@ -245,7 +247,7 @@
body.push(headCur);
board[headCur] = SNAKE;
paintIdx(headCur);
// 7. Create more food if needed.
if (foodEaten) {
var foodLoc = randomEmptySpace();
@ -267,7 +269,7 @@
dead = true;
//g.fillStyle = "white";
//g.fillRect(0, 0, canvas.width, canvas.height);
g.font = "24px sans-serif";
g.fillStyle = "red";
g.fillText("Press Space to retry.", 50, Math.floor(canvas.height/2), canvas.width - 100); }
@ -294,7 +296,7 @@
// Queue directions in the command queue
else if ((key > 36) && (key < 41)) cmdQueue.push(key);
// Anything else we don't care about.
else dontCare = true;
@ -342,7 +344,7 @@
g.strokeRect(
(cursorIdx % COLS) * tileWidth,
Math.floor(cursorIdx / COLS) * tileHeight,
tileWidth, tileHeight);
tileWidth, tileHeight);
// Consume events we care about and prevent them from bubbling up.
if (!dontCare) ke.preventDefault(); }
@ -360,11 +362,11 @@
growthFactor: startGrowthFactor,
growthFactorIncrease: startGFIncrease,
targetScore: targetScore,
fps: Math.ceil(1000 / skipTicks)}); }
fps: fps)}); }
// Load the editor data as a JSON string from the textarea.
function loadEditorLevelData() { }
// Draw the entire board.
function paintBoard() {
for (i = 0; i < board.length; i++) { paintIdx(i); } }
@ -385,7 +387,7 @@
(idx % COLS) * tileWidth,
Math.floor(idx / COLS) * tileHeight,
tileWidth, tileHeight); }
function paintIdx(idx) {
if (board[idx] == WALL) g.fillStyle = "black";
else if (board[idx] == FOOD) g.fillStyle = "green";
@ -398,5 +400,7 @@
tileWidth, tileHeight); }
S.initialize = initialize;
S.pause = function() { pause = true; }
S.currentLevel = {};
})();

View File

@ -34,7 +34,7 @@ ul { list-style: none; }
height: 1rem;
width: 1rem;
&:nth-child(1) {
top: -0.5rem; left: -0.5rem;
border-width: 0.5rem 0 0 0.5rem; }
@ -55,7 +55,7 @@ body {
border: solid 0.5rem $accent1;
background-color: $accent2;
padding: 0.5rem;
position: relative;
position: relative;
& > .corner {
width: 1.5rem;
@ -67,17 +67,17 @@ body {
border: solid 0.5rem $accent3;
background-color: $in;
color: $fg;
position: relative;
position: relative;
& > .corner {
background-color: $accent3;
border-color: $accent2; }
header {
text-align: center;
& > h1 { padding-top: 0.5rem; } }
section { transition: 1s; }
section p, section ol, section ul { margin-left: 0.5rem; }
section#editorControls { display: none; } }
@ -122,7 +122,7 @@ button {
.corner {
border: none;
background-color: $in;
height: 0.25rem;
width: 0.25rem;
@ -144,19 +144,19 @@ button {
@include forAspect(wide) {
body {
margin-top: 2rem;
margin-top: 2rem;
height: 37rem;
width: 73rem;
#container {
#container {
height: 35rem;
width: 71rem;
section {
display: inline-block;
vertical-align: top; }
section#gameContainer {
width: 30rem;
margin-left: 20rem;
@ -167,28 +167,30 @@ button {
height: 30rem; }
section#description, section#levelSelect, section#controls,
section#options {
section#options, section#score {
position: absolute;
width: 19rem; }
section#description { left: 0.5rem; }
section#levelSelect { right: 0.5rem; }
section#controls { left: 0.5rem; top: 13.5rem; }
section#options { left: 0.5rem; top: 20rem; }
section#levelSelect { height: 29rem; }
section#levelSelect { right: 0.5rem; top: 8rem; }
section#score { right: 0.5rem; }
section#levelSelect { height: 25rem; }
section#levelSelect h5 { margin-top: 1rem; } } }
}
@include forAspect(landscape) {
body {
width: 73rem;
height: 37rem;
margin-top: 2rem;
#container {
margin-top: 2rem;
#container {
height: 35rem;
width: 71rem; } }
}
@ -207,9 +209,10 @@ button {
.debug-size, .debug-aspect {
font-family: "PT Mono" !important;
position: fixed;
background: #333;
color: #CCC; }
background: black;
color: white; }
.debug-aspect {
left: 0;
@ -232,83 +235,3 @@ button {
@include forAspect(even) { .even-only { display: inline; } }
@include forAspect(portrait) { .portrait-only { display: inline; } }
@include forAspect(tall) { .tall-only { display: inline; } }
/* @include forSize(medium) {
html { font-size: 80%; }
body {
height: 36rem;
width: 62rem;
margin-top: 2rem;
#container {
height: 34rem;
width: 60rem; } } }
@include forSize(large) {
body {
height: 36rem;
width: 62rem;
margin-top: 2rem;
#container {
height: 34rem;
width: 60rem; } } }
@include forSize(ultraLarge) {
body {
height: 42rem;
width: 72rem;
margin-top: 4rem;
#container {
height: 40rem;
width: 70rem; } } }
*/
/*
html {
background-color: white;
color: #354650;
font-family: sans-serif;
}
body {
padding: 1em;
}
header {
background-color: #1E4119;
color: #FFFB51;
padding: 0.5rem 1rem;
font-family: "Exo 2";
font-weight: 900;
position: absolute;
left: 0; right: 0; top: 0;
}
header > h1 { font-size: 300%; }
canvas { border: solid thin gray; }
section {
display: inline-block;
margin: 0.5rem;
position: relative; }
section:first-of-type { margin-top: 6rem; }
label {
display: inline-block;
width: 12rem; }
input[type=button] {
position: absolute;
right: 0; }
#editorControls { display: none; }
@media (max-width: 600px) {
header { text-align: center; } }
*/