diff --git a/cat.html b/cat.html
index 62d176c..1fc09fe 100644
--- a/cat.html
+++ b/cat.html
@@ -74,6 +74,8 @@ var TURNSBARSPEEDUP = 0.02;
var TURNSBARSPEEDDOWN = 0.01;
var BAGCAPACITY = 6; // how many cats to pop a bag
+var BRICKHP = 9; // how many cats it takes to remove a brick
+var SLASHDIST = 3; // space between slash marks on bricks
// for background
var catalpha = 1.0;
@@ -90,14 +92,16 @@ var GOALVERB = {
'cat': 'Clear',
'goat': 'Clear',
'door': 'Enter',
- 'sun': 'Wait out',
+ 'sunlight': 'Wait out',
'bag': 'Burst',
'toad': 'Slap',
'whitecat': 'Attack',
+ 'brick': 'Break',
};
var GOALNAME = {
'whitecat': 'white cat',
+ 'sunlight': 'sun',
};
var prizetypes = [
@@ -300,6 +304,21 @@ function loadimage(name, filename) {
image[name].src = filename;
}
+function gridxyhasthingtype(gridx, gridy, wanttype) {
+ 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) && (things[i].type == wanttype)) {
+ if (!things[i].isanimating()) {
+ return things[i];
+ }
+ }
+ }
+ return null;
+}
+
+
function getgridthing(gridx, gridy) {
var i;
if (things == undefined) return null;
@@ -572,6 +591,10 @@ function canextendpath(overthing) {
if (!overthing) return false;
+ if (!isongrid(overthing.gridx, overthing.gridy)) {
+ return false;
+ }
+
pathtype = getpathtype();
if ( isadjacent(overthing, curpath[curpath.length-1]) && // adjacent to last thing in path?
@@ -829,6 +852,50 @@ function isadjacenttotype(what, wanttype, exceptionthing) {
return false;
}
+function addslash(slashes, w, h) {
+ slashes.push(Math.floor(rnd(w))); // x1
+ slashes.push(Math.floor(rnd(h))); // y1
+
+ slashes.push(Math.floor(rnd(w))); // x2
+ slashes.push(Math.floor(rnd(h))); // y2
+}
+
+function drawslashes(ctx, x, y, slashes) {
+ var i,n;
+ if (slashes == undefined || slashes.length <= 0) {
+ return;
+ }
+
+ for (i = 0; i < slashes.length; i+= 4) {
+ var dx,dy,xstep,ystep,angle;
+ // get angle of line
+ dx = slashes[i+2] - slashes[i];
+ dy = slashes[i+1] - slashes[i+3];
+//console.log("dxy is " + dx + "," + dy);
+ angle = Math.atan2(dy,dx);
+ //angle *= 180/Math.PI; // degrees
+
+ // add 90 degrees
+ angle += 90;
+
+ // back to radians
+ //angle *= Math.PI/180;
+
+ xstep = Math.cos(angle);
+ ystep = Math.sin(angle);
+//console.log("line " + i + " - angle is " + (angle * 180/Math.PI) + " steps are " + xstep + "," + ystep);
+
+ for (n = 0; n < 3; n++) {
+ var modx,mody;
+ modx = xstep * n * SLASHDIST;
+ mody = ystep * n * SLASHDIST;
+ drawline(ctx, x + slashes[i] + modx, y + slashes[i+1] + mody,
+ x + slashes[i+2] + modx, y + slashes[i+3] + mody,
+ "black", 1);
+ }
+ }
+}
+
function drawline(ctx,x1,y1,x2,y2,col,width) {
ctx.strokeStyle = col;
ctx.lineWidth = width;
@@ -1276,6 +1343,18 @@ var game = {
},
+ // x1, x2, y2, x3, y3....
+ addlevelbricks : function () {
+ var lev,newbrick,i;
+ lev = this.levels.length - 1;
+ for (i = 0 ; i < arguments.length; i += 2) {
+ newbrick = new Object();
+ newbrick.gridx = arguments[i];
+ newbrick.gridy = arguments[i+1];
+ this.levels[lev].bricks.push(newbrick);
+ }
+ },
+
addlevelbag : function (lev, y ) {
var mybag;
mybag = new Object();
@@ -1294,9 +1373,9 @@ var game = {
mylevel.goals = new Array();
mylevel.thinglist = new Array();
mylevel.forcelist = new Array();
- mylevel.allowedthings = new Array();
mylevel.maxturns = lev + 4; // default
mylevel.bags = [];
+ mylevel.bricks = [];
if (lev == 1) {
mylevel.gridsize = DEF_GRIDSIZE;
@@ -1313,6 +1392,14 @@ var game = {
mylevel.boardx = this.levels[lev-1].boardx;
}
+ mylevel.allowedthings = new Array();
+ if (lev > 1) {
+ // default to allowed things from previous level.
+ for (i = 0; i < this.levels[lev-1].allowedthings.length; i++) {
+ mylevel.allowedthings.push(this.levels[lev-1].allowedthings[i]);
+ }
+ }
+
this.levels[lev] = mylevel;
playerdata.levscore[lev] = 0;
@@ -1388,6 +1475,8 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
progress : function(type, amt) {
var i;
+ if (game.state != "running") return false;
+
// past last level!
if (curlevel >= game.levels.length) return false;
@@ -1473,6 +1562,10 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
min += GOATPOINTS * this.levels[lev].goals[i].count;
turnsreq += this.levels[lev].goals[i].count * 1;
break;
+ case "brick":
+ min += Math.min(CATPOINTS, SLEEPYCATPOINTS) * (BRICKHP/3) * this.levels[lev].goals[i].count;
+ turnsreq += this.levels[lev].goals[i].count * (BRICKHP/3); // avg parades to kill it, maybe a bit less
+ break;
case "turn":
// assume you'll get a parade on most turns.
num = (Math.min(CATPOINTS, SLEEPYCATPOINTS) * this.levels[lev].goals[i].count);
@@ -1542,6 +1635,7 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
this.levels = [];
this.addlevel(1, true);
this.addlevelgoals("food", 5);
+ this.addlevelallowedthings("cat", "food");
this.setstarpoints(1, 50, 60, 80);
this.addlevelthings( "cat", 50, "food", 50);
@@ -1550,41 +1644,38 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
this.addlevelthings("cat", 45, "food", 55);
this.addlevel(3, true);
- this.addlevelallowedthings("cat", "food", "llama");
+ this.addlevelallowedthings("llama");
this.addlevelgoals("llama", 4);
this.addlevel(4, true);
this.addlevelgoals("llama", 5);
this.addlevelgoals("food", 5);
- this.addlevelallowedthings("cat", "food", "llama");
this.addlevel(5, true);
this.addlevelgridwid(5, 6);
this.addlevelgoals("bag", 1);
this.addlevelgoals("turn", 10);
//this.addlevelgoals(5, "points", 600);
- this.addlevelallowedthings("cat", "food", "llama");
// introduce goats!
this.addlevel(6, true);
+ this.addlevelallowedthings("goat");
this.addlevelgoals("goat", 3);
this.addlevelthings("goat", 10, "cat", 50, "food", 30, "llama", 10); // higher than normal goat chance
this.addlevelforcethings("goat", 1);
this.addlevel(7, false);
- this.addlevelallowedthings("goat", "cat", "food", "llama");
this.addlevelgoals("llama", 6);
this.addlevelgoals("goat", 3);
this.addlevel(8, false);
- this.addlevelallowedthings("goat", "cat", "food", "llama");
this.addlevelgoals("llama", 6);
this.addlevelgoals("goat", 4);
this.addlevelgoals("food", 5);
// introduce doors
this.addlevel(9, true);
- this.addlevelallowedthings("goat", "cat", "food", "llama", "door");
+ this.addlevelallowedthings("door");
this.addlevelgoals("door", 1);
this.addlevelgoals("llama", 5);
this.addlevelgoals("cat", 13);
@@ -1592,20 +1683,19 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
this.addlevel(10, false);
this.addlevelgridwid(10, 7);
- this.addlevelallowedthings("goat", "cat", "food", "llama", "door");
this.addlevelgoals("turn", 15);
// introduce sunlight
this.addlevel(11, true);
- this.addlevelallowedthings("goat", "cat", "food", "llama", "door", "sunlight");
+ this.addlevelallowedthings("sunlight");
this.addlevelgoals("cat", 13);
this.addlevelgoals("food", 5);
- this.addlevelgoals("sun", 1);
+ this.addlevelgoals("sunlight", 1);
this.addlevelforcethings("sunlight", 1);
// introduce whitecat
this.addlevel(12, true);
- this.addlevelallowedthings("goat", "cat", "food", "llama", "door", "sunlight", "whitecat");
+ this.addlevelallowedthings("whitecat");
this.addlevelgoals("cat", 15);
this.addlevelgoals("whitecat", 1);
this.addlevelgoals("llama", 6);
@@ -1613,24 +1703,45 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
// introduce toad
this.addlevel(13, true);
- this.addlevelallowedthings("goat", "cat", "food", "llama", "door", "sunlight", "toad");
+ this.addlevelallowedthings("toad");
this.addlevelgoals("toad", 1);
this.addlevelgoals("cat", 20);
this.addlevelgoals("llama", 5);
this.addlevelforcethings("toad", 1);
this.addlevel(14, false);
- this.addlevelallowedthings("goat", "cat", "food", "llama", "door", "sunlight", "toad");
this.addlevelgoals("cat", 25);
this.addlevelgoals("llama", 6);
this.addlevelgoals("food", 15);
- this.addlevel(15, false);
+ // introduce bricks
+ this.addlevel(15, true);
this.addlevelgridwid(15, 8);
- this.addlevelallowedthings("goat", "cat", "food", "llama", "door", "sunlight", "toad");
- this.addlevelgoals("cat", 30);
- this.addlevelgoals("llama", 7);
- this.addlevelgoals("food", 20);
+ this.addlevelallowedthings("brick");
+ this.addlevelgoals("brick", 2);
+ this.addlevelbricks(3, 3,
+ 4, 4
+ );
+
+ this.addlevel(16, false);
+ this.addlevelbricks(3, 3, 4, 3,
+ 3, 4, 4, 4
+ );
+ this.addlevelgoals("brick", 4);
+
+ this.addlevel(17, false);
+ this.addlevelbricks(0,4, 1,4, 2,4, 3,4, 4,4, 5,4, 6,4, 7,4);
+ this.addlevelgoals("cat", 25);
+ this.addlevelgoals("llama", 6);
+
+
+
+ /*
+ hard brick pattern
+ this.addlevelbricks(2, 2, 5, 2,
+ 2, 5, 5, 5
+ );
+ */
for (i = 1; i < this.levels.length; i++) {
var extrastars;
@@ -1671,16 +1782,25 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
populategrid : function() {
var i;
while (!anyvalidmoves()) {
- var x,y,found;
+ var x,y,found,i;
console.log("populating grid...");
clearthings();
- // populate initial things
+ // add bricks
+ for (i = 0; i < game.levels[curlevel].bricks.length; i++) {
+ x = game.levels[curlevel].bricks[i].gridx;
+ y = game.levels[curlevel].bricks[i].gridy;
+ things.push(new thing(x, y, "brick"));
+ console.log("adding brick at " + x + "," + y);
+ }
+
+ // populate initial things in all other spots
for (y = 0; y < GRIDH; y++) {
for (x = 0; x < GRIDW; x++) {
- // start off above the grid
- things.push(new thing(x, y, "random"));
+ if (!getgridthing(x, y)) {
+ things.push(new thing(x, y, "random"));
+ }
}
}
@@ -1698,8 +1818,11 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
// while we don't have enough...
while (countthingsoftype(wanttype) < wantnum) {
// add one.
- var idx;
- idx = rnd(things.length);
+ var idx = -1;
+ // don't overwrite bricks
+ while (idx == -1 || things[idx].type == "brick") {
+ idx = rnd(things.length);
+ }
things[idx].type = wanttype;
donesomething = true;
}
@@ -1944,7 +2067,9 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
// goal description
var ess = "s";
- if (this.levels[curlevel].goals[n].count == 1) {
+ if (this.levels[curlevel].goals[n].type == "food") {
+ ess = "";
+ } else if (this.levels[curlevel].goals[n].count == 1) {
ess = "";
}
@@ -3108,13 +3233,13 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
// next one
x = midpoint2 + gridsize;
- ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ //ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
x += gridsize;
- ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ //ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
x += gridsize;
- ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ //ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
x += gridsize;
@@ -3136,7 +3261,7 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
y = cury + THINGSIZE/4 - HELPTEXTYSPACE/2;
shadowtext(ctx, "Tissue Box", HELPTEXTSIZE, pointscol,
THINGSIZE*1.5, y);
- shadowtext(ctx, "Wakes all sleeping cats.", HELPTEXTSIZE, pointscoldark,
+ shadowtext(ctx, "All sleeping cats wake up.", HELPTEXTSIZE, pointscoldark,
THINGSIZE*1.5, y + HELPTEXTYSPACE);
ctx.drawImage(image['tissues'], textxspace, cury, THINGSIZE, THINGSIZE);
cury += GRIDSIZE;
@@ -3144,7 +3269,7 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
y = cury + THINGSIZE/4 - HELPTEXTYSPACE/2;
shadowtext(ctx, "Shears", HELPTEXTSIZE, pointscol,
THINGSIZE*1.5, y);
- shadowtext(ctx, "Immediately clears all " + llamatext + "s.", HELPTEXTSIZE, pointscoldark,
+ shadowtext(ctx, "All " + llamatext + "s immediately run away.", HELPTEXTSIZE, pointscoldark,
THINGSIZE*1.5, y + HELPTEXTYSPACE);
ctx.drawImage(image['shears'], textxspace, cury, THINGSIZE, THINGSIZE);
cury += GRIDSIZE;
@@ -3152,10 +3277,10 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
y = cury + THINGSIZE/4 - HELPTEXTYSPACE/2;
shadowtext(ctx, "Magic Carpet", HELPTEXTSIZE, pointscol,
THINGSIZE*1.5, y);
- shadowtext(ctx, "Grants a magic fez to all cats.",
+ shadowtext(ctx, "Cats are given a magic fez.",
HELPTEXTSIZE, pointscoldark,
THINGSIZE*1.5, y + HELPTEXTYSPACE);
- shadowtext(ctx, "Fez wearing cats are not scared of " + llamatext + "s.",
+ shadowtext(ctx, "Fez-wearing cats are not scared of " + llamatext + "s.",
HELPTEXTSIZE, pointscoldark,
THINGSIZE*1.5, y + HELPTEXTYSPACE*2);
ctx.drawImage(image['magiccarpet'], textxspace, cury, THINGSIZE, THINGSIZE);
@@ -3263,6 +3388,9 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
y += HELPTEXTYSPACE;
shadowtext(ctx, "+" + GOATPOINTS + " points per goat", HELPTEXTSIZE,pointscol, x, y);
+ y += HELPTEXTYSPACE;
+ y += HELPTEXTYSPACE;
+ y += HELPTEXTYSPACE;
y += HELPTEXTYSPACE;
y += HELPTEXTYSPACE;
cury = y;
@@ -3681,12 +3809,19 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
x += gridsize;
+ cury = y;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
-
-
+ ctx.textAlign = "left";
+ ctx.textBaseline = "bottom";
+ shadowtext(ctx, "Cats must be awake to attack white cats.", HELPTEXTSIZE,helpcol, textxspace, cury);
+ cury += HELPTEXTYSPACE;
} else if (curlevel == 13) {
- cury = this.drawhelpsubtitle(ctx, "Toad", cury);
+ cury = this.drawhelpsubtitle(ctx, "Toads", cury);
ctx.textAlign = "left";
ctx.textBaseline = "bottom";
@@ -3824,6 +3959,206 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
// line to toad falling
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], "#dddd00", LINEWIDTH, PATHARROWSIZE);
+ cury = y;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+
+ ctx.textAlign = "left";
+ ctx.textBaseline = "bottom";
+ shadowtext(ctx, "Cats must be awake to slap toads.", HELPTEXTSIZE,helpcol, textxspace, cury);
+ cury += HELPTEXTYSPACE;
+ } else if (curlevel == 15) {
+ var tempslashes;
+ cury = this.drawhelpsubtitle(ctx, "Bricks", cury);
+
+ ctx.textAlign = "left";
+ ctx.textBaseline = "bottom";
+ shadowtext(ctx, "Like doors, bricks don't fall downwards.", HELPTEXTSIZE,helpcol, textxspace, cury);
+ cury += HELPTEXTYSPACE;
+ shadowtext(ctx, "Hit bricks with parades to damage them.", HELPTEXTSIZE,helpcol, textxspace, cury);
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+
+
+ // top line of brick demo
+ x = imgsize;
+ y = cury;
+ row1y = y;
+
+ ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
+ linex[1] = x + imgsize/2;
+ liney[1] = y + imgsize/2;
+ x += gridsize;
+
+ ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ ctx.drawImage(image['brick'], x, y, imgsize, imgsize);
+ linex[2] = x + imgsize/2;
+ liney[2] = y + imgsize/2;
+ x += gridsize;
+
+ x = imgsize;
+ y += gridsize;
+ row2y = y;
+ ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ linex[0] = x + imgsize/2;
+ liney[0] = y + imgsize/2;
+ x += gridsize;
+
+ ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+
+ // line to show path
+ drawline(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH);
+ drawarrow(ctx, linex[1], liney[1], linex[2], liney[2], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
+
+ // arrow to middle
+ drawarrow(ctx, x + gridsize/2, row2y, midpoint2 - 10, row2y, "red", HELPLINEWIDTH, HELPARROWSIZE);
+
+
+ // damage explanation
+ ctx.textAlign = "left";
+ ctx.textBaseline = "middle";
+ shadowtext(ctx, "(3 damage)", HELPTEXTSIZE,"#dddd00", midpoint2 + gridsize*3 , row2y);
+
+
+ x = midpoint2;
+ y = cury;
+ row1y = y;
+
+ //ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ //ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ ctx.drawImage(image['brick'], x, y, imgsize, imgsize);
+
+ tempslashes = [ imgsize * 0.10, imgsize * 0.25, imgsize * 0.90, imgsize * 0.75 ];
+ drawslashes(ctx, x, y, tempslashes);
+
+ x += gridsize;
+
+ x = midpoint2;
+ y += gridsize;
+ row2y = y;
+ //ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+
+ cury = y;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+ ctx.textAlign = "left";
+ ctx.textBaseline = "bottom";
+ shadowtext(ctx, "After " + BRICKHP + " damage, bricks will break.", HELPTEXTSIZE,helpcol, textxspace, cury);
+ cury += HELPTEXTYSPACE;
+
+ // top line of brick breaking demo
+ x = imgsize;
+ y = cury;
+ row1y = y;
+
+ ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
+ linex[1] = x + imgsize/2;
+ liney[1] = y + imgsize/2;
+ x += gridsize;
+
+ ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ ctx.drawImage(image['brick'], x, y, imgsize, imgsize);
+
+ tempslashes = [ imgsize * 0.20, imgsize * 0.15, imgsize * 0.90, imgsize * 0.75,
+ imgsize * 0.20, imgsize * 0.75, imgsize * 0.90, imgsize * 0.15,
+ imgsize * 0.33, imgsize * 0.25, imgsize * 0.80, imgsize * 0.25,
+ imgsize * 0.33, imgsize * 0.65, imgsize * 0.65, imgsize * 0.65 ];
+ drawslashes(ctx, x, y, tempslashes);
+
+ linex[2] = x + imgsize/2;
+ liney[2] = y + imgsize/2;
+ x += gridsize;
+
+ x = imgsize;
+ y += gridsize;
+ row2y = y;
+ ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ linex[0] = x + imgsize/2;
+ liney[0] = y + imgsize/2;
+ x += gridsize;
+
+ ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+
+ // line to show path
+ drawline(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH);
+ drawarrow(ctx, linex[1], liney[1], linex[2], liney[2], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
+
+ // arrow to middle
+ x = x + gridsize/2;
+ y = row2y;
+
+ x2 = midpoint2 - 10;
+ y2 = y;
+
+ drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
+
+
+ x = midpoint2;
+ y = cury;
+ row1y = y;
+
+ //ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ //ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
+
+ x += gridsize;
+
+ x = midpoint2;
+ y += gridsize;
+ row2y = y;
+ //ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+ ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
+ x += gridsize;
+
+
+ cury = y;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+ cury += HELPTEXTYSPACE;
+ ctx.textAlign = "left";
+ ctx.textBaseline = "bottom";
+ shadowtext(ctx, "Toads and white cats can also break bricks.", HELPTEXTSIZE,helpcol, textxspace, cury);
+ cury += HELPTEXTYSPACE;
}
ctx.textAlign = "center";
@@ -4219,8 +4554,8 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
console.log("changing last clicked thing thing at " + lastmx/GRIDSIZE + "," + lastmy/GRIDSIZE );
what = getthingxy(lastmx, lastmy);
if (what != undefined) {
- what.name = "forcedllama";
- what.type = "llama";
+ what.name = "xxx changed xx";
+ what.type = "sunlight";
game.dirty = true;
}
} else if (ch == 'm') {
@@ -4499,10 +4834,11 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
var i;
imagenames = ['cat', 'catfull', 'catscared', 'llama', 'cheese', 'title',
- 'goat','door','lock','catwalkl','catwalkr','starfull','starempty',
- 'sunlight', 'toad', // special things
- 'bag', 'bagpop', 'fez', 'pow', // effects
- 'tissues', 'shears', 'magiccarpet', 'whitecat' ];
+ 'goat', 'lock','catwalkl','catwalkr','starfull','starempty',
+ 'door', 'sunlight', 'toad', 'whitecat', // special things
+ 'brick', // obstacles
+ 'bag', 'bagpop', 'fez', 'pow', 'brickpop', // effects
+ 'tissues', 'shears', 'magiccarpet' ];
nimages = 0;
maximages = 0;
@@ -4663,7 +4999,7 @@ console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
for (i = 0; i < curpath.length; i++) {
// ... except doors
if (curpath[i].type == "door") {
- game.progress("door", 1);
+ //game.progress("door", 1);
console.log("path has doors!");
// add animation
things.push(new thing(curpath[i].gridx, curpath[i].gridy, "text", "x" + (globmulti+1)));
@@ -4843,7 +5179,7 @@ function getrandomtype() {
var roll,tot,type = null,i;
var thinglist,maxroll = 0;
var speciallist = null;
- var dodb = true;
+ var dodb = false;
if (curlevel >= game.levels.length) {
thinglist = null;
@@ -4862,8 +5198,10 @@ function getrandomtype() {
}
}
- if (dodb) console.log("speciallist is " + speciallist);
+ //if (dodb) console.log("speciallist is " + speciallist);
+ // normally we use default chances for objects, but some levels
+ // have special pre-defined chances.
if (thinglist == undefined || thinglist.length == 0) {
var f;
thinglist = new Array();
@@ -4908,7 +5246,7 @@ function getrandomtype() {
if (matchesgoal) {
var count;
- console.log("****** " + thingtype + " matches goal.");
+ if (dodb) console.log("****** " + thingtype + " matches goal.");
// check if any exist
count = countalivethingsoftype(lookforthing);
if (count <= 1) {
@@ -4937,7 +5275,12 @@ function getrandomtype() {
if (dodb) {
for (i = 0; i < thinglist.length; i++) {
- console.log(thinglist[i].type + ": " + ((thinglist[i].pct / maxroll)*100) + "% [roll " + maxroll + "/" + maxroll + "]");
+ var logline;
+ logline = thinglist[i].type + ": " + ((thinglist[i].pct / maxroll)*100) + "% [roll " + thinglist[i].pct + "/" + maxroll + "]";
+ if (thinglist[i].type == "special") {
+ logline = logline + " - " + speciallist;
+ }
+ console.log(logline);
}
}
@@ -4974,10 +5317,12 @@ function thing(gridx, gridy, type, text, col) {
this.matched = false; // temp for 'match3' things
this.gotfez = false; // for powerups
+ this.slashes = []; // drawing slashes on bricks when damaged
+ // list x,y coords. 0=x1 1=y2 3=x2 4=y2 etc.
if (type == "random") {
type = getrandomtype();
- console.log("got random type "+ type);
+ //console.log("got random type "+ type);
}
// used for various things
if (type == "sunlight") {
@@ -5037,6 +5382,11 @@ function thing(gridx, gridy, type, text, col) {
}
this.lifetime = 0;
+ if (this.type == "brick") {
+ this.hp = BRICKHP;
+ } else {
+ this.hp = -1;
+ }
this.gridx = gridx;
if (gridy == "top") {
@@ -5061,6 +5411,9 @@ function thing(gridx, gridy, type, text, col) {
if (this.type == "bagpop") {
this.yspeed = 0 - rndfloat(8);
this.xspeed = 0 - rndfloat(16) - 1;
+ } else if (this.type == "brickpop") {
+ this.yspeed = 0 - rndfloat(8);
+ this.xspeed = rndfloat(32) - 16;
} else {
this.yspeed = 0;
this.xspeed = 0;
@@ -5109,8 +5462,8 @@ function thing(gridx, gridy, type, text, col) {
}
this.canfall = function() {
- // doors can't fall after their initial drop
- if (this.type == "door") {
+ // doors and bricks can't fall after their initial drop
+ if ((this.type == "door") || (this.type == "brick")) {
if ((this.gridy >= 0) && (this.isnew == false)) {
return false;
}
@@ -5196,10 +5549,10 @@ function thing(gridx, gridy, type, text, col) {
if (this.type == "food") {
points = FOODPOINTS;
- game.progress("food", 1);
+ //game.progress("food", 1);
} else if (this.type == "llama") {
points = LLAMAPOINTS;
- game.progress("llama", 1);
+ //game.progress("llama", 1);
} else if (this.type == "cat") {
if (this.issleepy()) {
points = SLEEPYCATPOINTS;
@@ -5210,10 +5563,10 @@ function thing(gridx, gridy, type, text, col) {
if (this.gotfez) {
points *= 2;
}
- game.progress("cat", 1);
+ //game.progress("cat", 1);
} else if (this.type == "goat") {
points = GOATPOINTS;
- game.progress("goat", 1);
+ //game.progress("goat", 1);
}
// multiplier for path position
@@ -5311,9 +5664,8 @@ function thing(gridx, gridy, type, text, col) {
ctx.textBaseline = "middle";
shadowtext(ctx, this.name, this.size, this.color, BOARDX + this.x,BOARDY + this.y);
} else {
+ var myimage;
if (this.type == "cat") {
- var myimage;
-
if (this.state == "parade") {
myimage = image['cat'];
} else if (this.isscared()) {
@@ -5323,25 +5675,12 @@ function thing(gridx, gridy, type, text, col) {
} else {
myimage = image['cat'];
}
- } else if (this.type == "llama") {
- myimage = image['llama'];
} else if (this.type == "food") {
myimage = image['cheese'];
- } else if (this.type == "goat") {
- myimage = image['goat'];
- } else if (this.type == "door") {
- myimage = image['door'];
- } else if (this.type == "sunlight") {
- myimage = image['sunlight'];
- } else if (this.type == "toad") {
- myimage = image['toad'];
- } else if (this.type == "whitecat") {
- myimage = image['whitecat'];
- } else if (this.type == "bagpop") {
- myimage = image['bagpop'];
- } else if (this.type == "pow") {
- myimage = image['pow'];
} else {
+ myimage = image[this.type];
+ }
+ if (myimage == undefined || myimage == null) {
console.log("ERROR - no image for type " + this.type);
console.log(this);
}
@@ -5378,6 +5717,9 @@ function thing(gridx, gridy, type, text, col) {
ctx.drawImage(myimage, BOARDX + myx, BOARDY + myy, howbig, howbig);
+ // draw slashes on bricks
+ drawslashes(ctx, BOARDX + myx, BOARDY + myy, this.slashes);
+
if (this.gotfez) {
// fw = 0.78 * howbig;
// fh = 0.625 * howbig;
@@ -5507,6 +5849,8 @@ function thing(gridx, gridy, type, text, col) {
this.kill = function() {
// kill ourselves
+ game.progress(this.type, 1);
+
var idx = things.indexOf(this);
things.splice(idx, 1);
}
@@ -5543,7 +5887,7 @@ function thing(gridx, gridy, type, text, col) {
// add "pow"
things.push(new thing(toad.gridx, toad.gridy, "pow"));
- game.progress("toad", 1);
+ //game.progress("toad", 1);
console.log("slap");
}
@@ -5575,7 +5919,7 @@ function thing(gridx, gridy, type, text, col) {
whitecat.addabove();
whitecat.startexplode();
- game.progress("whitecat", 1);
+ //game.progress("whitecat", 1);
console.log("whitecat");
}
@@ -5616,12 +5960,40 @@ function thing(gridx, gridy, type, text, col) {
return false;
}
+ this.breakbrick = function() {
+ var i,nshards = 7;
+ for (i = 0; i < nshards; i++) {
+ things.push(new thing(this.gridx, this.gridy, "brickpop"));
+ }
+
+ this.givepoints();
+ this.addabove();
+ this.kill();
+ }
+
+ this.losehp = function() {
+ this.hp--;
+ console.log("brick hp is at " + this.hp);
+ if (this.hp <= 0) {
+ game.dirty = true; // need to redraw
+ this.breakbrick();
+ } else {
+ // add a slash from a random x/y to a random x/y
+ addslash(this.slashes, THINGSIZE, THINGSIZE);
+ }
+ }
+
this.startexplode = function(why) {
- this.expcount=1;
- this.expmax=EXPLODETICKS;
- this.expfadespeed = EXPLODEFADESPEED;
- this.state = "explode";
- this.explodereason = why;
+ if (this.type == "brick") {
+ // break it instead
+ this.breakbrick();
+ } else {
+ this.expcount=1;
+ this.expmax=EXPLODETICKS;
+ this.expfadespeed = EXPLODEFADESPEED;
+ this.state = "explode";
+ this.explodereason = why;
+ }
}
this.startshrink = function() {
@@ -5688,7 +6060,7 @@ function thing(gridx, gridy, type, text, col) {
var belowthing = null,atbottom = false;
- if (this.type == "bagpop") {
+ if ((this.type == "bagpop") || (this.type == "brickpop")) {
game.dirty = true; // need to redraw
// regular gravity
@@ -5819,7 +6191,7 @@ function thing(gridx, gridy, type, text, col) {
this.calcgridxy();
- // cat parade into a bag?
+ // cat parade into a bag or wall?
if (this.state == "parade") {
var bag;
// hit a bag?
@@ -5828,7 +6200,6 @@ function thing(gridx, gridy, type, text, col) {
if (bag.cats < bag.capacity) {
this.path = [];
this.startshrink();
-console.log("aaa");
bag.cats++;
if (bag.cats >= bag.capacity) {
@@ -5836,6 +6207,16 @@ console.log("aaa");
game.addbagpop(bag.y);
}
}
+ } else {
+ var brick;
+ brick = gridxyhasthingtype(this.gridx, this.gridy, "brick");
+ if (brick != undefined) {
+ // parade cat explodes.
+ this.path = [];
+ this.startexplode();
+
+ brick.losehp();
+ }
}
}
@@ -5843,9 +6224,12 @@ console.log("aaa");
if (xdone && ydone) {
this.poppath();
+ console.log("poppath for " + this.name + " - new len is " + this.path.length);
+
// path finished?
if (this.path == undefined || this.path.length == 0) {
- if (this.state == "catparade" ){
+ if (this.state == "parade" ){
+ console.log("calling kill for parading " + this.type);
this.kill();
} else {
this.state = "stop";
@@ -6055,19 +6439,28 @@ function mainloop() {
for (i = 0; i < things.length; i += 1) {
if (things[i].type == "sunlight" && things[i].gridy >= 0 && !things[i].isnew &&
things[i].state != "swapping" && things[i].counter == 0) {
- if ((things[i].gridy >= GRIDH-1)) {
+ var thingbelow,willdie = false;
+ thingbelow = getgridthing(things[i].gridx, things[i].gridy+1);
+
+ if (thingbelow != undefined && thingbelow.type == "brick") {
+ // bricks stop sun
+ willdie = true;
+ } else if ((things[i].gridy >= GRIDH-1)) {
+ // at bottom - disappear
+ willdie = true;
+ }
+
+ if (willdie) {
// at bottom - disappear
things[i].addabove();
things[i].startexplode("sun");
- game.progress("sun", 1);
+ //game.progress("sun", 1);
} else {
- var thingbelow;
- // move down
+ // move down (swap with thing below us)
things[i].pushpath(things[i].x, things[i].y + GRIDSIZE);
things[i].state = "swapping";
things[i].counter = 1;
- thingbelow = getgridthing(things[i].gridx, things[i].gridy+1);
if (thingbelow != undefined && thingbelow.state != "swapping" &&
thingbelow.type != "sunlight") {
thingbelow.pushpath(things[i].x, things[i].y);
@@ -6142,7 +6535,7 @@ function matchthreefrom(what, locdb) {
var nn;
// matched!
for (nn = 0; nn < setthings.length; nn++) {
- console.log(" "+setthings[nn].name + " x=",setthings[nn].x + ",y=" + setthings[nn].y);
+ //console.log(" "+setthings[nn].name + " x=",setthings[nn].x + ",y=" + setthings[nn].y);
setthings[nn].matched = true;
}
gotmatch = true;
diff --git a/images/brick.png b/images/brick.png
new file mode 100644
index 0000000..7fbbfe3
Binary files /dev/null and b/images/brick.png differ
diff --git a/images/brickpop.png b/images/brickpop.png
new file mode 100644
index 0000000..da21d60
Binary files /dev/null and b/images/brickpop.png differ
diff --git a/images/door.png b/images/door.png
index dca4204..6b1db10 100644
Binary files a/images/door.png and b/images/door.png differ
diff --git a/images/origdoor.png b/images/origdoor.png
new file mode 100644
index 0000000..dca4204
Binary files /dev/null and b/images/origdoor.png differ
diff --git a/todo b/todo
index c8f39c4..f97bb83 100644
--- a/todo
+++ b/todo
@@ -11,13 +11,33 @@ https://www.smashingmagazine.com/2012/10/design-your-own-mobile-game/
-------------------
-*only increase chance of goal items if you haven't already met the goal.
-*make increase chance work for "special" things!!! (eg. white cat)
-*stop increasing goal progress once we hit the required amount
-*seperate goal names and goal associated things
-OBSTACLES on later levels
- fixed position.
+*move goal progress increments to thing.kill() function
+*Make 'allowedthings' default to previous level's one.
+*fix lev6 help
+*bugfix: whitecats aren't ever appearing randomly?
+*new object: bricks
+*Don't allow extending path off the top of the grid.
+*fix incorrect pluralisation "foods" in goal text
+
+??????????????
+no points for cats hitting bricks
+ give points when things DIE, not when you start a parade.
+ make points for parades come from the _side_ of the screen.
+ (where the cats/whatever disappear)
+
+ make kill() take an arg ("don't give progress/points")
+
+ adjust brick points goal
+??????????????
+
+new door fell down on top of new goat!!
+ (or the other way around ??)
+ check code for doors falling when off the top of the screen.
+ check code for adding new objects at top of screen.
+
+Powerup to break bricks
+
other colour cats
@@ -29,14 +49,22 @@ more goals:
more prizes: ???
mouse - place to clear all cats in grid/column
- whitecat - place to clear 3 x 3 grid around it
-
overeat (cheese changes to niblet bags, can eat without sleep)
arrow/signpost - cat parades bounce off and take out htings in the path
diff colour cats which only match themselves
+actual fireworks when you achieve a goal rather than a flash.
+ fireworks later.
+
+random levels after 100
+ generate w/h increases (up to a maximum)
+ generate goals
+ generate obstacles
+ use existing maxturns code
+
+
---------
@@ -54,10 +82,6 @@ sofa/curtain
parade over to scratch
blow up and pow!
-fireworks when you achieve a goal
- *flash for now
- fireworks later.
-
show points for each element along path??