*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.
This commit is contained in:
Rob Pearce 2016-08-20 11:17:22 +10:00
parent 12f79e8b45
commit 225e527dd6
7 changed files with 508 additions and 177 deletions

508
cat.html
View File

@ -1,11 +1,16 @@
<!-- vim: set syntax=javascript : -->
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <!-- Viewport isn't scalable -->
ooooo
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<style> <style>
canvas { canvas {
border:1px solid #d3d3d3; border:1px solid #d3d3d3;
background-color: #f1f1f1; background-color: #000000;
} }
</style> </style>
</head> </head>
@ -14,7 +19,7 @@ canvas {
var myGamePiece; var myGamePiece;
var things = []; var things = [];
var myScore; var score = 0;
var curpath = []; var curpath = [];
var pathdir = -1; var pathdir = -1;
@ -24,10 +29,24 @@ var MAXDIRS = 4;
var DIRXMOD = [ 0, 1, 0, -1 ]; var DIRXMOD = [ 0, 1, 0, -1 ];
var DIRYMOD = [ -1, 0, 1, 0 ]; var DIRYMOD = [ -1, 0, 1, 0 ];
var SCREENW = 480;
var SCREENH = 640;
var GRAVITY = 0.5; var GRAVITY = 0.5;
var GRIDSIZE = 80; var GRIDSIZE = 80;
var THINGSIZE = 64; 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 LINEWIDTH=2;
var CROSSWIDTH=2; var CROSSWIDTH=2;
@ -36,15 +55,30 @@ var GRIDH = 5;
var PARADELENGTH = 3; 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) { function getgridthing(gridx, gridy) {
var i; var i;
if (things == undefined) return null; if (things == undefined) return null;
// only include non-animating things
for (i = 0; i < things.length; i += 1) { for (i = 0; i < things.length; i += 1) {
if ((things[i].gridx == gridx) && (things[i].gridy == gridy)) { if ((things[i].gridx == gridx) && (things[i].gridy == gridy)) {
if (!things[i].isanimating()) {
return things[i]; return things[i];
} }
} }
}
return null; return null;
} }
@ -274,6 +308,13 @@ function getdir(thing1, thing2) {
} }
function startGame() { 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(); game.start();
} }
@ -385,18 +426,26 @@ var game = {
canvas : document.createElement("canvas"), canvas : document.createElement("canvas"),
start : function() { start : function() {
var x,y; var x,y;
this.canvas.width = 480; this.canvas.width = SCREENW;
this.canvas.height = 640; this.canvas.height = SCREENH;
this.context = this.canvas.getContext("2d"); this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]); document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0; this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20); 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('mousedown', this.handlemousedown, false);
this.canvas.addEventListener('mouseup', this.handlemouseup, 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('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 // populate inital things
for (y = 0; y < GRIDH; y++) { for (y = 0; y < GRIDH; y++) {
for (x = 0; x < GRIDW; x++) { for (x = 0; x < GRIDW; x++) {
@ -410,13 +459,41 @@ var game = {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 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.strokeStyle = "black";
this.context.beginPath(); this.context.beginPath();
// draw grid // draw grid
for (y = 0; y < GRIDH*GRIDSIZE; y += GRIDSIZE) { for (y = 0; y < GRIDH*GRIDSIZE; y += GRIDSIZE) {
for (x = 0; x < GRIDW*GRIDSIZE; x += 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.strokeStyle = col;
ctx.lineWidth = LINEWIDTH; ctx.lineWidth = LINEWIDTH;
// draw line // draw line to show current path
ctx.beginPath(); 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++) { 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(); ctx.stroke();
@ -455,7 +532,7 @@ var game = {
x2 = curpath[curpath.length-1].x + (THINGSIZE/2); x2 = curpath[curpath.length-1].x + (THINGSIZE/2);
y2 = curpath[curpath.length-1].y + (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) { 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 // make sure nothing is moving
if (thingsmoving()) return; if (thingsmoving()) return;
@ -481,20 +564,31 @@ var game = {
clearpath(); clearpath();
// did you click on an object? // did you click on an object?
var onthing = getthingxy(event.pageX,event.pageY); var onthing = getthingxy(adjustx, adjusty);
if (onthing && canstartpath(onthing)) { if (onthing) {
if (canstartpath(onthing)) {
console.log("Initial click on " + onthing.name); console.log("Initial click on " + onthing.name);
addtopath(onthing); addtopath(onthing);
} else {
// just show description
overdesc = onthing.getdesc();
}
} }
}, },
handlemousemove : function(event) { 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 // make sure nothing is moving
if (thingsmoving()) return; if (thingsmoving()) return;
// existing path? // existing path?
if (curpath != undefined && curpath.length > 0) { if (curpath != undefined && curpath.length > 0) {
var overthing = getthingxy(event.pageX,event.pageY); var overthing = getthingxy(adjustx, adjusty);
var lastinpath,secondlast; var lastinpath,secondlast;
if (curpath == undefined) { if (curpath == undefined) {
@ -523,8 +617,13 @@ console.log("Initial click on " + onthing.name);
handlemouseup : function(event) { handlemouseup : function(event) {
var ok = true; 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 ptype = getpathtype();
var points = 0;
overdesc = "";
if ((curpath == undefined) || (curpath.length == 0)) { if ((curpath == undefined) || (curpath.length == 0)) {
console.log("mouseup() - no path"); console.log("mouseup() - no path");
@ -549,25 +648,43 @@ console.log("Initial click on " + onthing.name);
} }
// figure out path type // figure out path type
points = 0;
switch(ptype) { switch(ptype) {
case "chomp": case "chomp":
// killall except first and last // killall except first and last
if (curpath.length > 2) { if (curpath.length > 2) {
var i; var i;
for (i = 1; i < curpath.length - 1; 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 // first one chomps last one
curpath[0].chomp(curpath[curpath.length - 1]); curpath[0].chomp(curpath[curpath.length - 1]);
break; break;
case "parade": case "parade":
// kill all in path 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) { while (curpath != undefined && curpath.length > 0) {
curpath[0].givepoints();
curpath[0].addabove();
curpath[0].kill(); curpath[0].kill();
curpath.splice(0, 1); curpath.splice(0, 1);
} }
}
break; break;
} }
@ -614,9 +731,13 @@ function getrandomtype() {
return type; return type;
} }
function thing(gridx, gridy, type) { function coord(x,y) {
this.width = THINGSIZE; this.x = x;
this.height = THINGSIZE; this.y = y;
}
function thing(gridx, gridy, type, text) {
this.opacity = 1.0;
if (type == "random") { if (type == "random") {
type = getrandomtype(); type = getrandomtype();
@ -633,12 +754,26 @@ function thing(gridx, gridy, type) {
case "llama": case "llama":
this.color = "#cccccc"; this.color = "#cccccc";
break; break;
case "text":
this.color = "#00cc00";
break;
default: // should never happen default: // should never happen
this.color = getrandomcolour(); this.color = getrandomcolour();
break; break;
} }
if (this.type == "text") {
this.size = TEXTSIZE;
} else {
this.size = THINGSIZE;
}
this.lifetime = 0;
if (text == undefined) {
this.name = type + "-" + getrandomname(); this.name = type + "-" + getrandomname();
} else {
this.name = text;
}
this.gridx = gridx; this.gridx = gridx;
if (gridy == "top") { if (gridy == "top") {
@ -658,22 +793,144 @@ function thing(gridx, gridy, type) {
this.yspeed = 0; this.yspeed = 0;
this.state = "stop"; this.state = "stop";
this.x = gridx * GRIDSIZE + (GRIDSIZE/2) - (THINGSIZE/2); this.path = [];
this.y = gridy * GRIDSIZE + (GRIDSIZE/2) - (THINGSIZE/2); 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.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() { this.draw = function() {
var yoff; var yoff;
var inpath = false; var inpath = false;
var howbig,myx,myy;
ctx = game.context; ctx = game.context;
// check whether I'm in the drawn path
if (pathcontains(this)) {
inpath = true;
}
// set opacity
ctx.globalAlpha = this.opacity;
// draw myself // draw myself
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.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height); 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? // frozen cat?
if (this.type == "cat") { /*
if ((this.type == "cat") && !this.isanimating()) {
if (isadjacenttotype(this, "llama")) { if (isadjacenttotype(this, "llama")) {
// cross out // cross out
ctx.fillStyle = "red"; ctx.fillStyle = "red";
@ -681,30 +938,36 @@ function thing(gridx, gridy, type) {
ctx.strokeStyle = "red"; ctx.strokeStyle = "red";
// NW -> SE // NW -> SE
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(this.x, this.y); ctx.moveTo(BOARDX + this.x, BOARDY + this.y);
ctx.lineTo(this.x + THINGSIZE - 1, this.y + THINGSIZE - 1); ctx.lineTo(BOARDX + this.x + this.size - 1, BOARDY + this.y + this.size - 1);
ctx.stroke(); ctx.stroke();
// SW -> NE // SW -> NE
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(this.x, this.y + THINGSIZE - 1); ctx.moveTo(BOARDX + this.x, BOARDY + this.y + this.size - 1);
ctx.lineTo(this.x + THINGSIZE - 1, this.y); ctx.lineTo(BOARDX + this.x + this.size - 1, BOARDY + this.y);
ctx.stroke(); ctx.stroke();
} }
} }
*/
// highlight? // draw text on me
if (pathcontains(this)) { /*
inpath = true; if (this.type == "cat") {
} } else if (this.type == "llama") {
} else {
// draw text
ctx.fillStyle = "black"; ctx.fillStyle = "black";
ctx.fillText(this.name, this.x + 10, this.y + (THINGSIZE/2)); ctx.fillText(this.name, BOARDX + this.x + 10, BOARDY + this.y + (THINGSIZE/2));
ctx.fillText(this.eaten ? "FULL" : "", this.x + 10, this.y + (THINGSIZE/2) + 10); ctx.fillText(this.eaten ? "FULL" : "", BOARDX + this.x + 10, BOARDY + this.y + (THINGSIZE/2) + 10);
}
*/
// back to full opacity
ctx.globalAlpha = 1.0;
/*
// path outline // path outline
if (inpath) { if (inpath && this.state != "parade" && this.state != "explode") {
ctx.beginPath(); ctx.beginPath();
ctx.lineWidth = 1; ctx.lineWidth = 1;
ctx.fillStyle = "black"; ctx.fillStyle = "black";
@ -714,9 +977,10 @@ function thing(gridx, gridy, type) {
} else { } else {
ctx.strokeStyle = "red"; 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(); ctx.stroke();
} }
*/
} }
@ -741,11 +1005,12 @@ function thing(gridx, gridy, type) {
return null; return null;
} }
this.addabove = function() {
this.kill = function() {
// add a new cat above us // add a new cat above us
things.push(new thing(this.gridx, "top", "random")); things.push(new thing(this.gridx, "top", "random"));
}
this.kill = function() {
// kill ourselves // kill ourselves
var idx = things.indexOf(this); var idx = things.indexOf(this);
things.splice(idx, 1); things.splice(idx, 1);
@ -768,15 +1033,21 @@ function thing(gridx, gridy, type) {
origgx = this.gridx; origgx = this.gridx;
origgy = this.gridy; origgy = this.gridy;
// add new object above cat location
this.addabove();
// move cat to food location // move cat to food location
this.setgridxy(food.gridx,food.gridy); this.setgridxy(food.gridx,food.gridy);
// move food to cat location (so new object will // move food to cat location (so new object will
// be added in the correct column. // be added in the correct column.
food.setgridxy(origgx, origgy); //food.setgridxy(origgx, origgy);
// kill food // make food explode
food.kill(); //food.addabove();
//food.kill();
food.startexplode();
// mark that we've eaten something // mark that we've eaten something
this.eaten = true; this.eaten = true;
@ -784,10 +1055,133 @@ function thing(gridx, gridy, type) {
console.log("chomp"); 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() { this.move = function() {
// not at bottom and nothing fixed below us? // not at bottom and nothing fixed below us?
var dofall = false; var dofall = false;
var belowthing = null,atbottom = false; var belowthing = null,atbottom = false;
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)) { if ((this.gridy >= GRIDH-1)) {
atbottom = true; atbottom = true;
} }
@ -801,9 +1195,9 @@ function thing(gridx, gridy, type) {
// don't go below bottom of screen // don't go below bottom of screen
this.hitBottom(); this.hitBottom();
// calc new gridx / gridy // calc new gridx / gridy
this.gridx = Math.floor(this.x / GRIDSIZE); this.calcgridxy();
this.gridy = Math.floor(this.y / GRIDSIZE);
this.state = "fall"; this.state = "fall";
} }
@ -820,7 +1214,7 @@ function thing(gridx, gridy, type) {
this.state = "stop"; this.state = "stop";
} }
}
} }
this.hitBottom = function() { this.hitBottom = function() {
@ -837,18 +1231,32 @@ function updateGameArea() {
var i; var i;
game.clear(); game.clear();
game.draw(); game.drawgrid(); // draw grid
game.frameNo += 1; game.frameNo += 1;
// move objects
for (i = 0; i < things.length; i += 1) { for (i = 0; i < things.length; i += 1) {
things[i].move(); things[i].move();
}
// move and draw non-animating objects
for (i = 0; i < things.length; i += 1) {
if (!things[i].isanimating()) {
things[i].draw(); 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(); game.drawpath();
//myScore.text="SCORE: " + game.frameNo; //myScore.text="SCORE: " + game.frameNo;
//myScore.draw(); //myScore.draw();
//myGamePiece.move();
//myGamePiece.update();
} }
function everyinterval(n) { function everyinterval(n) {

BIN
images/alpaca.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
images/cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
images/catfull.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
images/catscared.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
images/cheese.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

101
todo
View File

@ -1,8 +1,5 @@
http://www.w3schools.com/games/tryit.asp?filename=trygame_default_gravity http://www.w3schools.com/games/tryit.asp?filename=trygame_default_gravity
test change.
cat game ??? cat game ???
gems gems
diff kinds of cats, and food diff kinds of cats, and food
@ -26,79 +23,21 @@ cat game ???
# of moves limit # of moves limit
score 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 phone fixes as per http://www.html5rocks.com/en/mobile/touch/
*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
make path part of game object make path part of game object
@ -109,24 +48,8 @@ ideas:
ensure that start of game has at least one valid move! 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 end if no valid moves
after each move: after each move: