diff --git a/cat.html b/cat.html index d5a35e2..120eaf6 100644 --- a/cat.html +++ b/cat.html @@ -1,11 +1,16 @@ + + - + +ooooo + + @@ -14,7 +19,7 @@ canvas { var myGamePiece; var things = []; -var myScore; +var score = 0; var curpath = []; var pathdir = -1; @@ -24,10 +29,24 @@ var MAXDIRS = 4; var DIRXMOD = [ 0, 1, 0, -1 ]; var DIRYMOD = [ -1, 0, 1, 0 ]; +var SCREENW = 480; +var SCREENH = 640; + var GRAVITY = 0.5; var GRIDSIZE = 80; var THINGSIZE = 64; +var TEXTSIZE = 36; // in points +var TEXTSPEED = 0.5; +var TEXTFADESPEED = 0.05; +var TEXTTIME = 35; + +var PARADESPEED=16; + +var EXPLODETICKS=20; +var EXPLODEGAIN= (THINGSIZE*2) / EXPLODETICKS; +var EXPLODEFADESPEED = 1.0 / EXPLODETICKS; + var LINEWIDTH=2; var CROSSWIDTH=2; @@ -36,13 +55,28 @@ var GRIDH = 5; var PARADELENGTH = 3; +var BOARDX = (SCREENW - (GRIDW * GRIDSIZE)) / 2; +var BOARDY = 64; + +var overdesc = ""; + +var image = new Array(); + +function loadimage(name, filename) { + image[name] = new Image(); + image[name].src = filename; +} + function getgridthing(gridx, gridy) { var i; if (things == undefined) return null; + // only include non-animating things for (i = 0; i < things.length; i += 1) { if ((things[i].gridx == gridx) && (things[i].gridy == gridy)) { - return things[i]; + if (!things[i].isanimating()) { + return things[i]; + } } } @@ -274,6 +308,13 @@ function getdir(thing1, thing2) { } function startGame() { + + loadimage('cat', 'images/cat.png'); + loadimage('catfull', 'images/catfull.png'); + loadimage('catscared', 'images/catscared.png'); + loadimage('llama', 'images/alpaca.png'); + loadimage('cheese', 'images/cheese.png'); + game.start(); } @@ -385,18 +426,26 @@ var game = { canvas : document.createElement("canvas"), start : function() { var x,y; - this.canvas.width = 480; - this.canvas.height = 640; + this.canvas.width = SCREENW; + this.canvas.height = SCREENH; + this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.frameNo = 0; this.interval = setInterval(updateGameArea, 20); - this.canvas.addEventListener('click', this.handleclick, false); +// this.canvas.addEventListener('click', this.handleclick, false); this.canvas.addEventListener('mousedown', this.handlemousedown, false); this.canvas.addEventListener('mouseup', this.handlemouseup, false); + this.canvas.addEventListener('mouseout', this.handlemouseup, false); this.canvas.addEventListener('mousemove', this.handlemousemove, false); + this.canvas.addEventListener('touchstart', this.handlemousedown, false); + this.canvas.addEventListener('touchend', this.handlemouseup, false); + this.canvas.addEventListener('touchcancel', this.handlemouseup, false); + this.canvas.addEventListener('touchleave', this.handlemouseup, false); + this.canvas.addEventListener('touchmove', this.handlemousemove, false); + // populate inital things for (y = 0; y < GRIDH; y++) { for (x = 0; x < GRIDW; x++) { @@ -410,13 +459,41 @@ var game = { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); }, - draw : function() { + drawtop : function() { + var texttodraw = overdesc; + + // clear + this.context.clearRect(0, 0, this.canvas.width-1, BOARDY-1); + + // show score + this.context.font = "16pt Futura"; + this.context.textAlign = "left"; + this.context.textBaseline = "top"; + this.context.fillStyle = "white"; + this.context.fillText("Score: " + score, 16, 16); + + // show current object + if ((curpath != undefined) && (curpath.length >= 1)) { + var lastone = curpath[curpath.length - 1]; + texttodraw = lastone.getdesc(); + } + + if (texttodraw != "") { + this.context.font = "16pt Futura"; + this.context.textAlign = "right"; + this.context.textBaseline = "top"; + this.context.fillStyle = "#aaaaaa"; // grey + this.context.fillText(texttodraw, SCREENW-16, 16); + } + }, + + drawgrid : function() { this.context.strokeStyle = "black"; this.context.beginPath(); // draw grid for (y = 0; y < GRIDH*GRIDSIZE; y += GRIDSIZE) { for (x = 0; x < GRIDW*GRIDSIZE; x += GRIDSIZE) { - this.context.rect(x, y, GRIDSIZE-1, GRIDSIZE-1); + this.context.rect(BOARDX + x, BOARDY + y, GRIDSIZE-1, GRIDSIZE-1); } } @@ -440,11 +517,11 @@ var game = { ctx.strokeStyle = col; ctx.lineWidth = LINEWIDTH; - // draw line + // draw line to show current path ctx.beginPath(); - ctx.moveTo(curpath[0].x + THINGSIZE/2, curpath[0].y + THINGSIZE/2); + ctx.moveTo(BOARDX + curpath[0].x + THINGSIZE/2, BOARDY + curpath[0].y + THINGSIZE/2); for (i = 1; i < curpath.length; i++) { - ctx.lineTo(curpath[i].x + THINGSIZE/2, curpath[i].y + THINGSIZE/2); + ctx.lineTo(BOARDX + curpath[i].x + THINGSIZE/2, BOARDY + curpath[i].y + THINGSIZE/2); } ctx.stroke(); @@ -455,9 +532,9 @@ var game = { x2 = curpath[curpath.length-1].x + (THINGSIZE/2); y2 = curpath[curpath.length-1].y + (THINGSIZE/2); - drawarrowhead(ctx, x1, y1, x2, y2, col); + drawarrowhead(ctx, BOARDX + x1, BOARDY + y1, BOARDX + x2, BOARDY + y2, col); } - + }, /* @@ -474,6 +551,12 @@ var game = { */ handlemousedown : function(event) { + var adjustx = event.pageX - BOARDX; + var adjusty = event.pageY - BOARDY; + + // ignore multi-touch + if ((curpath != undefined) && curpath.length >= 1) return; + // make sure nothing is moving if (thingsmoving()) return; @@ -481,20 +564,31 @@ var game = { clearpath(); // did you click on an object? - var onthing = getthingxy(event.pageX,event.pageY); - if (onthing && canstartpath(onthing)) { -console.log("Initial click on " + onthing.name); - addtopath(onthing); + var onthing = getthingxy(adjustx, adjusty); + if (onthing) { + if (canstartpath(onthing)) { + console.log("Initial click on " + onthing.name); + addtopath(onthing); + } else { + // just show description + overdesc = onthing.getdesc(); + } } }, handlemousemove : function(event) { + var adjustx = event.pageX - BOARDX; + var adjusty = event.pageY - BOARDY; + + // don't allow default movement to scroll + event.preventDefault(); + // make sure nothing is moving if (thingsmoving()) return; // existing path? if (curpath != undefined && curpath.length > 0) { - var overthing = getthingxy(event.pageX,event.pageY); + var overthing = getthingxy(adjustx, adjusty); var lastinpath,secondlast; if (curpath == undefined) { @@ -523,8 +617,13 @@ console.log("Initial click on " + onthing.name); handlemouseup : function(event) { var ok = true; - var overthing = getthingxy(event.pageX,event.pageY); + var adjustx = event.pageX - BOARDX; + var adjusty = event.pageY - BOARDY; + var overthing = getthingxy(adjustx, adjusty); var ptype = getpathtype(); + var points = 0; + + overdesc = ""; if ((curpath == undefined) || (curpath.length == 0)) { console.log("mouseup() - no path"); @@ -549,24 +648,42 @@ console.log("Initial click on " + onthing.name); } // figure out path type + points = 0; switch(ptype) { case "chomp": // killall except first and last if (curpath.length > 2) { var i; for (i = 1; i < curpath.length - 1; i++) { - curpath[i].kill(); + curpath[i].givepoints(); + curpath[i].addabove(); + //curpath[i].kill(); + curpath[i].startexplode(); } } + curpath[curpath.length-1].givepoints(); + // first one chomps last one curpath[0].chomp(curpath[curpath.length - 1]); break; case "parade": - // kill all in path - while (curpath != undefined && curpath.length > 0) { - curpath[0].kill(); - curpath.splice(0, 1); + if (curpath.length >= 2) { // should always be true + var i; + // everything in the path exits via a parade + for (i = 0; i < curpath.length; i++) { + curpath[i].givepoints(); + curpath[i].startparade(); + } + clearpath(); + } else { + // just kill everything in path + while (curpath != undefined && curpath.length > 0) { + curpath[0].givepoints(); + curpath[0].addabove(); + curpath[0].kill(); + curpath.splice(0, 1); + } } break; } @@ -614,9 +731,13 @@ function getrandomtype() { return type; } -function thing(gridx, gridy, type) { - this.width = THINGSIZE; - this.height = THINGSIZE; +function coord(x,y) { + this.x = x; + this.y = y; +} + +function thing(gridx, gridy, type, text) { + this.opacity = 1.0; if (type == "random") { type = getrandomtype(); @@ -633,12 +754,26 @@ function thing(gridx, gridy, type) { case "llama": this.color = "#cccccc"; break; + case "text": + this.color = "#00cc00"; + break; default: // should never happen this.color = getrandomcolour(); break; } - this.name = type + "-" + getrandomname(); + if (this.type == "text") { + this.size = TEXTSIZE; + } else { + this.size = THINGSIZE; + } + this.lifetime = 0; + + if (text == undefined) { + this.name = type + "-" + getrandomname(); + } else { + this.name = text; + } this.gridx = gridx; if (gridy == "top") { @@ -658,22 +793,144 @@ function thing(gridx, gridy, type) { this.yspeed = 0; this.state = "stop"; - this.x = gridx * GRIDSIZE + (GRIDSIZE/2) - (THINGSIZE/2); - this.y = gridy * GRIDSIZE + (GRIDSIZE/2) - (THINGSIZE/2); + this.path = []; + this.pathspeed = PARADESPEED; + + this.expcount = 0; + this.expmax = 0; + + if (this.type == "text" ) { + this.x = gridx * GRIDSIZE + (GRIDSIZE/2); + this.y = gridy * GRIDSIZE + (GRIDSIZE/2) - 10; // TODO: fix to 10! + } else { + this.x = gridx * GRIDSIZE + (GRIDSIZE/2) - (this.size/2); + this.y = gridy * GRIDSIZE + (GRIDSIZE/2) - (this.size/2); + } + this.eaten = false; + this.pushpath = function(x,y) { + this.path.push(new coord(x, y)); + } + + this.poppath = function() { + this.path.splice(0, 1); + } + + this.givepoints = function() { + var points = 0; + if (this.type == "food") { + points = 10; + } else if (this.type == "llama") { + points = 100; + } else if (this.type == "cat") { + if (this.eaten == true) { + points = 5; + } else { + points = 25; + } + } + score += points; + + // add animation + things.push(new thing(this.gridx, this.gridy, "text", "+" + points)); + } + + + this.getdesc = function() { + var desc = ""; + if (this.type == "cat") { + if (isadjacenttotype(this, "llama")) { + desc = "scared cat"; + } else if (this.eaten == true) { + desc = "sleepy cat"; + } else { + desc = "cat"; + } + } else if (this.type == "llama") { + var num; + num = (Math.floor(game.frameNo / 50)) % 2; + if (num == 0) { + desc = "llama"; + } else { + desc = "alpaca"; + } + } else if (this.type == "food") { + desc = "cheese"; + } + return desc; + } + this.draw = function() { var yoff; var inpath = false; + var howbig,myx,myy; ctx = game.context; + // check whether I'm in the drawn path + if (pathcontains(this)) { + inpath = true; + } + + // set opacity + ctx.globalAlpha = this.opacity; + // draw myself - ctx.fillStyle = this.color; - ctx.fillRect(this.x, this.y, this.width, this.height); + if (this.type == "text") { + ctx.textAlign = "center"; + ctx.textBaseline = "center"; + // shadows + ctx.fillStyle = "black"; + ctx.fillText(this.name, BOARDX + this.x-1, BOARDY + this.y-1); + ctx.fillText(this.name, BOARDX + this.x+1, BOARDY + this.y); + ctx.fillText(this.name, BOARDX + this.x+1, BOARDY + this.y+1); + ctx.fillText(this.name, BOARDX + this.x-1, BOARDY + this.y+1); + // real text + ctx.fillStyle = this.color; + ctx.fillText(this.name, BOARDX + this.x, BOARDY + this.y); + } else { + if (this.type == "cat") { + var myimage; + + if (this.state == "exploding") { + } + + if (isadjacenttotype(this, "llama")) { + myimage = image['catscared']; + } else if (this.eaten == true) { + myimage = image['catfull']; + } else { + myimage = image['cat']; + } + } else if (this.type == "llama") { + myimage = image['llama']; + } else if (this.type == "food") { + myimage = image['cheese']; + } + howbig = this.size; + myx = this.x; + myy = this.y; + if (inpath) { + var growpct = 50; + howbig = howbig * ((100+growpct) / 100); + myx -= (growpct/2/100) * this.size; + myy -= (growpct/2/100) * this.size; + } + + ctx.drawImage(myimage, BOARDX + myx, BOARDY + myy, howbig, howbig); + } + + /* + } else { + ctx.fillStyle = this.color; + ctx.fillRect(BOARDX + this.x, BOARDY + this.y, this.size, this.size); + } + */ // frozen cat? - if (this.type == "cat") { + /* + if ((this.type == "cat") && !this.isanimating()) { if (isadjacenttotype(this, "llama")) { // cross out ctx.fillStyle = "red"; @@ -681,30 +938,36 @@ function thing(gridx, gridy, type) { ctx.strokeStyle = "red"; // NW -> SE ctx.beginPath(); - ctx.moveTo(this.x, this.y); - ctx.lineTo(this.x + THINGSIZE - 1, this.y + THINGSIZE - 1); + ctx.moveTo(BOARDX + this.x, BOARDY + this.y); + ctx.lineTo(BOARDX + this.x + this.size - 1, BOARDY + this.y + this.size - 1); ctx.stroke(); // SW -> NE ctx.beginPath(); - ctx.moveTo(this.x, this.y + THINGSIZE - 1); - ctx.lineTo(this.x + THINGSIZE - 1, this.y); + ctx.moveTo(BOARDX + this.x, BOARDY + this.y + this.size - 1); + ctx.lineTo(BOARDX + this.x + this.size - 1, BOARDY + this.y); ctx.stroke(); } } + */ - // highlight? - if (pathcontains(this)) { - inpath = true; + // draw text on me + /* + if (this.type == "cat") { + } else if (this.type == "llama") { + } else { + ctx.fillStyle = "black"; + ctx.fillText(this.name, BOARDX + this.x + 10, BOARDY + this.y + (THINGSIZE/2)); + ctx.fillText(this.eaten ? "FULL" : "", BOARDX + this.x + 10, BOARDY + this.y + (THINGSIZE/2) + 10); } + */ - // draw text - ctx.fillStyle = "black"; - ctx.fillText(this.name, this.x + 10, this.y + (THINGSIZE/2)); - ctx.fillText(this.eaten ? "FULL" : "", this.x + 10, this.y + (THINGSIZE/2) + 10); + // back to full opacity + ctx.globalAlpha = 1.0; + /* // path outline - if (inpath) { + if (inpath && this.state != "parade" && this.state != "explode") { ctx.beginPath(); ctx.lineWidth = 1; ctx.fillStyle = "black"; @@ -714,9 +977,10 @@ function thing(gridx, gridy, type) { } else { ctx.strokeStyle = "red"; } - ctx.rect(this.x, this.y, this.width, this.height); + ctx.rect(BOARDX + this.x, BOARDY + this.y, this.size, this.size); ctx.stroke(); } + */ } @@ -741,11 +1005,12 @@ function thing(gridx, gridy, type) { return null; } - - this.kill = function() { + this.addabove = function() { // add a new cat above us things.push(new thing(this.gridx, "top", "random")); + } + this.kill = function() { // kill ourselves var idx = things.indexOf(this); things.splice(idx, 1); @@ -767,16 +1032,22 @@ function thing(gridx, gridy, type) { // remember cat loc origgx = this.gridx; origgy = this.gridy; + + // add new object above cat location + this.addabove(); // move cat to food location this.setgridxy(food.gridx,food.gridy); + // move food to cat location (so new object will // be added in the correct column. - food.setgridxy(origgx, origgy); + //food.setgridxy(origgx, origgy); - // kill food - food.kill(); + // make food explode + //food.addabove(); + //food.kill(); + food.startexplode(); // mark that we've eaten something this.eaten = true; @@ -784,43 +1055,166 @@ function thing(gridx, gridy, type) { console.log("chomp"); } + this.isanimating = function() { + if (this.type == "text") return true; + if (this.state == "explode") return true; + if (this.state == "parade") return true; + return false; + } + + this.startexplode = function() { + this.expcount=1; + this.expmax=EXPLODETICKS; + this.state = "explode"; + } + + this.startparade = function() { + var i,startidx=-1; + // find our position in the current path + for (i = 0; i < curpath.length; i++) { + if (curpath[i] == this) { + startidx = i; + break; + } + } + if (startidx == -1) { + // not in path?! + return; + } + + // populate our own movement path. + for (i = startidx; i < curpath.length; i++) { + var nextidx; + // add waypoint of next cell in selected path + nextidx = i+1; + if (nextidx >= curpath.length) { + var dir; + // we're at the end. move off the screen in the direction of the path. + + // find dir from previous to us... + // don't worry about checking for being the first element cause + // parades can't be 1 in length; + dir = getdir(curpath[i-1],curpath[i]); + this.pushpath(curpath[i].x + (DIRXMOD[dir]*GRIDSIZE*GRIDW), + curpath[i].y + (DIRYMOD[dir]*GRIDSIZE*GRIDH)); + } else { + this.pushpath(curpath[nextidx].x, curpath[nextidx].y); + } + } + console.log("Starting parade: " + this.name + " path len is [" + this.path.length + "]"); + + this.addabove(); // add cat above + this.state = "parade"; // go to parade mode + + } + + this.calcgridxy = function() { + this.gridx = Math.floor(this.x / GRIDSIZE); + this.gridy = Math.floor(this.y / GRIDSIZE); + } + this.move = function() { // not at bottom and nothing fixed below us? var dofall = false; var belowthing = null,atbottom = false; - if ((this.gridy >= GRIDH-1)) { - atbottom = true; + + if (this.type == "text") { + // slowly move up + this.y -= TEXTSPEED; + this.lifetime++; + if (this.lifetime >= TEXTTIME) { + this.opacity -= TEXTFADESPEED; + if (this.opacity <= 0) { + this.kill(); + } + } + } else if (this.state == "explode") { + this.expcount++; + if (this.expcount >= this.expmax) { + this.kill(); + } else { + // get bigger + this.size += EXPLODEGAIN; + this.opacity -= EXPLODEFADESPEED; + + if (this.opacity < 0) this.opacity = 0; + + // adjust x/y + this.x = (this.gridx * GRIDSIZE) + (GRIDSIZE/2) - (this.size/2); + this.y = (this.gridy * GRIDSIZE) + (GRIDSIZE/2) - (this.size/2); + + } + } else if (this.state == "parade") { + // move towards next cell in path + var nextx = this.path[0].x; + var nexty = this.path[0].y; + var xdone = 0, ydone = 0; + + if (this.x < nextx) { + this.x += this.pathspeed; + if (this.x > nextx) xdone = true; + } else if (this.x > nextx) { + this.x -= this.pathspeed; + if (this.x < nextx) xdone = true; + } else { + xdone = true; + } + + if (this.y < nexty) { + this.y += this.pathspeed; + if (this.y > nexty) ydone = true; + } else if (this.y > nexty) { + this.y -= this.pathspeed; + if (this.y < nexty) ydone = true; + } else { + ydone = true; + } + + this.calcgridxy(); + + // at destination? + if (xdone && ydone) { + this.poppath(); + // path finished? + if (this.path == undefined || this.path.length == 0) { + this.kill(); + } + } + } else { + // regular gravity + if ((this.gridy >= GRIDH-1)) { + atbottom = true; + } + if (!atbottom && !this.getstoppedbelowthing()) { + // accelerate + this.yspeed += GRAVITY; + + // move + this.y += this.yspeed; + + // don't go below bottom of screen + this.hitBottom(); + + + // calc new gridx / gridy + this.calcgridxy(); + + this.state = "fall"; + } + + // hit something? + if (atbottom || this.getstoppedbelowthing()) { + // something below us. + + // stop + this.yspeed = 0; + + // snap to grid + this.snaptogrid(); + + this.state = "stop"; + } } - if (!atbottom && !this.getstoppedbelowthing()) { - // accelerate - this.yspeed += GRAVITY; - - // move - this.y += this.yspeed; - - // don't go below bottom of screen - this.hitBottom(); - - // calc new gridx / gridy - this.gridx = Math.floor(this.x / GRIDSIZE); - this.gridy = Math.floor(this.y / GRIDSIZE); - - this.state = "fall"; - } - - // hit something? - if (atbottom || this.getstoppedbelowthing()) { - // something below us. - - // stop - this.yspeed = 0; - - // snap to grid - this.snaptogrid(); - - this.state = "stop"; - } - } this.hitBottom = function() { @@ -837,18 +1231,32 @@ function updateGameArea() { var i; game.clear(); - game.draw(); + game.drawgrid(); // draw grid game.frameNo += 1; + // move objects for (i = 0; i < things.length; i += 1) { things[i].move(); - things[i].draw(); } + // move and draw non-animating objects + for (i = 0; i < things.length; i += 1) { + if (!things[i].isanimating()) { + things[i].draw(); + } + } + // move and draw animating objects + for (i = 0; i < things.length; i += 1) { + if (things[i].isanimating()) { + things[i].draw(); + } + } + // hide top of canvads + game.drawtop(); + + // draw dragged arrow game.drawpath(); //myScore.text="SCORE: " + game.frameNo; //myScore.draw(); - //myGamePiece.move(); - //myGamePiece.update(); } function everyinterval(n) { diff --git a/images/alpaca.png b/images/alpaca.png new file mode 100644 index 0000000..dc54f5f Binary files /dev/null and b/images/alpaca.png differ diff --git a/images/cat.png b/images/cat.png new file mode 100644 index 0000000..7368a86 Binary files /dev/null and b/images/cat.png differ diff --git a/images/catfull.png b/images/catfull.png new file mode 100644 index 0000000..46268a1 Binary files /dev/null and b/images/catfull.png differ diff --git a/images/catscared.png b/images/catscared.png new file mode 100644 index 0000000..f3095af Binary files /dev/null and b/images/catscared.png differ diff --git a/images/cheese.png b/images/cheese.png new file mode 100644 index 0000000..b2392b5 Binary files /dev/null and b/images/cheese.png differ diff --git a/todo b/todo index 5aef0d6..3a497c3 100644 --- a/todo +++ b/todo @@ -1,8 +1,5 @@ http://www.w3schools.com/games/tryit.asp?filename=trygame_default_gravity -test change. - - cat game ??? gems diff kinds of cats, and food @@ -25,80 +22,22 @@ cat game ??? game params: # of moves limit score - - - - -array of "objects" (which can be a cat, food, etc) - each object is a fixed square size - applygravity() - obejcts always fall downwards if there is no obejct under them. - blowup() - give points or extra moves, then vanish. - -mouse down: - can't do this unless all objects are finished moving. - start dragging line, add current under-object to path. - -mouse move: - if dragging a line: - ...if under object isn't in path - ...and under object is valid for this path - (ie. a swap with first element before it, or a parade) - then add under obejct to path - - otherwise: - path becomes invalid. - -mouse up: - if valid path: - if swap: - chomp fruit - move cat to fruit's position - cat gets bigger? - if line: - all vanish (or zoom off) - - now decrement movesleft. - -main loop - move stuff - draw cats / score - check input - check for endgame (no moves left) - - ---------------------------- -start: +*animate parades +*animate chomps +*offset entire grid downwards to allow space for a header +*add images +*award points for stuff +*show score up the top +*animated points gaining (text fading out) +*touch events: +* touchstart: a finger is placed on a DOM element. +* touchmove: a finger is dragged along a DOM element. +* touchend: a finger is removed from a DOM element. -*have a grid of things -*click one, rest fall down and a new one is generated -*drag across multi, all disappear, rest fall, new are generated -*don't allow clicks until all grid locations are full -*allow cat->food or cat->...->cat - -*cat eating food should take its place -*parade must be at least 4 -*cat can only eat food once, but can eat multiple foods in one go -*dont let chomp lines change dir (but parades can) -*allow reversing a line -*draw arrow for lines - -*llama - *cats next to it can't move - *cat parades can include one (but only one). -*draw cats in centre of grid squares, not top left - -offset entire grid downwards to allow space for a header - -add pictures of: - cat - fat cat - scared cat - llama - food +phone fixes as per http://www.html5rocks.com/en/mobile/touch/ make path part of game object @@ -109,24 +48,8 @@ ideas: ensure that start of game has at least one valid move! -show score up the top - Score: (+20) 100 - points for chomp - points for parade - points for each empty cat - points for each full cat - extra points for llama - length 3 = 1x - length 4 = 2x - length 5 = 3x - multiplier for length - -animated points gaining - text fading out -animate parades -animate chomps end if no valid moves after each move: