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> <html>
<head> <head>
<meta charset=utf-8> <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"> <link href="snake.css" type="text/css" rel="stylesheet">
<script src="snake.js" type="application/javascript"></script> <script src="snake.js" type="application/javascript"></script>
<script src="snake-levels.js" type="application/javascript"></script>
</head> </head>
<body> <body>
<div class=corner></div><div class=corner></div><div class=corner></div><div class=corner></div> <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</label><input type=text id=growthFactor>
<label>Growth Increase</label><!-- <label>Growth Increase</label><!--
--><input type=text id=growthFactorIncrease> --><input type=text id=growthFactorIncrease>
</section><!--
--><section id=score>
<h4>Score</h4>
</section> </section>
</div> </div>
<div class=debug-aspect> <div class=debug-aspect>
@ -88,39 +93,31 @@
<script type="application/javascript"> <script type="application/javascript">
var canvas = document.getElementById("snakeCanvas"); var canvas = document.getElementById("snakeCanvas");
var scoreValue = document.querySelector("#score span.value");
canvas.width = canvas.clientWidth; canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight; canvas.height = canvas.clientHeight;
var loadLevel = function(event) { var loadLevel = function(ev) {
var levelEl = event.target; var levelEl = ev.target;
document.querySelector("#levelSelect li.selected").className = ""; document.querySelector("#levelSelect li.selected").className = "";
levelEl.className = "selected"; levelEl.className = "selected";
var levelNum = parseInt(levelEl.getAttribute("levelNum")); var levelNum = parseInt(levelEl.getAttribute("levelNum"));
Snake.initialize(levelData[levelNum]); }; Snake.initialize(levelData[levelNum]); };
var levelData = [ var nextLevel = function() {
// 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}, var updateScore = function(ev) {
// Level 3: North and South var curScore = parseInt(scoreValue.textContent);
{"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}, curScore += ev.detail.bodyLength;
// Level 4: Four Small Rooms curScore.textContent = curScore;
{"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 if (evDetail.score == Snake.currentLevel.targetScore)
{"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}, nextLevel(); };
// 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}, canvas.addEventListener('score', updateScore);
// 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}];
// Add listeners for each of the level list items. // Add listeners for each of the level list items.
var levelLis = document.querySelectorAll("#levelSelect li"); var levelLis = document.querySelectorAll("#levelSelect li");

View File

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

View File

@ -34,7 +34,7 @@ ul { list-style: none; }
height: 1rem; height: 1rem;
width: 1rem; width: 1rem;
&:nth-child(1) { &:nth-child(1) {
top: -0.5rem; left: -0.5rem; top: -0.5rem; left: -0.5rem;
border-width: 0.5rem 0 0 0.5rem; } border-width: 0.5rem 0 0 0.5rem; }
@ -55,7 +55,7 @@ body {
border: solid 0.5rem $accent1; border: solid 0.5rem $accent1;
background-color: $accent2; background-color: $accent2;
padding: 0.5rem; padding: 0.5rem;
position: relative; position: relative;
& > .corner { & > .corner {
width: 1.5rem; width: 1.5rem;
@ -67,17 +67,17 @@ body {
border: solid 0.5rem $accent3; border: solid 0.5rem $accent3;
background-color: $in; background-color: $in;
color: $fg; color: $fg;
position: relative; position: relative;
& > .corner { & > .corner {
background-color: $accent3; background-color: $accent3;
border-color: $accent2; } border-color: $accent2; }
header { header {
text-align: center; text-align: center;
& > h1 { padding-top: 0.5rem; } } & > h1 { padding-top: 0.5rem; } }
section { transition: 1s; } section { transition: 1s; }
section p, section ol, section ul { margin-left: 0.5rem; } section p, section ol, section ul { margin-left: 0.5rem; }
section#editorControls { display: none; } } section#editorControls { display: none; } }
@ -122,7 +122,7 @@ button {
.corner { .corner {
border: none; border: none;
background-color: $in; background-color: $in;
height: 0.25rem; height: 0.25rem;
width: 0.25rem; width: 0.25rem;
@ -144,19 +144,19 @@ button {
@include forAspect(wide) { @include forAspect(wide) {
body { body {
margin-top: 2rem; margin-top: 2rem;
height: 37rem; height: 37rem;
width: 73rem; width: 73rem;
#container { #container {
height: 35rem; height: 35rem;
width: 71rem; width: 71rem;
section { section {
display: inline-block; display: inline-block;
vertical-align: top; } vertical-align: top; }
section#gameContainer { section#gameContainer {
width: 30rem; width: 30rem;
margin-left: 20rem; margin-left: 20rem;
@ -167,28 +167,30 @@ button {
height: 30rem; } height: 30rem; }
section#description, section#levelSelect, section#controls, section#description, section#levelSelect, section#controls,
section#options { section#options, section#score {
position: absolute; position: absolute;
width: 19rem; } width: 19rem; }
section#description { left: 0.5rem; } section#description { left: 0.5rem; }
section#levelSelect { right: 0.5rem; }
section#controls { left: 0.5rem; top: 13.5rem; } section#controls { left: 0.5rem; top: 13.5rem; }
section#options { left: 0.5rem; top: 20rem; } 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; } } } section#levelSelect h5 { margin-top: 1rem; } } }
} }
@include forAspect(landscape) { @include forAspect(landscape) {
body { body {
width: 73rem; width: 73rem;
height: 37rem; height: 37rem;
margin-top: 2rem; margin-top: 2rem;
#container { #container {
height: 35rem; height: 35rem;
width: 71rem; } } width: 71rem; } }
} }
@ -207,9 +209,10 @@ button {
.debug-size, .debug-aspect { .debug-size, .debug-aspect {
font-family: "PT Mono" !important;
position: fixed; position: fixed;
background: #333; background: black;
color: #CCC; } color: white; }
.debug-aspect { .debug-aspect {
left: 0; left: 0;
@ -232,83 +235,3 @@ button {
@include forAspect(even) { .even-only { display: inline; } } @include forAspect(even) { .even-only { display: inline; } }
@include forAspect(portrait) { .portrait-only { display: inline; } } @include forAspect(portrait) { .portrait-only { display: inline; } }
@include forAspect(tall) { .tall-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; } }
*/