*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:
parent
12f79e8b45
commit
225e527dd6
582
cat.html
582
cat.html
|
@ -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,13 +55,28 @@ 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)) {
|
||||||
return things[i];
|
if (!things[i].isanimating()) {
|
||||||
|
return things[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
console.log("Initial click on " + onthing.name);
|
if (canstartpath(onthing)) {
|
||||||
addtopath(onthing);
|
console.log("Initial click on " + onthing.name);
|
||||||
|
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,24 +648,42 @@ 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
|
||||||
while (curpath != undefined && curpath.length > 0) {
|
var i;
|
||||||
curpath[0].kill();
|
// everything in the path exits via a parade
|
||||||
curpath.splice(0, 1);
|
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;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
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
|
||||||
ctx.fillStyle = this.color;
|
if (this.type == "text") {
|
||||||
ctx.fillRect(this.x, this.y, this.width, this.height);
|
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?
|
// 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 {
|
||||||
|
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
|
// back to full opacity
|
||||||
ctx.fillStyle = "black";
|
ctx.globalAlpha = 1.0;
|
||||||
ctx.fillText(this.name, this.x + 10, this.y + (THINGSIZE/2));
|
|
||||||
ctx.fillText(this.eaten ? "FULL" : "", this.x + 10, this.y + (THINGSIZE/2) + 10);
|
|
||||||
|
|
||||||
|
/*
|
||||||
// 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,43 +1055,166 @@ 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.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() {
|
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();
|
||||||
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();
|
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) {
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
101
todo
101
todo
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue