2016-08-18 14:14:48 +10:00
|
|
|
<!DOCTYPE html>
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
<html>
|
|
|
|
<head>
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
<!-- need utf8 for unicode chars -->
|
|
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF8">
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
<!-- Viewport isn't scalable -->
|
2016-08-27 18:00:09 +10:00
|
|
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1, user-scalable=0, minimal-ui">
|
2016-08-26 19:28:12 +10:00
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-26 19:07:47 +10:00
|
|
|
<title>Cat Parade</title>
|
2016-08-20 12:59:29 +10:00
|
|
|
<!-- for apps on home screen -->
|
|
|
|
<!-- for ios 7 style, multi-resolution icon of 152x152 -->
|
|
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
2016-08-27 18:00:09 +10:00
|
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
2016-08-20 15:12:32 +10:00
|
|
|
<link rel="apple-touch-icon" href="images/icon-152.png">
|
2016-08-26 19:07:47 +10:00
|
|
|
|
|
|
|
<!-- for Chrome on Android, multi-resolution icon of 192x192 -->
|
2016-08-20 12:59:29 +10:00
|
|
|
<meta name="mobile-web-app-capable" content="yes">
|
2016-08-26 19:07:47 +10:00
|
|
|
<link rel="manifest" href="manifest.json">
|
|
|
|
<link rel="icon" sizes="192x192" href="images/icon-192.png">
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
<style>
|
2016-08-28 08:27:20 +10:00
|
|
|
body {
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
background: #000000;
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
canvas {
|
2016-08-28 08:27:20 +10:00
|
|
|
display: block;
|
|
|
|
margin: 0 auto;
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
background-color: #000000;
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
2016-08-25 16:49:54 +10:00
|
|
|
@font-face {
|
|
|
|
font-family: "BlueStone";
|
|
|
|
src: url("BlueStone.ttf");
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
</style>
|
|
|
|
</head>
|
2016-08-27 18:00:09 +10:00
|
|
|
<body style="margin: 0; padding:0;" bgcolor="#000000" onload="startGame()">
|
2016-08-28 08:27:20 +10:00
|
|
|
<canvas></canvas>
|
2016-08-18 14:14:48 +10:00
|
|
|
<script>
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
var FONT = "BlueStone";
|
2016-08-28 08:27:20 +10:00
|
|
|
// canvas style did have : border:1px solid #d3d3d3;
|
2016-08-25 16:49:54 +10:00
|
|
|
|
2016-08-29 14:21:42 +10:00
|
|
|
|
2016-09-08 14:15:46 +10:00
|
|
|
var debug = false;
|
2016-08-29 14:21:42 +10:00
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
// game vars
|
2016-08-18 14:14:48 +10:00
|
|
|
var things = [];
|
2016-08-20 11:17:22 +10:00
|
|
|
var score = 0;
|
2016-08-29 19:24:29 +10:00
|
|
|
var globmulti = 0;
|
2016-08-20 12:27:15 +10:00
|
|
|
var overdesc = "";
|
2016-08-18 14:54:54 +10:00
|
|
|
var curpath = [];
|
2016-08-19 17:46:39 +10:00
|
|
|
var pathdir = -1;
|
2016-08-23 01:13:47 +10:00
|
|
|
var pathdoor = null;
|
2016-08-18 16:18:35 +10:00
|
|
|
var pathvalid = false;
|
2016-08-21 09:32:57 +10:00
|
|
|
var curlevel = 1;
|
2016-08-20 12:59:29 +10:00
|
|
|
var lastmx = -1, lastmy = -1;
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
var scorecols = [ "#cccc00", "#00cc00", "#00dddd", "#dd00dd" ];
|
2016-08-21 09:32:57 +10:00
|
|
|
|
2016-08-26 16:31:38 +10:00
|
|
|
var mbdown = false;
|
|
|
|
|
2016-08-25 20:01:45 +10:00
|
|
|
|
|
|
|
var FLASHSPEED = 0.05;
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
var TURNSBARSPEEDUP = 0.02;
|
|
|
|
var TURNSBARSPEEDDOWN = 0.01;
|
2016-08-25 20:01:45 +10:00
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
var BAGCAPACITY = 6; // how many cats to pop a bag
|
2016-09-03 10:52:03 +10:00
|
|
|
var BRICKHP = 6; // how many cats it takes to remove a brick
|
2016-09-02 11:48:48 +10:00
|
|
|
var CURTAINHP = 2; // how many climbs it takes to remove a curtain
|
2016-08-31 13:55:35 +10:00
|
|
|
var SLASHDIST = 3; // space between slash marks on bricks
|
2016-08-25 20:01:45 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
// for background
|
|
|
|
var catalpha = 1.0;
|
|
|
|
|
|
|
|
var ctx = null;
|
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
// goal types
|
|
|
|
var GOALVERB = {
|
2016-08-30 17:19:28 +10:00
|
|
|
'turn': 'Survive',
|
2016-08-29 19:24:29 +10:00
|
|
|
//'points': 'Earn',
|
|
|
|
//parades': 'Form',
|
2016-08-30 17:19:28 +10:00
|
|
|
'food': 'Eat',
|
|
|
|
'llama': 'Clear',
|
|
|
|
'cat': 'Clear',
|
|
|
|
'goat': 'Clear',
|
|
|
|
'door': 'Enter',
|
2016-08-31 13:55:35 +10:00
|
|
|
'sunlight': 'Wait out',
|
2016-08-30 17:19:28 +10:00
|
|
|
'bag': 'Burst',
|
|
|
|
'toad': 'Slap',
|
|
|
|
'whitecat': 'Attack',
|
2016-08-31 13:55:35 +10:00
|
|
|
'brick': 'Break',
|
2016-09-02 11:48:48 +10:00
|
|
|
'curtain': 'Shred',
|
2016-09-03 10:52:03 +10:00
|
|
|
'ambush': 'Launch',
|
2016-08-21 09:32:57 +10:00
|
|
|
};
|
|
|
|
|
2016-08-30 19:46:40 +10:00
|
|
|
var GOALNAME = {
|
|
|
|
'whitecat': 'white cat',
|
2016-08-31 13:55:35 +10:00
|
|
|
'sunlight': 'sun',
|
2016-08-30 19:46:40 +10:00
|
|
|
};
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
var prizetypes = [
|
2016-08-30 17:19:28 +10:00
|
|
|
"tissues", "shears", "magiccarpet",
|
2016-08-30 14:55:26 +10:00
|
|
|
];
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
var wipe = {
|
|
|
|
to: "",
|
|
|
|
dir: "",
|
|
|
|
count: 0,
|
|
|
|
active: false,
|
|
|
|
|
|
|
|
isactive : function() {
|
|
|
|
if (this.active) {
|
|
|
|
return this.dir;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
// howin and howoutout should be 'up' or 'down'
|
|
|
|
getval : function(fullamt, howin, howout, def) {
|
|
|
|
var num,how;
|
|
|
|
if (this.active) {
|
|
|
|
if (this.dir == "in") {
|
|
|
|
how = howin;
|
|
|
|
} else if (this.dir == "out") {
|
|
|
|
how = howout;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
num = (this.count / this.max) * fullamt;
|
|
|
|
if (how == "down") {
|
|
|
|
num = fullamt - num;
|
|
|
|
}
|
|
|
|
return num;
|
|
|
|
},
|
|
|
|
|
|
|
|
start : function(nextstate, dir, howlong) {
|
|
|
|
this.to = nextstate;
|
|
|
|
this.count = 0;
|
|
|
|
this.max = howlong;
|
|
|
|
this.dir = dir;
|
|
|
|
this.active = true;
|
|
|
|
},
|
|
|
|
|
|
|
|
tick : function() {
|
|
|
|
this.count++;
|
|
|
|
if (this.count >= this.max) {
|
|
|
|
var nextstate = this.to;
|
|
|
|
this.active = false;
|
|
|
|
this.to = "";
|
|
|
|
this.count = 0;
|
|
|
|
if (nextstate != "") {
|
|
|
|
game.setstate(nextstate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2016-08-26 16:27:42 +10:00
|
|
|
//var FULLSTAR = "\u2605";
|
|
|
|
//var EMPTYSTAR = "\u2606";
|
|
|
|
|
2016-08-27 13:18:03 +10:00
|
|
|
var STARWID_TOPGOALS = 16;
|
2016-08-26 16:27:42 +10:00
|
|
|
var STARWID_LEVSEL = 16;
|
|
|
|
var STARWID_LEVSEL_LOCKED = 16;
|
|
|
|
var STARWID_LEVSEL_TOP = 24;
|
|
|
|
var STARWID_ENDLEV = 32;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-24 22:47:23 +10:00
|
|
|
var DEF_GRIDSIZE = 80;
|
|
|
|
var DEF_THINGSIZE = 64;
|
|
|
|
var DEF_GRIDW = 5;
|
|
|
|
var DEF_GRIDH = 5;
|
|
|
|
var GRIDSIZE = null;
|
|
|
|
var THINGSIZE = null;
|
|
|
|
var GRIDW = null;
|
|
|
|
var GRIDH = null;
|
|
|
|
|
2016-08-31 15:19:51 +10:00
|
|
|
var FIREWORKSIZE = 5;
|
|
|
|
var FIREWORKFADESPEED = 0.015;
|
|
|
|
var FIREWORKSHARDS = 32;
|
|
|
|
var FIREWORKCOUNT = 4;
|
|
|
|
var FIREWORKTRAILLEN = 5;
|
|
|
|
|
2016-08-18 14:54:54 +10:00
|
|
|
var MAXDIRS = 4;
|
|
|
|
var DIRXMOD = [ 0, 1, 0, -1 ];
|
|
|
|
var DIRYMOD = [ -1, 0, 1, 0 ];
|
2016-08-30 14:55:26 +10:00
|
|
|
var DIRNAME = [ "n", "e", "s", "w"];
|
2016-08-18 14:54:54 +10:00
|
|
|
|
2016-08-30 17:19:28 +10:00
|
|
|
var MAXDIAGDIRS = 8;
|
|
|
|
var DIAGDIRXMOD = [ 0, 1, 1, 1, 0, -1, -1, -1 ];
|
|
|
|
var DIAGDIRYMOD = [ -1, -1, 0, 1, 1, 1, 0, -1 ];
|
|
|
|
var DIAGDIRNAME = [ "n", "ne", "e", "se", "s", "sw", "w", "nw"];
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
var NUMWINIMAGES = 26;
|
2016-08-22 19:52:15 +10:00
|
|
|
var WINIMGZOOMSPEED = 0.1;
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
var SCREENW = 480;
|
|
|
|
var SCREENH = 640;
|
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
var GRAVITY = 0.5;
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-29 14:21:42 +10:00
|
|
|
var TURNSLEFTTEXTSIZE = 12;
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
var TEXTSIZE = 16; // in points
|
2016-08-23 01:13:47 +10:00
|
|
|
var TEXTSIZEMULTIPLIER = 28; // in points
|
2016-08-20 11:17:22 +10:00
|
|
|
var TEXTSPEED = 0.5;
|
|
|
|
var TEXTFADESPEED = 0.05;
|
|
|
|
var TEXTTIME = 35;
|
2016-08-25 20:01:45 +10:00
|
|
|
var TEXTSIZEGOALGET = 38; // in points
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
var LEVELTEXTSIZE = 12;
|
|
|
|
var SCORETEXTSIZE = 14;
|
|
|
|
var STARPOINTTEXTSIZE = 10;
|
|
|
|
|
|
|
|
var TITLESIZELEVSELECT = 18; // in points
|
|
|
|
var TEXTSIZELEVSELECT = 20; // in points
|
|
|
|
var TEXTSIZETOTSTARS = 16; // in points
|
|
|
|
var TEXTSIZELEVSCORE = 8; // in points
|
2016-09-03 10:52:03 +10:00
|
|
|
var TEXTSIZELEVSTARS = 10; // in points
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
var TEXTSIZELEVSCROLL = 22; // in points
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
var HELPLINEWIDTH=4;
|
|
|
|
var HELPARROWSIZE=15;
|
|
|
|
var HELPTITLESIZE = 18;
|
2016-08-22 19:52:15 +10:00
|
|
|
var HELPSUBTITLESIZE = 14;
|
2016-08-25 16:49:54 +10:00
|
|
|
//var HELPTEXTSIZE = 12;
|
|
|
|
var HELPTEXTSIZE = 9;
|
2016-08-20 15:12:32 +10:00
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
var GOALTEXTSIZE = 14;
|
2016-08-21 09:32:57 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
var HELPTEXTYSPACE = HELPTEXTSIZE * 1.8;
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
var TITLETEXTSIZE = 36;
|
|
|
|
var TITLECREDITTEXTSIZE = 16;
|
|
|
|
var TITLESTARTTEXTSIZE = 26;
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
var BACKTOTITLESIZE = 20; // game over button
|
|
|
|
var TAPBUTTONSIZE = 26; // game over button
|
|
|
|
var TAPBUTTONSIZEC = 20; // levcomplete button
|
|
|
|
var TAPBUTTONSIZESTAR = 26; // levcomplete button
|
|
|
|
|
2016-08-24 22:47:23 +10:00
|
|
|
var PARADESPEED=12;
|
2016-08-20 11:17:22 +10:00
|
|
|
|
|
|
|
var EXPLODETICKS=20;
|
2016-08-24 22:47:23 +10:00
|
|
|
var EXPLODEGAIN= (DEF_THINGSIZE*2) / EXPLODETICKS;
|
2016-08-20 11:17:22 +10:00
|
|
|
var EXPLODEFADESPEED = 1.0 / EXPLODETICKS;
|
|
|
|
|
2016-08-23 01:13:47 +10:00
|
|
|
var SHRINKTICKS=20;
|
2016-08-24 22:47:23 +10:00
|
|
|
var SHRINKLOSE= (DEF_THINGSIZE / SHRINKTICKS);
|
2016-08-23 01:13:47 +10:00
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
var LINEWIDTH=2;
|
|
|
|
var CROSSWIDTH=2;
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
var BOTTOMBORDERWIDTH=3;
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
var LEVSELGRIDW = 5;
|
|
|
|
var LEVSELGRIDH = 6;
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
var PATHARROWSIZE = 10;
|
2016-08-25 16:49:54 +10:00
|
|
|
var PATHLINECOLGOOD = "#00ee00";
|
|
|
|
var PATHLINECOLBAD = "#ee0000";
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
var FALLARROWSIZE = 4;
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
var PARADELENGTH = 3;
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
var LEVSEL_X = Math.floor((SCREENW - (DEF_GRIDW * DEF_GRIDSIZE)) / 2);
|
|
|
|
var LEVSEL_Y = 64;
|
|
|
|
|
|
|
|
var DEF_BOARDX = Math.floor((SCREENW - (DEF_GRIDW * DEF_GRIDSIZE)) /2 );
|
|
|
|
var BOARDX = DEF_BOARDX;
|
2016-08-20 11:17:22 +10:00
|
|
|
var BOARDY = 64;
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// 'tap to continue' button
|
|
|
|
var tapx,tapy,tapw,taph;
|
|
|
|
|
|
|
|
// back to title screen buton
|
|
|
|
var levsel_contx = BOARDX;
|
2016-08-24 22:47:23 +10:00
|
|
|
var levsel_conty = BOARDY + (DEF_GRIDSIZE*DEF_GRIDH) + DEF_GRIDSIZE + DEF_GRIDSIZE/4;
|
2016-08-22 19:52:15 +10:00
|
|
|
var levsel_contw = SCREENW - (BOARDX*2);
|
2016-08-24 22:47:23 +10:00
|
|
|
var levsel_conth = (DEF_GRIDSIZE/2);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
var FOODPOINTS = 10;
|
|
|
|
var LLAMAPOINTS = 100;
|
2016-08-22 19:52:15 +10:00
|
|
|
var GOATPOINTS = 50;
|
|
|
|
var CATPOINTS = 20;
|
2016-08-23 01:13:47 +10:00
|
|
|
var SLEEPYCATPOINTS = 40;
|
2016-09-03 10:52:03 +10:00
|
|
|
var CATBOXPOINTS = 40;
|
2016-08-20 15:12:32 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
var overdesc = "";
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
var llamatext = "llama";
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
var image = new Array();
|
2016-08-22 19:52:15 +10:00
|
|
|
var winimg = null;
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-27 12:35:18 +10:00
|
|
|
|
2016-08-27 12:25:17 +10:00
|
|
|
var nimages = 0;
|
|
|
|
var maximages = 0;
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
function loadimage(name, filename) {
|
|
|
|
image[name] = new Image();
|
2016-08-28 08:27:20 +10:00
|
|
|
image[name].onload = game.incloadprogress;
|
2016-08-20 11:17:22 +10:00
|
|
|
image[name].src = filename;
|
|
|
|
}
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
function getgridthing(gridx, gridy) {
|
|
|
|
var i;
|
2016-08-19 17:46:39 +10:00
|
|
|
if (things == undefined) return null;
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
// only include non-animating things
|
2016-08-18 14:14:48 +10:00
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
if ((things[i].gridx == gridx) && (things[i].gridy == gridy)) {
|
2016-08-20 11:17:22 +10:00
|
|
|
if (!things[i].isanimating()) {
|
|
|
|
return things[i];
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getthingxy(x, y) {
|
2016-08-20 15:12:32 +10:00
|
|
|
var i,gridx,gridy;
|
|
|
|
var thing;
|
|
|
|
// use thing coords
|
|
|
|
/*
|
2016-08-18 14:14:48 +10:00
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
if ((x >= things[i].x) && (x <= things[i].x + THINGSIZE-1) &&
|
|
|
|
(y >= things[i].y) && (y <= things[i].y + THINGSIZE-1)) {
|
|
|
|
return things[i];
|
|
|
|
}
|
|
|
|
}
|
2016-08-20 15:12:32 +10:00
|
|
|
*/
|
|
|
|
// use grid coords
|
|
|
|
gridx = Math.floor(x / GRIDSIZE);
|
|
|
|
gridy = Math.floor(y / GRIDSIZE);
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
return getgridthing(gridx, gridy);
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
function clearpath() {
|
|
|
|
curpath = [];
|
2016-08-19 17:46:39 +10:00
|
|
|
pathdir = -1;
|
2016-08-18 16:18:35 +10:00
|
|
|
pathvalid = false;
|
|
|
|
}
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
function pathcomplete() {
|
|
|
|
// get path type
|
|
|
|
switch(getpathtype()) {
|
|
|
|
case "chomp":
|
2016-09-03 10:52:03 +10:00
|
|
|
if (curpath.length >= 2 &&
|
|
|
|
( (curpath[0].type == "cat" && !curpath[0].issleepy()) ||
|
|
|
|
(curpath[0].type == "box" && curpath[0].boxfull) ) ) {
|
2016-08-19 17:46:39 +10:00
|
|
|
var i;
|
2016-09-03 10:52:03 +10:00
|
|
|
var ok = true,lastok = false;
|
|
|
|
// everything else except last is food?
|
|
|
|
for (i = 1; i < curpath.length-1; i++) {
|
2016-08-19 17:46:39 +10:00
|
|
|
if (curpath[i].type != "food") {
|
|
|
|
ok = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-09-03 10:52:03 +10:00
|
|
|
|
|
|
|
// last one is food?
|
|
|
|
if (curpath[curpath.length-1].type == "food") {
|
|
|
|
lastok = true;
|
|
|
|
} else if (curpath[curpath.length-1].type == "box" &&
|
|
|
|
!curpath[curpath.length-1].boxfull &&
|
|
|
|
curpath[0].type == "cat") {
|
|
|
|
// last one is empty box, and first one was a cat?
|
|
|
|
lastok = true;
|
|
|
|
}
|
|
|
|
if (ok && lastok) {
|
2016-08-19 17:46:39 +10:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2016-08-30 17:19:28 +10:00
|
|
|
case "slap":
|
|
|
|
if ((curpath.length == 2) &&
|
|
|
|
(curpath[0].type == "cat") &&
|
|
|
|
(curpath[1].type == "toad") &&
|
|
|
|
!curpath[0].issleepy()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "attack":
|
|
|
|
if ((curpath.length == 2) &&
|
|
|
|
(curpath[0].type == "cat") &&
|
|
|
|
(curpath[1].type == "whitecat") &&
|
|
|
|
!curpath[0].issleepy()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
2016-08-19 17:46:39 +10:00
|
|
|
case "parade":
|
|
|
|
// long enough?
|
|
|
|
if (curpath.length >= PARADELENGTH) {
|
2016-08-22 19:52:15 +10:00
|
|
|
var lcount = 0,gcount = 0;
|
2016-08-19 17:46:39 +10:00
|
|
|
var i;
|
2016-08-31 17:45:15 +10:00
|
|
|
// includes <= 1 llama or has a goat?
|
2016-08-19 17:46:39 +10:00
|
|
|
for (i = 1; i < curpath.length; i++) {
|
|
|
|
if (curpath[i].type == "llama") {
|
2016-08-22 19:52:15 +10:00
|
|
|
lcount++;
|
|
|
|
} else if (curpath[i].type == "goat") {
|
|
|
|
gcount++;
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
if ((lcount <= 1) || (gcount)) {
|
2016-08-19 17:46:39 +10:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2016-09-02 11:48:48 +10:00
|
|
|
case "climb":
|
|
|
|
if ((curpath[0].type == "cat") &&
|
|
|
|
(curpath[1].type == "curtain") &&
|
|
|
|
(curpath[curpath.length-1].type != "curtain") &&
|
|
|
|
!curpath[0].issleepy()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function backspacepath() {
|
|
|
|
// remove last thing in path
|
|
|
|
curpath.splice(curpath.length-1, 1);
|
|
|
|
|
|
|
|
validatepath();
|
|
|
|
|
|
|
|
dumppath("Reduced path to: ",curpath);
|
|
|
|
}
|
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
function addtopath(what) {
|
|
|
|
console.log("addpath() " + what.name);
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
//dumppath("addpath pre: ", curpath);
|
2016-08-18 16:18:35 +10:00
|
|
|
|
|
|
|
curpath.push(what);
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
validatepath();
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
/*
|
2016-08-18 16:18:35 +10:00
|
|
|
if (curpath.length == 1) {
|
|
|
|
console.log("Starting path with " + what.name);
|
|
|
|
} else {
|
|
|
|
dumppath("Cur path is: ",curpath);
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
*/
|
2016-08-18 16:18:35 +10:00
|
|
|
}
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
function validatepath() {
|
|
|
|
if (pathcomplete()) {
|
|
|
|
pathvalid = true;
|
|
|
|
} else {
|
|
|
|
pathvalid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (curpath.length == 2) {
|
|
|
|
pathdir = getdir(curpath[0], curpath[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-18 14:54:54 +10:00
|
|
|
function pathcontains(what) {
|
|
|
|
var i;
|
|
|
|
if (curpath == undefined) return false;
|
|
|
|
|
|
|
|
for (i = 0; i < curpath.length; i += 1) {
|
|
|
|
if (curpath[i] == what) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-23 01:13:47 +10:00
|
|
|
// return sfirst thing of matching type
|
|
|
|
function pathcontainstype(type) {
|
|
|
|
var i;
|
|
|
|
if (curpath == undefined) return false;
|
|
|
|
|
|
|
|
for (i = 0; i < curpath.length; i += 1) {
|
|
|
|
if (curpath[i].type == type) {
|
|
|
|
return curpath[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
function catcolmatches(a, b) {
|
|
|
|
var cola,colb;
|
|
|
|
|
|
|
|
if (a.type == "box") {
|
|
|
|
cola = null;
|
|
|
|
} else {
|
|
|
|
cola = a.catcol;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (b.type == "box") {
|
|
|
|
colb = null;
|
|
|
|
} else {
|
|
|
|
colb = b.catcol;
|
|
|
|
}
|
|
|
|
if (cola == undefined) return true;
|
|
|
|
if (colb == undefined) return true;
|
|
|
|
if (cola == colb) return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
function isvalidpath(mypath) {
|
|
|
|
var valid = true;
|
2016-08-22 19:52:15 +10:00
|
|
|
var fcount = 0;
|
2016-08-19 17:46:39 +10:00
|
|
|
var lcount = 0;
|
2016-08-22 19:52:15 +10:00
|
|
|
var gcount = 0;
|
2016-08-23 01:13:47 +10:00
|
|
|
var count = 0;
|
2016-09-02 11:48:48 +10:00
|
|
|
var ccount = 0;
|
2016-08-19 17:46:39 +10:00
|
|
|
var i;
|
2016-09-03 10:52:03 +10:00
|
|
|
//var startcol = null;
|
|
|
|
var firstone = null;
|
2016-08-18 16:18:35 +10:00
|
|
|
|
|
|
|
for (i = 0; i < mypath.length - 1; i++) {
|
2016-08-30 17:19:28 +10:00
|
|
|
var thisone,nextone,dirtonext;
|
2016-08-18 16:18:35 +10:00
|
|
|
thisone = mypath[i];
|
|
|
|
/*
|
|
|
|
if (i == mypath.length - 1) { // last one
|
|
|
|
nextone = null;
|
|
|
|
} else {
|
|
|
|
nextone = mypath[i+1];
|
|
|
|
}
|
|
|
|
*/
|
2016-08-31 17:45:15 +10:00
|
|
|
|
|
|
|
if (i == 0) {
|
2016-09-03 10:52:03 +10:00
|
|
|
/*
|
|
|
|
if (thisone.type == "box") {
|
|
|
|
startcol = null;
|
|
|
|
} else {
|
|
|
|
startcol = thisone.catcol;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
firstone = thisone;
|
2016-08-31 17:45:15 +10:00
|
|
|
}
|
2016-08-18 16:18:35 +10:00
|
|
|
nextone = mypath[i+1];
|
|
|
|
|
2016-08-30 17:19:28 +10:00
|
|
|
dirtonext = getdir(thisone, nextone);
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
if (thisone.type == "food") {
|
|
|
|
fcount++;
|
|
|
|
}
|
|
|
|
if (thisone.type == "llama") {
|
|
|
|
lcount++;
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
if (thisone.type == "goat") {
|
|
|
|
gcount++;
|
|
|
|
}
|
2016-09-02 11:48:48 +10:00
|
|
|
if (thisone.type == "curtain") {
|
|
|
|
ccount++;
|
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
count++;
|
2016-08-19 17:46:39 +10:00
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
if ((thisone.type == "cat") && (nextone.type == "cat") && catcolmatches(nextone, firstone) && (ccount == 0)) {
|
2016-08-22 19:52:15 +10:00
|
|
|
// no parades on level 1
|
|
|
|
if (curlevel == 1) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-31 17:45:15 +10:00
|
|
|
// ...but otherwise lines of cats are ok if they're the right colour
|
2016-09-03 10:52:03 +10:00
|
|
|
} else if ((thisone.type == "cat") && (nextone.type == "box") && (nextone.boxfull == true) && (ccount == 0)) {
|
|
|
|
// full boxes can be part of parades, colour doesn't matter
|
|
|
|
} else if (thisone.type == "box" && thisone.boxfull &&
|
|
|
|
((nextone.type == "cat" && catcolmatches(nextone, firstone)) || nextone.type == "llama" || nextone.type == "goat")) {
|
|
|
|
|
|
|
|
// full boxes can be part of parades, colour doesn't matter
|
|
|
|
} else if (thisone.type == "box" && thisone.boxfull &&
|
|
|
|
nextone.type == "box" && nextone.boxfull) {
|
|
|
|
// full boxes can parade on to other full boxes
|
2016-09-02 11:48:48 +10:00
|
|
|
} else if ((thisone.type == "goat") && (ccount == 0) &&
|
2016-09-04 11:47:42 +10:00
|
|
|
((nextone.type == "cat" && catcolmatches(nextone, firstone)) || nextone.type == "llama" || nextone.type == "goat") || (nextone.type == "box" && nextone.boxfull == true)) {
|
|
|
|
// goat can go to llama or correctly coloured cat or cat-in-box
|
2016-08-22 19:52:15 +10:00
|
|
|
// ok
|
2016-09-02 11:48:48 +10:00
|
|
|
} else if ((nextone.type == "door") && (count >= PARADELENGTH) && (fcount == 0) && (ccount == 0) && (count >= 3) &&
|
2016-09-04 11:47:42 +10:00
|
|
|
(thisone.type == "goat" || thisone.type == "cat" || thisone.type == "llama" || (thisone.type == "box" && thisone.boxfull == true))) {
|
2016-08-23 01:13:47 +10:00
|
|
|
// completed parades can extend into doors
|
2016-09-02 11:48:48 +10:00
|
|
|
} else if ((thisone.type == "cat") && nextone.type == "llama" && (ccount == 0)) {
|
2016-08-22 19:52:15 +10:00
|
|
|
// no parades on level 1
|
|
|
|
if (curlevel == 1) {
|
2016-08-19 17:46:39 +10:00
|
|
|
return false;
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
// cat -> llama is only okay if:
|
|
|
|
// 1. there is no food in the path
|
2016-08-19 17:46:39 +10:00
|
|
|
if (fcount >= 1) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
// and either:
|
|
|
|
// 2a. there are no other llamas in the path
|
|
|
|
if (lcount >= 1) {
|
|
|
|
// or
|
|
|
|
// 2b. there is a goat in the path
|
|
|
|
if (!gcount) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2016-09-02 11:48:48 +10:00
|
|
|
} else if ((thisone.type == "cat") && nextone.type == "goat" && (ccount == 0)) {
|
2016-08-22 19:52:15 +10:00
|
|
|
// cat -> goat is okay
|
2016-09-03 10:52:03 +10:00
|
|
|
} else if ((thisone.type == "llama") && (ccount == 0) &&
|
|
|
|
((nextone.type == "cat" && catcolmatches(nextone, firstone)) || nextone.type == "goat")) {
|
2016-08-22 19:52:15 +10:00
|
|
|
// no parades on level 1
|
|
|
|
if (curlevel == 1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// ...but otherwise llama -> goat/cat is okay
|
|
|
|
|
2016-09-02 11:48:48 +10:00
|
|
|
} else if ((thisone.type == "llama") && (nextone.type == "llama") && !ccount) {
|
2016-08-22 19:52:15 +10:00
|
|
|
// llama -> llama okay if we have a goat in the path
|
|
|
|
if (!gcount) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-09-02 13:42:47 +10:00
|
|
|
} else if (thisone.type == "curtain") {
|
|
|
|
// anywhere from a curtain is okay. (direction checked in canextendpath())
|
2016-08-18 16:18:35 +10:00
|
|
|
} else if ((i == 0) && (thisone.type == "cat") && (nextone.type == "food")) {
|
|
|
|
// first cat -> food is ok
|
2016-09-03 10:52:03 +10:00
|
|
|
} else if ((i == 0) && (thisone.type == "box") && thisone.boxfull && (nextone.type == "food")) {
|
|
|
|
// first full box -> food is ok
|
2016-08-30 17:19:28 +10:00
|
|
|
} else if ((i == 0) && (thisone.type == "cat") && (nextone.type == "toad")) {
|
|
|
|
// first cat -> toad is ok
|
2016-09-02 13:42:47 +10:00
|
|
|
} else if ((i == 0) && (thisone.type == "cat") && (nextone.type == "curtain")) {
|
|
|
|
// first cat -> curtain is ok if we're going UP/DOWN only
|
2016-08-30 17:19:28 +10:00
|
|
|
} else if ((i == 0) && (thisone.type == "cat") && (nextone.type == "whitecat")) {
|
|
|
|
// first cat -> whitecat is ok
|
2016-09-03 10:52:03 +10:00
|
|
|
} else if ((i == 0) && (thisone.type == "cat") && (nextone.type == "box") && !nextone.boxfull) {
|
|
|
|
// first cat -> box is ok
|
|
|
|
} else if ((i != 0) && (firstone.type == "cat" || firstone.type == "box") && (ccount == 0) && (thisone.type == "food") && (nextone.type == "food")) {
|
|
|
|
// not the first one, first one was a cat/box, this one and next are food
|
|
|
|
} else if ((i != 0) && (firstone.type == "cat") && (ccount == 0) && (thisone.type == "food") &&
|
|
|
|
(nextone.type == "box") && !nextone.boxfull) {
|
|
|
|
// not the first one, first one was a cat, food -> box
|
2016-08-18 16:18:35 +10:00
|
|
|
} else {
|
|
|
|
// not ok
|
|
|
|
valid = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
// would adding 'overthing' to our existing path result in a valid path?
|
|
|
|
function canextendpath(overthing) {
|
2016-08-21 11:31:19 +10:00
|
|
|
var pathtype;
|
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
if (!overthing) return false;
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
if (!isongrid(overthing.gridx, overthing.gridy)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-21 11:31:19 +10:00
|
|
|
pathtype = getpathtype();
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
if ( isadjacent(overthing, curpath[curpath.length-1]) && // adjacent to last thing in path?
|
|
|
|
!pathcontains(overthing) && // path doesn't already contain this?
|
2016-08-21 11:31:19 +10:00
|
|
|
(pathtype == "parade" || isinpathdir(overthing)) // path in a straight line
|
2016-08-19 17:46:39 +10:00
|
|
|
) {
|
2016-08-18 16:18:35 +10:00
|
|
|
// create a fake new path containing this.
|
|
|
|
var fakepath = curpath.slice();
|
2016-08-21 11:31:19 +10:00
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
fakepath.push(overthing);
|
|
|
|
if (isvalidpath(fakepath)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-18 14:54:54 +10:00
|
|
|
function isadjacent(thing1, thing2) {
|
|
|
|
// is thing1 adjacent to thing2?
|
|
|
|
var newgridx,newgridy;
|
2016-08-19 17:46:39 +10:00
|
|
|
var i;
|
2016-08-18 14:54:54 +10:00
|
|
|
|
|
|
|
if (thing1 == thing2) return false;
|
|
|
|
|
|
|
|
for (i = 0; i < MAXDIRS; i++) {
|
|
|
|
newgridx = thing1.gridx + DIRXMOD[i];
|
|
|
|
newgridy = thing1.gridy + DIRYMOD[i];
|
|
|
|
if ((thing2.gridx == newgridx) && (thing2.gridy == newgridy)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
function isinpathdir(what) {
|
|
|
|
var thisdir;
|
|
|
|
if (curpath.length <= 1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get dir from last cell to what
|
|
|
|
thisdir = getdir(curpath[curpath.length - 1], what);
|
|
|
|
if ((thisdir != -1) && (thisdir == pathdir)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getdir(thing1, thing2) {
|
|
|
|
var i;
|
|
|
|
for (i = 0; i < MAXDIRS; i++) {
|
|
|
|
var newgx = thing1.gridx + DIRXMOD[i];
|
|
|
|
var newgy = thing1.gridy + DIRYMOD[i];
|
|
|
|
|
|
|
|
if ((thing2.gridx == newgx) && (thing2.gridy == newgy)) {
|
|
|
|
return i;
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
|
|
|
}
|
2016-08-19 17:46:39 +10:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
function startGame() {
|
2016-08-25 16:49:54 +10:00
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
game.init();
|
2016-08-21 09:32:57 +10:00
|
|
|
game.initlevels();
|
2016-08-20 12:59:29 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
playerdata.load();
|
|
|
|
|
2016-08-26 16:27:42 +10:00
|
|
|
//window.addEventListener('load', game.init, false);
|
2016-08-20 12:59:29 +10:00
|
|
|
window.addEventListener('resize', game.resize, false);
|
2016-08-20 15:12:32 +10:00
|
|
|
|
|
|
|
mainloop();
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
// valid types:
|
|
|
|
// none
|
|
|
|
// chomp
|
|
|
|
// parade
|
|
|
|
function getpathtype() {
|
|
|
|
if (curpath.length <= 1) return "none"
|
|
|
|
|
|
|
|
if (curpath[0].type == "cat") {
|
2016-09-03 10:52:03 +10:00
|
|
|
if ((curpath[1].type == "food") || (curpath[1].type == "box" && !curpath[1].boxfull)) {
|
2016-08-19 17:46:39 +10:00
|
|
|
return "chomp";
|
2016-08-30 17:19:28 +10:00
|
|
|
} else if (curpath[1].type == "toad") {
|
|
|
|
return "slap";
|
2016-09-02 11:48:48 +10:00
|
|
|
} else if (curpath[1].type == "curtain") {
|
|
|
|
return "climb";
|
2016-08-30 17:19:28 +10:00
|
|
|
} else if (curpath[1].type == "whitecat") {
|
|
|
|
return "attack";
|
2016-09-03 10:52:03 +10:00
|
|
|
} else if ((curpath[1].type == "cat") || (curpath[1].type == "llama") || (curpath[1].type == "goat")
|
|
|
|
|| (curpath[1].type == "box" && curpath[1].boxfull) ) {
|
|
|
|
return "parade";
|
|
|
|
}
|
|
|
|
} else if (curpath[0].type == "box") {
|
|
|
|
if (curpath[1].type == "food") {
|
|
|
|
return "chomp";
|
|
|
|
} else if ((curpath[1].type == "cat") || (curpath[1].type == "llama") || (curpath[1].type == "goat")
|
|
|
|
|| (curpath[1].type == "box" && curpath[1].boxfull) ) {
|
2016-08-19 17:46:39 +10:00
|
|
|
return "parade";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "none";
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
function dumppath(prefix,arr) {
|
2016-08-18 14:54:54 +10:00
|
|
|
var str;
|
2016-08-19 17:46:39 +10:00
|
|
|
var i;
|
2016-08-18 14:54:54 +10:00
|
|
|
str = "";
|
2016-08-18 16:18:35 +10:00
|
|
|
for (i = 0; i < arr.length; i++) {
|
|
|
|
str = str + " " + arr[i].name;
|
2016-08-18 14:54:54 +10:00
|
|
|
}
|
2016-08-18 16:18:35 +10:00
|
|
|
console.log(prefix + str);
|
2016-08-18 14:54:54 +10:00
|
|
|
}
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
function thingsfalling() {
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
/*
|
|
|
|
switch (things[i].state) {
|
|
|
|
case "parade": // ok
|
|
|
|
case "chomp": // ok
|
|
|
|
case "stop": //ok
|
|
|
|
break;
|
|
|
|
default: // anything else
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
if (things[i].state == "fall") {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-18 14:54:54 +10:00
|
|
|
function thingsmoving() {
|
2016-08-19 17:46:39 +10:00
|
|
|
var i;
|
2016-08-20 11:34:25 +10:00
|
|
|
for (i = 0; i < things.length; i += 1) {
|
2016-08-23 01:13:47 +10:00
|
|
|
if ((things[i].state == "parade") || (things[i].state == "shrink")) {
|
2016-08-20 11:34:25 +10:00
|
|
|
return "parade";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
if (things[i].state == "explode") {
|
2016-08-30 14:55:26 +10:00
|
|
|
return things[i].explodereason;
|
2016-08-20 11:34:25 +10:00
|
|
|
}
|
|
|
|
}
|
2016-08-18 14:54:54 +10:00
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
if (things[i].state != "stop") {
|
2016-08-20 11:34:25 +10:00
|
|
|
return "other";
|
2016-08-18 14:54:54 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
function canstartpath(what) {
|
2016-09-03 10:52:03 +10:00
|
|
|
|
|
|
|
if (what.type == "cat") {
|
|
|
|
// cats can start paths
|
|
|
|
} else if (what.type == "box" && what.boxfull) {
|
|
|
|
// full boxes can start paths
|
|
|
|
} else {
|
|
|
|
console.log("not a cat");
|
2016-08-19 17:46:39 +10:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
//if (isadjacenttotype(what, "llama")) {
|
|
|
|
if (what.isscared()) {
|
2016-08-19 17:46:39 +10:00
|
|
|
// cats adjacent to llamas are frozen
|
|
|
|
console.log("next to a llama");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
function clearthings() {
|
|
|
|
while (things.length > 0) {
|
|
|
|
things.pop();
|
|
|
|
}
|
|
|
|
things = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function getmousexy(event) {
|
|
|
|
var e,scale;
|
2016-08-22 19:52:15 +10:00
|
|
|
var x,y;
|
2016-08-20 12:27:15 +10:00
|
|
|
var adjustx, adjusty;
|
2016-08-25 16:49:54 +10:00
|
|
|
var xoff=0,yoff=0;
|
|
|
|
var element = game.canvas;
|
2016-08-20 12:59:29 +10:00
|
|
|
|
|
|
|
scale = game.curw / SCREENW;
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
//var rect = game.canvas.getBoundingClientRect();
|
|
|
|
|
|
|
|
|
|
|
|
if (element.offsetParent !== undefined) {
|
|
|
|
do {
|
|
|
|
xoff += element.offsetLeft;
|
|
|
|
yoff += element.offsetTop;
|
|
|
|
} while ((element = element.offsetParent));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add padding and border style widths to offset
|
|
|
|
// Also add the <html> offsets in case there's a position:fixed bar
|
|
|
|
|
|
|
|
var _stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(game.canvas, null)['paddingLeft'], 10) || 0;
|
|
|
|
var _stylePaddingTop = parseInt(document.defaultView.getComputedStyle(game.canvas, null)['paddingTop'], 10) || 0;
|
|
|
|
var _styleBorderLeft = parseInt(document.defaultView.getComputedStyle(game.canvas, null)['borderLeftWidth'], 10) || 0;
|
|
|
|
var _styleBorderTop = parseInt(document.defaultView.getComputedStyle(game.canvas, null)['borderTopWidth'], 10) || 0;
|
|
|
|
var html = document.body.parentNode;
|
|
|
|
var _htmlTop = html.offsetTop;
|
|
|
|
var _htmlLeft = html.offsetLeft;
|
|
|
|
|
|
|
|
|
|
|
|
xoff += _stylePaddingLeft + _styleBorderLeft + _htmlLeft;
|
|
|
|
yoff += _stylePaddingTop + _styleBorderTop + _htmlTop;
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-20 12:59:29 +10:00
|
|
|
if (event.type == "touchup") {
|
2016-08-25 16:49:54 +10:00
|
|
|
//x = (event.changedTouches[0].pageX - xoff) / scale;
|
|
|
|
//y = (event.changedTouches[0].pageY - yoff) / scale;
|
|
|
|
//adjustx = (event.changedTouches[0].pageX - xoff - BOARDX) / scale;
|
|
|
|
//adjusty = (event.changedTouches[0].pageY - yoff -BOARDY) / scale;
|
|
|
|
x = (event.touches[0].clientX - xoff) / scale;
|
|
|
|
y = (event.touches[0].clientY - yoff) / scale;
|
|
|
|
//adjustx = (event.changedTouches[0].clientX - xoff - BOARDX) / scale;
|
|
|
|
//adjusty = (event.changedTouches[0].clientY - yoff -BOARDY) / scale;
|
2016-08-20 12:59:29 +10:00
|
|
|
} else if (event.touches != undefined) {
|
2016-08-25 16:49:54 +10:00
|
|
|
x = (event.touches[0].clientX - xoff) / scale;
|
|
|
|
y = (event.touches[0].clientY - yoff) / scale;
|
|
|
|
//adjustx = (event.touches[0].clientX - xoff - BOARDX) / scale;
|
|
|
|
//adjusty = (event.touches[0].clientY - yoff - BOARDY) / scale;
|
2016-08-20 12:27:15 +10:00
|
|
|
} else {
|
2016-08-25 16:49:54 +10:00
|
|
|
x = (event.pageX - xoff) / scale;
|
|
|
|
y = (event.pageY - yoff) / scale;
|
|
|
|
//adjustx = (event.pageX - xoff - BOARDX) / scale;
|
|
|
|
//adjusty = (event.pageY - yoff - BOARDY) / scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (game.state == "levselect") {
|
|
|
|
adjustx = x - LEVSEL_X;
|
|
|
|
adjusty = y - LEVSEL_Y;
|
|
|
|
} else {
|
|
|
|
adjustx = x - BOARDX;
|
|
|
|
adjusty = y - BOARDY;
|
2016-08-20 12:27:15 +10:00
|
|
|
}
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
return [ adjustx, adjusty, x, y ];
|
2016-08-20 12:27:15 +10:00
|
|
|
}
|
2016-08-19 17:46:39 +10:00
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
|
2016-08-31 17:45:15 +10:00
|
|
|
//
|
2016-09-03 10:52:03 +10:00
|
|
|
function isadjacenttotype(what, wanttype, exceptionthing, catcol, boxfull) {
|
2016-08-19 17:46:39 +10:00
|
|
|
var newgridx,newgridy;
|
|
|
|
var i;
|
|
|
|
|
|
|
|
for (i = 0; i < MAXDIRS; i++) {
|
|
|
|
newgridx = what.gridx + DIRXMOD[i];
|
|
|
|
newgridy = what.gridy + DIRYMOD[i];
|
|
|
|
|
|
|
|
if (isonscreen(newgridx,newgridy)) {
|
|
|
|
adjthing = getgridthing(newgridx, newgridy);
|
2016-08-22 19:52:15 +10:00
|
|
|
if ((adjthing != undefined) && (adjthing.type == wanttype) && (adjthing != exceptionthing)) {
|
2016-09-03 10:52:03 +10:00
|
|
|
var ok = true;
|
|
|
|
if (catcol != undefined) {
|
|
|
|
if (adjthing.catcol != what.catcol) {
|
|
|
|
ok = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (boxfull != undefined) {
|
|
|
|
if (adjthing.boxfull != boxfull) {
|
|
|
|
ok = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ok) {
|
2016-08-31 17:45:15 +10:00
|
|
|
return true;
|
|
|
|
}
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
function drawline(ctx,x1,y1,x2,y2,col,width) {
|
|
|
|
ctx.strokeStyle = col;
|
|
|
|
ctx.lineWidth = width;
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.moveTo(x1, y1);
|
|
|
|
ctx.lineTo(x2, y2);
|
|
|
|
ctx.stroke();
|
|
|
|
}
|
|
|
|
|
2016-08-21 07:56:41 +10:00
|
|
|
function addcommas(num) {
|
|
|
|
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
|
|
}
|
|
|
|
|
2016-08-21 09:57:40 +10:00
|
|
|
function hashelp(lev) {
|
|
|
|
// past last level!
|
|
|
|
if (lev >= game.levels.length) return false;
|
|
|
|
|
|
|
|
return game.levels[lev].hashelp;
|
|
|
|
}
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
function drawtick(ctx, x1, y1, x2, y2, col,wid) {
|
|
|
|
var w,h;
|
|
|
|
w = x2 - x1;
|
|
|
|
h = y2 - y1;
|
|
|
|
|
|
|
|
var tickleftx = x1 + w/4;
|
|
|
|
var ticklefty = y1 + h/2;
|
|
|
|
var tickbasex = x1 + w/2;
|
|
|
|
var tickbasey = y1+h-h/8;
|
|
|
|
var tickrightx = x1 + w - w/5;
|
|
|
|
var tickrighty = y1 + h/8;
|
|
|
|
drawline(ctx, tickleftx,ticklefty, tickbasex, tickbasey, col, wid);
|
|
|
|
drawline(ctx, tickbasex, tickbasey, tickrightx, tickrighty, col, wid);
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawcross(ctx, x, y, x2, y2, col, width) {
|
2016-08-21 09:32:57 +10:00
|
|
|
// cross out
|
|
|
|
ctx.fillStyle = col
|
|
|
|
ctx.lineWidth = width;
|
|
|
|
ctx.strokeStyle = col;
|
|
|
|
// NW -> SE
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.moveTo(x, y);
|
|
|
|
ctx.lineTo(x2, y2);
|
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
// SW -> NE
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.moveTo(x, y2);
|
|
|
|
ctx.lineTo(x2, y);
|
|
|
|
ctx.stroke();
|
|
|
|
}
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
function drawarrow(ctx,x1,y1,x2,y2,col,width, arrowsize) {
|
|
|
|
drawline(ctx, x1, y1, x2, y2, col, width);
|
|
|
|
drawarrowhead(ctx, x1, y1, x2, y2, col, arrowsize);
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawarrowhead(ctx, x1, y1, x2, y2, col, size) {
|
2016-08-19 17:46:39 +10:00
|
|
|
var startrads,endrads;
|
2016-08-20 15:12:32 +10:00
|
|
|
var size2;
|
|
|
|
size2 = size * 1.5;
|
2016-08-19 17:46:39 +10:00
|
|
|
|
|
|
|
startrads = Math.atan((y2 - y1) / (x2 - x1));
|
|
|
|
if (x2 >= x1) {
|
|
|
|
startrads += -90*Math.PI/180;
|
|
|
|
} else {
|
|
|
|
startrads += 90*Math.PI/180;
|
|
|
|
}
|
|
|
|
|
|
|
|
endrads = Math.atan((y2 - y1) / (x2 - x1));
|
|
|
|
if (x2 >= x1) {
|
|
|
|
endrads += 90 * Math.PI / 180;
|
|
|
|
} else {
|
|
|
|
endrads += -90 * Math.PI / 180;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.strokeStyle = col;
|
|
|
|
ctx.fillStyle = col;
|
|
|
|
|
|
|
|
ctx.save();
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.translate(x2,y2);
|
|
|
|
ctx.rotate(endrads);
|
|
|
|
ctx.moveTo(0,0);
|
2016-08-20 15:12:32 +10:00
|
|
|
ctx.lineTo(size,size2);
|
|
|
|
ctx.lineTo(-size,size2);
|
2016-08-19 17:46:39 +10:00
|
|
|
ctx.closePath();
|
|
|
|
ctx.restore();
|
|
|
|
ctx.fill();
|
|
|
|
}
|
|
|
|
|
2016-08-30 17:19:28 +10:00
|
|
|
function countalivethingsoftype(type) {
|
|
|
|
var i,count=0;
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (things[i].type == type) {
|
|
|
|
if (!things[i].isanimating()) {
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
function countthingsoftype(type) {
|
|
|
|
var i,count=0;
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (things[i].type == type) {
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
var playerdata = {
|
2016-09-05 14:22:21 +10:00
|
|
|
totstars: 0,
|
2016-08-22 19:52:15 +10:00
|
|
|
levscore: [],
|
|
|
|
|
|
|
|
saveall : function() {
|
|
|
|
if (game.cheat) return;
|
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
console.log("*** saving tot stars = " + this.totstars);
|
2016-08-22 19:52:15 +10:00
|
|
|
// save max level
|
|
|
|
localStorage.setItem('totstars',this.totstars);
|
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
// save level scores
|
|
|
|
localStorage.setItem("levscores", JSON.stringify(this.levscore));
|
2016-08-22 19:52:15 +10:00
|
|
|
},
|
|
|
|
|
|
|
|
load : function() {
|
2016-09-05 14:22:21 +10:00
|
|
|
var num,i,temp;
|
2016-08-22 19:52:15 +10:00
|
|
|
// local star count
|
|
|
|
num = localStorage.getItem('totstars');
|
|
|
|
if (num != undefined) {
|
|
|
|
this.totstars = num;
|
|
|
|
console.log("playerdata.load() - totstars is " + this.totstars);
|
2016-09-05 14:22:21 +10:00
|
|
|
} else {
|
|
|
|
console.log("playerdata.load() - couldn't find totstars");
|
|
|
|
this.totstars = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// load scores
|
|
|
|
temp = localStorage.getItem("levscores");
|
|
|
|
if (temp == undefined) {
|
|
|
|
this.levscore = [];
|
|
|
|
} else {
|
|
|
|
this.levscore = JSON.parse(temp);
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
|
|
|
|
/*
|
|
|
|
// save level scores
|
|
|
|
localStorage.setItem("levscores", JSON.stringify(this.levscore));
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// load level hiscores
|
|
|
|
for (i = 0; i < game.levels.length; i++) {
|
|
|
|
num = localStorage.getItem("levscore" + i);
|
|
|
|
if (num == undefined) {
|
|
|
|
this.levscore[i] = 0;
|
|
|
|
} else {
|
2016-09-05 14:22:21 +10:00
|
|
|
|
|
|
|
//console.log("load() - lev " + i + " score " + num);
|
2016-08-22 19:52:15 +10:00
|
|
|
this.levscore[i] = num;
|
|
|
|
}
|
2016-09-05 14:22:21 +10:00
|
|
|
console.log("load() - lev " + i + " score is " + this.levscore[i]);
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-09-05 14:22:21 +10:00
|
|
|
*/
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// calculate player stars based on scores
|
|
|
|
this.settotstars(game.countplayerstars());
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
getlevscore : function (lev) {
|
|
|
|
if (this.levscore[lev] == undefined) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return this.levscore[lev];
|
|
|
|
},
|
|
|
|
|
|
|
|
clearall : function() {
|
2016-09-05 14:22:21 +10:00
|
|
|
//localStorage.removeItem("maxlevel"); // old one
|
|
|
|
|
|
|
|
/*
|
2016-08-22 19:52:15 +10:00
|
|
|
localStorage.removeItem("totstars");
|
2016-09-05 14:22:21 +10:00
|
|
|
for (i = 0; i < 100; i++) {
|
2016-08-22 19:52:15 +10:00
|
|
|
localStorage.removeItem("levscore" + i);
|
|
|
|
}
|
2016-09-05 14:22:21 +10:00
|
|
|
*/
|
|
|
|
localStorage.clear();
|
2016-08-22 19:52:15 +10:00
|
|
|
console.log("cleared local storage.");
|
|
|
|
},
|
|
|
|
|
|
|
|
settotstars : function(num) {
|
2016-09-05 14:22:21 +10:00
|
|
|
console.log("settotstars() - setting total stars to " + num);
|
2016-08-22 19:52:15 +10:00
|
|
|
this.totstars = num;
|
2016-09-05 14:22:21 +10:00
|
|
|
this.saveall();
|
2016-08-22 19:52:15 +10:00
|
|
|
},
|
|
|
|
|
|
|
|
setlevscore : function(lev, num) {
|
|
|
|
this.levscore[lev] = num;
|
2016-09-05 14:22:21 +10:00
|
|
|
this.saveall();
|
2016-08-22 19:52:15 +10:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
var game = {
|
2016-08-20 12:27:15 +10:00
|
|
|
ratio: null,
|
|
|
|
curw: null,
|
|
|
|
curh: null,
|
2016-08-21 09:32:57 +10:00
|
|
|
levels: null,
|
2016-08-27 16:44:24 +10:00
|
|
|
state: "",
|
2016-08-30 14:55:26 +10:00
|
|
|
explodereason: "",
|
2016-08-22 19:52:15 +10:00
|
|
|
cheat: 0,
|
|
|
|
winimgsize: 0,
|
2016-08-25 16:49:54 +10:00
|
|
|
frameNo: 0,
|
2016-08-29 14:21:42 +10:00
|
|
|
turnsleft: 0,
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-09-08 14:15:46 +10:00
|
|
|
fontloaded: false,
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
levseloff: 0,
|
2016-09-08 14:15:46 +10:00
|
|
|
resetcount: 0,
|
2016-09-04 11:47:42 +10:00
|
|
|
|
|
|
|
rng: null,
|
|
|
|
|
2016-09-02 11:48:48 +10:00
|
|
|
goatdir: 1,
|
|
|
|
goatx: 0,
|
|
|
|
goaty: 0,
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
goalbooster: 0, // extra chance of a goal object appearing
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
turnsbarpct: 0,
|
|
|
|
|
2016-08-25 20:01:45 +10:00
|
|
|
screenflash: 0,
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
newestlevel: null,
|
|
|
|
|
2016-08-26 16:27:42 +10:00
|
|
|
canvas: null,
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
setrndseed : function(seed) {
|
|
|
|
if (this.rng != undefined) {
|
|
|
|
delete this.rng;
|
|
|
|
}
|
|
|
|
this.rng = new RNG(seed);
|
|
|
|
},
|
|
|
|
|
|
|
|
seedrnd : function(min, max) {
|
|
|
|
return this.rng.rndrange(min, max);
|
|
|
|
},
|
|
|
|
|
2016-09-08 14:15:46 +10:00
|
|
|
checkfont : function() {
|
|
|
|
var tempctx = this.temp.getContext("2d");
|
|
|
|
var result = false;
|
2016-09-08 13:49:23 +10:00
|
|
|
|
2016-09-08 14:15:46 +10:00
|
|
|
tempctx.font = TITLETEXTSIZE + "pt " + FONT;
|
|
|
|
tempctx.fillText("www", 0, 0);
|
|
|
|
|
|
|
|
try {
|
|
|
|
result = document.fonts.check(TITLETEXTSIZE + "pt " + FONT);
|
2016-09-08 13:49:23 +10:00
|
|
|
}
|
2016-09-08 14:15:46 +10:00
|
|
|
catch(err) {
|
|
|
|
console.log("document.fonts.check() not found, just assuming font is okay.");
|
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result) {
|
|
|
|
console.log("font ok");
|
|
|
|
}
|
|
|
|
|
|
|
|
game.fontloaded = result;
|
|
|
|
|
|
|
|
return result;
|
2016-09-08 13:49:23 +10:00
|
|
|
},
|
|
|
|
|
2016-08-31 15:19:51 +10:00
|
|
|
addfireworks : function() {
|
|
|
|
var delay = 0;
|
|
|
|
for (i = 0; i < FIREWORKCOUNT; i++) {
|
|
|
|
this.addfirework(delay);
|
|
|
|
delay += 5;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
addfirework : function(delay) {
|
|
|
|
var i,nshards = FIREWORKSHARDS;
|
|
|
|
var x,y,col;
|
|
|
|
switch (rnd(6)) {
|
|
|
|
case 0: col = "#ff0000"; break;
|
|
|
|
case 1: col = "#00ff00"; break;
|
|
|
|
case 2: col = "#0000ff"; break;
|
|
|
|
case 3: col = "#ffff00"; break;
|
|
|
|
case 4: col = "#00ffff"; break;
|
|
|
|
case 5: col = "#ff00ff"; break;
|
|
|
|
default: col = "#ff0000"; break;
|
|
|
|
}
|
|
|
|
x = rnd(GRIDW);
|
|
|
|
y = rnd(GRIDH);
|
2016-09-02 11:48:48 +10:00
|
|
|
//console.log("adding fw at " + x + "," + y);
|
2016-08-31 15:19:51 +10:00
|
|
|
for (i = 0; i < nshards; i++) {
|
|
|
|
things.push(new thing(x, y, "firework", "firework-text", col));
|
|
|
|
if (delay != undefined) {
|
|
|
|
things[things.length-1].delay = delay;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
addflash : function() {
|
2016-08-25 20:01:45 +10:00
|
|
|
this.screenflash = 1.0;
|
2016-08-30 14:55:26 +10:00
|
|
|
game.dirty = true;
|
|
|
|
},
|
|
|
|
|
|
|
|
addbagpop : function(gridy) {
|
|
|
|
var i,nshards = 10;
|
2016-08-30 17:19:28 +10:00
|
|
|
game.progress("bag", 1);
|
2016-08-30 14:55:26 +10:00
|
|
|
for (i = 0; i < nshards; i++) {
|
|
|
|
things.push(new thing(GRIDW, gridy, "bagpop"));
|
|
|
|
}
|
2016-08-25 20:01:45 +10:00
|
|
|
},
|
2016-08-20 12:27:15 +10:00
|
|
|
|
2016-08-26 19:07:47 +10:00
|
|
|
fullscreen : function(i) {
|
|
|
|
// go full-screen
|
|
|
|
if (i.requestFullscreen) {
|
|
|
|
i.requestFullscreen();
|
|
|
|
} else if (i.webkitRequestFullscreen) {
|
|
|
|
i.webkitRequestFullscreen();
|
|
|
|
} else if (i.mozRequestFullScreen) {
|
|
|
|
i.mozRequestFullScreen();
|
|
|
|
} else if (i.msRequestFullscreen) {
|
|
|
|
i.msRequestFullscreen();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-08-27 12:25:17 +10:00
|
|
|
incloadprogress : function() {
|
2016-08-27 13:18:03 +10:00
|
|
|
/*
|
2016-08-27 12:35:18 +10:00
|
|
|
setTimeout(function () {
|
|
|
|
nimages++;
|
|
|
|
console.log(nimages + " / " + maximages + " images loaded.");
|
|
|
|
}, (rnd(3)+1) * 1000);
|
2016-08-27 13:18:03 +10:00
|
|
|
*/
|
|
|
|
nimages++;
|
2016-09-05 14:22:21 +10:00
|
|
|
//console.log(nimages + " / " + maximages + " images loaded.");
|
2016-08-27 12:25:17 +10:00
|
|
|
},
|
|
|
|
|
|
|
|
drawloader : function() {
|
2016-08-27 12:35:18 +10:00
|
|
|
var bgcol = "#008c8c";
|
2016-08-27 12:25:17 +10:00
|
|
|
var pct = nimages / maximages;
|
|
|
|
|
|
|
|
ctx.fillStyle = bgcol;
|
|
|
|
this.context.fillRect(0, 0, this.canvas.width, pct * this.canvas.height);
|
|
|
|
this.dirty = true;
|
|
|
|
},
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
init : function() {
|
2016-08-26 16:27:42 +10:00
|
|
|
|
2016-08-28 08:27:20 +10:00
|
|
|
//this.canvas = document.createElement("canvas");
|
|
|
|
this.canvas = document.getElementsByTagName('canvas')[0];
|
2016-08-27 13:18:03 +10:00
|
|
|
this.stargoalbanner = document.createElement("canvas");
|
2016-09-08 13:49:23 +10:00
|
|
|
this.temp = document.createElement("canvas");
|
2016-08-26 16:27:42 +10:00
|
|
|
|
2016-08-27 12:25:17 +10:00
|
|
|
this.hratio = SCREENH / SCREENW;
|
|
|
|
this.wratio = SCREENW / SCREENH;
|
2016-08-20 12:27:15 +10:00
|
|
|
this.curw = SCREENW;
|
|
|
|
this.curh = SCREENH;
|
|
|
|
|
2016-08-27 13:18:03 +10:00
|
|
|
this.stargoalbanner.width = SCREENW;
|
|
|
|
this.stargoalbanner.height = STARWID_TOPGOALS;
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
this.canvas.width = SCREENW;
|
|
|
|
this.canvas.height = SCREENH;
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
this.context = this.canvas.getContext("2d");
|
2016-08-20 12:27:15 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx = this.context;
|
2016-08-20 12:27:15 +10:00
|
|
|
|
2016-08-26 19:07:47 +10:00
|
|
|
//this.fullscreen(this.canvas);
|
|
|
|
|
2016-08-20 12:59:29 +10:00
|
|
|
// find ipad/android/iphone so we can hide the address bar
|
|
|
|
this.ua = navigator.userAgent.toLowerCase();
|
|
|
|
this.android = this.ua.indexOf('android') > -1 ? true : false;
|
|
|
|
this.ios = ( this.ua.indexOf('iphone') > -1 || this.ua.indexOf('ipad') > -1 ) ? true : false;
|
2016-08-20 12:27:15 +10:00
|
|
|
|
2016-08-31 15:24:16 +10:00
|
|
|
if (this.ios || this.android) {
|
|
|
|
FIREWORKSHARDS /= 2;
|
|
|
|
}
|
|
|
|
|
2016-08-28 08:27:20 +10:00
|
|
|
// don't need this now that we statically define the canvas.
|
|
|
|
//document.body.insertBefore(this.canvas, document.body.childNodes[0]);
|
2016-08-20 12:59:29 +10:00
|
|
|
|
|
|
|
// try to go full screen?
|
2016-08-27 18:05:42 +10:00
|
|
|
/*
|
2016-08-20 12:59:29 +10:00
|
|
|
var body = document.documentElement;
|
|
|
|
if (body.requestFullscreen) {
|
|
|
|
body.requestFullscreen();
|
|
|
|
} else if (body.webkitrequestFullscreen) {
|
|
|
|
body.webkitrequestFullscreen();
|
|
|
|
} else if (body.mozrequestFullscreen) {
|
|
|
|
body.mozrequestFullscreen();
|
|
|
|
} else if (body.msrequestFullscreen) {
|
|
|
|
body.msrequestFullscreen();
|
|
|
|
}
|
2016-08-27 18:05:42 +10:00
|
|
|
*/
|
2016-08-20 12:59:29 +10:00
|
|
|
|
|
|
|
this.resize();
|
|
|
|
|
2016-08-27 16:17:52 +10:00
|
|
|
window.requestAnimFrame = (function(){
|
|
|
|
return window.requestAnimationFrame ||
|
|
|
|
window.webkitRequestAnimationFrame ||
|
|
|
|
window.mozRequestAnimationFrame ||
|
|
|
|
window.oRequestAnimationFrame ||
|
|
|
|
window.msRequestAnimationFrame ||
|
2016-08-27 17:47:39 +10:00
|
|
|
function( callback ) {
|
2016-08-27 16:17:52 +10:00
|
|
|
window.setTimeout(mainloop, 1000 / 60);
|
|
|
|
};
|
2016-08-27 17:47:39 +10:00
|
|
|
})();
|
2016-08-19 17:46:39 +10:00
|
|
|
|
2016-08-29 14:21:42 +10:00
|
|
|
if (debug) {
|
|
|
|
window.onerror = function (errorMsg, url, lineNumber) {
|
|
|
|
alert('Error: ' + errorMsg + ' Script: ' + url + ' Line: ' + lineNumber);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
this.canvas.addEventListener('mousedown', this.handlemousedown, false);
|
|
|
|
this.canvas.addEventListener('mouseup', this.handlemouseup, false);
|
2016-08-20 11:17:22 +10:00
|
|
|
this.canvas.addEventListener('mouseout', this.handlemouseup, false);
|
2016-08-19 17:46:39 +10:00
|
|
|
this.canvas.addEventListener('mousemove', this.handlemousemove, false);
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
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);
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
window.addEventListener('keypress', this.handlekeypress, false);
|
2016-08-20 12:27:15 +10:00
|
|
|
|
2016-08-27 16:44:24 +10:00
|
|
|
game.setstate("loader");
|
2016-08-20 12:27:15 +10:00
|
|
|
},
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
isbanned : function(lev, what) {
|
|
|
|
var i;
|
|
|
|
|
|
|
|
// no list of allowed things means everything is allowed.
|
|
|
|
if (this.levels[lev].allowedthings == undefined) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0 ; i < this.levels[lev].allowedthings.length; i++) {
|
|
|
|
if (this.levels[lev].allowedthings.indexOf(what) != -1) {
|
|
|
|
// ok
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
2016-08-23 01:13:47 +10:00
|
|
|
turneffects : function() {
|
|
|
|
var i;
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
// suns can move again
|
|
|
|
if (things[i].type == "sunlight" && things[i].counter == 1) {
|
|
|
|
things[i].counter = 0;
|
|
|
|
}
|
|
|
|
}
|
2016-08-29 14:21:42 +10:00
|
|
|
|
2016-08-30 17:19:28 +10:00
|
|
|
game.progress("turn", 1);
|
|
|
|
|
2016-08-29 14:21:42 +10:00
|
|
|
game.turnsleft--;
|
2016-08-29 19:24:29 +10:00
|
|
|
if (game.turnsleft < 0) game.turnsleft = 0;
|
2016-08-29 14:21:42 +10:00
|
|
|
|
|
|
|
game.dirty = true;
|
2016-09-04 11:47:42 +10:00
|
|
|
|
|
|
|
game.goalbooster = 0;
|
2016-08-23 01:13:47 +10:00
|
|
|
},
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
resize : function() {
|
2016-08-27 12:25:17 +10:00
|
|
|
if (window.innerWidth > window.innerHeight) {
|
|
|
|
console.log("scaling to wid");
|
|
|
|
// scale to width
|
|
|
|
game.curh = window.innerHeight;
|
|
|
|
game.curw = game.curh * game.wratio;
|
|
|
|
} else {
|
|
|
|
console.log("scaling to height");
|
|
|
|
// scale to width
|
|
|
|
game.curw = window.innerWidth - 16;
|
|
|
|
game.curh = game.curw * game.hratio;
|
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
|
|
|
|
// hide address bar on phones
|
2016-08-26 16:27:42 +10:00
|
|
|
if (game.android || game.ios) {
|
2016-09-05 14:22:21 +10:00
|
|
|
//document.body.style.height = (window.innerHeight + 50) + 'px';
|
|
|
|
document.body.style.height = (game.curh + 50) + 'px';
|
2016-08-20 12:27:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// scale canvas
|
2016-08-26 16:27:42 +10:00
|
|
|
game.canvas.style.width = game.curw + 'px';
|
|
|
|
game.canvas.style.height = game.curh + 'px';
|
2016-08-20 12:27:15 +10:00
|
|
|
|
|
|
|
window.setTimeout(function() {
|
|
|
|
window.scrollTo(0, 1);
|
|
|
|
}, 1);
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
initgamevars : function() {
|
2016-08-21 09:32:57 +10:00
|
|
|
score = 0;
|
2016-08-29 19:24:29 +10:00
|
|
|
globmulti = 0;
|
2016-08-21 09:57:40 +10:00
|
|
|
this.frameNo = 0;
|
2016-09-04 11:47:42 +10:00
|
|
|
this.goalbooster = 0;
|
2016-08-21 09:32:57 +10:00
|
|
|
},
|
|
|
|
|
|
|
|
initlevelvars : function() {
|
2016-08-30 14:55:26 +10:00
|
|
|
var i;
|
|
|
|
var nbags;
|
2016-08-20 12:27:15 +10:00
|
|
|
// kill any existing objects
|
|
|
|
clearthings();
|
|
|
|
|
|
|
|
overdesc = "";
|
2016-08-23 01:13:47 +10:00
|
|
|
clearpath();
|
2016-08-24 22:47:23 +10:00
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
|
2016-08-24 22:47:23 +10:00
|
|
|
// set grid size
|
|
|
|
if (game.levels[curlevel].gridsize == undefined) {
|
|
|
|
GRIDSIZE = DEF_GRIDSIZE;
|
|
|
|
THINGSIZE = DEF_THINGSIZE;
|
|
|
|
GRIDW = DEF_GRIDW;
|
|
|
|
GRIDH = DEF_GRIDH;
|
2016-08-25 16:49:54 +10:00
|
|
|
BOARDX = DEF_BOARDX;
|
2016-08-24 22:47:23 +10:00
|
|
|
} else {
|
|
|
|
GRIDSIZE = game.levels[curlevel].gridsize;
|
|
|
|
THINGSIZE = game.levels[curlevel].thingsize;
|
|
|
|
GRIDW = game.levels[curlevel].gridw;
|
|
|
|
GRIDH = game.levels[curlevel].gridh;
|
2016-08-25 16:49:54 +10:00
|
|
|
BOARDX = game.levels[curlevel].boardx;
|
2016-08-24 22:47:23 +10:00
|
|
|
}
|
2016-08-30 14:55:26 +10:00
|
|
|
|
|
|
|
|
|
|
|
// add shopping bags
|
|
|
|
game.levels[curlevel].bags = [];
|
|
|
|
// 0-4 = no bags
|
|
|
|
// 5 - 14 = 1 bag
|
|
|
|
// 15 - 24 = 2 bags
|
|
|
|
// 25 - 34 = 3 bags
|
2016-09-04 11:47:42 +10:00
|
|
|
nbags = game.getmaxbags(curlevel);
|
2016-09-03 10:52:03 +10:00
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
for (i = 0; i < nbags; i++) {
|
2016-09-03 10:52:03 +10:00
|
|
|
this.addlevelbag(curlevel);
|
2016-08-30 14:55:26 +10:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
getmaxbags : function(lev) {
|
|
|
|
var max;
|
|
|
|
max = Math.floor((lev+5) / 10)
|
|
|
|
if (max > 4) max = 4;
|
|
|
|
return max;
|
|
|
|
},
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
// x1, x2, y2, x3, y3....
|
|
|
|
addlevelbricks : function () {
|
|
|
|
var lev,newbrick,i;
|
2016-09-04 11:47:42 +10:00
|
|
|
lev = this.newestlevel;
|
2016-08-31 13:55:35 +10:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
addlevelbag : function (lev) {
|
|
|
|
var mybag,y;
|
2016-08-30 14:55:26 +10:00
|
|
|
mybag = new Object();
|
2016-09-03 10:52:03 +10:00
|
|
|
|
|
|
|
y = rnd(GRIDH);
|
|
|
|
while (getbagaty(y)) {
|
|
|
|
y = rnd(GRIDH);
|
|
|
|
}
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
mybag.y = y;
|
|
|
|
mybag.cats = 0;
|
|
|
|
mybag.prize = "";
|
|
|
|
mybag.capacity = this.levels[lev].gridw;
|
|
|
|
mybag.prize = prizetypes[rnd(prizetypes.length)];
|
|
|
|
this.levels[lev].bags.push(mybag);
|
2016-08-20 12:27:15 +10:00
|
|
|
},
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
addlevel : function (lev, hashelp) {
|
2016-08-21 09:57:40 +10:00
|
|
|
var mylevel;
|
2016-09-04 11:47:42 +10:00
|
|
|
var plev;
|
|
|
|
|
|
|
|
// find previous level
|
|
|
|
for (plev = lev-1; plev >= 0; plev--) {
|
|
|
|
if (this.levels[plev] != undefined) break;
|
|
|
|
}
|
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
mylevel = new Object();
|
2016-08-21 09:57:40 +10:00
|
|
|
mylevel.hashelp = hashelp;
|
2016-08-21 09:32:57 +10:00
|
|
|
mylevel.goals = new Array();
|
2016-08-21 11:31:19 +10:00
|
|
|
mylevel.thinglist = new Array();
|
2016-08-22 19:52:15 +10:00
|
|
|
mylevel.forcelist = new Array();
|
2016-08-29 14:21:42 +10:00
|
|
|
mylevel.maxturns = lev + 4; // default
|
2016-08-30 14:55:26 +10:00
|
|
|
mylevel.bags = [];
|
2016-08-31 13:55:35 +10:00
|
|
|
mylevel.bricks = [];
|
2016-09-04 11:47:42 +10:00
|
|
|
mylevel.random = false;
|
2016-08-25 16:49:54 +10:00
|
|
|
|
|
|
|
if (lev == 1) {
|
|
|
|
mylevel.gridsize = DEF_GRIDSIZE;
|
|
|
|
mylevel.thingsize = DEF_THINGSIZE;
|
|
|
|
mylevel.gridw = DEF_GRIDW;
|
|
|
|
mylevel.gridh = DEF_GRIDH;
|
|
|
|
mylevel.boardx = (SCREENW - (DEF_GRIDW * DEF_GRIDSIZE))/2;
|
2016-08-31 17:45:15 +10:00
|
|
|
mylevel.catcols = 1;
|
2016-08-25 16:49:54 +10:00
|
|
|
} else {
|
|
|
|
// default to size of previous one
|
2016-09-04 11:47:42 +10:00
|
|
|
mylevel.gridsize = this.levels[plev].gridsize;
|
|
|
|
mylevel.thingsize = this.levels[plev].thingsize;
|
|
|
|
mylevel.gridw = this.levels[plev].gridw;
|
|
|
|
mylevel.gridh = this.levels[plev].gridh;
|
|
|
|
mylevel.boardx = this.levels[plev].boardx;
|
2016-08-31 17:45:15 +10:00
|
|
|
// default to # cat colours from previous one
|
2016-09-04 11:47:42 +10:00
|
|
|
mylevel.catcols = this.levels[plev].catcols;
|
2016-08-25 16:49:54 +10:00
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
mylevel.allowedthings = new Array();
|
|
|
|
if (lev > 1) {
|
|
|
|
// default to allowed things from previous level.
|
2016-09-04 11:47:42 +10:00
|
|
|
for (i = 0; i < this.levels[plev].allowedthings.length; i++) {
|
|
|
|
mylevel.allowedthings.push(this.levels[plev].allowedthings[i]);
|
2016-08-31 13:55:35 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-21 09:57:40 +10:00
|
|
|
this.levels[lev] = mylevel;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
playerdata.levscore[lev] = 0;
|
2016-08-30 14:55:26 +10:00
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
this.newestlevel = lev;
|
|
|
|
},
|
|
|
|
|
|
|
|
levhasgoal : function(lev, gtype) {
|
|
|
|
var i;
|
|
|
|
for (i = 0; i < game.levels[lev].goals.length; i++) {
|
|
|
|
if (game.levels[lev].goals[i].type == gtype) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
genrandomlevel : function (lev) {
|
2016-09-07 15:23:36 +10:00
|
|
|
var ngoals,i,n,pctleft;
|
|
|
|
var nbricks = 0,bricktype, xmin,ymin,xmax,ymax,totbricks = 0, wantbricks;
|
|
|
|
var gw,gh;
|
2016-09-04 11:47:42 +10:00
|
|
|
|
|
|
|
// set random seed based on level
|
|
|
|
game.setrndseed(lev+50);
|
|
|
|
|
|
|
|
ngoals = game.seedrnd(2,3);
|
|
|
|
|
|
|
|
// first create the level
|
|
|
|
if (game.levels[lev] == undefined) {
|
|
|
|
game.addlevel(lev, false);
|
|
|
|
}
|
|
|
|
|
2016-09-07 15:23:36 +10:00
|
|
|
gw = game.levels[lev].gridw;
|
|
|
|
gh = game.levels[lev].gridh;
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
// generate goals
|
|
|
|
pctleft = 100;
|
|
|
|
for (i = 0; i < ngoals; i++) {
|
|
|
|
var allgoals = [],goal,goalpct;
|
|
|
|
// make list of all possible goals
|
|
|
|
for (goal in GOALVERB) {
|
|
|
|
if (!game.levhasgoal(lev, goal) && (goal != "turn")) {
|
|
|
|
allgoals.push(goal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// pick a random goal
|
|
|
|
goal = allgoals[game.seedrnd(0,allgoals.length-1)];
|
|
|
|
|
|
|
|
// generate a percentage of max count for this goal
|
|
|
|
// this will be replaced with an actual number in a second.
|
|
|
|
if (i == ngoals-1) {
|
|
|
|
// last one
|
|
|
|
goalpct = pctleft;
|
|
|
|
} else {
|
|
|
|
goalpct = game.seedrnd(pctleft/4,pctleft/2);
|
|
|
|
}
|
|
|
|
|
|
|
|
game.addlevelgoals(goal, goalpct);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < ngoals; i++) {
|
2016-09-05 14:22:21 +10:00
|
|
|
var mm,min,max,count;
|
2016-09-04 11:47:42 +10:00
|
|
|
// turn goal percentages into actual numbers
|
2016-09-05 14:22:21 +10:00
|
|
|
mm = game.getgoalminmax(lev, game.levels[lev].goals[i].type);
|
|
|
|
|
|
|
|
min = mm[0];
|
|
|
|
max = mm[1];
|
2016-09-09 18:23:23 +10:00
|
|
|
//console.log("genrandomlev() - lev " + lev + " goal " + i + " type=" + game.levels[lev].goals[i].type + " min="+min + " max=" + max);
|
2016-09-05 14:22:21 +10:00
|
|
|
|
|
|
|
count = min + Math.floor((game.levels[lev].goals[i].count / 100) * (max - min))
|
2016-09-04 11:47:42 +10:00
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
if (count < 1) count = 1;
|
2016-09-04 11:47:42 +10:00
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
game.levels[lev].goals[i].count = count;
|
2016-09-07 15:23:36 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// add random bricks - 66% chance
|
|
|
|
nbricks = 0;
|
|
|
|
brickpos = new Array();
|
|
|
|
bricktype = game.seedrnd(1,4);
|
|
|
|
//bricktype = 4;
|
|
|
|
if (game.seedrnd(1,3) > 1) {
|
|
|
|
wantbricks = true;
|
|
|
|
} else {
|
|
|
|
wantbricks = false;
|
|
|
|
}
|
|
|
|
//wantbricks = true;
|
|
|
|
|
|
|
|
if (wantbricks) {
|
|
|
|
switch (bricktype) {
|
|
|
|
case 1: // random
|
|
|
|
nbricks = game.seedrnd(1,8); // ie. max 8
|
|
|
|
xmin = 0;
|
|
|
|
ymin = 0;
|
|
|
|
xmax = gw-1;
|
|
|
|
ymax = gh-1;
|
|
|
|
break;
|
|
|
|
case 2: // vert flip
|
|
|
|
nbricks = game.seedrnd(1,4); // ie. max 8
|
|
|
|
xmin = 0;
|
|
|
|
ymin = 0;
|
|
|
|
xmax = gw-1;
|
|
|
|
if (gh % 2 == 0) {
|
|
|
|
ymax = Math.floor(gh/2)-1;
|
|
|
|
} else {
|
|
|
|
ymax = Math.floor(gh/2);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3: // horz flip
|
|
|
|
nbricks = game.seedrnd(1,4); // ie. max 8
|
|
|
|
xmin = 0;
|
|
|
|
ymin = 0;
|
|
|
|
if (gw % 2 == 0) {
|
|
|
|
xmax = Math.floor(gw/2)-1;
|
|
|
|
} else {
|
|
|
|
xmax = Math.floor(gw/2);
|
|
|
|
}
|
|
|
|
ymax = gw-1;
|
|
|
|
break;
|
|
|
|
case 4: // quads
|
|
|
|
nbricks = game.seedrnd(1,3); // ie. max 12
|
|
|
|
xmin = 0;
|
|
|
|
ymin = 0;
|
|
|
|
if (gw % 2 == 0) {
|
|
|
|
xmax = Math.floor(gw/2)-1;
|
|
|
|
} else {
|
|
|
|
xmax = Math.floor(gw/2);
|
|
|
|
}
|
|
|
|
if (gh % 2 == 0) {
|
|
|
|
ymax = Math.floor(gh/2)-1;
|
|
|
|
} else {
|
|
|
|
ymax = Math.floor(gh/2);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// console.log("bricktype = " + bricktype + " nbricks = " + nbricks);
|
|
|
|
|
|
|
|
// generate coords
|
|
|
|
bricksleft = nbricks;
|
|
|
|
for (n = 0; n < nbricks; n++) {
|
|
|
|
var x,y,coord,found = true;
|
|
|
|
while (found) {
|
|
|
|
found = false;
|
|
|
|
// pick random x/y
|
|
|
|
x = game.seedrnd(0,xmax);
|
|
|
|
y = game.seedrnd(0,ymax);
|
|
|
|
// make sure its not used
|
|
|
|
for (i = 0; i < brickpos.length; i++) {
|
|
|
|
if ((brickpos[i].x == x) && (brickpos[i].y == y)){
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
coord = new Object();
|
|
|
|
coord.x = x;
|
|
|
|
coord.y = y;
|
|
|
|
brickpos.push(coord);
|
|
|
|
//console.log("--- brick at " + x + "," + y);
|
|
|
|
}
|
|
|
|
//console.log("--- gw is " + gw + " gh is " + gh);
|
|
|
|
|
|
|
|
// place bricks
|
|
|
|
totbricks = 0;
|
|
|
|
for (i = 0; i < nbricks; i++) {
|
|
|
|
var newx, newy;
|
2016-09-04 11:47:42 +10:00
|
|
|
|
2016-09-07 15:23:36 +10:00
|
|
|
// add initial one
|
|
|
|
game.addlevelbricks(brickpos[i].x, brickpos[i].y);
|
|
|
|
totbricks++;
|
|
|
|
|
|
|
|
switch (bricktype) {
|
|
|
|
case 1: // normal
|
|
|
|
break;
|
|
|
|
case 2: // vert flip
|
|
|
|
newy = -1;
|
|
|
|
if (gh % 2 == 0) {
|
|
|
|
newy = (ymax+1) + (ymax - brickpos[i].y);
|
|
|
|
} else {
|
|
|
|
if (brickpos[i].y != ymax) { // don't flip on middle line
|
|
|
|
newy = ymax + (ymax - brickpos[i].y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (newy != -1) {
|
2016-09-09 18:23:23 +10:00
|
|
|
//console.log(" " + brickpos[i].x + "," + brickpos[i].y + " flipped to " + brickpos[i].x + "," + newy);
|
2016-09-07 15:23:36 +10:00
|
|
|
game.addlevelbricks(brickpos[i].x, newy);
|
|
|
|
totbricks++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3: // horz flip
|
|
|
|
newx = -1;
|
|
|
|
if (gw % 2 == 0) {
|
|
|
|
newx = (xmax+1) + (xmax - brickpos[i].x);
|
|
|
|
} else {
|
|
|
|
if (brickpos[i].x != xmax) { // don't flip on middle line
|
|
|
|
newx = xmax + (xmax - brickpos[i].x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (newx != -1) {
|
|
|
|
game.addlevelbricks(newx, brickpos[i].y);
|
|
|
|
totbricks++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4: // quads (ie. flip x, y, and both)
|
|
|
|
|
|
|
|
// flip y
|
|
|
|
newy = -1;
|
|
|
|
if (gh % 2 == 0) {
|
|
|
|
newy = (ymax+1) + (ymax - brickpos[i].y);
|
|
|
|
} else {
|
|
|
|
if (brickpos[i].y != ymax) { // don't flip on middle line
|
|
|
|
newy = (ymax) + (ymax - brickpos[i].y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (newy != -1) {
|
|
|
|
game.addlevelbricks(brickpos[i].x, newy);
|
|
|
|
totbricks++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// flip x
|
|
|
|
newx = -1;
|
|
|
|
if (gw % 2 == 0) {
|
|
|
|
newx = ((xmax)+1) + (xmax - brickpos[i].x);
|
|
|
|
} else {
|
|
|
|
if (brickpos[i].x != xmax) { // don't flip on middle line
|
|
|
|
newx = (xmax) + (xmax - brickpos[i].x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (newx != -1) {
|
|
|
|
game.addlevelbricks(newx, brickpos[i].y);
|
|
|
|
totbricks++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// flip x + y
|
|
|
|
if (newx == -1) newx = brickpos[i].x;
|
|
|
|
if (newy == -1) newy = brickpos[i].y;
|
|
|
|
if ((newx != brickpos[i].x) || (newy != brickpos[i].y)) {
|
|
|
|
game.addlevelbricks(newx, newy);
|
|
|
|
totbricks++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// add forced things based on goals
|
|
|
|
for (i = 0; i < ngoals; i++) {
|
2016-09-04 11:47:42 +10:00
|
|
|
switch (game.levels[lev].goals[i].type) {
|
|
|
|
case "brick":
|
2016-09-07 15:23:36 +10:00
|
|
|
if (totbricks < game.levels[lev].goals[i].count ) {
|
|
|
|
var extras = game.levels[lev].goals[i].count - totbricks;
|
|
|
|
game.addlevelforcethings(game.levels[lev].goals[i].type, extras);
|
|
|
|
}
|
2016-09-04 11:47:42 +10:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// calculate star point cutoffs, max turns, etc
|
|
|
|
game.calclevparams(lev);
|
|
|
|
|
|
|
|
game.levels[lev].random = true;
|
|
|
|
|
2016-08-21 09:57:40 +10:00
|
|
|
},
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
addlevelgridwid : function (lev, newwid) {
|
2016-08-24 22:47:23 +10:00
|
|
|
var ratio;
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
ratio = newwid / DEF_GRIDW;
|
|
|
|
|
2016-09-09 18:25:43 +10:00
|
|
|
//console.log("lev " + lev + " newwid " + newwid + " ratio " + ratio);
|
2016-08-24 22:47:23 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
this.levels[lev].gridsize = DEF_GRIDSIZE / ratio;
|
|
|
|
this.levels[lev].thingsize = DEF_THINGSIZE / ratio;
|
|
|
|
this.levels[lev].gridw = DEF_GRIDW * ratio;
|
|
|
|
this.levels[lev].gridh = DEF_GRIDH * ratio;
|
|
|
|
this.levels[lev].boardx = Math.floor((SCREENW - (this.levels[lev].gridw * this.levels[lev].gridsize)) / 2);
|
2016-08-24 22:47:23 +10:00
|
|
|
},
|
|
|
|
|
2016-08-21 11:31:19 +10:00
|
|
|
// thingtype pct
|
2016-08-30 14:55:26 +10:00
|
|
|
addlevelthings: function () {
|
|
|
|
var i,idx,lev;
|
2016-09-04 11:47:42 +10:00
|
|
|
lev = this.newestlevel;
|
2016-08-30 14:55:26 +10:00
|
|
|
for (i = 0 ; i < arguments.length; i += 2) {
|
2016-08-21 11:31:19 +10:00
|
|
|
idx = this.levels[lev].thinglist.push(new Object()) - 1;
|
|
|
|
this.levels[lev].thinglist[idx].type = arguments[i];
|
|
|
|
this.levels[lev].thinglist[idx].pct = arguments[i+1];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// thingtype howmany
|
2016-08-30 14:55:26 +10:00
|
|
|
addlevelforcethings: function () {
|
|
|
|
var i,idx,lev;
|
2016-09-04 11:47:42 +10:00
|
|
|
lev = this.newestlevel;
|
2016-08-30 14:55:26 +10:00
|
|
|
for (i = 0 ; i < arguments.length; i += 2) {
|
2016-08-22 19:52:15 +10:00
|
|
|
idx = this.levels[lev].forcelist.push(new Object()) - 1;
|
|
|
|
this.levels[lev].forcelist[idx].type = arguments[i];
|
|
|
|
this.levels[lev].forcelist[idx].howmany = arguments[i+1];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
clearlevelprogress : function (lev) {
|
|
|
|
var i,idx;
|
|
|
|
for (i = 0 ; i < this.levels[lev].goals.length; i++) {
|
|
|
|
this.levels[lev].goals[i].progress = 0;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
// thing1, thing2, etc
|
2016-08-30 14:55:26 +10:00
|
|
|
addlevelallowedthings : function () {
|
|
|
|
var i,lev;
|
2016-09-04 11:47:42 +10:00
|
|
|
lev = this.newestlevel;
|
2016-08-30 14:55:26 +10:00
|
|
|
for (i = 0 ; i < arguments.length; i++) {
|
2016-08-22 19:52:15 +10:00
|
|
|
this.levels[lev].allowedthings.push(arguments[i]);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-08-31 17:45:15 +10:00
|
|
|
setlevelcatcols : function (numcols) {
|
|
|
|
var lev;
|
|
|
|
lev = this.levels.length - 1;
|
|
|
|
this.levels[lev].catcols = numcols;
|
|
|
|
},
|
|
|
|
|
2016-08-21 09:57:40 +10:00
|
|
|
// goal1type goal1count goal2type goal2count etc...
|
2016-08-30 14:55:26 +10:00
|
|
|
addlevelgoals : function () {
|
|
|
|
var i,idx,lev;
|
2016-09-04 11:47:42 +10:00
|
|
|
lev = this.newestlevel;
|
2016-08-30 14:55:26 +10:00
|
|
|
|
|
|
|
for (i = 0 ; i < arguments.length; i += 2) {
|
2016-08-21 09:57:40 +10:00
|
|
|
idx = this.levels[lev].goals.push(new Object()) - 1;
|
|
|
|
this.levels[lev].goals[idx].type = arguments[i];
|
|
|
|
this.levels[lev].goals[idx].count = arguments[i+1];
|
|
|
|
this.levels[lev].goals[idx].progress = 0;
|
2016-09-03 10:52:03 +10:00
|
|
|
|
|
|
|
// make sure the level has enough bags!
|
|
|
|
if (arguments[i] == "bag") {
|
|
|
|
while (this.levels[lev].nbags < arguments[i+1]) {
|
|
|
|
this.addlevelbag(lev);
|
|
|
|
}
|
|
|
|
}
|
2016-08-21 09:32:57 +10:00
|
|
|
}
|
|
|
|
},
|
2016-08-20 12:27:15 +10:00
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
// earn progress towards goals
|
|
|
|
progress : function(type, amt) {
|
|
|
|
var i;
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
if (game.state != "running") return false;
|
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
// past last level!
|
|
|
|
if (curlevel >= game.levels.length) return false;
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
//console.log("progress()");
|
2016-08-21 09:32:57 +10:00
|
|
|
for (i = 0 ; i < this.levels[curlevel].goals.length; i++ ) {
|
2016-08-22 19:52:15 +10:00
|
|
|
//console.log("this goal type is " + this.levels[curlevel].goals[i].type);
|
2016-08-30 19:46:40 +10:00
|
|
|
|
|
|
|
// already met the goal?
|
|
|
|
if (this.levels[curlevel].goals[i].progress >= this.levels[curlevel].goals[i].count) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// goal matches what we just progressed in?
|
2016-08-21 09:32:57 +10:00
|
|
|
if (this.levels[curlevel].goals[i].type == type) {
|
2016-08-30 19:46:40 +10:00
|
|
|
// increase progress.
|
2016-08-21 09:32:57 +10:00
|
|
|
this.levels[curlevel].goals[i].progress += amt;
|
|
|
|
if (this.levels[curlevel].goals[i].progress >= this.levels[curlevel].goals[i].count) {
|
2016-08-25 20:01:45 +10:00
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
this.levels[curlevel].goals[i].progress = this.levels[curlevel].goals[i].count;
|
2016-08-25 20:01:45 +10:00
|
|
|
|
|
|
|
// add goal animation - fireworks ?
|
2016-08-31 15:19:51 +10:00
|
|
|
game.addflash();
|
|
|
|
game.addfireworks();
|
2016-08-21 09:32:57 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
calcstars : function (lev, points) {
|
|
|
|
var i;
|
|
|
|
for (i = 2; i >= 0; i--) {
|
2016-09-05 14:22:21 +10:00
|
|
|
if (this.levels[lev] == undefined) {
|
|
|
|
console.log("** error - lev " + lev + " is undefined");
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
if (points >= this.levels[lev].starpoints[i]) {
|
|
|
|
return (i+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
calcstartext : function (nstars) {
|
|
|
|
var i;
|
|
|
|
var met = "", notmet = "";
|
|
|
|
for (i = 0; i < nstars; i++) {
|
|
|
|
met = met + FULLSTAR;
|
|
|
|
}
|
|
|
|
for (; i < 3; i++) {
|
|
|
|
notmet = notmet + EMPTYSTAR;
|
|
|
|
}
|
|
|
|
return [ met, notmet ] ;
|
|
|
|
},
|
|
|
|
*/
|
|
|
|
|
|
|
|
setstarpoints : function( lev, p1, p2, p3 ) {
|
|
|
|
this.levels[lev].starpoints = new Array();
|
|
|
|
this.levels[lev].starpoints[0] = p1;
|
|
|
|
this.levels[lev].starpoints[1] = p2;
|
|
|
|
this.levels[lev].starpoints[2] = p3;
|
|
|
|
},
|
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
getgoalminmax : function (lev, gtype) {
|
|
|
|
var min = 1,max = -1;
|
2016-09-04 11:47:42 +10:00
|
|
|
switch (gtype) {
|
|
|
|
case "food":
|
2016-09-05 14:22:21 +10:00
|
|
|
min = lev * 0.5;
|
2016-09-04 11:47:42 +10:00
|
|
|
max = lev * 1.2;
|
|
|
|
break;
|
|
|
|
case "llama":
|
2016-09-05 14:22:21 +10:00
|
|
|
min = lev * 0.16;
|
2016-09-04 11:47:42 +10:00
|
|
|
max = lev * 0.5;
|
|
|
|
break;
|
|
|
|
case "cat":
|
2016-09-05 14:22:21 +10:00
|
|
|
min = lev * 0.8;
|
2016-09-04 11:47:42 +10:00
|
|
|
max = lev * 1.5;
|
|
|
|
break;
|
|
|
|
case "goat":
|
2016-09-05 14:22:21 +10:00
|
|
|
min = lev * 0.17;
|
2016-09-04 11:47:42 +10:00
|
|
|
max = lev * 0.25;
|
|
|
|
break;
|
|
|
|
case "brick":
|
2016-09-05 14:22:21 +10:00
|
|
|
min = lev * 0.03;
|
2016-09-04 11:47:42 +10:00
|
|
|
max = lev * 0.1;
|
|
|
|
break;
|
|
|
|
case "door":
|
2016-09-05 14:22:21 +10:00
|
|
|
min = lev * 0.03;
|
2016-09-04 11:47:42 +10:00
|
|
|
max = lev * 0.1;
|
|
|
|
break;
|
2016-09-05 14:22:21 +10:00
|
|
|
case "sunlight":
|
|
|
|
min = lev * 0.06;
|
|
|
|
max = lev * 0.16;
|
2016-09-04 11:47:42 +10:00
|
|
|
break;
|
|
|
|
case "bag":
|
2016-09-05 14:22:21 +10:00
|
|
|
min = 1;
|
|
|
|
max = game.getmaxbags(lev);
|
|
|
|
break;
|
|
|
|
case "toad":
|
|
|
|
min = lev * 0.06;
|
|
|
|
max = lev * 0.15;
|
2016-09-04 11:47:42 +10:00
|
|
|
break;
|
|
|
|
default: // should never happen
|
2016-09-05 14:22:21 +10:00
|
|
|
min = 1;
|
2016-09-04 11:47:42 +10:00
|
|
|
max = lev * 0.2;
|
|
|
|
break;
|
|
|
|
}
|
2016-09-05 14:22:21 +10:00
|
|
|
|
|
|
|
min = Math.floor(min);
|
2016-09-04 11:47:42 +10:00
|
|
|
max = Math.floor(max);
|
2016-09-05 14:22:21 +10:00
|
|
|
|
|
|
|
if (min < 1) min = 1;
|
|
|
|
if (max < min) max = min;
|
|
|
|
return [ min, max];
|
2016-09-04 11:47:42 +10:00
|
|
|
},
|
|
|
|
|
2016-08-29 14:21:42 +10:00
|
|
|
calclevparams : function( lev ) {
|
2016-08-24 22:47:23 +10:00
|
|
|
var i,num;
|
2016-08-23 01:13:47 +10:00
|
|
|
var min = 0,pointsgoal = false;
|
2016-08-29 14:21:42 +10:00
|
|
|
var turnsreq = 0;
|
2016-08-29 19:24:29 +10:00
|
|
|
var forceturnsreq = false;
|
2016-08-22 19:52:15 +10:00
|
|
|
// calculate minimum points required to win
|
|
|
|
// first pass
|
|
|
|
for (i = 0; i < this.levels[lev].goals.length; i++) {
|
|
|
|
switch (this.levels[lev].goals[i].type) {
|
|
|
|
case "food":
|
|
|
|
min += FOODPOINTS * this.levels[lev].goals[i].count;
|
2016-08-29 14:21:42 +10:00
|
|
|
turnsreq += this.levels[lev].goals[i].count * 0.5;
|
2016-08-22 19:52:15 +10:00
|
|
|
break;
|
2016-08-30 17:19:28 +10:00
|
|
|
case "llama":
|
2016-08-22 19:52:15 +10:00
|
|
|
// actually a bit more than this, since you need cats to get rid of llamas.
|
2016-08-30 14:55:26 +10:00
|
|
|
min += (LLAMAPOINTS) * this.levels[lev].goals[i].count;
|
|
|
|
turnsreq += this.levels[lev].goals[i].count * 1.5;
|
2016-08-22 19:52:15 +10:00
|
|
|
break;
|
2016-08-30 17:19:28 +10:00
|
|
|
case "cat": // use smaller amount of catpoints
|
2016-08-22 19:52:15 +10:00
|
|
|
min += Math.min(CATPOINTS, SLEEPYCATPOINTS) * this.levels[lev].goals[i].count;
|
2016-08-29 19:24:29 +10:00
|
|
|
turnsreq += this.levels[lev].goals[i].count / 3;
|
2016-08-22 19:52:15 +10:00
|
|
|
break;
|
2016-08-30 17:19:28 +10:00
|
|
|
case "goat":
|
2016-08-22 19:52:15 +10:00
|
|
|
min += GOATPOINTS * this.levels[lev].goals[i].count;
|
2016-08-29 14:21:42 +10:00
|
|
|
turnsreq += this.levels[lev].goals[i].count * 1;
|
2016-08-22 19:52:15 +10:00
|
|
|
break;
|
2016-08-31 13:55:35 +10:00
|
|
|
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;
|
2016-08-30 17:19:28 +10:00
|
|
|
case "turn":
|
2016-08-24 22:47:23 +10:00
|
|
|
// assume you'll get a parade on most turns.
|
2016-08-25 16:49:54 +10:00
|
|
|
num = (Math.min(CATPOINTS, SLEEPYCATPOINTS) * this.levels[lev].goals[i].count);
|
2016-08-24 22:47:23 +10:00
|
|
|
if (!game.isbanned(curlevel, "door")) {
|
|
|
|
num *= 1.5;
|
|
|
|
}
|
|
|
|
min += num;
|
2016-08-23 01:13:47 +10:00
|
|
|
break;
|
2016-08-30 17:19:28 +10:00
|
|
|
case "door":
|
2016-08-23 01:13:47 +10:00
|
|
|
// double the value of a minimum-score parade
|
|
|
|
min += Math.min(CATPOINTS, SLEEPYCATPOINTS) * 3 * 2 * this.levels[lev].goals[i].count;
|
2016-08-29 14:21:42 +10:00
|
|
|
turnsreq += this.levels[lev].goals[i].count * 1;
|
2016-09-04 11:47:42 +10:00
|
|
|
break;
|
2016-09-05 14:22:21 +10:00
|
|
|
case "sunlight":
|
|
|
|
min += Math.min(CATPOINTS, SLEEPYCATPOINTS)*this.levels[lev].gridh * this.levels[lev].goals[i].count;
|
2016-08-29 14:21:42 +10:00
|
|
|
turnsreq += this.levels[lev].gridh;
|
2016-08-23 01:13:47 +10:00
|
|
|
break;
|
2016-09-05 14:22:21 +10:00
|
|
|
case "curtain":
|
|
|
|
min += Math.min(CATPOINTS, SLEEPYCATPOINTS) * this.levels[lev].goals[i].count;
|
|
|
|
turnsreq += this.levels[lev].goals[i].count * 1.2;
|
|
|
|
break;
|
|
|
|
case "bag":
|
|
|
|
min += Math.min(CATPOINTS, SLEEPYCATPOINTS) * BAGCAPACITY * this.levels[lev].goals[i].count;
|
|
|
|
turnsreq += this.levels[lev].goals[i].count * 1.2;
|
|
|
|
break;
|
|
|
|
case "toad":
|
|
|
|
min += Math.min(CATPOINTS, SLEEPYCATPOINTS)*this.levels[lev].gridh * this.levels[lev].goals[i].count;
|
|
|
|
turnsreq += this.levels[lev].goals[i].count * 2;
|
|
|
|
break;
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
}
|
2016-08-24 22:47:23 +10:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// second pass - overrides
|
|
|
|
for (i = 0; i < this.levels[lev].goals.length; i++) {
|
|
|
|
switch (this.levels[lev].goals[i].type) {
|
2016-08-29 14:21:42 +10:00
|
|
|
/*
|
2016-08-22 19:52:15 +10:00
|
|
|
case "points":
|
2016-08-23 01:13:47 +10:00
|
|
|
pointsgoal = this.levels[lev].goals[i].count;
|
2016-08-22 19:52:15 +10:00
|
|
|
break;
|
2016-08-29 14:21:42 +10:00
|
|
|
*/
|
2016-08-30 17:19:28 +10:00
|
|
|
case "turn":
|
2016-08-29 14:21:42 +10:00
|
|
|
turnsreq = this.levels[lev].goals[i].count;
|
2016-08-29 19:24:29 +10:00
|
|
|
forceturnsreq = true;
|
2016-08-29 14:21:42 +10:00
|
|
|
break;
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
}
|
2016-08-24 22:47:23 +10:00
|
|
|
|
|
|
|
// adjust for level size
|
|
|
|
if (this.levels[lev].gridsize != DEF_GRIDSIZE) {
|
|
|
|
var ratio;
|
|
|
|
ratio = (this.levels[lev].gridw * this.levels[lev].gridh) /
|
2016-08-30 14:55:26 +10:00
|
|
|
(DEF_GRIDW * DEF_GRIDH);
|
2016-08-24 22:47:23 +10:00
|
|
|
|
|
|
|
min *= ratio;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
this.levels[lev].starpoints = new Array();
|
2016-08-30 14:55:26 +10:00
|
|
|
this.levels[lev].starpoints[0] = Math.floor(min);
|
2016-09-08 10:23:17 +10:00
|
|
|
this.levels[lev].starpoints[1] = Math.floor(min * 2);
|
|
|
|
this.levels[lev].starpoints[2] = Math.floor(min * 3);
|
2016-08-29 14:21:42 +10:00
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
if ((turnsreq > this.levels[lev].maxturns) || forceturnsreq) {
|
2016-08-29 14:21:42 +10:00
|
|
|
this.levels[lev].maxturns = turnsreq;
|
|
|
|
}
|
2016-08-29 19:24:29 +10:00
|
|
|
|
|
|
|
// must be an integer
|
|
|
|
this.levels[lev].maxturns = Math.floor(this.levels[lev].maxturns);
|
2016-09-01 08:20:38 +10:00
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
/*
|
2016-09-01 08:20:38 +10:00
|
|
|
// calc stars to unlock
|
|
|
|
// must use 'lev-1' so that level 1 requires no stars.
|
|
|
|
// 1.2 * level num
|
|
|
|
if (lev < 5) {
|
|
|
|
this.levels[lev].starsrequired = Math.floor(1.2 * (lev-1));
|
|
|
|
} else {
|
|
|
|
this.levels[lev].starsrequired = Math.floor(1.5 * (lev-1));
|
|
|
|
}
|
2016-09-04 11:47:42 +10:00
|
|
|
*/
|
2016-09-01 08:20:38 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
},
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
getstarsrequired : function (lev) {
|
|
|
|
var req;
|
|
|
|
// calc stars to unlock
|
|
|
|
// must use 'lev-1' so that level 1 requires no stars.
|
|
|
|
// 1.2 * level num
|
|
|
|
if (lev < 5) {
|
|
|
|
req = Math.floor(1.2 * (lev-1));
|
|
|
|
} else {
|
|
|
|
req = Math.floor(1.5 * (lev-1));
|
|
|
|
}
|
|
|
|
return req;
|
|
|
|
},
|
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
initlevels : function ( ) {
|
|
|
|
var mylevel,i,n;
|
|
|
|
|
|
|
|
console.log("doing level init");
|
|
|
|
this.levels = [];
|
2016-08-21 09:57:40 +10:00
|
|
|
this.addlevel(1, true);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelgoals("food", 5);
|
2016-08-31 13:55:35 +10:00
|
|
|
this.addlevelallowedthings("cat", "food");
|
2016-08-22 19:52:15 +10:00
|
|
|
this.setstarpoints(1, 50, 60, 80);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelthings( "cat", 50, "food", 50);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
this.addlevel(2, true);
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("cat", 12);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelthings("cat", 45, "food", 55);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
this.addlevel(3, true);
|
2016-08-31 13:55:35 +10:00
|
|
|
this.addlevelallowedthings("llama");
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("llama", 4);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
this.addlevel(4, true);
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("llama", 5);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelgoals("food", 5);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevel(5, true);
|
2016-08-25 16:49:54 +10:00
|
|
|
this.addlevelgridwid(5, 6);
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("bag", 1);
|
|
|
|
this.addlevelgoals("turn", 10);
|
2016-08-24 22:47:23 +10:00
|
|
|
//this.addlevelgoals(5, "points", 600);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// introduce goats!
|
|
|
|
this.addlevel(6, true);
|
2016-08-31 13:55:35 +10:00
|
|
|
this.addlevelallowedthings("goat");
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("goat", 3);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelthings("goat", 10, "cat", 50, "food", 30, "llama", 10); // higher than normal goat chance
|
|
|
|
this.addlevelforcethings("goat", 1);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
this.addlevel(7, false);
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("llama", 6);
|
|
|
|
this.addlevelgoals("goat", 3);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
this.addlevel(8, false);
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("llama", 6);
|
|
|
|
this.addlevelgoals("goat", 4);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelgoals("food", 5);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// introduce doors
|
2016-08-23 01:13:47 +10:00
|
|
|
this.addlevel(9, true);
|
2016-08-31 13:55:35 +10:00
|
|
|
this.addlevelallowedthings("door");
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("door", 1);
|
|
|
|
this.addlevelgoals("llama", 5);
|
|
|
|
this.addlevelgoals("cat", 13);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelforcethings("door", 1);
|
2016-08-23 01:13:47 +10:00
|
|
|
|
|
|
|
this.addlevel(10, false);
|
2016-08-25 16:49:54 +10:00
|
|
|
this.addlevelgridwid(10, 7);
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("turn", 15);
|
2016-08-23 01:13:47 +10:00
|
|
|
|
|
|
|
// introduce sunlight
|
|
|
|
this.addlevel(11, true);
|
2016-08-31 13:55:35 +10:00
|
|
|
this.addlevelallowedthings("sunlight");
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("cat", 13);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelgoals("food", 5);
|
2016-08-31 13:55:35 +10:00
|
|
|
this.addlevelgoals("sunlight", 1);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelforcethings("sunlight", 1);
|
|
|
|
|
2016-08-30 17:19:28 +10:00
|
|
|
// introduce whitecat
|
|
|
|
this.addlevel(12, true);
|
2016-08-31 13:55:35 +10:00
|
|
|
this.addlevelallowedthings("whitecat");
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("cat", 15);
|
|
|
|
this.addlevelgoals("whitecat", 1);
|
|
|
|
this.addlevelgoals("llama", 6);
|
|
|
|
this.addlevelforcethings("whitecat", 1);
|
|
|
|
|
|
|
|
// introduce toad
|
|
|
|
this.addlevel(13, true);
|
2016-08-31 13:55:35 +10:00
|
|
|
this.addlevelallowedthings("toad");
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("toad", 1);
|
|
|
|
this.addlevelgoals("cat", 20);
|
|
|
|
this.addlevelgoals("llama", 5);
|
|
|
|
this.addlevelforcethings("toad", 1);
|
2016-08-30 14:55:26 +10:00
|
|
|
|
|
|
|
this.addlevel(14, false);
|
2016-08-30 17:19:28 +10:00
|
|
|
this.addlevelgoals("cat", 25);
|
|
|
|
this.addlevelgoals("llama", 6);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelgoals("food", 15);
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
// introduce bricks
|
|
|
|
this.addlevel(15, true);
|
2016-08-30 14:55:26 +10:00
|
|
|
this.addlevelgridwid(15, 8);
|
2016-08-31 13:55:35 +10:00
|
|
|
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);
|
|
|
|
|
2016-08-31 17:45:15 +10:00
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
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);
|
|
|
|
|
2016-08-31 17:45:15 +10:00
|
|
|
// introduce other coloured cats.
|
|
|
|
this.addlevel(18, true);
|
|
|
|
this.setlevelcatcols(2);
|
|
|
|
this.addlevelgoals("cat", 30);
|
2016-08-31 13:55:35 +10:00
|
|
|
|
2016-09-02 11:48:48 +10:00
|
|
|
this.addlevel(19, false);
|
|
|
|
this.addlevelbricks(2,2, 3,2, 4,2, 5,2,
|
|
|
|
2,3, 5,3,
|
|
|
|
2,4, 5,4,
|
|
|
|
2,5, 3,5, 4,5, 5,5);
|
2016-09-08 14:35:44 +10:00
|
|
|
this.addlevelgoals("cat", 20);
|
|
|
|
this.addlevelgoals("llama", 3);
|
2016-09-02 11:48:48 +10:00
|
|
|
this.addlevelgoals("brick", 3);
|
|
|
|
|
|
|
|
this.addlevel(20, false);
|
|
|
|
this.addlevelgridwid(20, 9);
|
|
|
|
this.addlevelbricks( 1,0, 5,0, 6,0, 7,0,
|
|
|
|
0,1, 2,1, 5,1,
|
|
|
|
0,2, 1,2, 2,2, 5,2, 6,2, 7,2,
|
|
|
|
0,3, 2,3, 7,3,
|
|
|
|
5,4, 6,4, 7,4,
|
|
|
|
|
|
|
|
3,6, 5,6,
|
|
|
|
3,7, 4,7, 5,7,
|
|
|
|
3,8, 5,8 );
|
|
|
|
this.addlevelgoals("food", 25);
|
|
|
|
|
2016-09-02 16:32:20 +10:00
|
|
|
this.addlevel(21, true);
|
2016-09-02 13:42:47 +10:00
|
|
|
this.addlevelallowedthings("curtain");
|
2016-09-02 11:48:48 +10:00
|
|
|
this.addlevelforcethings("curtain", 2);
|
2016-09-03 10:52:03 +10:00
|
|
|
this.addlevelgoals("curtain", 2, "cat", 30);
|
|
|
|
|
|
|
|
this.addlevel(22, false);
|
|
|
|
this.addlevelgoals("curtain", 2, "bag", 2);
|
|
|
|
|
|
|
|
|
|
|
|
this.addlevel(23, false);
|
|
|
|
this.addlevelgoals("cat", 20, "food", 20);
|
|
|
|
|
|
|
|
this.addlevel(24, true); // introduce boxes
|
|
|
|
this.addlevelallowedthings("box");
|
|
|
|
this.addlevelforcethings("box", 2);
|
|
|
|
this.addlevelgoals("ambush", 5, "cat", 20);
|
|
|
|
|
|
|
|
this.addlevel(25, false);
|
|
|
|
this.addlevelbricks( 3,4, 5,4 );
|
|
|
|
|
|
|
|
|
|
|
|
this.addlevelgoals("ambush", 2, "door", 3, "cat", 20);
|
|
|
|
|
|
|
|
this.addlevel(26, false);
|
|
|
|
this.addlevelbricks(8,0,
|
|
|
|
8,1,
|
|
|
|
8,2,
|
|
|
|
8,3,
|
|
|
|
8,4,
|
|
|
|
8,5,
|
|
|
|
8,6,
|
|
|
|
8,7,
|
|
|
|
8,8);
|
|
|
|
this.addlevelgoals("cat", 30, "bag", 2);
|
|
|
|
|
|
|
|
|
|
|
|
this.addlevel(27, false);
|
|
|
|
this.addlevelbricks( 4,3,
|
|
|
|
3,4,4,4,5,4,
|
|
|
|
4,5);
|
|
|
|
this.addlevelgoals("brick", 3, "ambush", 1, "llama", 15);
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
|
|
|
|
/*
|
|
|
|
hard brick pattern
|
|
|
|
this.addlevelbricks(2, 2, 5, 2,
|
|
|
|
2, 5, 5, 5
|
|
|
|
);
|
|
|
|
*/
|
2016-08-21 09:57:40 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
for (i = 1; i < this.levels.length; i++) {
|
|
|
|
var extrastars;
|
|
|
|
// calc star point cutoffs
|
|
|
|
if (this.levels[i].starpoints == undefined) {
|
2016-08-29 14:21:42 +10:00
|
|
|
this.calclevparams(i);
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2016-08-21 11:31:19 +10:00
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
|
|
|
|
/*
|
2016-08-21 09:57:40 +10:00
|
|
|
for (i = 1; i < this.levels.length; i++) {
|
|
|
|
console.log("Level " + (i) + " goals:");
|
2016-08-21 09:32:57 +10:00
|
|
|
for (n = 0; n < this.levels[i].goals.length; n++) {
|
|
|
|
console.log(GOALVERB[this.levels[i].goals[n].type] + " " +
|
|
|
|
this.levels[i].goals[n].count + " " +
|
|
|
|
this.levels[i].goals[n].type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
},
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
/*
|
2016-08-21 09:57:40 +10:00
|
|
|
startlevel : function() {
|
2016-08-21 09:32:57 +10:00
|
|
|
this.initlevelvars();
|
|
|
|
this.populategrid();
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
this.setstate("running");
|
|
|
|
this.dirty = true;
|
2016-08-21 09:32:57 +10:00
|
|
|
},
|
2016-08-25 16:49:54 +10:00
|
|
|
*/
|
2016-08-20 12:27:15 +10:00
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
populategrid : function() {
|
|
|
|
var i;
|
2016-08-20 12:27:15 +10:00
|
|
|
while (!anyvalidmoves()) {
|
2016-08-31 13:55:35 +10:00
|
|
|
var x,y,found,i;
|
2016-08-21 11:31:19 +10:00
|
|
|
|
|
|
|
console.log("populating grid...");
|
2016-08-20 12:27:15 +10:00
|
|
|
clearthings();
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
// 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
|
2016-08-20 12:27:15 +10:00
|
|
|
for (y = 0; y < GRIDH; y++) {
|
|
|
|
for (x = 0; x < GRIDW; x++) {
|
2016-08-31 13:55:35 +10:00
|
|
|
if (!getgridthing(x, y)) {
|
|
|
|
things.push(new thing(x, y, "random"));
|
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
}
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
// fix up problems
|
|
|
|
donesomething=true;
|
|
|
|
while (donesomething) {
|
|
|
|
donesomething=false;
|
|
|
|
// force items
|
|
|
|
if (game.levels[curlevel].forcelist != undefined) {
|
|
|
|
for (i = 0; i < game.levels[curlevel].forcelist.length; i++) {
|
|
|
|
var wanttype,wantnum;
|
|
|
|
wanttype = game.levels[curlevel].forcelist[i].type;
|
|
|
|
wantnum = game.levels[curlevel].forcelist[i].howmany;
|
|
|
|
|
|
|
|
// while we don't have enough...
|
|
|
|
while (countthingsoftype(wanttype) < wantnum) {
|
|
|
|
// add one.
|
2016-08-31 13:55:35 +10:00
|
|
|
var idx = -1;
|
|
|
|
// don't overwrite bricks
|
|
|
|
while (idx == -1 || things[idx].type == "brick") {
|
|
|
|
idx = rnd(things.length);
|
|
|
|
}
|
2016-09-02 11:48:48 +10:00
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
things[idx].type = wanttype;
|
2016-09-02 11:48:48 +10:00
|
|
|
things[idx].init();
|
2016-08-30 14:55:26 +10:00
|
|
|
donesomething = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ensure no matches to start with
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (matchthreefrom(things[i])) {
|
|
|
|
things[i].type = getrandomtype(); // change its type
|
|
|
|
donesomething=true;
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
}
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
|
|
|
|
// now move everything up so they'll fall down into the initial
|
|
|
|
// positions.
|
|
|
|
for (i = 0; i < things.length; i++) {
|
2016-08-30 14:55:26 +10:00
|
|
|
things[i].matched = false; // un-match it.
|
2016-08-20 12:27:15 +10:00
|
|
|
things[i].gridy -= GRIDH;
|
|
|
|
things[i].updatexy();
|
|
|
|
}
|
2016-08-21 09:32:57 +10:00
|
|
|
},
|
|
|
|
|
2016-08-25 20:01:45 +10:00
|
|
|
drawflash : function() {
|
|
|
|
if (!this.screenflash) return;
|
|
|
|
game.dirty = true;
|
|
|
|
|
|
|
|
ctx.globalAlpha = this.screenflash;
|
|
|
|
|
|
|
|
this.screenflash -= FLASHSPEED;
|
|
|
|
if (this.screenflash < 0) this.screenflash = 0;
|
|
|
|
|
|
|
|
ctx.fillStyle = "#ffffff";
|
|
|
|
this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
|
|
|
ctx.globalAlpha = 1.0;
|
|
|
|
},
|
2016-08-18 14:14:48 +10:00
|
|
|
|
|
|
|
clear : function() {
|
|
|
|
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
2016-08-27 12:25:17 +10:00
|
|
|
},
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
drawtop : function() {
|
|
|
|
var texttodraw = overdesc;
|
2016-08-20 11:34:25 +10:00
|
|
|
var col = "#aaaaaa";
|
2016-08-25 16:49:54 +10:00
|
|
|
var i,n;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
//ctx = this.context;
|
2016-08-20 11:17:22 +10:00
|
|
|
|
|
|
|
// clear
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.clearRect(0, 0, this.canvas.width-1, BOARDY-1);
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
if (game.state == "running") {
|
2016-08-22 19:52:15 +10:00
|
|
|
var y1 = 10;
|
2016-08-27 13:18:03 +10:00
|
|
|
var y2 = 20;
|
2016-08-22 19:52:15 +10:00
|
|
|
var y3 = 45;
|
|
|
|
var x,y = 10;
|
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
// show level
|
2016-08-22 19:52:15 +10:00
|
|
|
/*
|
|
|
|
ctx.font = "16pt Futura";
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
ctx.fillStyle = "#00aaee";
|
|
|
|
ctx.fillText("Level " + curlevel, SCREENW/2, y1);
|
|
|
|
*/
|
|
|
|
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "middle";
|
|
|
|
shadowtext(ctx, "Level " + curlevel, LEVELTEXTSIZE, "#00aaee", SCREENW/2, y1);
|
|
|
|
|
2016-08-27 13:18:03 +10:00
|
|
|
// just blit pre-generated star goal targets
|
|
|
|
ctx.drawImage(this.stargoalbanner, 0, y2, this.stargoalbanner.width, this.stargoalbanner.height);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2016-08-22 19:52:15 +10:00
|
|
|
var starsize = 10;
|
|
|
|
var starindent = 16;
|
2016-08-25 20:01:45 +10:00
|
|
|
var startextcol = "#eeee00";
|
|
|
|
var startextcoldark = "#999900";
|
2016-08-22 19:52:15 +10:00
|
|
|
x = SCREENW/4;
|
2016-08-27 13:18:03 +10:00
|
|
|
// TODO: use star image instead.
|
2016-08-22 19:52:15 +10:00
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
var n,starx,stars = "";
|
|
|
|
for (n = 0; n < (i+1); n++) {
|
|
|
|
stars = stars + "\u2605"
|
|
|
|
|
|
|
|
}
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "middle";
|
2016-08-25 20:01:45 +10:00
|
|
|
shadowtext(ctx, stars + " = " + addcommas(game.levels[curlevel].starpoints[i]), STARPOINTTEXTSIZE,
|
|
|
|
(score >= game.levels[curlevel].starpoints[i]) ? startextcol : startextcoldark,
|
2016-08-22 19:52:15 +10:00
|
|
|
x, y2);
|
|
|
|
x += (SCREENW / 4);
|
|
|
|
}
|
2016-08-27 13:18:03 +10:00
|
|
|
*/
|
2016-08-21 09:32:57 +10:00
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
// show score
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "middle";
|
|
|
|
shadowtext(ctx, "Score: " + addcommas(score), SCORETEXTSIZE, "white", 16, y3);
|
|
|
|
/*
|
|
|
|
ctx.font = "16pt Futura";
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
ctx.fillStyle = "white";
|
|
|
|
ctx.fillText("Score: " + addcommas(score), 16, y2);
|
|
|
|
*/
|
2016-08-20 12:27:15 +10:00
|
|
|
|
|
|
|
switch (thingsmoving()) {
|
|
|
|
case "parade":
|
|
|
|
col = "#00ff00";
|
2016-08-30 14:55:26 +10:00
|
|
|
texttodraw = "CAT PARADE!";
|
2016-08-20 12:27:15 +10:00
|
|
|
break;
|
2016-09-02 13:42:47 +10:00
|
|
|
case "climb":
|
|
|
|
col = "#00ff00";
|
|
|
|
texttodraw = "Climb";
|
|
|
|
break;
|
2016-08-20 12:27:15 +10:00
|
|
|
case "chomp":
|
|
|
|
col = "#00cc00";
|
2016-08-30 14:55:26 +10:00
|
|
|
texttodraw = "Chomp!";
|
|
|
|
break;
|
2016-08-30 17:19:28 +10:00
|
|
|
case "pow":
|
|
|
|
col = "#00cc00";
|
|
|
|
texttodraw = "Attack!";
|
|
|
|
break;
|
|
|
|
case "slap":
|
|
|
|
col = "#00cc00";
|
|
|
|
texttodraw = "Slap!";
|
|
|
|
break;
|
2016-08-30 14:55:26 +10:00
|
|
|
case "matchthree":
|
|
|
|
col = "#00cc00";
|
|
|
|
texttodraw = "OVERLOAD!";
|
|
|
|
break;
|
2016-09-05 14:22:21 +10:00
|
|
|
case "sunlight":
|
2016-08-30 14:55:26 +10:00
|
|
|
// do nothing
|
|
|
|
break;
|
|
|
|
case "shears":
|
|
|
|
col = "#00cc00";
|
|
|
|
texttodraw = "Shears!";
|
|
|
|
// do nothing
|
2016-08-20 12:27:15 +10:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// show current object in path
|
|
|
|
if ((curpath != undefined) && (curpath.length >= 1)) {
|
|
|
|
var lastone = curpath[curpath.length - 1];
|
|
|
|
texttodraw = lastone.getdesc();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (texttodraw != "") {
|
2016-08-22 19:52:15 +10:00
|
|
|
/*
|
|
|
|
ctx.font = "16pt Futura";
|
|
|
|
ctx.textAlign = "right";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
ctx.fillStyle = col;
|
|
|
|
ctx.fillText(texttodraw, SCREENW-16, y2);
|
|
|
|
*/
|
|
|
|
|
|
|
|
ctx.textAlign = "right";
|
|
|
|
ctx.textBaseline = "middle";
|
|
|
|
shadowtext(ctx, texttodraw, SCORETEXTSIZE, col, SCREENW-16, y3);
|
2016-08-20 12:27:15 +10:00
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
} else if (game.state == "gameover") {
|
2016-08-29 19:24:29 +10:00
|
|
|
var text;
|
|
|
|
if (game.turnsleft <= 0) {
|
|
|
|
text = "Out of moves!";
|
|
|
|
} else {
|
|
|
|
text = "No valid moves!";
|
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
this.context.textAlign = "center";
|
|
|
|
this.context.textBaseline = "top";
|
2016-08-29 19:24:29 +10:00
|
|
|
shadowtext(this.context, text, 20, "red", SCREENW / 2, 5);
|
2016-08-21 07:56:41 +10:00
|
|
|
shadowtext(this.context, "Final Score: " + addcommas(score), 16, "white", SCREENW / 2, 35);
|
2016-08-21 09:32:57 +10:00
|
|
|
} else if (game.state == "levelcomplete") {
|
|
|
|
this.context.textAlign = "center";
|
|
|
|
this.context.textBaseline = "top";
|
|
|
|
shadowtext(this.context, "LEVEL COMPLETE!", 20, "#00ee00", SCREENW / 2, 5);
|
|
|
|
shadowtext(this.context, "Score: " + addcommas(score), 16, "white", SCREENW / 2, 35);
|
2016-08-20 15:12:32 +10:00
|
|
|
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
drawbottom : function() {
|
2016-08-25 16:49:54 +10:00
|
|
|
var bx = 0,by = BOARDY + GRIDH*GRIDSIZE + 25;
|
|
|
|
var bw = SCREENW - BOTTOMBORDERWIDTH, bh = SCREENH - by - BOTTOMBORDERWIDTH;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
var x,y;
|
2016-08-21 09:32:57 +10:00
|
|
|
var margin = 10;
|
|
|
|
var indent = 50;
|
2016-08-30 19:46:40 +10:00
|
|
|
var progindent = 25;
|
2016-08-21 09:32:57 +10:00
|
|
|
var boxindent = 20;
|
2016-08-25 16:49:54 +10:00
|
|
|
//ctx = this.context;
|
2016-08-21 09:32:57 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
if ((game.state == "running") || (game.state == "levelcomplete") || (game.state == "gameover")) {
|
2016-08-21 09:32:57 +10:00
|
|
|
var texth = GOALTEXTSIZE+10;
|
|
|
|
var gradient;
|
|
|
|
var borderwidth = 5;
|
|
|
|
var goaltitlecol = "#00aaee";
|
|
|
|
|
|
|
|
// background
|
|
|
|
gradient = this.context.createLinearGradient(0, 0, bw, bh);
|
|
|
|
gradient.addColorStop(0, "#0000ff");
|
|
|
|
gradient.addColorStop(1, "#000055");
|
|
|
|
ctx.fillStyle = gradient;
|
|
|
|
ctx.fillRect(bx, by, bw, bh);
|
|
|
|
|
|
|
|
//outline
|
2016-08-30 14:55:26 +10:00
|
|
|
ctx.strokeStyle = "white";
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.lineWidth = BOTTOMBORDERWIDTH;
|
2016-08-21 09:32:57 +10:00
|
|
|
ctx.beginPath();
|
2016-08-30 14:55:26 +10:00
|
|
|
ctx.rect(bx+(borderwidth/2)-1, by+(borderwidth/2)-1, bw-(borderwidth/2), bh-(borderwidth/2));
|
2016-08-21 09:32:57 +10:00
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
// draw goals
|
|
|
|
x = bx + margin;
|
|
|
|
y = by + margin;
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
shadowtext(ctx, "Goals:", GOALTEXTSIZE,goaltitlecol, x , y); y += texth;
|
|
|
|
|
|
|
|
if (curlevel < this.levels.length) {
|
|
|
|
for (n = 0; n < this.levels[curlevel].goals.length; n++) {
|
|
|
|
var goalcol = "#aaee00";
|
|
|
|
var goalmet = false;
|
|
|
|
|
2016-08-25 20:01:45 +10:00
|
|
|
// for checkbox
|
|
|
|
var boxsize = texth-8;
|
|
|
|
var boxx = x+boxindent;
|
|
|
|
var boxy = y + texth/2 - boxsize/2;
|
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
if (this.levels[curlevel].goals[n].progress >= this.levels[curlevel].goals[n].count) {
|
|
|
|
goalmet = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (goalmet) {
|
|
|
|
goalcol = "#00ddff";
|
|
|
|
} else {
|
|
|
|
goalcol = "#aaee00";
|
|
|
|
}
|
|
|
|
|
2016-08-30 19:46:40 +10:00
|
|
|
// goal description
|
2016-08-30 17:19:28 +10:00
|
|
|
var ess = "s";
|
2016-09-03 10:52:03 +10:00
|
|
|
if (this.levels[curlevel].goals[n].count == 1) {
|
2016-08-31 13:55:35 +10:00
|
|
|
ess = "";
|
2016-09-03 10:52:03 +10:00
|
|
|
} else if (this.levels[curlevel].goals[n].type == "food") {
|
2016-08-30 17:19:28 +10:00
|
|
|
ess = "";
|
2016-09-03 10:52:03 +10:00
|
|
|
} else if (this.levels[curlevel].goals[n].type == "ambush") {
|
|
|
|
var ess = "es";
|
2016-08-30 17:19:28 +10:00
|
|
|
}
|
2016-08-30 19:46:40 +10:00
|
|
|
|
|
|
|
|
|
|
|
var goalname;
|
|
|
|
if (GOALNAME[this.levels[curlevel].goals[n].type] == undefined) {
|
|
|
|
goalname = this.levels[curlevel].goals[n].type;
|
|
|
|
} else {
|
|
|
|
goalname = GOALNAME[this.levels[curlevel].goals[n].type];
|
|
|
|
}
|
2016-08-30 17:19:28 +10:00
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
var goaltext = GOALVERB[this.levels[curlevel].goals[n].type] + " " +
|
|
|
|
this.levels[curlevel].goals[n].count + " " +
|
2016-08-30 19:46:40 +10:00
|
|
|
goalname + ess;
|
2016-08-21 09:32:57 +10:00
|
|
|
|
|
|
|
var progtext = "[" + this.levels[curlevel].goals[n].progress + " / " +
|
|
|
|
this.levels[curlevel].goals[n].count + "]";
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
shadowtext(ctx, goaltext, GOALTEXTSIZE,goalcol, x+indent, y);
|
|
|
|
|
|
|
|
ctx.textAlign = "right";
|
|
|
|
ctx.textBaseline = "top";
|
2016-08-30 19:46:40 +10:00
|
|
|
|
|
|
|
shadowtext(ctx, progtext, GOALTEXTSIZE,goalcol, SCREENW-progindent, y);
|
2016-08-21 09:32:57 +10:00
|
|
|
|
2016-08-25 20:01:45 +10:00
|
|
|
// completed?
|
|
|
|
if (goalmet) {
|
|
|
|
var crossouth = 4;
|
|
|
|
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.fillStyle = goalcol;
|
|
|
|
ctx.fillRect(x+indent,boxy+boxsize/2-crossouth/2,SCREENW - indent*2 - x, crossouth);
|
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.strokeStyle = "black";
|
|
|
|
ctx.lineWidth = 1;
|
|
|
|
ctx.rect(x+indent,boxy+boxsize/2-crossouth/2,SCREENW - indent*2 - x, crossouth);
|
|
|
|
ctx.stroke();
|
|
|
|
}
|
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
// checkbox
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.lineWidth = 3;
|
|
|
|
ctx.strokeStyle = "black";
|
|
|
|
ctx.rect(boxx,boxy,boxsize,boxsize); // shadow1
|
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.lineWidth = 2;
|
|
|
|
ctx.strokeStyle = goalcol;
|
|
|
|
ctx.rect(boxx,boxy,boxsize,boxsize); // shadow1
|
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
// ticked ?
|
|
|
|
if (goalmet) {
|
2016-08-22 19:52:15 +10:00
|
|
|
drawtick(ctx, boxx, boxy, boxx + boxsize-1, boxy + boxsize-1, goalcol, 2);
|
2016-08-21 09:32:57 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
y += texth;
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
y += texth;
|
2016-08-21 09:32:57 +10:00
|
|
|
} else {
|
|
|
|
// past last level
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
shadowtext(ctx, "(none)", GOALTEXTSIZE,goaltitlecol, x+indent, y);
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
zoomwinimg : function() {
|
|
|
|
var orig;
|
|
|
|
orig = this.winimgsize;
|
|
|
|
this.winimgsize += WINIMGZOOMSPEED;
|
|
|
|
if (this.winimgsize > 1) this.winimgsize = 1;
|
|
|
|
|
|
|
|
if (this.winimgsize != orig) {
|
|
|
|
// recalc image position
|
|
|
|
tapx = (SCREENW/2) - ((tapw * this.winimgsize)/2);
|
|
|
|
tapy = BOARDY + ((GRIDH*GRIDSIZE)/2) - ((taph*this.winimgsize)/2);
|
|
|
|
game.dirty = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
drawcontinuebutton : function() {
|
|
|
|
var borderwidth = 5;
|
2016-08-25 16:49:54 +10:00
|
|
|
//var /ctx = this.context;
|
2016-08-22 19:52:15 +10:00
|
|
|
var col,y;
|
|
|
|
|
|
|
|
|
|
|
|
if (game.state == "gameover") {
|
|
|
|
//fill
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.fillStyle = "black";
|
|
|
|
ctx.fillRect(tapx+(borderwidth/2), tapy+(borderwidth/2), tapw-(borderwidth), taph-(borderwidth/2));
|
|
|
|
ctx.stroke();
|
|
|
|
} else {
|
|
|
|
var zoomw,zoomh;
|
|
|
|
// draw winning cat image
|
2016-08-23 01:13:47 +10:00
|
|
|
//console.log("drawing win img. tapx:" + tapx + " tapy:" + tapy + " tapw:" + tapw + " taph:" + taph);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
zoomw = tapw * game.winimgsize;
|
|
|
|
zoomh = taph * game.winimgsize;
|
|
|
|
|
|
|
|
this.context.drawImage(winimg, tapx, tapy, zoomw, zoomh);
|
|
|
|
}
|
|
|
|
|
|
|
|
//outline
|
|
|
|
if (game.state == "gameover") {
|
|
|
|
col = "#dd0000";
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.strokeStyle = col;
|
|
|
|
ctx.lineWidth = 5;
|
|
|
|
ctx.rect(tapx+(borderwidth/2), tapy+(borderwidth/2), tapw-(borderwidth), taph-(borderwidth/2));
|
|
|
|
ctx.stroke();
|
|
|
|
} else if (game.winimgsize >= 1) {
|
|
|
|
col = "#00dd00";
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.strokeStyle = col;
|
|
|
|
ctx.lineWidth = 5;
|
|
|
|
ctx.rect(tapx+(borderwidth/2), tapy+(borderwidth/2), tapw-(borderwidth), taph-(borderwidth/2));
|
|
|
|
ctx.stroke();
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
|
|
|
|
if (game.state == "gameover") {
|
|
|
|
y = tapy + taph/2;
|
|
|
|
ctx.textBaseline = "middle";
|
|
|
|
shadowtext(ctx, "Tap here to continue", TAPBUTTONSIZE, col, SCREENW / 2, y);
|
|
|
|
} else if (game.winimgsize >= 1) {
|
|
|
|
var nstars;
|
|
|
|
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
|
|
|
|
y = tapy + taph - 5 - TAPBUTTONSIZE*1.5;
|
|
|
|
shadowtext(ctx, "Tap to continue", TAPBUTTONSIZEC, col, SCREENW / 2, y);
|
|
|
|
|
|
|
|
y += TAPBUTTONSIZEC;
|
|
|
|
|
|
|
|
nstars = game.calcstars(curlevel, score);
|
2016-08-26 16:27:42 +10:00
|
|
|
game.drawstars(ctx, SCREENW / 2, y, TAPBUTTONSIZESTAR, nstars, STARWID_ENDLEV);
|
2016-09-09 18:25:43 +10:00
|
|
|
//console.log("earned " + nstars + " stars");
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2016-08-26 16:27:42 +10:00
|
|
|
drawstars : function(ctx, x, y, size, stars, starwid) {
|
2016-08-22 19:52:15 +10:00
|
|
|
var i;
|
|
|
|
var starcol = "#dddd00";
|
2016-08-26 16:27:42 +10:00
|
|
|
var starspace = starwid / 10;
|
2016-08-22 19:52:15 +10:00
|
|
|
var sx;
|
|
|
|
|
2016-08-26 16:27:42 +10:00
|
|
|
sx = x - (starwid+starspace);
|
2016-08-22 19:52:15 +10:00
|
|
|
for (i = 1;i <= 3; i++) {
|
2016-08-26 16:27:42 +10:00
|
|
|
var thiscol,imgname;
|
2016-08-22 19:52:15 +10:00
|
|
|
if (stars >= i) {
|
2016-08-26 16:27:42 +10:00
|
|
|
imgname = "starfull";
|
2016-08-22 19:52:15 +10:00
|
|
|
} else {
|
2016-08-26 16:27:42 +10:00
|
|
|
imgname = "starempty";
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "middle";
|
2016-08-26 16:27:42 +10:00
|
|
|
this.context.drawImage(image[imgname], sx - (starwid/2), y - (starwid/2), starwid, starwid);
|
|
|
|
|
|
|
|
sx += starwid + starspace;
|
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
drawbg : function() {
|
|
|
|
var gradient,x,y,off;
|
|
|
|
var catscale,catsize,catspeed;
|
|
|
|
var wantalpha,alphaspeed;
|
2016-08-26 23:38:53 +10:00
|
|
|
var titlebg = "#008c8c";
|
|
|
|
var origtitlebg = "#005051";
|
2016-08-20 15:12:32 +10:00
|
|
|
// background
|
2016-08-25 16:49:54 +10:00
|
|
|
/*
|
2016-08-20 15:12:32 +10:00
|
|
|
gradient = this.context.createLinearGradient(0, 0, 0, SCREENH);
|
|
|
|
gradient.addColorStop(0, "black");
|
|
|
|
gradient.addColorStop(1, "blue");
|
|
|
|
|
|
|
|
this.context.fillStyle = gradient;
|
2016-08-25 16:49:54 +10:00
|
|
|
*/
|
2016-08-26 23:38:53 +10:00
|
|
|
this.context.fillStyle = titlebg;
|
2016-08-20 15:12:32 +10:00
|
|
|
this.context.fillRect(0, 0, SCREENW, SCREENH);
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
// moving cats
|
2016-08-25 20:01:45 +10:00
|
|
|
catscale = 1;
|
2016-09-02 11:48:48 +10:00
|
|
|
catspeed = 1;
|
2016-08-25 16:49:54 +10:00
|
|
|
alphaspeed = 0.02;
|
|
|
|
|
|
|
|
catsize = DEF_GRIDSIZE * catscale;
|
|
|
|
if (game.state == "help" ){
|
|
|
|
wantalpha = 0.2;
|
|
|
|
} else if (game.state == "levselect") {
|
|
|
|
wantalpha = 0.6;
|
|
|
|
} else {
|
|
|
|
wantalpha = 1.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (catalpha > wantalpha) {
|
|
|
|
catalpha -= alphaspeed;
|
|
|
|
if (catalpha < wantalpha) catalpha = wantalpha;
|
|
|
|
} else if (catalpha < wantalpha) {
|
|
|
|
catalpha += alphaspeed;
|
|
|
|
if (catalpha > wantalpha) catalpha = wantalpha;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.globalAlpha = catalpha;
|
|
|
|
off = game.frameNo % (catsize / catspeed);
|
2016-09-02 11:48:48 +10:00
|
|
|
|
|
|
|
if (off == 0) {
|
|
|
|
var goatmove = false;
|
|
|
|
|
|
|
|
this.goatx += this.goatdir;
|
|
|
|
|
|
|
|
if (this.goatx >= (SCREENW/catsize) && this.goatdir > 0) {
|
|
|
|
goatmove = true;
|
|
|
|
// change dirs
|
|
|
|
} else if (this.goatx < 0 && this.goatdir < 0) {
|
|
|
|
goatmove = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (goatmove) {
|
|
|
|
this.placetitlegoat(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//console.log(this.goatx + "," + this.goaty);
|
|
|
|
//console.log(off);
|
2016-08-25 16:49:54 +10:00
|
|
|
for (y = -catsize*2; y < SCREENH; y += catsize*2) {
|
|
|
|
for (x = -catsize*2; x < SCREENW+catsize*2; x += catsize) {
|
2016-09-02 11:48:48 +10:00
|
|
|
var iname;
|
|
|
|
/*
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.strokeStyle = "red";
|
|
|
|
ctx.rect(x, y, catsize,catsize);
|
|
|
|
ctx.stroke();
|
|
|
|
*/
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
//ctx.fillStyle = "red";
|
|
|
|
//ctx.fillRect(x +(catsize/4)+off, y +(catsize/4)+off, catsize/2, catsize/2);
|
2016-09-02 11:48:48 +10:00
|
|
|
if ((this.goatdir == 1) && ((y/catsize) == this.goaty) && (x / catsize) == this.goatx) {
|
|
|
|
iname = 'goatwalkr';
|
|
|
|
} else {
|
|
|
|
iname = 'catwalkr';
|
|
|
|
}
|
|
|
|
this.context.drawImage(image[iname], x +(catsize/4)+off*catspeed, y +(catsize/2)-image[iname].height/2,
|
|
|
|
image[iname].width*catscale,
|
|
|
|
image[iname].height*catscale);
|
2016-08-25 16:49:54 +10:00
|
|
|
|
2016-09-02 11:48:48 +10:00
|
|
|
if ((this.goatdir == -1) && ((y+catsize)/catsize == this.goaty) && (x / catsize) == this.goatx) {
|
|
|
|
iname = 'goatwalkl';
|
|
|
|
} else {
|
|
|
|
iname = 'catwalkl';
|
|
|
|
}
|
|
|
|
this.context.drawImage(image[iname], x +(catsize/4)-off*catspeed, y +(catsize/2)-image[iname].height/2+catsize,
|
|
|
|
image[iname].width*catscale,
|
|
|
|
image[iname].height*catscale);
|
2016-08-25 16:49:54 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ctx.globalAlpha = 1.0;
|
|
|
|
},
|
|
|
|
|
|
|
|
drawtitle : function() {
|
|
|
|
var ratio,w,h;
|
|
|
|
var img = image['title'];
|
|
|
|
var catyoff = 0;
|
|
|
|
var titlexoff = 0;
|
|
|
|
var titley = 10;
|
|
|
|
var creditsy = 64;
|
2016-09-05 14:22:21 +10:00
|
|
|
var birthdayy = 96;
|
2016-08-25 16:49:54 +10:00
|
|
|
var textgrad;
|
|
|
|
|
|
|
|
// background
|
|
|
|
this.drawbg();
|
|
|
|
|
|
|
|
// big cat
|
2016-08-20 15:12:32 +10:00
|
|
|
ratio = SCREENW / img.width;
|
|
|
|
w = img.width * ratio;
|
|
|
|
h = img.height * ratio;
|
2016-08-25 16:49:54 +10:00
|
|
|
|
|
|
|
catyoff = wipe.getval(h, "down", "up", 0);
|
|
|
|
this.context.drawImage(img, SCREENW/16, SCREENH - h + catyoff, w, h);
|
2016-08-20 15:12:32 +10:00
|
|
|
|
|
|
|
// text
|
|
|
|
this.context.textAlign = "center";
|
|
|
|
this.context.textBaseline = "top";
|
2016-08-25 16:49:54 +10:00
|
|
|
|
|
|
|
titlexoff = wipe.getval(SCREENW, "down", "up", 0);
|
|
|
|
|
|
|
|
|
|
|
|
shadowtext(this.context, "Cat Parade", TITLETEXTSIZE,"red", SCREENW / 2 - titlexoff, titley, "#ff0000", "#ffff00", "white");
|
|
|
|
shadowtext(this.context, "rpearce, 2016", TITLECREDITTEXTSIZE, "#00aaee", SCREENW / 2 - titlexoff, creditsy);
|
2016-08-20 15:12:32 +10:00
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
var today = new Date();
|
|
|
|
var dd = today.getDate();
|
|
|
|
var mm = today.getMonth()+1;
|
|
|
|
var yy = today.getFullYear();
|
|
|
|
|
|
|
|
// 11th sep
|
|
|
|
if (dd == 11 && mm == 9) {
|
|
|
|
shadowtext(this.context, "HAPPY BIRTHDAY BETH!", TITLECREDITTEXTSIZE, "#ff0000", SCREENW / 2 - titlexoff, birthdayy);
|
|
|
|
}
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
this.context.textBaseline = "bottom";
|
2016-08-25 16:49:54 +10:00
|
|
|
shadowtext(this.context, "Tap to start", TITLESTARTTEXTSIZE, "#00dd00", SCREENW / 2 + titlexoff, SCREENH - 64);
|
2016-08-20 15:12:32 +10:00
|
|
|
},
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
levelexists : function (lev) {
|
|
|
|
if (lev > 0 && lev < game.levels.length) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
countplayerstars : function () {
|
|
|
|
var i;
|
|
|
|
var total = 0;
|
|
|
|
|
|
|
|
for (i = 1 ; i < game.levels.length; i++ ) {
|
2016-09-09 18:25:43 +10:00
|
|
|
//console.log("countplayerstars() - lev " + i + " score " + playerdata.getlevscore(i) + " stars " + game.calcstars(i, playerdata.getlevscore(i)));
|
2016-08-22 19:52:15 +10:00
|
|
|
total += game.calcstars(i, playerdata.getlevscore(i));
|
|
|
|
}
|
|
|
|
return total;
|
|
|
|
},
|
|
|
|
|
|
|
|
levellocked : function (lev) {
|
2016-09-04 11:47:42 +10:00
|
|
|
if (playerdata.totstars < game.getstarsrequired(lev)) return true;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
// returns new y val
|
|
|
|
drawhelpsubtitle : function(ctx, text, y) {
|
2016-08-25 16:49:54 +10:00
|
|
|
var subtitlecol = "#cc00cc";
|
2016-08-22 19:52:15 +10:00
|
|
|
var xindent = 10;
|
|
|
|
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, text, HELPSUBTITLESIZE,subtitlecol, SCREENW / 2, y);
|
|
|
|
return (y + HELPTEXTYSPACE*1.5);
|
|
|
|
},
|
|
|
|
|
2016-08-21 09:57:40 +10:00
|
|
|
// return TRUE if there is no help for this level
|
2016-08-20 15:12:32 +10:00
|
|
|
drawhelp : function() {
|
|
|
|
var divamt = 2;
|
|
|
|
var imgsize = THINGSIZE / divamt;
|
|
|
|
var gridsize = GRIDSIZE / divamt;
|
2016-08-25 16:49:54 +10:00
|
|
|
var gradient,x,y,x2,y2,curx,cury;
|
2016-08-29 19:24:29 +10:00
|
|
|
var row1y,row2y,row3y,row4y;
|
2016-08-20 15:12:32 +10:00
|
|
|
var i;
|
|
|
|
var linex = [];
|
|
|
|
var liney = [];
|
|
|
|
|
|
|
|
var textxspace = 10;
|
|
|
|
|
|
|
|
var midpoint1 = SCREENW/8 * 5;
|
|
|
|
var midpoint2 = SCREENW/8 * 4;
|
2016-08-25 16:49:54 +10:00
|
|
|
var titlecol = "#00ccff";
|
|
|
|
var helpcol = "#00cc00";
|
2016-08-22 19:52:15 +10:00
|
|
|
var pointscoldark = "#888800";
|
2016-08-25 16:49:54 +10:00
|
|
|
var pointscol = "#dddd00";
|
2016-08-30 14:55:26 +10:00
|
|
|
var llamatitle = llamatext[0].toUpperCase() + llamatext.substring(1);
|
|
|
|
var aoran;
|
|
|
|
|
|
|
|
if (llamatext[0] == 'a') aoran = "an";
|
|
|
|
else aoran = "a";
|
2016-08-20 15:12:32 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
//ctx = this.context;
|
2016-08-20 15:12:32 +10:00
|
|
|
|
|
|
|
// background
|
2016-08-25 16:49:54 +10:00
|
|
|
/*
|
2016-08-20 15:12:32 +10:00
|
|
|
gradient = this.context.createLinearGradient(0, 0, 0, SCREENH);
|
|
|
|
gradient.addColorStop(0, "black");
|
|
|
|
gradient.addColorStop(1, "blue");
|
|
|
|
|
|
|
|
ctx.fillStyle = gradient;
|
|
|
|
ctx.fillRect(0, 0, SCREENW, SCREENH);
|
2016-08-25 16:49:54 +10:00
|
|
|
*/
|
|
|
|
|
|
|
|
this.drawbg();
|
2016-08-20 15:12:32 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// top text
|
|
|
|
cury = HELPTEXTYSPACE*2;
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "bottom";
|
2016-08-20 15:12:32 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
shadowtext(ctx, "Level " + curlevel + ": Instructions", HELPTITLESIZE,titlecol, SCREENW / 2, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
|
|
|
|
// original help text for reference. maybe use this
|
|
|
|
// for a 'continuous mode' later.
|
2016-09-05 14:22:21 +10:00
|
|
|
if (curlevel == 1) {
|
2016-08-22 19:52:15 +10:00
|
|
|
cury = this.drawhelpsubtitle(ctx, "Chomping Food", cury);
|
2016-08-21 09:57:40 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Drag a cat to eat cheese.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-25 16:49:54 +10:00
|
|
|
cury += HELPTEXTYSPACE*1.5;
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
shadowtext(ctx, "Cats can eat any amount of cheese, but cannot turn", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-22 19:52:15 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
shadowtext(ctx, "corners whilst doing so.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE*1.5;
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
shadowtext(ctx, "Cats get tired after eating and cannot eat again.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// help on eating
|
|
|
|
// row 1
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x2 = x + gridsize;
|
|
|
|
y2 = y;
|
|
|
|
ctx.drawImage(image['cheese'], x2, y2, imgsize, imgsize);
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.strokeStyle = PATHLINECOLGOOD;
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.lineWidth = LINEWIDTH;
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.moveTo(x + imgsize/2, y + imgsize/2);
|
|
|
|
ctx.lineTo(x2 + imgsize/2, y2 + imgsize/2);
|
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
drawarrow(ctx, x + (imgsize/2), y + (imgsize/2),
|
2016-08-25 16:49:54 +10:00
|
|
|
x2 + (imgsize/2), y2 + (imgsize/2), PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
cury = y2 + gridsize;
|
|
|
|
|
|
|
|
// row 2
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row2y = y;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x2 = x + gridsize;
|
|
|
|
y2 = y;
|
|
|
|
ctx.drawImage(image['cheese'], x2, y2, imgsize, imgsize);
|
|
|
|
|
|
|
|
x2 = x2 + gridsize;
|
|
|
|
y2 = y;
|
|
|
|
ctx.drawImage(image['cheese'], x2, y2, imgsize, imgsize);
|
|
|
|
|
|
|
|
x2 = x2 + gridsize;
|
|
|
|
y2 = y;
|
|
|
|
ctx.drawImage(image['cheese'], x2, y2, imgsize, imgsize);
|
|
|
|
|
|
|
|
drawarrow(ctx, x + (imgsize/2), y + (imgsize/2),
|
2016-08-25 16:49:54 +10:00
|
|
|
x2 + (imgsize/2), y2 + (imgsize/2), PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
cury = y2 + gridsize;
|
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
x = x2 + gridsize;
|
|
|
|
y = row1y + (imgsize);
|
|
|
|
|
|
|
|
x2 = x + gridsize*1.5;
|
|
|
|
y2 = y;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// middle
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
|
|
|
|
x = midpoint1;
|
|
|
|
y = row1y+10;
|
|
|
|
shadowtext(ctx, "+" + FOODPOINTS + " points", HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
y = row2y-10;
|
|
|
|
shadowtext(ctx, "per cheese", HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
|
|
|
|
|
|
|
|
// arrow to right
|
|
|
|
x = midpoint1 + gridsize + 10;
|
|
|
|
y = row1y + (imgsize);
|
|
|
|
|
|
|
|
x2 = SCREENW - imgsize*2;
|
|
|
|
y2 = y;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// right
|
|
|
|
x = SCREENW - imgsize*2;
|
|
|
|
y = row1y;
|
|
|
|
ctx.drawImage(image['catfull'], x, y, imgsize, imgsize);
|
|
|
|
y = row2y;
|
|
|
|
ctx.drawImage(image['catfull'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// GOAL HELP
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Goals", cury);
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Each level has one of more goals to fulfil.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-30 14:55:26 +10:00
|
|
|
shadowtext(ctx, "Complete all goals to complete the level!", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-22 19:52:15 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-25 16:49:54 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// GAME OVER HELP
|
2016-08-30 14:55:26 +10:00
|
|
|
cury = this.drawhelpsubtitle(ctx, "Failure", cury);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
2016-08-30 14:55:26 +10:00
|
|
|
shadowtext(ctx, "If you run out of valid moves, or the turn counter", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-29 19:24:29 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-30 14:55:26 +10:00
|
|
|
shadowtext(ctx, "reaches zero, you must try the level again.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-22 19:52:15 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
} else if (curlevel == 2) {
|
|
|
|
|
|
|
|
// PARADE HELP
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Cat Parades", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Drag a path through multiple cats to start a parade.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "Parades can change directions as many times as you like.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of parade
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[3] = x + imgsize/2;
|
|
|
|
liney[3] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[4] = x + imgsize/2;
|
|
|
|
liney[4] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
row2y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catfull'], x, y, imgsize, imgsize);
|
|
|
|
linex[2] = x + imgsize/2;
|
|
|
|
liney[2] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
2016-08-22 19:52:15 +10:00
|
|
|
linex[5] = x + imgsize/2;
|
|
|
|
liney[5] = y + imgsize/2;
|
|
|
|
cury = y + HELPTEXTYSPACE;
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
for (i = 0; i < 3; i++) {
|
2016-08-25 16:49:54 +10:00
|
|
|
drawline(ctx, linex[i], liney[i], linex[i+1], liney[i+1], PATHLINECOLGOOD, LINEWIDTH);
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-08-29 19:24:29 +10:00
|
|
|
drawarrow(ctx, linex[3], liney[3], linex[4], liney[4], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
x = x + gridsize;
|
|
|
|
y = row1y + (imgsize);
|
|
|
|
|
|
|
|
x2 = midpoint2 - 10;
|
|
|
|
y2 = y;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// explain points for parades
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
x = midpoint2;
|
|
|
|
y = row1y + HELPTEXTYSPACE/2;
|
|
|
|
shadowtext(ctx, "+" + CATPOINTS + " points per cat", HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "+" + SLEEPYCATPOINTS + " points per sleepy cat", HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
|
|
|
|
cury = y + HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-29 19:24:29 +10:00
|
|
|
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Score Multiplier", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Longer parades score more points.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// top line of second parade - 5 cats
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
row2y = y;
|
|
|
|
|
|
|
|
// 2nd line of second parade - 3 cats
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[3] = x + imgsize/2;
|
|
|
|
liney[3] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[2] = x + imgsize/2;
|
|
|
|
liney[2] = y + imgsize/2;
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
row3y = y;
|
|
|
|
|
|
|
|
// 3rd line of second parade - 3 cats
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[4] = x + imgsize/2;
|
|
|
|
liney[4] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[5] = x + imgsize/2;
|
|
|
|
liney[5] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
row4y = y;
|
|
|
|
|
|
|
|
// 4th line of second parade - 3 cats
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[7] = x + imgsize/2;
|
|
|
|
liney[7] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[6] = x + imgsize/2;
|
|
|
|
liney[6] = y + imgsize/2;
|
|
|
|
|
|
|
|
|
|
|
|
cury = y + HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// path lines
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
|
|
drawline(ctx, linex[i], liney[i], linex[i+1], liney[i+1], PATHLINECOLGOOD, LINEWIDTH);
|
|
|
|
}
|
|
|
|
drawarrow(ctx, linex[6], liney[6], linex[7], liney[7], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
x = x + gridsize;
|
|
|
|
y = row1y + (imgsize);
|
|
|
|
|
|
|
|
x2 = midpoint2 - 10;
|
|
|
|
y2 = y;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// explain multipliers
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
x = midpoint2;
|
|
|
|
y = y - HELPTEXTYSPACE/2;
|
|
|
|
shadowtext(ctx, "Cats 1-5 = x1", HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
x = midpoint2;
|
|
|
|
y = row3y + HELPTEXTYSPACE/2;
|
|
|
|
shadowtext(ctx, "Cats 6-8 = x2", HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
|
|
|
|
x = midpoint2;
|
|
|
|
y = row4y + HELPTEXTYSPACE/2;
|
|
|
|
shadowtext(ctx, "Cats 9-11 = x3", HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
|
|
|
|
x = midpoint2;
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "...etc", HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
|
|
|
|
cury = y + HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
} else if (curlevel == 3) {
|
2016-08-30 14:55:26 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
cury = this.drawhelpsubtitle(ctx, llamatitle + "s", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
2016-08-25 16:49:54 +10:00
|
|
|
shadowtext(ctx, "Cats are scared of " + llamatext + "s and can't move while nearby.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-22 19:52:15 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
x = (SCREENW / 2) - gridsize/2 - gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-25 16:49:54 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Cat + " + llamatitle + " Parades", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Each cat parade may include a single " + llamatext + " only.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of parade
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
linex[3] = x + imgsize/2;
|
|
|
|
liney[3] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
linex[4] = x + imgsize/2;
|
|
|
|
liney[4] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
row2y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catfull'], x, y, imgsize, imgsize);
|
|
|
|
linex[2] = x + imgsize/2;
|
|
|
|
liney[2] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
linex[5] = x + imgsize/2;
|
|
|
|
liney[5] = y + imgsize/2;
|
|
|
|
cury = y + HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
2016-08-25 16:49:54 +10:00
|
|
|
drawline(ctx, linex[i], liney[i], linex[i+1], liney[i+1], PATHLINECOLGOOD, LINEWIDTH);
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-08-25 16:49:54 +10:00
|
|
|
drawarrow(ctx, linex[4], liney[4], linex[5], liney[5], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
x = x + gridsize;
|
|
|
|
y = row1y + (imgsize);
|
|
|
|
|
|
|
|
x2 = midpoint2 - 10;
|
|
|
|
y2 = y;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// explain points for parades
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
x = midpoint2;
|
|
|
|
y = row1y;
|
|
|
|
shadowtext(ctx, "+" + CATPOINTS + " points per cat", HELPTEXTSIZE,pointscoldark, x, y);
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "+" + SLEEPYCATPOINTS + " points per sleepy cat", HELPTEXTSIZE,pointscoldark, x, y);
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "+" + LLAMAPOINTS + " points per " + llamatext, HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
|
|
|
|
cury = y + HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-30 14:55:26 +10:00
|
|
|
|
|
|
|
cury = this.drawhelpsubtitle(ctx, llamatitle + " Overload", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Three or more " + llamatext + "s in a row defies reality.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "They will vanish in " + aoran + " " + llamatitle + " Overload.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of llama overload
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
row2y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
x = x + gridsize;
|
|
|
|
y = row1y + (imgsize);
|
|
|
|
|
|
|
|
x2 = midpoint2 - 10;
|
|
|
|
y2 = y;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
|
|
|
|
// top line of post-overload
|
|
|
|
x = midpoint2;
|
|
|
|
y = row1y;
|
|
|
|
|
|
|
|
//ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
//ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
linex[2] = x + imgsize/2;
|
|
|
|
liney[2] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
//ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
linex[4] = x + imgsize/2;
|
|
|
|
liney[4] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
x = midpoint2;
|
|
|
|
y = row2y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
linex[3] = x + imgsize/2;
|
|
|
|
liney[3] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[5] = x + imgsize/2;
|
|
|
|
liney[5] = y + imgsize/2;
|
|
|
|
|
|
|
|
|
|
|
|
// falling down liens
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], "#660000", LINEWIDTH, FALLARROWSIZE);
|
|
|
|
drawarrow(ctx, linex[2], liney[2], linex[3], liney[3], "#660000", LINEWIDTH, FALLARROWSIZE);
|
|
|
|
drawarrow(ctx, linex[4], liney[4], linex[5], liney[5], "#660000", LINEWIDTH, FALLARROWSIZE);
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
} else if (curlevel == 4) {
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Later Levels", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "As you complete levels, more features will be introduced.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "For example:", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
shadowtext(ctx, "Goats (level 6)", HELPTEXTSIZE, pointscol, THINGSIZE*1.5, cury + THINGSIZE/2 - HELPTEXTYSPACE/2);
|
|
|
|
ctx.drawImage(image['goat'], textxspace, cury, THINGSIZE, THINGSIZE);
|
|
|
|
cury += GRIDSIZE;
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
shadowtext(ctx, "Doors (level 9)", HELPTEXTSIZE,pointscol, THINGSIZE*1.5, cury + THINGSIZE/2 - HELPTEXTYSPACE/2);
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.drawImage(image['door'], textxspace, cury, THINGSIZE, THINGSIZE);
|
|
|
|
cury += GRIDSIZE;
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
shadowtext(ctx, "Sunlight (level 11)", HELPTEXTSIZE,pointscol, THINGSIZE*1.5, cury + THINGSIZE/2 - HELPTEXTYSPACE/2);
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.drawImage(image['sunlight'], textxspace, cury, THINGSIZE, THINGSIZE);
|
|
|
|
cury += GRIDSIZE;
|
2016-08-30 17:19:28 +10:00
|
|
|
|
|
|
|
shadowtext(ctx, "White cat (level 12)", HELPTEXTSIZE,pointscol, THINGSIZE*1.5, cury + THINGSIZE/2 - HELPTEXTYSPACE/2);
|
|
|
|
ctx.drawImage(image['whitecat'], textxspace, cury, THINGSIZE, THINGSIZE);
|
|
|
|
cury += GRIDSIZE;
|
|
|
|
|
|
|
|
shadowtext(ctx, "Toad (level 13)", HELPTEXTSIZE,pointscol, THINGSIZE*1.5, cury + THINGSIZE/2 - HELPTEXTYSPACE/2);
|
|
|
|
ctx.drawImage(image['toad'], textxspace, cury, THINGSIZE, THINGSIZE);
|
|
|
|
cury += GRIDSIZE;
|
2016-08-30 14:55:26 +10:00
|
|
|
} else if (curlevel == 5) {
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Shopping Bags", cury);
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Cat find shopping bags irresistable.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "Lead a cat parade into a shopping bag to fill it up.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of bag demo
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
ctx.drawImage(image['bag'], x, y + imgsize/2 - imgsize*0.1, imgsize, imgsize*0.2);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
drawarrow(ctx, linex[0], liney[0],
|
|
|
|
linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
|
|
|
|
|
|
|
// arrow to next one
|
|
|
|
|
|
|
|
drawarrow(ctx, midpoint2 - gridsize, y+gridsize/2,
|
|
|
|
midpoint2 + gridsize*0.75, y+gridsize/2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// next one
|
|
|
|
x = midpoint2 + gridsize;
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
//ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
2016-08-30 14:55:26 +10:00
|
|
|
x += gridsize;
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
//ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
2016-08-30 14:55:26 +10:00
|
|
|
x += gridsize;
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
//ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
2016-08-30 14:55:26 +10:00
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
ctx.drawImage(image['bag'], x, y + imgsize/2 - imgsize*0.5, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
y += gridsize;
|
|
|
|
y += gridsize;
|
|
|
|
|
|
|
|
cury = y;
|
|
|
|
shadowtext(ctx, "Full shopping bags explode to reveal a random prize.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "Tap the prize for a special effect!", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
y = cury + THINGSIZE/4 - HELPTEXTYSPACE/2;
|
|
|
|
shadowtext(ctx, "Tissue Box", HELPTEXTSIZE, pointscol,
|
|
|
|
THINGSIZE*1.5, y);
|
2016-08-31 13:55:35 +10:00
|
|
|
shadowtext(ctx, "All sleeping cats wake up.", HELPTEXTSIZE, pointscoldark,
|
2016-08-30 14:55:26 +10:00
|
|
|
THINGSIZE*1.5, y + HELPTEXTYSPACE);
|
|
|
|
ctx.drawImage(image['tissues'], textxspace, cury, THINGSIZE, THINGSIZE);
|
|
|
|
cury += GRIDSIZE;
|
|
|
|
|
|
|
|
y = cury + THINGSIZE/4 - HELPTEXTYSPACE/2;
|
|
|
|
shadowtext(ctx, "Shears", HELPTEXTSIZE, pointscol,
|
|
|
|
THINGSIZE*1.5, y);
|
2016-08-31 13:55:35 +10:00
|
|
|
shadowtext(ctx, "All " + llamatext + "s immediately run away.", HELPTEXTSIZE, pointscoldark,
|
2016-08-30 14:55:26 +10:00
|
|
|
THINGSIZE*1.5, y + HELPTEXTYSPACE);
|
|
|
|
ctx.drawImage(image['shears'], textxspace, cury, THINGSIZE, THINGSIZE);
|
|
|
|
cury += GRIDSIZE;
|
|
|
|
|
|
|
|
y = cury + THINGSIZE/4 - HELPTEXTYSPACE/2;
|
|
|
|
shadowtext(ctx, "Magic Carpet", HELPTEXTSIZE, pointscol,
|
|
|
|
THINGSIZE*1.5, y);
|
2016-08-31 13:55:35 +10:00
|
|
|
shadowtext(ctx, "Cats are given a magic fez.",
|
2016-08-30 14:55:26 +10:00
|
|
|
HELPTEXTSIZE, pointscoldark,
|
|
|
|
THINGSIZE*1.5, y + HELPTEXTYSPACE);
|
2016-08-31 13:55:35 +10:00
|
|
|
shadowtext(ctx, "Fez-wearing cats are not scared of " + llamatext + "s.",
|
2016-08-30 14:55:26 +10:00
|
|
|
HELPTEXTSIZE, pointscoldark,
|
|
|
|
THINGSIZE*1.5, y + HELPTEXTYSPACE*2);
|
|
|
|
ctx.drawImage(image['magiccarpet'], textxspace, cury, THINGSIZE, THINGSIZE);
|
|
|
|
cury += GRIDSIZE;
|
|
|
|
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
} else if (curlevel == 6) {
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Goats", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Goats and cats can gang up on " + llamatext + "s.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
2016-09-05 14:22:21 +10:00
|
|
|
shadowtext(ctx, "Parades with a goat can contain any number of " + llamatext + "s.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-22 19:52:15 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of parade
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
linex[3] = x + imgsize/2;
|
|
|
|
liney[3] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
linex[4] = x + imgsize/2;
|
|
|
|
liney[4] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
// middle line of parade
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
row2y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
linex[2] = x + imgsize/2;
|
|
|
|
liney[2] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
linex[5] = x + imgsize/2;
|
|
|
|
liney[5] = y + imgsize/2;
|
|
|
|
|
|
|
|
// bottom line of parade
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
row3y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
linex[8] = x + imgsize/2;
|
|
|
|
liney[8] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
linex[7] = x + imgsize/2;
|
|
|
|
liney[7] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
linex[6] = x + imgsize/2;
|
|
|
|
liney[6] = y + imgsize/2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// lines
|
|
|
|
cury = y + HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
|
|
|
|
// parade lines
|
|
|
|
for (i = 0; i < 7; i++) {
|
2016-08-25 16:49:54 +10:00
|
|
|
drawline(ctx, linex[i], liney[i], linex[i+1], liney[i+1], PATHLINECOLGOOD, LINEWIDTH);
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-08-25 16:49:54 +10:00
|
|
|
drawarrow(ctx, linex[7], liney[7], linex[8], liney[8], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
x = x + gridsize;
|
|
|
|
y = row2y + imgsize/2;
|
|
|
|
|
|
|
|
x2 = midpoint2 - 10;
|
|
|
|
y2 = y;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// explain points for parades
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
x = midpoint2;
|
|
|
|
y = row1y + HELPTEXTYSPACE/2;
|
|
|
|
shadowtext(ctx, "+" + CATPOINTS + " points per cat", HELPTEXTSIZE,pointscoldark, x, y);
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "+" + SLEEPYCATPOINTS + " points per sleepy cat", HELPTEXTSIZE,pointscoldark, x, y);
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "+" + LLAMAPOINTS + " points per " + llamatext, HELPTEXTSIZE,pointscoldark, x, y);
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "+" + GOATPOINTS + " points per goat", HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
y += HELPTEXTYSPACE;
|
2016-08-22 19:52:15 +10:00
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
y += HELPTEXTYSPACE;
|
|
|
|
cury = y;
|
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
shadowtext(ctx, "Goats can't start parades.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "Parades must start with a cat.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-22 19:52:15 +10:00
|
|
|
cury += HELPTEXTYSPACE * 1.5;
|
|
|
|
|
|
|
|
// bad example
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize*2;
|
|
|
|
|
|
|
|
y += gridsize;
|
|
|
|
cury = y;
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLBAD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
drawcross(ctx, x+imgsize/8, row1y+imgsize/8, x + imgsize-imgsize/8, row1y + imgsize-imgsize/8, PATHLINECOLBAD, 3);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// good example
|
|
|
|
x = imgsize;
|
|
|
|
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['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize*2;
|
|
|
|
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
drawtick(ctx, x, row2y, x + imgsize, row2y + imgsize, PATHLINECOLGOOD, 3);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
y += gridsize;
|
|
|
|
cury = y;
|
2016-08-23 01:13:47 +10:00
|
|
|
} else if (curlevel == 9) {
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Doors", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Cats love escaping outside through doors.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "Ending a parade on a door will score double points!", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of parade
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
linex[3] = x + imgsize/2;
|
|
|
|
liney[3] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
linex[4] = x + imgsize/2;
|
|
|
|
liney[4] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
// middle line of parade
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
row2y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
linex[2] = x + imgsize/2;
|
|
|
|
liney[2] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['door'], x, y, imgsize, imgsize);
|
|
|
|
linex[5] = x + imgsize/2;
|
|
|
|
liney[5] = y + imgsize/2;
|
|
|
|
|
|
|
|
|
|
|
|
// parade lines
|
|
|
|
cury = y + HELPTEXTYSPACE;
|
|
|
|
for (i = 0; i < 5; i++) {
|
2016-08-25 16:49:54 +10:00
|
|
|
drawline(ctx, linex[i], liney[i], linex[i+1], liney[i+1], PATHLINECOLGOOD, LINEWIDTH);
|
2016-08-23 01:13:47 +10:00
|
|
|
}
|
2016-08-25 16:49:54 +10:00
|
|
|
drawarrow(ctx, linex[4], liney[4], linex[5], liney[5], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
2016-08-23 01:13:47 +10:00
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
x = x + gridsize;
|
|
|
|
y = row2y;
|
|
|
|
|
|
|
|
x2 = midpoint2 - 10;
|
|
|
|
y2 = y;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// explain points for doors
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
x = midpoint2;
|
|
|
|
|
|
|
|
y = row2y - HELPTEXTYSPACE/2;
|
|
|
|
shadowtext(ctx, "x2 points", HELPTEXTSIZE,pointscol, x, y);
|
|
|
|
|
|
|
|
cury = y;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Doors don't fall down like other objects.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "They are only removed when a parade enters them.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of door fall example
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['door'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
// middle line of parade
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
row2y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
// cat eating food line
|
2016-08-25 16:49:54 +10:00
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
2016-08-23 01:13:47 +10:00
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
x = x + gridsize;
|
|
|
|
y = row2y;
|
|
|
|
|
|
|
|
x2 = midpoint2 - 10;
|
|
|
|
y2 = y;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// top line of part 2 of door fall example
|
|
|
|
x = midpoint2;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['door'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
// middle line of parade
|
|
|
|
x = midpoint2;
|
|
|
|
y += gridsize;
|
|
|
|
row2y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
|
|
|
|
x += gridsize*2;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
} else if (curlevel == 11) {
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Sunlight", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Cats love luxuriating in sunlight.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "Any cats next to a sun will fall asleep.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
x = (SCREENW / 2) - gridsize/2 - gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['catfull'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['sunlight'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['catfull'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
cury += gridsize;
|
|
|
|
|
|
|
|
x = (SCREENW / 2) - gridsize/2 - gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
shadowtext(ctx, "Each turn, suns swap places with the object below.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "Cats will awaken once out of the sunlight.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
x = (SCREENW / 2) - gridsize/2 - gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
cury += gridsize;
|
|
|
|
|
|
|
|
x = (SCREENW / 2) - gridsize/2 - gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['sunlight'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
y = cury;
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], "#dd0000", LINEWIDTH, PATHARROWSIZE);
|
|
|
|
drawarrow(ctx, linex[1], liney[1], linex[0], liney[0], "#dd0000", LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
shadowtext(ctx, "Suns set after reaching the the bottom of the play area.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-23 01:13:47 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-30 17:19:28 +10:00
|
|
|
} else if (curlevel == 12) {
|
2016-08-31 17:45:15 +10:00
|
|
|
cury = this.drawhelpsubtitle(ctx, "White Stuffed Cats", cury);
|
2016-08-30 17:19:28 +10:00
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
2016-08-31 17:45:15 +10:00
|
|
|
shadowtext(ctx, "Cats and white stuffed cats like fighting.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-30 17:19:28 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "Fights clear out all objects around the white cat.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of white cat demo
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['whitecat'], 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;
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], 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 = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
|
|
|
|
// line to show path
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
|
|
|
// arrow to next frame
|
|
|
|
drawarrow(ctx, x + gridsize*1.5, y, x + gridsize*1.5, y + gridsize, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
cury = y + gridsize*1.5;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['cheese'], 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;
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
cury = y;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-30 17:19:28 +10:00
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Cats must be awake to attack white cats.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
2016-08-30 17:19:28 +10:00
|
|
|
|
|
|
|
} else if (curlevel == 13) {
|
2016-08-31 13:55:35 +10:00
|
|
|
cury = this.drawhelpsubtitle(ctx, "Toads", cury);
|
2016-08-30 17:19:28 +10:00
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "For some reason, cats like slapping toads off things.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "Slapped toads will drop down, clearing objects below.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of toad demo
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['toad'], 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;
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catscared'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['cheese'], 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 = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
|
|
|
|
// line to show path
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
|
|
|
// arrow to next frame
|
|
|
|
drawarrow(ctx, x + gridsize*1.5, y, x + gridsize*1.5, y + gridsize, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
cury = y + gridsize*1.5;
|
|
|
|
|
|
|
|
// frame 1
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['goat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y ;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
x = imgsize;
|
|
|
|
y += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y;
|
|
|
|
ctx.drawImage(image['toad'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
|
|
|
|
// line to toad falling
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], "#dddd00", LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
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;
|
2016-08-31 17:45:15 +10:00
|
|
|
} else if (curlevel == 18) {
|
|
|
|
var tempslashes;
|
2016-09-12 09:03:02 +10:00
|
|
|
cury = this.drawhelpsubtitle(ctx, "Mice", cury);
|
2016-08-31 17:45:15 +10:00
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
2016-09-12 09:03:02 +10:00
|
|
|
shadowtext(ctx, "Mice are a lot like cats. They can form parades, eat", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "cheese, gang up on llamas, and basically act like a cat.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "However, cats and mice cannot be in the same parade.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-08-31 17:45:15 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
cury += HELPTEXTYSPACE * 1.5;
|
|
|
|
|
|
|
|
// bad example
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat1'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize*2;
|
|
|
|
|
|
|
|
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLBAD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
drawcross(ctx, x+imgsize/8, row1y+imgsize/8, x + imgsize-imgsize/8, row1y + imgsize-imgsize/8, PATHLINECOLBAD, 3);
|
|
|
|
|
|
|
|
y += gridsize;
|
|
|
|
cury = y;
|
|
|
|
|
|
|
|
// good example 1
|
|
|
|
x = imgsize;
|
|
|
|
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['cat'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize*2;
|
|
|
|
|
|
|
|
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
drawtick(ctx, x, row2y, x + imgsize, row2y + imgsize, PATHLINECOLGOOD, 3);
|
|
|
|
|
|
|
|
y += gridsize;
|
|
|
|
cury = y;
|
|
|
|
|
|
|
|
// good example 2
|
|
|
|
x = imgsize;
|
|
|
|
row2y = y;
|
|
|
|
ctx.drawImage(image['cat1'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat1'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat1'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize*2;
|
|
|
|
|
|
|
|
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
drawtick(ctx, x, row2y, x + imgsize, row2y + imgsize, PATHLINECOLGOOD, 3);
|
|
|
|
|
|
|
|
|
2016-09-02 16:32:20 +10:00
|
|
|
} else if (curlevel == 21) {
|
|
|
|
var tempslashes;
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Curtains", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Cats like climbing curtains.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "Climb across curtains to swap places with", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "anything on the other side.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
shadowtext(ctx, "This also causes the curtains to become damaged.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
cury += HELPTEXTYSPACE * 1.5;
|
|
|
|
|
|
|
|
// top line of curtain demo
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['curtain'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['curtain'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
// line to show path
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
y = row1y + imgsize/2;
|
|
|
|
|
|
|
|
x2 = x + gridsize*2;
|
|
|
|
y2 = row1y + imgsize/2;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
/////////////
|
|
|
|
x = x2 + 10;
|
|
|
|
y = y2 - imgsize/2;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['curtainshred'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['curtainshred'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catfull'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
cury = y + gridsize;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
shadowtext(ctx, "Climbing a damaged curtain will shred and destroy it!", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
|
|
|
|
// top line of curtain blow up demo
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['curtainshred'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['curtainshred'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
// line to show path
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
y = row1y + imgsize/2;
|
|
|
|
|
|
|
|
x2 = x + gridsize*2;
|
|
|
|
y2 = row1y + imgsize/2;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
/////////////
|
|
|
|
x = x2 + 10;
|
|
|
|
y = y2 - imgsize/2;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['catfull'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
2016-09-03 10:52:03 +10:00
|
|
|
} else if (curlevel == 24) {
|
|
|
|
var tempslashes;
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Boxes", cury);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
2016-09-12 09:03:02 +10:00
|
|
|
shadowtext(ctx, "Boxes are fantastic. Cats and mice can enter adjacent", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-09-03 10:52:03 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
2016-09-12 09:03:02 +10:00
|
|
|
shadowtext(ctx, "boxes, and can even do so while chomping food.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-09-03 10:52:03 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of box demo - cat -> box
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[0] = x + imgsize/2;
|
|
|
|
liney[0] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['box'], x, y, imgsize, imgsize);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
// cat -> cheese -> box
|
|
|
|
y += gridsize;
|
|
|
|
x = imgsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[2] = x + imgsize/2;
|
|
|
|
liney[2] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['box'], x, y, imgsize, imgsize);
|
|
|
|
linex[3] = x + imgsize/2;
|
|
|
|
liney[3] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
// line to show path
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
drawarrow(ctx, linex[2], liney[2], linex[3], liney[3], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
y = row1y + imgsize/2;
|
|
|
|
|
|
|
|
x2 = x + gridsize*2;
|
|
|
|
y2 = row1y + imgsize/2 + gridsize/2;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y2, x2, y2, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// rhs - cats in boxes
|
|
|
|
x = x2 + imgsize/2;
|
|
|
|
y = row1y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['boxback'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['boxfront'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
// rhs - cats in boxes
|
|
|
|
x = x2 + imgsize/2;
|
|
|
|
y = row1y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
y += gridsize;
|
|
|
|
x = x2 + imgsize/2;
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['boxback'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['boxfront'], x, y, imgsize, imgsize);
|
|
|
|
|
|
|
|
cury = y + gridsize*1.5;
|
|
|
|
|
2016-09-12 09:03:02 +10:00
|
|
|
shadowtext(ctx, "Creatures in boxes can chomp food without getting tired.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-09-03 10:52:03 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
2016-09-12 09:03:02 +10:00
|
|
|
|
|
|
|
// box eating demo
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['boxback'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['boxfront'], 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);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
drawarrow(ctx, linex[0], liney[0], linex[1], liney[1], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
|
|
|
cury = y;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
cury = this.drawhelpsubtitle(ctx, "Box Parades", cury);
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
shadowtext(ctx, "Boxes hide whatever is inside, so cats or mice in boxes", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-09-03 10:52:03 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
2016-09-12 09:03:02 +10:00
|
|
|
shadowtext(ctx, "can join parades with each other.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-09-03 10:52:03 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
cury += HELPTEXTYSPACE;
|
2016-09-12 09:03:02 +10:00
|
|
|
shadowtext(ctx, "Parades started by a lived-in box may contain", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-09-03 10:52:03 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
2016-09-12 09:03:02 +10:00
|
|
|
shadowtext(ctx, "both cats and mice.", HELPTEXTSIZE,helpcol, textxspace, cury);
|
2016-09-03 10:52:03 +10:00
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
// top line of box parade demo
|
2016-09-12 09:03:02 +10:00
|
|
|
row1y = cury;
|
|
|
|
/*
|
2016-09-03 10:52:03 +10:00
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['boxback'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['boxfront'], 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);
|
|
|
|
linex[1] = x + imgsize/2;
|
|
|
|
liney[1] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
2016-09-12 09:03:02 +10:00
|
|
|
*/
|
2016-09-03 10:52:03 +10:00
|
|
|
|
|
|
|
// next line
|
|
|
|
x = imgsize;
|
2016-09-12 09:03:02 +10:00
|
|
|
y = cury + gridsize;
|
2016-09-03 10:52:03 +10:00
|
|
|
row2y = y;
|
|
|
|
|
2016-09-12 09:03:02 +10:00
|
|
|
y -= gridsize/2;
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
ctx.drawImage(image['boxback'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['boxfront'], x, y, imgsize, imgsize);
|
|
|
|
linex[2] = x + imgsize/2;
|
|
|
|
liney[2] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat1'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[3] = x + imgsize/2;
|
|
|
|
liney[3] = y + imgsize/2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// fourth example
|
|
|
|
x = midpoint2;
|
|
|
|
y = row1y;
|
|
|
|
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat1'], x, y, imgsize, imgsize);
|
|
|
|
linex[4] = x + imgsize/2;
|
|
|
|
liney[4] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['boxback'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['boxfront'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat1'], x, y, imgsize, imgsize);
|
|
|
|
linex[5] = x + imgsize/2;
|
|
|
|
liney[5] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// next line of 4th example
|
|
|
|
x = midpoint2;
|
|
|
|
y += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
linex[6] = x + imgsize/2;
|
|
|
|
liney[6] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['boxback'], x, y, imgsize, imgsize);
|
2016-09-12 09:03:02 +10:00
|
|
|
ctx.drawImage(image['cat1'], x, y, imgsize, imgsize);
|
2016-09-03 10:52:03 +10:00
|
|
|
ctx.drawImage(image['boxfront'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
2016-09-12 09:03:02 +10:00
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
2016-09-03 10:52:03 +10:00
|
|
|
linex[7] = x + imgsize/2;
|
|
|
|
liney[7] = y + imgsize/2;
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
|
|
|
drawarrow(ctx, linex[2], liney[2], linex[3], liney[3], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
drawarrow(ctx, linex[4], liney[4], linex[5], liney[5], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
drawarrow(ctx, linex[6], liney[6], linex[7], liney[7], PATHLINECOLGOOD, LINEWIDTH, PATHARROWSIZE);
|
|
|
|
|
|
|
|
|
|
|
|
cury = y + gridsize*1.5;
|
|
|
|
|
|
|
|
shadowtext(ctx, "Cats in boxes will automatically ambush " + llamatext + "s!", HELPTEXTSIZE,helpcol, textxspace, cury);
|
|
|
|
cury += HELPTEXTYSPACE;
|
|
|
|
|
|
|
|
|
|
|
|
// top line of box parade demo
|
|
|
|
x = imgsize;
|
|
|
|
y = cury;
|
|
|
|
row1y = y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['boxback'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['boxfront'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['llama'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
// arrow to middle
|
|
|
|
y = row1y + imgsize/2;
|
|
|
|
|
|
|
|
x2 = x + gridsize*2;
|
|
|
|
|
|
|
|
drawarrow(ctx, x, y, x2, y, "red", HELPLINEWIDTH, HELPARROWSIZE);
|
|
|
|
|
|
|
|
// rhs - pow!
|
|
|
|
x = x2 + imgsize/2;
|
|
|
|
y = row1y;
|
|
|
|
|
|
|
|
ctx.drawImage(image['cheese'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['boxback'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['cat'], x, y, imgsize, imgsize);
|
|
|
|
ctx.drawImage(image['boxfront'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
ctx.drawImage(image['pow'], x, y, imgsize, imgsize);
|
|
|
|
x += gridsize;
|
|
|
|
|
|
|
|
|
2016-09-02 16:32:20 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
this.context.textBaseline = "bottom";
|
|
|
|
shadowtext(this.context, "Tap to start", TITLESTARTTEXTSIZE, "#00dd00", SCREENW / 2, SCREENH - HELPTEXTYSPACE*2);
|
|
|
|
|
|
|
|
if (!hashelp(curlevel)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
drawlevselect : function() {
|
|
|
|
var titley = 5;
|
|
|
|
var pstarsy = 32;
|
2016-08-25 16:49:54 +10:00
|
|
|
var x,y,i;
|
2016-08-22 19:52:15 +10:00
|
|
|
var levnum = 1;
|
|
|
|
var levcol = "#555500";
|
|
|
|
//var gridcol = "#aaaa00";
|
2016-08-25 16:49:54 +10:00
|
|
|
var gridcol = "#000000";
|
|
|
|
var crosscol = "#bbbbbb";
|
2016-08-22 19:52:15 +10:00
|
|
|
var textcol = "#dddd00";
|
2016-09-04 11:47:42 +10:00
|
|
|
var scrollcol = "#dddd00";
|
2016-08-22 19:52:15 +10:00
|
|
|
var titlecol = "#00aaee";
|
|
|
|
var scorecol = "#00dd00";
|
|
|
|
var starcol = "#dddd00";
|
2016-08-25 16:49:54 +10:00
|
|
|
var buttontextcol = "#bbbbbb";
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
var gridblack = "#111111";
|
|
|
|
|
|
|
|
var gridgrad,buttongrad;
|
|
|
|
|
|
|
|
var titleyoff = 0;
|
|
|
|
var buttonyoff = 0;
|
|
|
|
var gridalpha = 1.0;
|
|
|
|
|
2016-08-26 16:27:42 +10:00
|
|
|
var topstarsize =
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
//ctx = this.context;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// background
|
2016-08-25 16:49:54 +10:00
|
|
|
this.drawbg();
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "top";
|
2016-08-25 16:49:54 +10:00
|
|
|
|
|
|
|
titleyoff = wipe.getval(titley*5, "down", "up", 0);
|
|
|
|
shadowtext(ctx, "Level Selection", TITLESIZELEVSELECT,titlecol, SCREENW / 2, titley - titleyoff);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-26 16:27:42 +10:00
|
|
|
ctx.drawImage(image['starfull'], LEVSEL_X, pstarsy - titleyoff, STARWID_LEVSEL_TOP, STARWID_LEVSEL_TOP);
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
2016-08-26 16:27:42 +10:00
|
|
|
shadowtext(ctx, playerdata.totstars, TEXTSIZETOTSTARS,starcol, LEVSEL_X + STARWID_LEVSEL_TOP*1.2, pstarsy - titleyoff);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
gridalpha = wipe.getval(1.0, "up", "down", 1.0);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
|
|
|
|
levnum = 1 + game.levseloff;
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// grid
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.globalAlpha = gridalpha;
|
2016-08-22 19:52:15 +10:00
|
|
|
for (y = 0; y < LEVSELGRIDH*GRIDSIZE; y += GRIDSIZE) {
|
|
|
|
for (x = 0; x < LEVSELGRIDW*GRIDSIZE; x += GRIDSIZE) {
|
2016-09-03 10:52:03 +10:00
|
|
|
var levy = LEVSEL_Y + y + GRIDSIZE/4;
|
2016-09-04 11:47:42 +10:00
|
|
|
var randomlev = false;
|
|
|
|
|
|
|
|
var nextsize = GRIDSIZE * 0.75;
|
2016-09-03 10:52:03 +10:00
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
// "prev" ?
|
|
|
|
if (x == 0 && y == 0 && game.levseloff > 0) {
|
|
|
|
/*
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.lineWidth = 3;
|
|
|
|
ctx.strokeStyle = gridcol;
|
|
|
|
gridgrad = this.context.createLinearGradient(x, y, LEVSEL_X+x+GRIDSIZE, LEVSEL_Y+y+GRIDSIZE);
|
|
|
|
gridgrad.addColorStop(0, "#eeee00");
|
|
|
|
gridgrad.addColorStop(1, gridblack);
|
|
|
|
ctx.fillStyle = gridgrad;
|
|
|
|
ctx.fillRect(LEVSEL_X + x, LEVSEL_Y + y, GRIDSIZE-1, GRIDSIZE-1);
|
|
|
|
ctx.stroke();
|
2016-09-03 10:52:03 +10:00
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "middle";
|
|
|
|
shadowtext(ctx, "<<", TEXTSIZELEVSCROLL, scrollcol,
|
|
|
|
LEVSEL_X + x + GRIDSIZE/2, LEVSEL_Y + y + GRIDSIZE/2);
|
|
|
|
*/
|
|
|
|
ctx.drawImage(image['prevlev'],
|
|
|
|
LEVSEL_X + x + GRIDSIZE/2 - nextsize/2, LEVSEL_Y + y + GRIDSIZE/2 - nextsize/2,
|
|
|
|
nextsize,nextsize);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
} else if (y >= (LEVSELGRIDH*GRIDSIZE - GRIDSIZE) && x >= (LEVSELGRIDW*GRIDSIZE - GRIDSIZE)) {
|
|
|
|
// "next" ?
|
|
|
|
/*
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.lineWidth = 3;
|
|
|
|
ctx.strokeStyle = gridcol;
|
|
|
|
gridgrad = this.context.createLinearGradient(x, y, LEVSEL_X+x+GRIDSIZE, LEVSEL_Y+y+GRIDSIZE);
|
|
|
|
gridgrad.addColorStop(0, "#eeee00");
|
|
|
|
gridgrad.addColorStop(1, gridblack);
|
|
|
|
ctx.fillStyle = gridgrad;
|
|
|
|
ctx.fillRect(LEVSEL_X + x, LEVSEL_Y + y, GRIDSIZE-1, GRIDSIZE-1);
|
|
|
|
ctx.stroke();
|
|
|
|
*/
|
|
|
|
|
2016-09-09 18:23:23 +10:00
|
|
|
|
|
|
|
if ( !this.levellocked(levnum)) {
|
|
|
|
ctx.drawImage(image['nextlev'],
|
|
|
|
LEVSEL_X + x + GRIDSIZE/2 - nextsize/2, LEVSEL_Y + y + GRIDSIZE/2 - nextsize/2,
|
|
|
|
nextsize,nextsize);
|
|
|
|
} else {
|
2016-09-09 18:25:43 +10:00
|
|
|
//console.log("levle " + (levnum) + " is locked!");
|
2016-09-09 18:23:23 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
/*
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "middle";
|
|
|
|
shadowtext(ctx, ">>", TEXTSIZELEVSCROLL, scrollcol,
|
|
|
|
LEVSEL_X + x + GRIDSIZE/2, LEVSEL_Y + y + GRIDSIZE/2);
|
|
|
|
*/
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-09 18:23:23 +10:00
|
|
|
//if (this.levelexists(levnum)) {
|
|
|
|
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
|
|
|
|
// create it if required.
|
|
|
|
if (!game.levelexists(levnum)) {
|
2016-09-05 14:22:21 +10:00
|
|
|
var n;
|
|
|
|
// create levels up to this one
|
|
|
|
for (n = 1; n <= levnum; n++) {
|
|
|
|
if (!game.levelexists(n)) {
|
|
|
|
game.genrandomlevel(n);
|
|
|
|
}
|
|
|
|
}
|
2016-09-04 11:47:42 +10:00
|
|
|
}
|
|
|
|
randomlev = game.levels[levnum].random;
|
|
|
|
|
2016-09-09 18:23:23 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.beginPath();
|
|
|
|
ctx.lineWidth = 3;
|
|
|
|
ctx.strokeStyle = gridcol;
|
2016-08-25 16:49:54 +10:00
|
|
|
gridgrad = this.context.createLinearGradient(x, y, LEVSEL_X+x+GRIDSIZE, LEVSEL_Y+y+GRIDSIZE);
|
2016-08-22 19:52:15 +10:00
|
|
|
//gridgrad.addColorStop(0, "#eeee00");
|
2016-09-04 11:47:42 +10:00
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
if ( this.levellocked(levnum)) {
|
2016-08-22 19:52:15 +10:00
|
|
|
gridgrad.addColorStop(0, "#eeeeee");
|
2016-09-03 10:52:03 +10:00
|
|
|
} else {
|
|
|
|
// unlocked
|
|
|
|
gridgrad.addColorStop(0, "#00ee00");
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-08-25 16:49:54 +10:00
|
|
|
gridgrad.addColorStop(1, gridblack);
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.fillStyle = gridgrad;
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.fillRect(LEVSEL_X + x, LEVSEL_Y + y, GRIDSIZE-1, GRIDSIZE-1);
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.stroke();
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
if (this.levellocked(levnum)) {
|
2016-09-03 10:52:03 +10:00
|
|
|
var lockh = GRIDSIZE / 2.8;
|
|
|
|
var lockw = (lockh / image['lock'].height) * image['lock'].width;
|
|
|
|
var lockx = LEVSEL_X + x + GRIDSIZE/2 - lockw/2;
|
|
|
|
var locky = LEVSEL_Y + y + TEXTSIZELEVSELECT*1.5;
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
// show level num
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "middle";
|
|
|
|
shadowtext(ctx, levnum, TEXTSIZELEVSELECT,
|
|
|
|
//randomlev ? "red" : textcol,
|
|
|
|
textcol,
|
|
|
|
LEVSEL_X + x + GRIDSIZE/2,levy);
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// locked
|
2016-09-03 10:52:03 +10:00
|
|
|
ctx.drawImage(image['lock'], lockx, locky, lockw, lockh);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// # stars to unlock
|
2016-09-03 10:52:03 +10:00
|
|
|
var starreqx = LEVSEL_X + x + GRIDSIZE/2;
|
|
|
|
//var starreqy = LEVSEL_Y + y + GRIDSIZE - (GRIDSIZE/4)
|
|
|
|
// - (STARWID_LEVSEL_LOCKED/2);
|
|
|
|
//var starreqy = locky + lockh * 0.9;
|
|
|
|
var starreqy = LEVSEL_Y + y + GRIDSIZE - TEXTSIZELEVSTARS*2;
|
|
|
|
|
|
|
|
|
2016-08-26 16:27:42 +10:00
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
ctx.drawImage(image['stargrey'],
|
2016-08-26 16:27:42 +10:00
|
|
|
LEVSEL_X + x + GRIDSIZE/2 - STARWID_LEVSEL_LOCKED*1.25,
|
2016-09-03 10:52:03 +10:00
|
|
|
//LEVSEL_Y + y + GRIDSIZE - (GRIDSIZE/4) - (STARWID_LEVSEL_LOCKED/2),
|
|
|
|
starreqy,
|
2016-08-26 16:27:42 +10:00
|
|
|
STARWID_LEVSEL_LOCKED, STARWID_LEVSEL_LOCKED);
|
|
|
|
|
|
|
|
ctx.textAlign = "left";
|
|
|
|
ctx.textBaseline = "top";
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
shadowtext(ctx, game.getstarsrequired(levnum),
|
2016-09-03 10:52:03 +10:00
|
|
|
TEXTSIZELEVSTARS, "#cccccc",
|
|
|
|
starreqx, starreqy);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
} else {
|
|
|
|
var hiscore,starcount,stars = "";
|
2016-08-25 16:49:54 +10:00
|
|
|
var scorey = LEVSEL_Y + y + GRIDSIZE - 5;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
var stary = levy + ((scorey - levy) / 2); // half way between
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
// show level num
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "middle";
|
2016-09-04 11:47:42 +10:00
|
|
|
shadowtext(ctx, levnum, TEXTSIZELEVSELECT,
|
|
|
|
//randomlev ? "red" : textcol,
|
|
|
|
textcol,
|
2016-08-25 16:49:54 +10:00
|
|
|
LEVSEL_X + x + GRIDSIZE/2,levy);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
// show hiscore
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "middle";
|
2016-09-04 11:47:42 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// get player hiscore
|
|
|
|
hiscore = playerdata.getlevscore(levnum);
|
|
|
|
|
|
|
|
// show stars
|
|
|
|
if (hiscore != undefined) {
|
|
|
|
starcount = game.calcstars(levnum, hiscore);
|
|
|
|
} else {
|
|
|
|
starcount = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-26 16:27:42 +10:00
|
|
|
game.drawstars(ctx, LEVSEL_X + x + GRIDSIZE/2, stary, TEXTSIZELEVSTARS, starcount, STARWID_LEVSEL);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
/*
|
|
|
|
stars = game.calcstartext(starcount);
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "middle";
|
|
|
|
shadowtext(ctx, stars, TEXTSIZELEVSTARS, starcol,
|
2016-08-25 16:49:54 +10:00
|
|
|
LEVSEL_X + x + GRIDSIZE/2,stary);
|
2016-08-22 19:52:15 +10:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// show hiscore
|
|
|
|
hiscore = playerdata.getlevscore(levnum);
|
2016-09-04 11:47:42 +10:00
|
|
|
if (hiscore == undefined) hiscore = 0;
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "bottom";
|
|
|
|
if (hiscore == 0) {
|
|
|
|
shadowtext(ctx, "NEW!", TEXTSIZELEVSCORE, "#ee44ee",
|
|
|
|
LEVSEL_X + x + GRIDSIZE/2,scorey);
|
|
|
|
} else {
|
|
|
|
hiscore = addcommas(hiscore) + "pts";
|
|
|
|
shadowtext(ctx, hiscore, TEXTSIZELEVSCORE, scorecol,
|
|
|
|
LEVSEL_X + x + GRIDSIZE/2,scorey);
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
}
|
2016-09-04 11:47:42 +10:00
|
|
|
//} else {
|
2016-08-22 19:52:15 +10:00
|
|
|
// level doesn't exist
|
2016-09-04 11:47:42 +10:00
|
|
|
|
|
|
|
/*
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.beginPath();
|
|
|
|
ctx.lineWidth = 3;
|
|
|
|
ctx.strokeStyle = gridcol;
|
2016-08-25 16:49:54 +10:00
|
|
|
gridgrad = this.context.createLinearGradient(x, y, LEVSEL_X+x+GRIDSIZE, LEVSEL_Y+y+GRIDSIZE);
|
2016-08-22 19:52:15 +10:00
|
|
|
gridgrad.addColorStop(0, "#eeeeee");
|
2016-08-25 16:49:54 +10:00
|
|
|
gridgrad.addColorStop(1, gridblack);
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.fillStyle = gridgrad;
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.fillRect(LEVSEL_X + x, LEVSEL_Y + y, GRIDSIZE-1, GRIDSIZE-1);
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
// cross it out
|
2016-08-25 16:49:54 +10:00
|
|
|
drawcross(ctx,LEVSEL_X + x, LEVSEL_Y + y, LEVSEL_X + x + GRIDSIZE-1, BOARDY + y + GRIDSIZE-1, crosscol, 3);
|
2016-09-04 11:47:42 +10:00
|
|
|
*/
|
|
|
|
//}
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// outline square
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.lineWidth = 3;
|
|
|
|
ctx.strokeStyle = gridcol;
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.rect(LEVSEL_X + x, LEVSEL_Y + y, GRIDSIZE-1, GRIDSIZE-1);
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
levnum++;
|
|
|
|
}
|
|
|
|
}
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.globalAlpha = 1.0;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
buttongrad = this.context.createLinearGradient(0, 0, levsel_contx + levsel_contw, 0);
|
|
|
|
buttongrad.addColorStop(0, "#999999");
|
|
|
|
buttongrad.addColorStop(1, "black");
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
if (wipe.isactive()) {
|
|
|
|
var fullamt = SCREENH - levsel_conty;
|
|
|
|
buttonyoff = fullamt - ((wipe.count / wipe.max) * fullamt);
|
|
|
|
}
|
|
|
|
|
|
|
|
buttonyoff = wipe.getval(SCREENH - levsel_conty, "down", "up", 0);
|
|
|
|
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.beginPath();
|
|
|
|
ctx.fillStyle = buttongrad;
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.fillRect(levsel_contx, levsel_conty + buttonyoff, levsel_contw, levsel_conth);
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.stroke();
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.lineWidth = 3;
|
|
|
|
ctx.strokeStyle = gridcol;
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.rect(levsel_contx, levsel_conty + buttonyoff, levsel_contw, levsel_conth);
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "middle";
|
2016-08-25 16:49:54 +10:00
|
|
|
shadowtext(ctx, "Back to title screen", BACKTOTITLESIZE, buttontextcol,
|
|
|
|
levsel_contx + levsel_contw/2, levsel_conty + levsel_conth/2 + buttonyoff);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
},
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
|
|
|
|
moveturnsleftbar : function() {
|
|
|
|
var turnspct;
|
|
|
|
|
|
|
|
// turnspct = how high the bar should be
|
|
|
|
// game.turnsbarpct = how high the bar _is_
|
|
|
|
turnspct = (game.turnsleft / game.levels[curlevel].maxturns);
|
|
|
|
|
|
|
|
// move it towards what it should be.
|
|
|
|
if (game.turnsbarpct > turnspct) {
|
|
|
|
game.turnsbarpct -= TURNSBARSPEEDDOWN;
|
|
|
|
if (game.turnsbarpct < turnspct) game.turnsbarpct = turnspct;
|
|
|
|
game.dirty = true;
|
|
|
|
} else if (game.turnsbarpct < turnspct) {
|
|
|
|
game.turnsbarpct += TURNSBARSPEEDUP;
|
|
|
|
if (game.turnsbarpct > turnspct) game.turnsbarpct = turnspct;
|
|
|
|
game.dirty = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-08-29 14:21:42 +10:00
|
|
|
drawsides : function() {
|
2016-08-30 14:55:26 +10:00
|
|
|
var x,y,w,h,y2,h2,i;
|
2016-08-29 14:21:42 +10:00
|
|
|
var turnscol = "#00dddd";
|
|
|
|
|
|
|
|
/// left - turns left
|
|
|
|
x = 0;
|
|
|
|
y = BOARDY;
|
|
|
|
w = BOARDX-1;
|
|
|
|
h = GRIDH * GRIDSIZE;
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
h2 = game.turnsbarpct * (h-2);
|
|
|
|
|
|
|
|
//y2 = y + (h - game.turnsbarh);
|
2016-08-30 14:55:26 +10:00
|
|
|
y2 = y + (h - h2) -1;
|
2016-08-29 14:21:42 +10:00
|
|
|
|
|
|
|
// black background
|
|
|
|
ctx.beginPath();
|
2016-08-30 14:55:26 +10:00
|
|
|
ctx.fillStyle = "black";
|
|
|
|
ctx.fillRect(x+1,y+1,w-1,h-1);
|
2016-08-29 14:21:42 +10:00
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
// turns left bar
|
|
|
|
if (game.turnsleft > 0) {
|
2016-08-29 19:24:29 +10:00
|
|
|
var gradient;
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
// blue gradient bar showing turns left
|
2016-08-29 14:21:42 +10:00
|
|
|
ctx.beginPath();
|
2016-08-29 19:24:29 +10:00
|
|
|
gradient = ctx.createLinearGradient(0, 0, 0, h2);
|
|
|
|
gradient.addColorStop(0, "#0000ff");
|
2016-08-30 14:55:26 +10:00
|
|
|
gradient.addColorStop(1, "#000066");
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
ctx.fillStyle = gradient;
|
2016-08-30 14:55:26 +10:00
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
ctx.fillRect(x+1,y2,w-1,h2);
|
2016-08-29 14:21:42 +10:00
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
// turns left text
|
|
|
|
ctx.textAlign = "center";
|
|
|
|
ctx.textBaseline = "top";
|
2016-08-29 19:24:29 +10:00
|
|
|
shadowtext(ctx, Math.floor(game.turnsleft), TURNSLEFTTEXTSIZE, turnscol, x + (w/2), y2 + 2);
|
2016-08-30 14:55:26 +10:00
|
|
|
shadowtext(ctx, "turn" + (game.turnsleft == 1) ? "" : "s", TURNSLEFTTEXTSIZE, turnscol, x + (w/2), y2 + 2 +
|
|
|
|
TURNSLEFTTEXTSIZE);
|
2016-08-29 14:21:42 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// border
|
|
|
|
ctx.beginPath();
|
2016-08-30 14:55:26 +10:00
|
|
|
ctx.strokeStyle = "#dddddd";
|
|
|
|
ctx.lineWidth = 2;
|
|
|
|
ctx.rect(x+1,y,w,h);
|
2016-08-29 14:21:42 +10:00
|
|
|
ctx.stroke();
|
2016-08-30 14:55:26 +10:00
|
|
|
|
|
|
|
// right: bags
|
2016-08-30 19:46:40 +10:00
|
|
|
|
|
|
|
var SMALLBAGAMT = 0.2;
|
2016-08-30 14:55:26 +10:00
|
|
|
if (game.levels[curlevel].bags != undefined) {
|
|
|
|
for (i = 0; i < game.levels[curlevel].bags.length; i++) {
|
|
|
|
var bagh,thisbag;
|
|
|
|
thisbag = game.levels[curlevel].bags[i];
|
|
|
|
x = BOARDX + (GRIDW * GRIDSIZE);
|
|
|
|
y = BOARDY + (thisbag.y * GRIDSIZE);
|
|
|
|
if (thisbag.cats < thisbag.capacity) {
|
2016-08-30 19:46:40 +10:00
|
|
|
bagh = THINGSIZE*SMALLBAGAMT; // base height
|
|
|
|
bagh += (thisbag.cats / thisbag.capacity) * (THINGSIZE*(1-SMALLBAGAMT)); // increase based on fullness
|
2016-08-30 14:55:26 +10:00
|
|
|
ctx.drawImage(image['bag'], x, y + GRIDSIZE/2 - bagh/2, THINGSIZE, bagh);
|
|
|
|
} else if (thisbag.prize != "") { // not collected yet
|
|
|
|
var size = SCREENW - (GRIDW*GRIDSIZE + BOARDX) ;
|
|
|
|
// bag is open!
|
|
|
|
ctx.drawImage(image[thisbag.prize], x, y + GRIDSIZE/2 - size/2, size, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-29 14:21:42 +10:00
|
|
|
},
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
drawgrid : function() {
|
2016-08-25 16:49:54 +10:00
|
|
|
/*
|
|
|
|
this.context.strokeStyle = "red";
|
|
|
|
this.context.lineWidth = 2;
|
2016-08-22 19:52:15 +10:00
|
|
|
this.context.beginPath();
|
|
|
|
// draw grid
|
|
|
|
for (y = 0; y < GRIDH*GRIDSIZE; y += GRIDSIZE) {
|
|
|
|
for (x = 0; x < GRIDW*GRIDSIZE; x += GRIDSIZE) {
|
|
|
|
this.context.rect(BOARDX + x, BOARDY + y, GRIDSIZE-1, GRIDSIZE-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.context.stroke();
|
2016-08-25 16:49:54 +10:00
|
|
|
*/
|
2016-08-22 19:52:15 +10:00
|
|
|
},
|
|
|
|
|
|
|
|
drawpath : function() {
|
2016-08-25 16:49:54 +10:00
|
|
|
//var ctx = this.context;
|
2016-08-19 17:46:39 +10:00
|
|
|
var col;
|
|
|
|
var i;
|
|
|
|
|
|
|
|
if ((curpath == undefined) || (curpath.length < 1)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pathvalid) {
|
2016-08-25 16:49:54 +10:00
|
|
|
col = PATHLINECOLGOOD;
|
2016-08-19 17:46:39 +10:00
|
|
|
} else {
|
2016-08-25 16:49:54 +10:00
|
|
|
col = PATHLINECOLBAD;
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
|
|
|
ctx.strokeStyle = col;
|
|
|
|
ctx.lineWidth = LINEWIDTH;
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
// draw line to show current path
|
2016-08-19 17:46:39 +10:00
|
|
|
ctx.beginPath();
|
2016-08-20 11:17:22 +10:00
|
|
|
ctx.moveTo(BOARDX + curpath[0].x + THINGSIZE/2, BOARDY + curpath[0].y + THINGSIZE/2);
|
2016-08-19 17:46:39 +10:00
|
|
|
for (i = 1; i < curpath.length; i++) {
|
2016-08-20 11:17:22 +10:00
|
|
|
ctx.lineTo(BOARDX + curpath[i].x + THINGSIZE/2, BOARDY + curpath[i].y + THINGSIZE/2);
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
if (curpath.length >= 2) {
|
|
|
|
x1 = curpath[curpath.length-2].x + (THINGSIZE/2);
|
|
|
|
y1 = curpath[curpath.length-2].y + (THINGSIZE/2);
|
|
|
|
|
|
|
|
x2 = curpath[curpath.length-1].x + (THINGSIZE/2);
|
|
|
|
y2 = curpath[curpath.length-1].y + (THINGSIZE/2);
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
drawarrowhead(ctx, BOARDX + x1, BOARDY + y1, BOARDX + x2, BOARDY + y2, col, PATHARROWSIZE);
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
},
|
|
|
|
|
2016-08-18 14:54:54 +10:00
|
|
|
/*
|
2016-08-18 14:14:48 +10:00
|
|
|
handleclick : function(event) {
|
2016-08-18 14:54:54 +10:00
|
|
|
// make sure nothing is moving
|
|
|
|
if (thingsmoving()) return;
|
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
// did you click on an object?
|
|
|
|
var clickedthing = getthingxy(event.pageX,event.pageY);
|
|
|
|
if (clickedthing) {
|
|
|
|
clickedthing.kill();
|
|
|
|
}
|
2016-08-18 14:54:54 +10:00
|
|
|
},
|
|
|
|
*/
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
handlekeypress : function(event) {
|
|
|
|
var ch;
|
|
|
|
ch = String.fromCharCode(event.keyCode || event.charCode);
|
|
|
|
console.log("pressed " + ch);
|
|
|
|
if (ch == 'a') {
|
2016-08-22 19:52:15 +10:00
|
|
|
console.log("chear() - ending game");
|
|
|
|
game.setstate("gameover");
|
|
|
|
game.cheat = 1;
|
2016-08-30 19:46:40 +10:00
|
|
|
} else if (ch == 'i') {
|
|
|
|
var what;
|
|
|
|
what = getthingxy(lastmx, lastmy);
|
|
|
|
if (what != undefined) {
|
|
|
|
|
|
|
|
console.log("info for " + what.name);
|
|
|
|
console.log(what);
|
|
|
|
}
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
} else if (ch == 'c') {
|
|
|
|
playerdata.clearall();
|
2016-08-30 14:55:26 +10:00
|
|
|
} else if (ch == 'f') {
|
|
|
|
var i;
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (things[i].type == "cat") things[i].gotfez = true;
|
|
|
|
}
|
|
|
|
game.dirty = true;
|
2016-08-25 20:01:45 +10:00
|
|
|
} else if (ch == 't') {
|
2016-08-31 15:19:51 +10:00
|
|
|
game.addflash();
|
|
|
|
game.addfireworks();
|
2016-09-02 11:48:48 +10:00
|
|
|
} else if (ch == 'p') {
|
|
|
|
var what;
|
|
|
|
console.log("changing last clicked thing thing at " + lastmx/GRIDSIZE + "," + lastmy/GRIDSIZE );
|
|
|
|
what = getthingxy(lastmx, lastmy);
|
|
|
|
if (what != undefined) {
|
|
|
|
what.name = "xxx changed xx";
|
2016-09-03 10:52:03 +10:00
|
|
|
what.type = "cat";
|
|
|
|
what.catcol = 0;
|
2016-09-02 11:48:48 +10:00
|
|
|
game.dirty = true;
|
|
|
|
}
|
2016-08-30 14:55:26 +10:00
|
|
|
} else if (ch == 'l') {
|
|
|
|
var what;
|
|
|
|
console.log("changing last clicked thing thing at " + lastmx/GRIDSIZE + "," + lastmy/GRIDSIZE );
|
|
|
|
what = getthingxy(lastmx, lastmy);
|
|
|
|
if (what != undefined) {
|
2016-08-31 13:55:35 +10:00
|
|
|
what.name = "xxx changed xx";
|
2016-09-03 10:52:03 +10:00
|
|
|
what.type = "llama";
|
|
|
|
game.dirty = true;
|
|
|
|
}
|
|
|
|
} else if (ch == 'b') {
|
|
|
|
var what;
|
|
|
|
console.log("changing last clicked thing thing at " + lastmx/GRIDSIZE + "," + lastmy/GRIDSIZE );
|
|
|
|
what = getthingxy(lastmx, lastmy);
|
|
|
|
if (what != undefined) {
|
|
|
|
what.name = "xxx changed xx";
|
|
|
|
what.type = "box";
|
2016-08-30 14:55:26 +10:00
|
|
|
game.dirty = true;
|
|
|
|
}
|
|
|
|
} else if (ch == 'm') {
|
|
|
|
var what;
|
|
|
|
console.log("checking for matches from " + lastmx/GRIDSIZE + "," + lastmy/GRIDSIZE );
|
|
|
|
what = getthingxy(lastmx, lastmy);
|
|
|
|
if (what != undefined) {
|
|
|
|
if (matchthreefrom(what, true)) {
|
|
|
|
console.log("--found match");
|
|
|
|
} else {
|
|
|
|
console.log("--no match");
|
|
|
|
}
|
|
|
|
}
|
2016-08-21 09:32:57 +10:00
|
|
|
} else if (ch == 'n') {
|
2016-08-22 19:52:15 +10:00
|
|
|
var i;
|
|
|
|
score += 10;
|
|
|
|
for (i = 0 ; i < game.levels[curlevel].goals.length; i++ ) {
|
|
|
|
game.levels[curlevel].goals[i].progress = game.levels[curlevel].goals[i].count;
|
|
|
|
}
|
|
|
|
game.cheat = 1;
|
|
|
|
console.log("cheat() - finishingl level");
|
|
|
|
} else if (ch == 'u') {
|
|
|
|
game.cheat = 1;
|
2016-09-09 18:23:23 +10:00
|
|
|
if (playerdata.totstars < 43) {
|
|
|
|
playerdata.settotstars(43);
|
|
|
|
} else {
|
|
|
|
playerdata.settotstars(85);
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
console.log("cheat() - set tot stars to " + playerdata.totstars);
|
2016-08-20 11:34:25 +10:00
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
},
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-20 11:34:25 +10:00
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
handlemousedown : function(event) {
|
2016-08-22 19:52:15 +10:00
|
|
|
var coords,adjustx,adjusty,realx,realy;
|
2016-08-20 11:34:25 +10:00
|
|
|
event.preventDefault();
|
2016-08-26 16:31:38 +10:00
|
|
|
|
|
|
|
mbdown = true;
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
coords = getmousexy(event);
|
|
|
|
adjustx = coords[0];
|
|
|
|
adjusty = coords[1];
|
|
|
|
realx = coords[2];
|
|
|
|
realy = coords[3];
|
|
|
|
// remember coords for touch screens
|
|
|
|
if (event.type == "touchstart") {
|
|
|
|
lastmx = adjustx;
|
|
|
|
lastmy = adjusty;
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
if (wipe.isactive()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
if (game.state == "running") {
|
|
|
|
// ignore multi-touch
|
2016-08-22 19:52:15 +10:00
|
|
|
//if ((curpath != undefined) && curpath.length >= 1) return;
|
|
|
|
|
|
|
|
game.dirty = true; // need to redraw
|
2016-08-18 14:54:54 +10:00
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
// make sure nothing is moving
|
|
|
|
if (thingsfalling()) return;
|
2016-08-18 14:54:54 +10:00
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
// clear existing path
|
|
|
|
clearpath();
|
|
|
|
|
|
|
|
// did you click on an object?
|
|
|
|
var onthing = getthingxy(adjustx, adjusty);
|
|
|
|
if (onthing) {
|
|
|
|
if (canstartpath(onthing)) {
|
|
|
|
console.log("Initial click on " + onthing.name);
|
|
|
|
addtopath(onthing);
|
|
|
|
} else {
|
|
|
|
// just show description
|
|
|
|
overdesc = onthing.getdesc();
|
|
|
|
}
|
2016-08-30 14:55:26 +10:00
|
|
|
} else {
|
|
|
|
var bag;
|
|
|
|
// did you click on a bag?
|
|
|
|
bag = getbagaty(Math.floor(adjusty / GRIDSIZE));
|
|
|
|
if ((bag != undefined) && (adjustx > GRIDSIZE*GRIDW)) {
|
|
|
|
if (bag.cats >= bag.capacity) {
|
|
|
|
collectprize(bag);
|
|
|
|
}
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
} else if (game.state == "gameover") {
|
2016-08-22 19:52:15 +10:00
|
|
|
if ((realx >= tapx) && (realx <= tapx + tapw) &&
|
|
|
|
(realy >= tapy) && (realy <= tapy + taph)) {
|
2016-08-23 01:13:47 +10:00
|
|
|
game.clearlevelprogress(curlevel);
|
2016-08-25 16:49:54 +10:00
|
|
|
|
|
|
|
wipe.start("levselect", "out", 20);
|
|
|
|
//game.setstate("levselect");
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-08-20 15:12:32 +10:00
|
|
|
} else if (game.state == "title") {
|
2016-08-25 16:49:54 +10:00
|
|
|
wipe.start("levselect", "out", 15);
|
|
|
|
} else if (game.state == "levselect") {
|
2016-08-22 19:52:15 +10:00
|
|
|
// find where you clicked
|
|
|
|
if ((realx >= levsel_contx) && (realx <= levsel_contx + levsel_contw) &&
|
|
|
|
(realy >= levsel_conty) && (realy <= levsel_conty + levsel_conth)) {
|
2016-09-04 11:47:42 +10:00
|
|
|
// back to title screen
|
2016-08-25 16:49:54 +10:00
|
|
|
wipe.start("title", "out", 15);
|
2016-08-22 19:52:15 +10:00
|
|
|
} else {
|
|
|
|
var gridx,gridy,levsel;
|
|
|
|
|
|
|
|
gridx = Math.floor(adjustx / GRIDSIZE);
|
|
|
|
gridy = Math.floor(adjusty / GRIDSIZE);
|
2016-08-25 16:49:54 +10:00
|
|
|
//gridx = Math.floor((realx - BOARDX) / GRIDSIZE);
|
|
|
|
//gridy = Math.floor((realy - BOARDY) / GRIDSIZE);
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-09-08 14:15:46 +10:00
|
|
|
if ((gridy == -1) && (gridx == 4)) {
|
|
|
|
game.resetcount++;
|
|
|
|
console.log(game.resetcount);
|
|
|
|
if (game.resetcount >= 10) {
|
|
|
|
if (confirm("Clear game data?")) {
|
|
|
|
playerdata.clearall();
|
|
|
|
playerdata.load();
|
|
|
|
}
|
|
|
|
game.resetcount = 0;
|
|
|
|
}
|
|
|
|
} else if ((gridx == LEVSELGRIDW-1) && (gridy == LEVSELGRIDH - 1)) {
|
2016-09-09 18:23:23 +10:00
|
|
|
var inc,nextlev;
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
// "next"
|
2016-09-09 18:23:23 +10:00
|
|
|
if (game.levseloff == 0) {
|
|
|
|
inc = ((LEVSELGRIDW*LEVSELGRIDH)-1);
|
|
|
|
} else {
|
|
|
|
inc = ((LEVSELGRIDW*LEVSELGRIDH)-2);
|
|
|
|
}
|
|
|
|
nextlev = curlevel + game.levseloff + inc;
|
|
|
|
if (!game.levellocked(nextlev)) {
|
|
|
|
game.levseloff += inc;
|
|
|
|
} else {
|
|
|
|
console.log("level " + nextlev + " locked = " + game.levellocked(nextlev));
|
|
|
|
}
|
2016-09-04 11:47:42 +10:00
|
|
|
} else if (game.levseloff > 0 && gridx == 0 && gridy == 0) {
|
2016-09-09 18:23:23 +10:00
|
|
|
var dec;
|
|
|
|
// "prev"
|
|
|
|
|
|
|
|
if (game.levseloff == 29) {
|
|
|
|
dec = ((LEVSELGRIDW*LEVSELGRIDH)-1);
|
|
|
|
} else {
|
|
|
|
dec = ((LEVSELGRIDW*LEVSELGRIDH)-2);
|
|
|
|
}
|
|
|
|
|
|
|
|
game.levseloff -= dec;
|
2016-09-04 11:47:42 +10:00
|
|
|
if (game.levseloff < 0) game.levseloff = 0;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
levsel = game.levseloff + (gridy*LEVSELGRIDW) + gridx + 1;
|
|
|
|
if (game.levseloff > 0) levsel--;
|
|
|
|
|
2016-09-08 14:15:46 +10:00
|
|
|
if (levsel >= 1) {
|
|
|
|
if (!game.levellocked(levsel)) {
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-09-08 14:15:46 +10:00
|
|
|
curlevel = levsel;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-09-08 14:15:46 +10:00
|
|
|
game.initgamevars();
|
|
|
|
game.helporstartlev();
|
|
|
|
}
|
2016-09-04 11:47:42 +10:00
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
}
|
2016-08-20 15:12:32 +10:00
|
|
|
} else if (game.state == "help") {
|
2016-08-25 16:49:54 +10:00
|
|
|
game.setstate("running");
|
2016-08-21 09:32:57 +10:00
|
|
|
} else if (game.state == "levelcomplete") {
|
2016-08-22 19:52:15 +10:00
|
|
|
if ((realx >= tapx) && (realx <= tapx + tapw) &&
|
|
|
|
(realy >= tapy) && (realy <= tapy + taph)) {
|
|
|
|
|
|
|
|
// clear goals in case we do this level again
|
|
|
|
game.clearlevelprogress(curlevel);
|
|
|
|
|
|
|
|
game.setstate("levselect");
|
|
|
|
}
|
2016-08-21 09:57:40 +10:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
helporstartlev : function() {
|
|
|
|
if (hashelp(curlevel)) {
|
2016-08-25 16:49:54 +10:00
|
|
|
wipe.start("help", "out", 15);
|
|
|
|
//game.setstate("help");
|
2016-08-21 09:57:40 +10:00
|
|
|
} else {
|
2016-08-25 16:49:54 +10:00
|
|
|
//game.startlevel();
|
|
|
|
wipe.start("running", "out", 15);
|
2016-08-18 14:54:54 +10:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-08-27 13:18:03 +10:00
|
|
|
generatestargoalbanner : function() {
|
|
|
|
var i,x,y;
|
|
|
|
var topctx = this.stargoalbanner.getContext("2d");
|
|
|
|
|
|
|
|
// show star targets
|
|
|
|
var starsize = STARWID_TOPGOALS;
|
|
|
|
var spacewid = starsize / 2;
|
|
|
|
var starindent = 16;
|
|
|
|
var startextcol = "#eeee00";
|
|
|
|
var startextcoldark = "#999900";
|
|
|
|
|
|
|
|
x = SCREENW/4;
|
|
|
|
y = 0;
|
|
|
|
|
|
|
|
// clear top buffer
|
|
|
|
topctx.clearRect(0, 0, this.stargoalbanner.width, this.stargoalbanner.height);
|
|
|
|
|
|
|
|
// for each points goal, generate a temp image and paste it.
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
var xx = 0,yy = 0;
|
|
|
|
var n;
|
|
|
|
var textw,pointtext;
|
|
|
|
|
|
|
|
// create third temp buffer for this star images + points
|
|
|
|
var a = document.createElement("canvas");
|
|
|
|
var actx = a.getContext("2d");
|
|
|
|
|
|
|
|
// figure out how big text will be
|
|
|
|
pointtext = addcommas(game.levels[curlevel].starpoints[i]);
|
|
|
|
textw = gettextw(actx, pointtext, STARPOINTTEXTSIZE);
|
|
|
|
|
|
|
|
// size third temp buffer based on text width
|
|
|
|
a.width = starsize*3 + spacewid + textw;
|
|
|
|
a.height = this.stargoalbanner.height;
|
|
|
|
a.id = "a";
|
|
|
|
|
|
|
|
actx.clearRect(0, 0, a.width, a.height);
|
|
|
|
|
|
|
|
|
|
|
|
for (n = 0; n < (i+1); n++) {
|
|
|
|
// draw star on to third buffer
|
|
|
|
actx.drawImage(image['starfull'], xx, yy, starsize, starsize);
|
|
|
|
xx += starsize;
|
|
|
|
}
|
|
|
|
|
|
|
|
xx += starsize/4;
|
|
|
|
|
|
|
|
// draw text on to third buffer
|
|
|
|
actx.textAlign = "left";
|
|
|
|
actx.textBaseline = "top";
|
|
|
|
shadowtext(actx, pointtext, STARPOINTTEXTSIZE,
|
|
|
|
(score >= game.levels[curlevel].starpoints[i]) ? startextcol : startextcoldark,
|
|
|
|
xx, yy);
|
|
|
|
|
|
|
|
|
|
|
|
// blit third buffer to top buffer then move along
|
|
|
|
//console.log("i: " + i + ", x = " + x + " y = " + y + " a.dims = " + a.width + "," + a.height);
|
|
|
|
topctx.drawImage(a, x - a.width/2, y, a.width, a.height);
|
|
|
|
x += (SCREENW / 4);
|
|
|
|
|
|
|
|
// remove temp third buffer
|
|
|
|
//document.removeChild(document.getElementById("a"));
|
|
|
|
}
|
2016-08-27 17:47:39 +10:00
|
|
|
|
|
|
|
this.dirty = true;
|
2016-08-27 13:18:03 +10:00
|
|
|
},
|
|
|
|
|
2016-09-02 11:48:48 +10:00
|
|
|
placetitlegoat : function(randomx) {
|
|
|
|
// randomly place the title screen goat
|
|
|
|
this.goaty = rnd((SCREENH / DEF_GRIDSIZE)-1);
|
|
|
|
if (this.goaty % 2 == 0) this.goatdir = 1;
|
|
|
|
else this.goatdir = -1;
|
|
|
|
|
|
|
|
if (randomx) {
|
|
|
|
this.goatx = rnd((SCREENW / DEF_GRIDSIZE)-1);
|
|
|
|
} else {
|
|
|
|
if (this.goatdir == 1) {
|
|
|
|
this.goatx = -1;
|
|
|
|
} else {
|
|
|
|
this.goatx = 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
//console.log("goat coords " + this.goatx + "," + this.goaty + " dir " + this.goatdir);
|
2016-09-02 11:48:48 +10:00
|
|
|
|
|
|
|
},
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
setstate : function(newstate) {
|
2016-08-27 12:35:18 +10:00
|
|
|
console.log("setstate() = " + newstate);
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
if (newstate != this.state) {
|
|
|
|
this.dirty = true;
|
|
|
|
}
|
2016-08-27 12:35:18 +10:00
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
if (newstate == "help") {
|
|
|
|
// decide which word to use
|
|
|
|
if (onein(2)) {
|
|
|
|
llamatext = "llama";
|
|
|
|
} else {
|
|
|
|
llamatext = "alpaca";
|
|
|
|
}
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
if (newstate == "gameover") {
|
|
|
|
tapx = 0, tapy = BOARDY + (GRIDH/2)*GRIDSIZE;
|
|
|
|
tapw = SCREENW, taph = GRIDSIZE;
|
|
|
|
} else if (newstate == "levelcomplete") {
|
|
|
|
var newsize;
|
|
|
|
//tapx = 0, tapy = BOARDY;
|
|
|
|
//tapw = SCREENW, taph = GRIDH*GRIDSIZE;
|
|
|
|
|
|
|
|
// calc size of continue button based on image size
|
|
|
|
newsize = getimgsize(winimg.width,winimg.height, SCREENW, GRIDH*GRIDSIZE);
|
|
|
|
tapw = newsize.width;
|
|
|
|
taph = newsize.height;
|
|
|
|
//tapx = (SCREENW / 2) - (tapw/2);
|
|
|
|
//tapy = BOARDY + ((GRIDH*GRIDSIZE)/2) - (taph/2);
|
|
|
|
tapx = 0;
|
|
|
|
tapy = BOARDY;
|
2016-08-31 15:19:51 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
} else if (newstate == "running") {
|
2016-08-25 16:49:54 +10:00
|
|
|
this.initlevelvars();
|
|
|
|
this.populategrid();
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// get a new cat picture for if we win
|
|
|
|
if (winimg != undefined) delete winimg;
|
|
|
|
winimg = new Image();
|
2016-09-04 11:47:42 +10:00
|
|
|
//var n = rnd(NUMWINIMAGES);
|
|
|
|
var n = curlevel % NUMWINIMAGES;
|
2016-08-22 19:52:15 +10:00
|
|
|
winimg.src = "images/win" + n + ".png";
|
|
|
|
this.winimgsize = 0.1;
|
2016-08-25 16:49:54 +10:00
|
|
|
|
2016-08-27 13:18:03 +10:00
|
|
|
// generate starpoint goal banner for top of screen
|
2016-08-27 17:47:39 +10:00
|
|
|
game.generatestargoalbanner();
|
2016-08-27 13:18:03 +10:00
|
|
|
|
2016-08-29 14:21:42 +10:00
|
|
|
// reset turns left
|
|
|
|
game.turnsleft = game.levels[curlevel].maxturns;
|
2016-08-29 19:24:29 +10:00
|
|
|
// start turns left bar at bottom so it ticks up.
|
|
|
|
game.turnsbarpct = 0;
|
2016-08-29 14:21:42 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
wipe.start("", "in", 50);
|
2016-08-22 19:52:15 +10:00
|
|
|
} else if (newstate == "levselect") {
|
2016-09-08 14:15:46 +10:00
|
|
|
// reset counters for clearing data
|
|
|
|
game.resetcount = 0;
|
|
|
|
|
2016-08-24 22:47:23 +10:00
|
|
|
// reset grid size
|
|
|
|
GRIDSIZE = DEF_GRIDSIZE;
|
|
|
|
THINGSIZE = DEF_THINGSIZE;
|
|
|
|
GRIDW = DEF_GRIDW;
|
|
|
|
GRIDH = DEF_GRIDH;
|
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
console.log("going to levsel state, game.countplayerstars() is " + game.countplayerstars());
|
2016-08-22 19:52:15 +10:00
|
|
|
// count player stars
|
|
|
|
playerdata.settotstars(game.countplayerstars());
|
2016-08-25 16:49:54 +10:00
|
|
|
|
|
|
|
// start fade in
|
|
|
|
wipe.start("", "in", 15);
|
|
|
|
} else if (newstate == "title") {
|
2016-09-02 11:48:48 +10:00
|
|
|
this.placetitlegoat(true);
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
// start fade in
|
|
|
|
wipe.start("", "in", 15);
|
2016-08-27 12:25:17 +10:00
|
|
|
} else if (newstate == "loader") {
|
2016-08-27 12:35:18 +10:00
|
|
|
// start loading images
|
|
|
|
var i;
|
2016-08-27 12:25:17 +10:00
|
|
|
|
2016-08-31 17:45:15 +10:00
|
|
|
imagenames = [ 'cat', 'catfull', 'catscared',
|
|
|
|
'cat1', 'catfull1', 'catscared1',
|
|
|
|
'llama', 'cheese', 'title',
|
2016-09-02 11:48:48 +10:00
|
|
|
'goat', 'lock','catwalkl','catwalkr','goatwalkl','goatwalkr',
|
2016-09-03 10:52:03 +10:00
|
|
|
'starfull','starempty', 'stargrey', 'curtain','curtainshred', 'curtainfall',
|
2016-08-31 13:55:35 +10:00
|
|
|
'door', 'sunlight', 'toad', 'whitecat', // special things
|
2016-09-03 10:52:03 +10:00
|
|
|
'box', 'boxfront', 'boxback',
|
2016-09-04 11:47:42 +10:00
|
|
|
'nextlev','prevlev',
|
2016-08-31 13:55:35 +10:00
|
|
|
'brick', // obstacles
|
|
|
|
'bag', 'bagpop', 'fez', 'pow', 'brickpop', // effects
|
|
|
|
'tissues', 'shears', 'magiccarpet' ];
|
2016-08-27 12:35:18 +10:00
|
|
|
|
|
|
|
nimages = 0;
|
|
|
|
maximages = 0;
|
|
|
|
for (i in imagenames) {
|
|
|
|
maximages++;
|
|
|
|
loadimage(imagenames[i], 'images/' + imagenames[i] + '.png');
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
this.state = newstate;
|
|
|
|
},
|
|
|
|
|
2016-08-20 11:34:25 +10:00
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
handlemousemove : function(event) {
|
2016-08-22 19:52:15 +10:00
|
|
|
var coords,adjustx,adjusty,realx,realy;
|
2016-08-20 12:27:15 +10:00
|
|
|
coords = getmousexy(event);
|
|
|
|
adjustx = coords[0];
|
|
|
|
adjusty = coords[1];
|
2016-08-22 19:52:15 +10:00
|
|
|
realx = coords[2];
|
|
|
|
realy = coords[3];
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-20 12:59:29 +10:00
|
|
|
// remember coords for touch screens
|
2016-08-30 14:55:26 +10:00
|
|
|
//if (event.type == "touchmove") {
|
|
|
|
lastmx = adjustx;
|
|
|
|
lastmy = adjusty;
|
|
|
|
//}
|
2016-08-20 12:59:29 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
event.preventDefault();
|
|
|
|
|
2016-08-26 16:31:38 +10:00
|
|
|
if (!mbdown) return;
|
2016-08-20 12:27:15 +10:00
|
|
|
if (game.state != "running") return;
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
game.dirty = true; // need to redraw
|
|
|
|
|
2016-08-18 14:54:54 +10:00
|
|
|
// make sure nothing is moving
|
|
|
|
if (thingsmoving()) return;
|
|
|
|
|
|
|
|
// existing path?
|
|
|
|
if (curpath != undefined && curpath.length > 0) {
|
2016-08-20 11:17:22 +10:00
|
|
|
var overthing = getthingxy(adjustx, adjusty);
|
2016-08-19 17:46:39 +10:00
|
|
|
var lastinpath,secondlast;
|
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
if (curpath == undefined) {
|
|
|
|
lastinpath = null;
|
|
|
|
} else {
|
|
|
|
lastinpath = curpath[curpath.length-1];
|
2016-08-19 17:46:39 +10:00
|
|
|
if (curpath.length >= 2) {
|
|
|
|
secondlast = curpath[curpath.length-2];
|
|
|
|
} else {
|
|
|
|
secondlast = null;
|
|
|
|
}
|
2016-08-18 16:18:35 +10:00
|
|
|
}
|
2016-08-18 14:54:54 +10:00
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
if ((secondlast != undefined) && (overthing == secondlast)) {
|
|
|
|
backspacepath();
|
|
|
|
} else if (canextendpath(overthing)) {
|
2016-08-18 14:54:54 +10:00
|
|
|
// add it to the path
|
2016-08-18 16:18:35 +10:00
|
|
|
addtopath(overthing);
|
2016-08-19 17:46:39 +10:00
|
|
|
} else if (pathcontains(overthing) && pathcomplete()) {
|
2016-08-18 16:18:35 +10:00
|
|
|
pathvalid = true;
|
|
|
|
} else {
|
|
|
|
pathvalid = false;
|
2016-08-18 14:54:54 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
handlemouseup : function(event) {
|
2016-09-02 11:48:48 +10:00
|
|
|
var ok = true,i,curtaindie;
|
2016-08-22 19:52:15 +10:00
|
|
|
var adjustx, adjusty,realx,realy;
|
2016-08-20 12:27:15 +10:00
|
|
|
var ptype;
|
2016-08-20 11:17:22 +10:00
|
|
|
var points = 0;
|
2016-08-20 11:34:25 +10:00
|
|
|
var overthing = null;
|
|
|
|
|
|
|
|
event.preventDefault();
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-26 16:31:38 +10:00
|
|
|
mbdown = false;
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
if (game.state != "running") return;
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
game.dirty = true; // need to redraw
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
ptype = getpathtype();
|
|
|
|
|
2016-08-20 12:59:29 +10:00
|
|
|
// special case for touch screens, as the 'touchend' events don't have x/y
|
|
|
|
if ((event.type == "touchend") || (event.type == "touchleave") || (event.type == "touchcancel")) {
|
|
|
|
adjustx = lastmx;
|
|
|
|
adjusty = lastmy;
|
|
|
|
} else {
|
|
|
|
coords = getmousexy(event);
|
|
|
|
adjustx = coords[0];
|
|
|
|
adjusty = coords[1];
|
2016-08-22 19:52:15 +10:00
|
|
|
realx = coords[2];
|
|
|
|
realy = coords[3];
|
2016-08-20 12:59:29 +10:00
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
|
|
|
|
overthing = getthingxy(adjustx, adjusty);
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
overdesc = "";
|
2016-08-19 17:46:39 +10:00
|
|
|
|
|
|
|
if ((curpath == undefined) || (curpath.length == 0)) {
|
2016-08-22 19:52:15 +10:00
|
|
|
//console.log("mouseup() - no path");
|
2016-08-19 17:46:39 +10:00
|
|
|
ok = false;
|
|
|
|
} else if (thingsmoving()) {
|
2016-08-22 19:52:15 +10:00
|
|
|
//console.log("mouseup() - things are moving");
|
2016-08-18 16:18:35 +10:00
|
|
|
ok = false;
|
|
|
|
} else if (!isvalidpath(curpath)) {
|
2016-08-22 19:52:15 +10:00
|
|
|
//console.log("mouseup() - path isn't valid");
|
2016-08-18 16:18:35 +10:00
|
|
|
ok = false;
|
2016-08-19 17:46:39 +10:00
|
|
|
} else if (!pathcomplete(curpath)) {
|
2016-08-22 19:52:15 +10:00
|
|
|
//console.log("mouseup() - path ("+ ptype + ") isn't complete");
|
2016-08-19 17:46:39 +10:00
|
|
|
ok = false;
|
2016-08-18 16:18:35 +10:00
|
|
|
} else if ((overthing == undefined) || !pathcontains(overthing)) {
|
2016-08-22 19:52:15 +10:00
|
|
|
//console.log("mouseup() - not over something in path");
|
2016-08-18 16:18:35 +10:00
|
|
|
ok = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ok) {
|
|
|
|
clearpath();
|
|
|
|
return;
|
|
|
|
}
|
2016-08-18 14:54:54 +10:00
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
// figure out path type
|
2016-08-20 11:17:22 +10:00
|
|
|
points = 0;
|
2016-08-19 17:46:39 +10:00
|
|
|
switch(ptype) {
|
|
|
|
case "chomp":
|
|
|
|
// killall except first and last
|
|
|
|
if (curpath.length > 2) {
|
|
|
|
var i;
|
|
|
|
for (i = 1; i < curpath.length - 1; i++) {
|
2016-08-20 11:17:22 +10:00
|
|
|
curpath[i].givepoints();
|
|
|
|
curpath[i].addabove();
|
|
|
|
//curpath[i].kill();
|
2016-08-30 14:55:26 +10:00
|
|
|
curpath[i].startexplode("chomp");
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
curpath[curpath.length-1].givepoints();
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
|
|
|
|
// first one chomps last one (or enters it, if it's a box)
|
|
|
|
if (curpath[curpath.length - 1].type == "box") {
|
|
|
|
curpath[0].enterbox(curpath[curpath.length - 1]);
|
|
|
|
} else {
|
|
|
|
curpath[0].chomp(curpath[curpath.length - 1]);
|
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
|
2016-09-02 11:48:48 +10:00
|
|
|
break;
|
|
|
|
case "climb": // cat climbs up the curtain
|
|
|
|
// all curtains lose hp
|
|
|
|
curtaindie = false;
|
|
|
|
for (i = 1; i < curpath.length-1; i++) {
|
|
|
|
curpath[i].losehp();
|
|
|
|
if (curpath[i].hp <= 0) {
|
|
|
|
curtaindie = true;
|
|
|
|
}
|
|
|
|
}
|
2016-09-02 13:42:47 +10:00
|
|
|
|
|
|
|
// first cat swaps places with last object
|
|
|
|
curpath[0].pushpath(curpath[curpath.length-1].x, curpath[curpath.length-1].y);
|
|
|
|
curpath[0].state = "swapping";
|
|
|
|
curpath[0].counter = 1;
|
|
|
|
// ...then becomes sleepy
|
|
|
|
curpath[0].sleepy = true;
|
|
|
|
|
|
|
|
|
|
|
|
curpath[curpath.length-1].pushpath(curpath[0].x, curpath[0].y);
|
|
|
|
curpath[curpath.length-1].state = "swapping";
|
|
|
|
|
|
|
|
|
2016-09-02 11:48:48 +10:00
|
|
|
if (curtaindie) {
|
|
|
|
// if any curtains died, _all_ curtains die
|
|
|
|
for (i = 1; i < curpath.length-1; i++) {
|
|
|
|
while (curpath[i].hp > 0) {
|
|
|
|
curpath[i].losehp();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-30 17:19:28 +10:00
|
|
|
break;
|
|
|
|
case "slap": // toad drops down.
|
|
|
|
curpath[0].slap(curpath[curpath.length - 1]);
|
|
|
|
break;
|
|
|
|
case "attack": // whitecat and 8 surrounding things are cleared
|
|
|
|
curpath[0].attack(curpath[curpath.length - 1]);
|
2016-08-19 17:46:39 +10:00
|
|
|
break;
|
|
|
|
case "parade":
|
2016-08-29 19:24:29 +10:00
|
|
|
globmulti = 0;
|
2016-08-20 11:17:22 +10:00
|
|
|
if (curpath.length >= 2) { // should always be true
|
|
|
|
var i;
|
|
|
|
// everything in the path exits via a parade
|
2016-08-23 01:13:47 +10:00
|
|
|
|
|
|
|
pathdoor = pathcontainstype("door");
|
2016-08-29 19:24:29 +10:00
|
|
|
if (pathdoor) globmulti++;
|
2016-08-23 01:13:47 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
for (i = 0; i < curpath.length; i++) {
|
2016-08-23 01:13:47 +10:00
|
|
|
// ... except doors
|
|
|
|
if (curpath[i].type == "door") {
|
2016-08-31 13:55:35 +10:00
|
|
|
//game.progress("door", 1);
|
2016-08-23 01:13:47 +10:00
|
|
|
console.log("path has doors!");
|
|
|
|
// add animation
|
2016-08-29 19:24:29 +10:00
|
|
|
things.push(new thing(curpath[i].gridx, curpath[i].gridy, "text", "x" + (globmulti+1)));
|
2016-08-23 01:13:47 +10:00
|
|
|
} else {
|
2016-08-29 19:24:29 +10:00
|
|
|
curpath[i].givepoints(i);
|
2016-08-23 01:13:47 +10:00
|
|
|
curpath[i].startparade();
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
2016-08-19 17:46:39 +10:00
|
|
|
}
|
2016-08-29 19:24:29 +10:00
|
|
|
globmulti = 0;
|
2016-08-19 17:46:39 +10:00
|
|
|
break;
|
2016-08-18 14:54:54 +10:00
|
|
|
}
|
2016-08-19 17:46:39 +10:00
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
clearpath();
|
2016-08-23 01:13:47 +10:00
|
|
|
|
|
|
|
// things that happen once per turn.
|
|
|
|
game.turneffects();
|
2016-08-18 14:54:54 +10:00
|
|
|
},
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
// Seeded random numbers, from http://stackoverflow.com/questions/424292/seedable-javascript-random-number-generator
|
|
|
|
function RNG(seed) {
|
|
|
|
// LCG using GCC's constants
|
|
|
|
this.m = 0x80000000; // 2**31;
|
|
|
|
this.a = 1103515245;
|
|
|
|
this.c = 12345;
|
|
|
|
|
|
|
|
this.state = seed ? seed : Math.floor(Math.random() * (this.m-1));
|
|
|
|
}
|
|
|
|
RNG.prototype.rndint = function() {
|
|
|
|
this.state = (this.a * this.state + this.c) % this.m;
|
|
|
|
return this.state;
|
|
|
|
}
|
|
|
|
RNG.prototype.rndfloat = function() {
|
|
|
|
// returns in range [0,1]
|
|
|
|
return this.rndint() / (this.m - 1);
|
|
|
|
}
|
|
|
|
RNG.prototype.rndrange = function(start, end) {
|
|
|
|
// returns in range [start, end): including start, excluding end
|
|
|
|
// can't modulu nextInt because of weak randomness in lower bits
|
|
|
|
var rangeSize = end - start;
|
|
|
|
var randomUnder1 = this.rndint() / this.m;
|
|
|
|
return start + Math.floor(randomUnder1 * rangeSize);
|
|
|
|
}
|
|
|
|
RNG.prototype.rndchoice = function(array) {
|
|
|
|
return array[this.rndrange(0, array.length)];
|
|
|
|
}
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
function getimgsize(srcWidth, srcHeight, maxWidth, maxHeight) {
|
|
|
|
|
|
|
|
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
|
|
|
|
|
|
|
|
return { width: srcWidth*ratio, height: srcHeight*ratio };
|
2016-09-04 11:47:42 +10:00
|
|
|
}
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// returns number in range 0 .. num-1
|
|
|
|
function rnd(num) {
|
|
|
|
var roll;
|
|
|
|
roll = Math.floor(Math.random() * num);
|
|
|
|
return roll;
|
|
|
|
}
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
function rndfloat(num) {
|
|
|
|
var roll;
|
|
|
|
roll = Math.random() * num;
|
|
|
|
return roll;
|
|
|
|
}
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
function onein(num) {
|
|
|
|
var roll;
|
|
|
|
roll = Math.floor(Math.random() * num);
|
|
|
|
if (roll == 0) return true;
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
|
|
|
|
function getrandomcolour() {
|
|
|
|
var letters = '0123456789ABCDEF';
|
|
|
|
var col = '#';
|
|
|
|
for (var i = 0; i < 6; i++ ) {
|
|
|
|
col += letters[Math.floor(Math.random() * 16)];
|
|
|
|
}
|
|
|
|
return col;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getrandomname() {
|
|
|
|
var letters = '0123456789';
|
2016-08-18 16:18:35 +10:00
|
|
|
var name = "";
|
2016-08-18 14:14:48 +10:00
|
|
|
for (var i = 0; i < 3; i++ ) {
|
|
|
|
name += letters[Math.floor(Math.random() * 10)];
|
|
|
|
}
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
function isonscreen(x,y) {
|
|
|
|
if ((x < 0) || (y < 0) || (x >= GRIDW) || (y >= GRIDH)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
function gettextw(ctx, text, size) {
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.font = size + "pt " + FONT;
|
2016-08-22 19:52:15 +10:00
|
|
|
return ctx.measureText(text).width + 2; // add space for shadow
|
|
|
|
}
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
// extra args are gradient
|
2016-08-20 15:12:32 +10:00
|
|
|
function shadowtext(ctx, text, size, col, x, y) {
|
2016-08-25 16:49:54 +10:00
|
|
|
var i,textcol,gradidx = 0;
|
|
|
|
|
|
|
|
if (arguments.length > 6) {
|
|
|
|
var y1,y2,adjsize,gradinc;
|
|
|
|
|
|
|
|
adjsize = size*2;
|
|
|
|
if (game.context.textBaseline == "top") {
|
|
|
|
y1 = y;
|
|
|
|
y2 = y + adjsize;
|
|
|
|
} else {
|
|
|
|
y1 = y - adjsize/2;
|
|
|
|
y2 = y + adjsize/2;
|
|
|
|
}
|
|
|
|
textcol = game.context.createLinearGradient(0, y1, 0, y2);
|
|
|
|
|
|
|
|
gradinc = 1.0 / (arguments.length - 6-1);
|
|
|
|
|
|
|
|
for (i = 6 ; i < arguments.length; i ++) {
|
|
|
|
textcol.addColorStop(gradidx, arguments[i]);
|
|
|
|
|
|
|
|
gradidx += gradinc;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
textcol = col;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.font = size + "pt " + FONT;
|
2016-08-20 15:12:32 +10:00
|
|
|
// shadows
|
|
|
|
ctx.fillStyle = "black";
|
|
|
|
ctx.fillText(text, x-1, y-1);
|
|
|
|
ctx.fillText(text, x+1, y);
|
|
|
|
ctx.fillText(text, x+1, y+1);
|
|
|
|
ctx.fillText(text, x-1, y+1);
|
|
|
|
// real text
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.fillStyle = textcol;
|
2016-08-20 15:12:32 +10:00
|
|
|
ctx.fillText(text, x, y);
|
|
|
|
}
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
function collectprize(bag) {
|
|
|
|
var i;
|
|
|
|
|
|
|
|
if (bag.prize == "") return;
|
|
|
|
|
2016-08-31 15:19:51 +10:00
|
|
|
game.addflash();
|
2016-08-30 14:55:26 +10:00
|
|
|
|
|
|
|
switch (bag.prize) {
|
|
|
|
case "tissues": // all sleepy cats wake up
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (things[i].type == "cat") {
|
2016-09-02 13:42:47 +10:00
|
|
|
things[i].sleepy = false;
|
2016-08-30 14:55:26 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "shears": // clear all llamas
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (things[i].type == "llama") {
|
|
|
|
things[i].givepoints();
|
|
|
|
things[i].addabove();
|
|
|
|
things[i].startexplode("shears");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "magiccarpet":
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (things[i].type == "cat") things[i].gotfez = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
game.dirty = true;
|
|
|
|
|
|
|
|
// mark bag as collected
|
|
|
|
bag.prize = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
function getbagaty(gridy) {
|
|
|
|
var i;
|
|
|
|
if (game.levels[curlevel].bags != undefined) {
|
|
|
|
for (i = 0; i < game.levels[curlevel].bags.length; i++) {
|
|
|
|
if (game.levels[curlevel].bags[i].y == gridy) {
|
|
|
|
return game.levels[curlevel].bags[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
function getrandomtype() {
|
2016-08-22 19:52:15 +10:00
|
|
|
var roll,tot,type = null,i;
|
|
|
|
var thinglist,maxroll = 0;
|
2016-08-23 01:13:47 +10:00
|
|
|
var speciallist = null;
|
2016-08-31 13:55:35 +10:00
|
|
|
var dodb = false;
|
2016-09-04 11:47:42 +10:00
|
|
|
var goalthings;
|
2016-08-21 11:31:19 +10:00
|
|
|
|
|
|
|
if (curlevel >= game.levels.length) {
|
|
|
|
thinglist = null;
|
2016-08-19 17:46:39 +10:00
|
|
|
} else {
|
2016-08-21 11:31:19 +10:00
|
|
|
thinglist = game.levels[curlevel].thinglist;
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
|
2016-08-23 01:13:47 +10:00
|
|
|
// construct a list of permitted special things
|
2016-09-03 10:52:03 +10:00
|
|
|
var poss = [ "door", "sunlight", "toad", "whitecat", "curtain" ] ;
|
2016-08-23 01:13:47 +10:00
|
|
|
for (i in poss ) {
|
|
|
|
if (!game.isbanned(curlevel, poss[i])) {
|
|
|
|
if (speciallist == undefined) {
|
|
|
|
speciallist = [];
|
|
|
|
}
|
|
|
|
speciallist.push(poss[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
//if (dodb) console.log("speciallist is " + speciallist);
|
2016-08-23 01:13:47 +10:00
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
// normally we use default chances for objects, but some levels
|
|
|
|
// have special pre-defined chances.
|
2016-08-21 11:31:19 +10:00
|
|
|
if (thinglist == undefined || thinglist.length == 0) {
|
2016-08-22 19:52:15 +10:00
|
|
|
var f;
|
|
|
|
thinglist = new Array();
|
|
|
|
|
2016-08-21 11:31:19 +10:00
|
|
|
// default thinglist
|
2016-08-22 19:52:15 +10:00
|
|
|
// must be sorted from low to high!
|
2016-08-30 19:46:40 +10:00
|
|
|
//if (!game.isbanned(curlevel, 'door')) thinglist.push({ type: 'door', pct: 10 } );
|
2016-08-23 01:13:47 +10:00
|
|
|
if (speciallist != undefined) {
|
2016-08-30 14:55:26 +10:00
|
|
|
if (dodb) console.log("specials are possible");
|
|
|
|
thinglist.push({ type: 'special', pct: 5 } );
|
2016-08-23 01:13:47 +10:00
|
|
|
}
|
2016-09-03 10:52:03 +10:00
|
|
|
if (!game.isbanned(curlevel, 'box')) thinglist.push({ type: 'box', pct: 5 } );
|
2016-09-04 11:47:42 +10:00
|
|
|
if (!game.isbanned(curlevel, 'goat')) thinglist.push({ type: 'goat', pct: 12 } );
|
|
|
|
if (!game.isbanned(curlevel, 'llama')) thinglist.push({ type: 'llama', pct: 10 } );
|
2016-08-23 01:13:47 +10:00
|
|
|
if (!game.isbanned(curlevel, 'food')) thinglist.push({ type: 'food', pct: 40 } );
|
|
|
|
if (!game.isbanned(curlevel, 'cat')) thinglist.push({ type: 'cat', pct: 45 } );
|
2016-08-21 11:31:19 +10:00
|
|
|
}
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
goalthings = [];
|
2016-08-30 19:46:40 +10:00
|
|
|
|
2016-08-30 17:19:28 +10:00
|
|
|
// increase the chance of something appearing if
|
|
|
|
// a. it's a goal
|
|
|
|
// b. we don't have any
|
|
|
|
if (game.state == "running") {
|
|
|
|
var n;
|
|
|
|
for (i = 0; i < thinglist.length; i++) {
|
|
|
|
for (n = 0 ; n < game.levels[curlevel].goals.length; n++ ) {
|
2016-08-30 19:46:40 +10:00
|
|
|
var matchesgoal = false;
|
|
|
|
var thingtype = thinglist[i].type
|
|
|
|
var goaltype = game.levels[curlevel].goals[n].type;
|
|
|
|
var lookforthing;
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
if (goaltype == "ambush") {
|
|
|
|
goaltype = "box"; // need 'box' objects for this
|
|
|
|
}
|
|
|
|
|
2016-08-30 19:46:40 +10:00
|
|
|
if (game.levels[curlevel].goals[n].progress < game.levels[curlevel].goals[n].count) {
|
|
|
|
if (goaltype == thingtype) {
|
|
|
|
matchesgoal = true;
|
|
|
|
lookforthing = thingtype;
|
|
|
|
} else if ((thingtype == "special") &&
|
|
|
|
speciallist.indexOf(goaltype) != -1) {
|
|
|
|
// change it.
|
|
|
|
lookforthing = goaltype;
|
|
|
|
matchesgoal = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (matchesgoal) {
|
2016-08-30 17:19:28 +10:00
|
|
|
var count;
|
2016-08-31 13:55:35 +10:00
|
|
|
if (dodb) console.log("****** " + thingtype + " matches goal.");
|
2016-08-30 17:19:28 +10:00
|
|
|
// check if any exist
|
2016-08-30 19:46:40 +10:00
|
|
|
count = countalivethingsoftype(lookforthing);
|
2016-08-30 17:19:28 +10:00
|
|
|
if (count <= 1) {
|
2016-08-30 19:46:40 +10:00
|
|
|
console.log("****** no things of type " + lookforthing);
|
2016-09-04 11:47:42 +10:00
|
|
|
|
2016-08-30 17:19:28 +10:00
|
|
|
// extra chance!
|
2016-09-04 11:47:42 +10:00
|
|
|
//thinglist[i].pct *= goalbooster;
|
|
|
|
|
|
|
|
game.goalbooster += 15;
|
|
|
|
if (thinglist[i].pct < game.goalbooster) thinglist[i].pct = game.goalbooster;
|
|
|
|
console.log("extra chance of " + thingtype + "(" + lookforthing + ") - " + game.goalbooster);
|
2016-09-03 10:52:03 +10:00
|
|
|
dodb = true;
|
2016-09-04 11:47:42 +10:00
|
|
|
goalthings.push(thingtype);
|
2016-08-30 19:46:40 +10:00
|
|
|
|
|
|
|
// if the thing in question is 'special',
|
|
|
|
// cheat on the random check later to make sure we
|
|
|
|
// only get the right kind of special thing.
|
|
|
|
if (thingtype == "special") {
|
|
|
|
speciallist.splice(0, speciallist.length);
|
|
|
|
speciallist.push(goaltype);
|
|
|
|
}
|
2016-08-30 17:19:28 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-21 11:31:19 +10:00
|
|
|
for (i = 0; i < thinglist.length; i++) {
|
2016-08-22 19:52:15 +10:00
|
|
|
maxroll += thinglist[i].pct;
|
2016-08-23 01:13:47 +10:00
|
|
|
//console.log(thinglist[i].type + ": " + thinglist[i].pct + " [" + maxroll + "]");
|
2016-08-25 16:49:54 +10:00
|
|
|
}
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
if (dodb) {
|
|
|
|
for (i = 0; i < thinglist.length; i++) {
|
2016-08-31 13:55:35 +10:00
|
|
|
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);
|
2016-08-30 14:55:26 +10:00
|
|
|
}
|
2016-08-21 11:31:19 +10:00
|
|
|
}
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
roll = rnd(maxroll);
|
|
|
|
tot = 0;
|
2016-08-21 11:31:19 +10:00
|
|
|
for (i = 0; i < thinglist.length; i++) {
|
2016-08-22 19:52:15 +10:00
|
|
|
tot += thinglist[i].pct;
|
|
|
|
if (roll <= tot) {
|
2016-08-30 14:55:26 +10:00
|
|
|
if (dodb) console.log("rolled " + roll + "/" + maxroll + " --> " + thinglist[i].type + " [<= " + tot + "]");
|
2016-08-23 01:13:47 +10:00
|
|
|
|
2016-08-21 11:31:19 +10:00
|
|
|
type = thinglist[i].type;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-05 14:22:21 +10:00
|
|
|
if (goalthings.indexOf(type) != -1) {
|
|
|
|
console.log("got type '" + type + "' - goalthing is '" + goalthings + "' - resetting goalbooster");
|
2016-09-04 11:47:42 +10:00
|
|
|
game.goalbooster = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-23 01:13:47 +10:00
|
|
|
if (type == null || type == undefined) {
|
2016-08-22 19:52:15 +10:00
|
|
|
console.log("couldn't find type! roll is " + roll);
|
2016-08-21 11:31:19 +10:00
|
|
|
type = 'cat';
|
2016-08-23 01:13:47 +10:00
|
|
|
} else if (type == "special") {
|
|
|
|
// pick from list of specials
|
|
|
|
type = speciallist[rnd(speciallist.length)];
|
2016-08-18 16:18:35 +10:00
|
|
|
}
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
function coord(x,y) {
|
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
function thing(gridx, gridy, type, text, col) {
|
2016-08-20 11:17:22 +10:00
|
|
|
this.opacity = 1.0;
|
2016-08-23 01:13:47 +10:00
|
|
|
this.isnew = true;
|
2016-08-30 14:55:26 +10:00
|
|
|
this.matched = false; // temp for 'match3' things
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
this.boxfull = false; // for box objects
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
this.gotfez = false; // for powerups
|
2016-08-31 13:55:35 +10:00
|
|
|
this.slashes = []; // drawing slashes on bricks when damaged
|
|
|
|
// list x,y coords. 0=x1 1=y2 3=x2 4=y2 etc.
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-31 15:19:51 +10:00
|
|
|
this.lastx = []; // for firework trails
|
|
|
|
this.lasty = [];
|
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
if (type == "random") {
|
|
|
|
type = getrandomtype();
|
2016-08-31 13:55:35 +10:00
|
|
|
//console.log("got random type "+ type);
|
2016-08-23 01:13:47 +10:00
|
|
|
}
|
|
|
|
// used for various things
|
|
|
|
if (type == "sunlight") {
|
|
|
|
this.counter = 1;
|
|
|
|
} else {
|
|
|
|
this.counter = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (type == undefined) {
|
|
|
|
console.log("type is now " + type);
|
|
|
|
debugger;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (text == undefined) {
|
|
|
|
this.name = type + "-" + getrandomname();
|
|
|
|
} else {
|
|
|
|
this.name = text;
|
2016-08-18 16:18:35 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
this.type = type;
|
2016-08-29 19:24:29 +10:00
|
|
|
|
2016-08-31 17:45:15 +10:00
|
|
|
if (this.type == "cat") {
|
|
|
|
this.catcol = rnd(game.levels[curlevel].catcols);
|
2016-09-02 11:48:48 +10:00
|
|
|
//console.log("added cat with col = " + this.catcol + " / " + game.levels[curlevel].catcols);
|
2016-08-31 17:45:15 +10:00
|
|
|
} else {
|
|
|
|
this.catcol = null;
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
if (col == undefined) {
|
|
|
|
switch (this.type) {
|
|
|
|
case "cat":
|
|
|
|
this.color = "#b5dea8";
|
|
|
|
break;
|
|
|
|
case "food":
|
|
|
|
this.color = "#d8db03";
|
|
|
|
break;
|
|
|
|
case "llama":
|
|
|
|
this.color = "#cccccc";
|
|
|
|
break;
|
|
|
|
case "text":
|
|
|
|
// default, might ver overridden
|
|
|
|
if (this.name.indexOf("x") == 0) {
|
|
|
|
this.color = "#00dddd";
|
|
|
|
} else {
|
|
|
|
this.color = "#00cc00";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default: // should never happen
|
|
|
|
this.color = getrandomcolour();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.color = col;
|
2016-08-18 16:18:35 +10:00
|
|
|
}
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
if (this.type == "text") {
|
2016-08-23 01:13:47 +10:00
|
|
|
if (this.name.indexOf("x") == 0) {
|
|
|
|
this.size = TEXTSIZEMULTIPLIER;
|
|
|
|
} else {
|
|
|
|
this.size = TEXTSIZE;
|
|
|
|
}
|
2016-08-31 15:19:51 +10:00
|
|
|
} else if (this.type == "firework") {
|
|
|
|
this.size = FIREWORKSIZE;
|
2016-08-20 11:17:22 +10:00
|
|
|
} else {
|
|
|
|
this.size = THINGSIZE;
|
|
|
|
}
|
|
|
|
this.lifetime = 0;
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
if (this.type == "brick") {
|
|
|
|
this.hp = BRICKHP;
|
2016-09-02 11:48:48 +10:00
|
|
|
} else if (this.type == "curtain") {
|
|
|
|
this.hp = CURTAINHP;
|
2016-08-31 13:55:35 +10:00
|
|
|
} else {
|
|
|
|
this.hp = -1;
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-09-02 11:48:48 +10:00
|
|
|
this.init = function() {
|
|
|
|
if (this.type == "brick") {
|
|
|
|
this.hp = BRICKHP;
|
|
|
|
} else if (this.type == "curtain") {
|
|
|
|
this.hp = CURTAINHP;
|
|
|
|
} else {
|
|
|
|
this.hp = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
this.gridx = gridx;
|
|
|
|
if (gridy == "top") {
|
2016-08-19 17:46:39 +10:00
|
|
|
var i;
|
2016-08-18 14:14:48 +10:00
|
|
|
highest = 999;
|
|
|
|
// find highest
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
if ((things[i].gridx == gridx) &&
|
2016-08-18 14:54:54 +10:00
|
|
|
(things[i].gridy <= highest)) {
|
|
|
|
highest = things[i].gridy-1;
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
gridy = highest;
|
|
|
|
//console.log("adding thing at gridy = " + gridy);
|
|
|
|
}
|
2016-08-18 14:54:54 +10:00
|
|
|
this.gridy = gridy;
|
2016-08-30 14:55:26 +10:00
|
|
|
|
2016-08-31 15:19:51 +10:00
|
|
|
this.delay = 0; // for fireworks
|
|
|
|
|
2016-08-30 17:19:28 +10:00
|
|
|
this.expcount = 0;
|
|
|
|
this.expfadespeed = 0;
|
|
|
|
this.expmax = 0;
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
if (this.type == "bagpop") {
|
|
|
|
this.yspeed = 0 - rndfloat(8);
|
|
|
|
this.xspeed = 0 - rndfloat(16) - 1;
|
2016-09-02 13:42:47 +10:00
|
|
|
} else if (this.type == "curtainfall") {
|
|
|
|
this.yspeed = 0 - rndfloat(8);
|
|
|
|
this.xspeed = rndfloat(8) - 4;
|
2016-08-31 13:55:35 +10:00
|
|
|
} else if (this.type == "brickpop") {
|
|
|
|
this.yspeed = 0 - rndfloat(8);
|
|
|
|
this.xspeed = rndfloat(32) - 16;
|
2016-08-31 15:19:51 +10:00
|
|
|
} else if (this.type == "firework") {
|
|
|
|
this.yspeed = 0 - rndfloat(16);
|
|
|
|
this.xspeed = rndfloat(16) - 8;
|
2016-08-30 14:55:26 +10:00
|
|
|
} else {
|
|
|
|
this.yspeed = 0;
|
|
|
|
this.xspeed = 0;
|
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
if (this.type == "text") {
|
|
|
|
this.state = "text";
|
2016-08-30 17:19:28 +10:00
|
|
|
} else if (this.type == "pow") {
|
|
|
|
this.state = "explode";
|
2016-08-20 12:27:15 +10:00
|
|
|
} else {
|
|
|
|
this.state = "stop";
|
|
|
|
}
|
2016-08-19 17:46:39 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
this.path = [];
|
|
|
|
this.pathspeed = PARADESPEED;
|
2016-09-02 13:42:47 +10:00
|
|
|
this.sleepy = false;
|
2016-08-20 11:17:22 +10:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-08-30 17:19:28 +10:00
|
|
|
if (this.type == "pow") {
|
|
|
|
this.expcount=1;
|
|
|
|
this.expfadespeed = EXPLODEFADESPEED/2;
|
|
|
|
this.expmax=EXPLODETICKS*2;
|
|
|
|
this.state = "explode";
|
|
|
|
this.explodereason = "pow";
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setname = function() {
|
|
|
|
this.name = type + "-" + getrandomname();
|
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
|
|
|
|
this.issleepy = function() {
|
|
|
|
if (this.type == "cat") {
|
2016-09-02 13:42:47 +10:00
|
|
|
if (this.sleepy == true) {
|
2016-08-23 01:13:47 +10:00
|
|
|
return true;
|
|
|
|
} else if (isadjacenttotype(this, "sunlight")) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.canfall = function() {
|
2016-08-31 13:55:35 +10:00
|
|
|
// doors and bricks can't fall after their initial drop
|
|
|
|
if ((this.type == "door") || (this.type == "brick")) {
|
2016-08-30 19:46:40 +10:00
|
|
|
if ((this.gridy >= 0) && (this.isnew == false)) {
|
2016-08-23 01:13:47 +10:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
this.pushpath = function(x,y) {
|
|
|
|
this.path.push(new coord(x, y));
|
|
|
|
}
|
|
|
|
|
|
|
|
this.poppath = function() {
|
|
|
|
this.path.splice(0, 1);
|
|
|
|
}
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
// are there any valid moves starting with this thing?
|
|
|
|
this.hasvalidmoves = function() {
|
|
|
|
var i,newx,newy;
|
|
|
|
|
2016-08-24 22:47:23 +10:00
|
|
|
if (this.gridy < 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
if (this.isanimating()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (this.type != "cat") {
|
2016-09-03 10:52:03 +10:00
|
|
|
if (this.type == "box" && !this.boxfull) {
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
}
|
2016-08-30 14:55:26 +10:00
|
|
|
//if (isadjacenttotype(this, "llama")) {
|
2016-09-03 10:52:03 +10:00
|
|
|
if (this.type == "cat" && this.isscared()) {
|
2016-08-20 12:27:15 +10:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// chomp
|
2016-09-03 10:52:03 +10:00
|
|
|
if (isadjacenttotype(this, "food")) {
|
|
|
|
if (this.type == "box" || !this.issleepy()) {
|
|
|
|
return true;
|
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// parade - this is the hardest to check for.
|
2016-08-22 19:52:15 +10:00
|
|
|
// check for any adjacent cats or llamas or goats
|
|
|
|
// cat: if it also has an adjacent cat/llama/goat, we're good
|
|
|
|
// llama: if it also has an adjacent cat/goat, we're good
|
2016-09-03 10:52:03 +10:00
|
|
|
if ((this.type == "cat") || (this.type == "box" && this.boxfull)) {
|
|
|
|
for (i = 0; i < MAXDIRS; i++) {
|
|
|
|
var adj;
|
|
|
|
newx = this.gridx + DIRXMOD[i];
|
|
|
|
newy = this.gridy + DIRYMOD[i];
|
|
|
|
if (isonscreen(newx, newy)) {
|
|
|
|
adj = getgridthing(newx, newy);
|
|
|
|
if (adj != undefined) {
|
|
|
|
if ((adj.type == "cat") && catcolmatches(adj,this)) {
|
|
|
|
// cat -> adjacent cat
|
|
|
|
if (isadjacenttotype(adj, "llama", this) ||
|
|
|
|
isadjacenttotype(adj, "cat", this, this.catcol) ||
|
|
|
|
isadjacenttotype(adj, "goat", this)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (isadjacenttotype(adj, "box", this, null, true)) {
|
|
|
|
// cat -> adj cat -> full box
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else if (adj.type == "goat") {
|
|
|
|
// cat -> adjacent goat
|
|
|
|
if (isadjacenttotype(adj, "llama", this) ||
|
|
|
|
isadjacenttotype(adj, "cat", this, this.catcol) ||
|
|
|
|
isadjacenttotype(adj, "goat", this)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (isadjacenttotype(adj, "box", this, null, true)) {
|
|
|
|
// cat -> adj goat -> full box
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (adj.type == "llama") {
|
|
|
|
// cat -> adjacent llama
|
|
|
|
if (isadjacenttotype(adj, "cat", this, this.catcol) ||
|
|
|
|
isadjacenttotype(adj, "goat", this)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (isadjacenttotype(adj, "box", this, null, true)) {
|
|
|
|
// cat -> llama -> full box
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else if (adj.type == "box") {
|
|
|
|
// cat -> adjacent box
|
|
|
|
if (adj.boxfull) {
|
|
|
|
// full box - can continue a parade?
|
|
|
|
if (isadjacenttotype(adj, "cat", this, this.catcol) ||
|
|
|
|
isadjacenttotype(adj, "goat", this) ||
|
|
|
|
isadjacenttotype(adj, "llama", this)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// we can enter the box.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else if (adj.type == "curtain") {
|
|
|
|
var nx2,ny2;
|
|
|
|
// next step along still on the grid?
|
|
|
|
nx2 = adj.gridx + DIRXMOD[i];
|
|
|
|
ny2 = adj.gridy + DIRYMOD[i];
|
|
|
|
if (isonscreen(nx2, ny2)) return true;
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
this.givepoints = function(pathpos) {
|
2016-08-20 11:17:22 +10:00
|
|
|
var points = 0;
|
2016-08-27 17:47:39 +10:00
|
|
|
var prestars,poststars;
|
2016-08-29 19:24:29 +10:00
|
|
|
var thismulti = 1;
|
|
|
|
var colidx = 0;
|
|
|
|
|
2016-08-27 17:47:39 +10:00
|
|
|
prestars = game.calcstars(curlevel, score);
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
if (pathpos == undefined) {
|
|
|
|
pathpos = 0;
|
|
|
|
}
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
if (this.type == "food") {
|
2016-08-20 15:12:32 +10:00
|
|
|
points = FOODPOINTS;
|
2016-08-31 13:55:35 +10:00
|
|
|
//game.progress("food", 1);
|
2016-08-20 11:17:22 +10:00
|
|
|
} else if (this.type == "llama") {
|
2016-08-20 15:12:32 +10:00
|
|
|
points = LLAMAPOINTS;
|
2016-08-31 13:55:35 +10:00
|
|
|
//game.progress("llama", 1);
|
2016-09-03 10:52:03 +10:00
|
|
|
} else if (this.type == "box") {
|
2016-09-04 11:47:42 +10:00
|
|
|
points = CATBOXPOINTS;
|
2016-08-20 11:17:22 +10:00
|
|
|
} else if (this.type == "cat") {
|
2016-08-23 01:13:47 +10:00
|
|
|
if (this.issleepy()) {
|
2016-08-20 15:12:32 +10:00
|
|
|
points = SLEEPYCATPOINTS;
|
2016-08-20 11:17:22 +10:00
|
|
|
} else {
|
2016-08-20 15:12:32 +10:00
|
|
|
points = CATPOINTS;
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
2016-08-30 14:55:26 +10:00
|
|
|
// fez multiplier
|
|
|
|
if (this.gotfez) {
|
|
|
|
points *= 2;
|
|
|
|
}
|
2016-08-31 13:55:35 +10:00
|
|
|
//game.progress("cat", 1);
|
2016-08-22 19:52:15 +10:00
|
|
|
} else if (this.type == "goat") {
|
|
|
|
points = GOATPOINTS;
|
2016-08-31 13:55:35 +10:00
|
|
|
//game.progress("goat", 1);
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
// multiplier for path position
|
|
|
|
thismulti = Math.floor((pathpos+1) / 3); // ie. 1-5=x1 6-8=x2 9-11=x3 etc
|
|
|
|
if (thismulti < 1) thismulti = 1;
|
|
|
|
|
|
|
|
// global multiplier (doors etc)
|
|
|
|
thismulti += globmulti;
|
2016-08-30 14:55:26 +10:00
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
|
|
|
|
points *= thismulti;
|
2016-08-23 01:13:47 +10:00
|
|
|
|
|
|
|
if (points > 0) {
|
2016-08-29 19:24:29 +10:00
|
|
|
//console.log("scoring " + points + " points for " + this.name + "(globmulti is " + thismulti + ")" );
|
2016-08-23 01:13:47 +10:00
|
|
|
score += points;
|
2016-08-29 19:24:29 +10:00
|
|
|
//game.progress("points", points);
|
2016-08-23 01:13:47 +10:00
|
|
|
|
|
|
|
// add animation
|
2016-08-29 19:24:29 +10:00
|
|
|
colidx = thismulti;
|
|
|
|
if (colidx > (scorecols.length-1)) colidx = scorecols.length-1;
|
|
|
|
things.push(new thing(this.gridx, this.gridy, "text", "+" + points, scorecols[colidx]));
|
|
|
|
|
2016-08-27 17:47:39 +10:00
|
|
|
|
|
|
|
poststars = game.calcstars(curlevel, score);
|
|
|
|
if (poststars != prestars) {
|
|
|
|
// regenerate star colors at top, if required
|
|
|
|
game.generatestargoalbanner();
|
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
this.isscared = function() {
|
|
|
|
if (this.type != "cat") return false;
|
|
|
|
if (this.isanimating()) return false;
|
|
|
|
|
|
|
|
if (isadjacenttotype(this, "llama")) {
|
|
|
|
if (!this.gotfez) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
this.getdesc = function() {
|
|
|
|
var desc = "";
|
|
|
|
if (this.type == "cat") {
|
2016-09-12 09:03:02 +10:00
|
|
|
var noun ="cat";
|
|
|
|
if (this.catcol == 1) {
|
|
|
|
noun = "mouse";
|
|
|
|
}
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
if (this.isscared()) {
|
2016-08-23 01:13:47 +10:00
|
|
|
if (this.issleepy() == true) {
|
2016-09-12 09:03:02 +10:00
|
|
|
desc = "scared sleepy " + noun;
|
2016-08-20 11:34:25 +10:00
|
|
|
} else {
|
2016-09-12 09:03:02 +10:00
|
|
|
desc = "scared " + noun;
|
2016-08-20 11:34:25 +10:00
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
} else if (this.issleepy() == true) {
|
2016-09-12 09:03:02 +10:00
|
|
|
desc = "sleepy " + noun;
|
2016-08-20 11:17:22 +10:00
|
|
|
} else {
|
2016-09-12 09:03:02 +10:00
|
|
|
desc = noun;
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
|
|
|
} 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;
|
|
|
|
}
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
// z is just used for drawing front/back of boxes
|
|
|
|
this.draw = function(z) {
|
2016-08-18 14:14:48 +10:00
|
|
|
var yoff;
|
2016-08-18 14:54:54 +10:00
|
|
|
var inpath = false;
|
2016-08-20 11:17:22 +10:00
|
|
|
var howbig,myx,myy;
|
2016-08-30 14:55:26 +10:00
|
|
|
var fhowbig,fw,fh,fx,fy;
|
2016-08-18 14:54:54 +10:00
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
//ctx = game.context;
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-31 15:19:51 +10:00
|
|
|
// don't draw delaying things
|
|
|
|
if (this.delay > 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
// check whether I'm in the drawn path
|
|
|
|
if (pathcontains(this)) {
|
|
|
|
inpath = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set opacity
|
2016-08-25 16:49:54 +10:00
|
|
|
if (!wipe.isactive()) {
|
|
|
|
ctx.globalAlpha = this.opacity;
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-31 15:19:51 +10:00
|
|
|
|
2016-08-18 14:54:54 +10:00
|
|
|
// draw myself
|
2016-08-20 11:17:22 +10:00
|
|
|
if (this.type == "text") {
|
|
|
|
ctx.textAlign = "center";
|
2016-08-22 19:52:15 +10:00
|
|
|
ctx.textBaseline = "middle";
|
2016-08-23 01:13:47 +10:00
|
|
|
shadowtext(ctx, this.name, this.size, this.color, BOARDX + this.x,BOARDY + this.y);
|
2016-08-31 15:19:51 +10:00
|
|
|
} else if (this.type == "firework") {
|
|
|
|
var myx,myy;
|
|
|
|
|
|
|
|
|
|
|
|
// draw trail
|
|
|
|
if (this.lastx != undefined) {
|
|
|
|
var i;
|
|
|
|
for (i = 0; i < this.lastx.length ; i++) {
|
|
|
|
var newopac = this.opacity + ((i+1)*FIREWORKFADESPEED);
|
|
|
|
var nextx,netxy;
|
|
|
|
if (newopac > 1) newopac = 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
if (i == 0) {
|
|
|
|
nextx = this.x - this.size/2;
|
|
|
|
nexty = this.y - this.size/2;
|
|
|
|
} else {
|
|
|
|
nextx = this.lastx[i-1] - this.size/2;
|
|
|
|
nexty = this.lasty[i-1] - this.size/2;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
myx = this.lastx[i] - this.size/2;
|
|
|
|
myy = this.lasty[i] - this.size/2;
|
|
|
|
|
|
|
|
//console.log("fw line: " + myx + "," + myy + " -> " + nextx + "," + nexty);
|
|
|
|
|
|
|
|
ctx.globalAlpha = newopac;
|
|
|
|
ctx.fillStyle = this.color;
|
|
|
|
ctx.lineWidth = this.size;
|
|
|
|
ctx.fillRect(BOARDX + myx, BOARDY + myy, this.size, this.size);
|
|
|
|
/*
|
|
|
|
drawline(ctx, BOARDX + myx, BOARDY + myy,
|
|
|
|
BOARDX + nextx, BOARDY + nexty,
|
|
|
|
this.col, this.size);
|
|
|
|
*/
|
|
|
|
ctx.globalAlpha = 1.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
myx = this.x - this.size/2;
|
|
|
|
myy = this.y - this.size/2;
|
|
|
|
|
|
|
|
ctx.globalAlpha = this.opacity;
|
|
|
|
ctx.fillStyle = this.color;
|
|
|
|
ctx.fillRect(BOARDX + myx, BOARDY + myy, this.size, this.size);
|
|
|
|
ctx.globalAlpha = 1.0;
|
2016-08-20 11:17:22 +10:00
|
|
|
} else {
|
2016-09-03 10:52:03 +10:00
|
|
|
var myimage,myimage2 = null;
|
2016-08-20 11:17:22 +10:00
|
|
|
if (this.type == "cat") {
|
2016-08-31 17:45:15 +10:00
|
|
|
var imgname;
|
2016-08-24 22:47:23 +10:00
|
|
|
if (this.state == "parade") {
|
2016-08-31 17:45:15 +10:00
|
|
|
imgname = 'cat';
|
2016-08-30 14:55:26 +10:00
|
|
|
} else if (this.isscared()) {
|
2016-08-31 17:45:15 +10:00
|
|
|
imgname = 'catscared';
|
2016-08-23 01:13:47 +10:00
|
|
|
} else if (this.issleepy() == true) {
|
2016-08-31 17:45:15 +10:00
|
|
|
imgname = 'catfull';
|
2016-08-20 11:17:22 +10:00
|
|
|
} else {
|
2016-08-31 17:45:15 +10:00
|
|
|
imgname = 'cat';
|
|
|
|
}
|
|
|
|
if (this.catcol > 0) {
|
|
|
|
// ie. catfull1, catfull2 etc
|
|
|
|
imgname = imgname + this.catcol;
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
2016-08-31 17:45:15 +10:00
|
|
|
myimage = image[imgname];
|
2016-09-03 10:52:03 +10:00
|
|
|
} else if (this.type == "box") {
|
|
|
|
if (z == 0) {
|
|
|
|
var imgname2;
|
|
|
|
imgname = 'boxback';
|
|
|
|
if (this.boxfull) {
|
|
|
|
imgname2 = 'cat';
|
|
|
|
if (this.catcol > 0) {
|
|
|
|
imgname2 = imgname2 + this.catcol;
|
|
|
|
}
|
|
|
|
myimage2 = image[imgname2];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
imgname = 'boxfront';
|
|
|
|
}
|
|
|
|
myimage = image[imgname];
|
2016-09-02 11:48:48 +10:00
|
|
|
} else if (this.type == "curtain") {
|
|
|
|
if (this.hp == CURTAINHP) {
|
|
|
|
imgname = 'curtain';
|
|
|
|
} else {
|
|
|
|
imgname = 'curtainshred';
|
|
|
|
}
|
|
|
|
myimage = image[imgname];
|
2016-08-20 11:17:22 +10:00
|
|
|
} else if (this.type == "food") {
|
|
|
|
myimage = image['cheese'];
|
2016-08-23 01:13:47 +10:00
|
|
|
} else {
|
2016-08-31 13:55:35 +10:00
|
|
|
myimage = image[this.type];
|
|
|
|
}
|
|
|
|
if (myimage == undefined || myimage == null) {
|
2016-08-23 01:13:47 +10:00
|
|
|
console.log("ERROR - no image for type " + this.type);
|
|
|
|
console.log(this);
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
|
|
|
howbig = this.size;
|
2016-08-30 14:55:26 +10:00
|
|
|
fw = (image['fez'].width / myimage.width) * this.size;
|
|
|
|
fh = (image['fez'].height / myimage.height) * this.size;
|
2016-08-20 11:17:22 +10:00
|
|
|
myx = this.x;
|
|
|
|
myy = this.y;
|
2016-08-30 14:55:26 +10:00
|
|
|
|
|
|
|
fx = (this.gridx * GRIDSIZE) + (GRIDSIZE/2) - (fw/2);
|
|
|
|
fy = this.y;
|
2016-08-20 11:17:22 +10:00
|
|
|
if (inpath) {
|
|
|
|
var growpct = 50;
|
2016-08-30 14:55:26 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
howbig = howbig * ((100+growpct) / 100);
|
|
|
|
myx -= (growpct/2/100) * this.size;
|
|
|
|
myy -= (growpct/2/100) * this.size;
|
2016-08-30 14:55:26 +10:00
|
|
|
|
|
|
|
fw = fw * ((100+growpct) / 100);
|
|
|
|
fh = fh * ((100+growpct) / 100);
|
|
|
|
|
|
|
|
fx = (this.gridx * GRIDSIZE) + (GRIDSIZE/2) - (fw/2);
|
|
|
|
fy -= (growpct/2/100) * this.size;
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
/* hilight non-snapped things
|
|
|
|
var snapto = Math.floor((this.gridy * GRIDSIZE) + (GRIDSIZE/2) - (howbig/2));
|
|
|
|
if (myy != snapto) {
|
|
|
|
console.log("not aligned");
|
|
|
|
ctx.fillStyle = "green";
|
|
|
|
ctx.fillRect(BOARDX + myx, BOARDY + myy, howbig, howbig);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
ctx.drawImage(myimage, BOARDX + myx, BOARDY + myy, howbig, howbig);
|
2016-09-03 10:52:03 +10:00
|
|
|
if (myimage2 != undefined) {
|
|
|
|
ctx.drawImage(myimage2, BOARDX + myx, BOARDY + myy, howbig, howbig);
|
|
|
|
}
|
2016-08-30 14:55:26 +10:00
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
// draw slashes on bricks
|
|
|
|
drawslashes(ctx, BOARDX + myx, BOARDY + myy, this.slashes);
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
if (this.gotfez) {
|
|
|
|
// fw = 0.78 * howbig;
|
|
|
|
// fh = 0.625 * howbig;
|
|
|
|
|
|
|
|
|
|
|
|
// centre
|
|
|
|
//fx = BOARDX + (this.gridx * GRIDSIZE) + (GRIDSIZE/2) - (fw/2);
|
|
|
|
//fy = BOARDY + (this.gridy * GRIDSIZE) + (fh/6);
|
|
|
|
|
|
|
|
ctx.drawImage(image['fez'], BOARDX + fx, BOARDY + fy, fw, fh);
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
} else {
|
|
|
|
ctx.fillStyle = this.color;
|
|
|
|
ctx.fillRect(BOARDX + this.x, BOARDY + this.y, this.size, this.size);
|
|
|
|
}
|
|
|
|
*/
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
// frozen cat?
|
2016-08-20 11:17:22 +10:00
|
|
|
/*
|
|
|
|
if ((this.type == "cat") && !this.isanimating()) {
|
2016-08-19 17:46:39 +10:00
|
|
|
if (isadjacenttotype(this, "llama")) {
|
|
|
|
// cross out
|
|
|
|
ctx.fillStyle = "red";
|
|
|
|
ctx.lineWidth = CROSSWIDTH;
|
|
|
|
ctx.strokeStyle = "red";
|
|
|
|
// NW -> SE
|
|
|
|
ctx.beginPath();
|
2016-08-20 11:17:22 +10:00
|
|
|
ctx.moveTo(BOARDX + this.x, BOARDY + this.y);
|
|
|
|
ctx.lineTo(BOARDX + this.x + this.size - 1, BOARDY + this.y + this.size - 1);
|
2016-08-19 17:46:39 +10:00
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
// SW -> NE
|
|
|
|
ctx.beginPath();
|
2016-08-20 11:17:22 +10:00
|
|
|
ctx.moveTo(BOARDX + this.x, BOARDY + this.y + this.size - 1);
|
|
|
|
ctx.lineTo(BOARDX + this.x + this.size - 1, BOARDY + this.y);
|
2016-08-19 17:46:39 +10:00
|
|
|
ctx.stroke();
|
|
|
|
}
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
*/
|
2016-08-19 17:46:39 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
// draw text on me
|
|
|
|
/*
|
|
|
|
if (this.type == "cat") {
|
|
|
|
} else if (this.type == "llama") {
|
|
|
|
} else {
|
|
|
|
ctx.fillStyle = "black";
|
|
|
|
ctx.fillText(this.name, BOARDX + this.x + 10, BOARDY + this.y + (THINGSIZE/2));
|
2016-09-02 13:42:47 +10:00
|
|
|
ctx.fillText(this.sleepy ? "FULL" : "", BOARDX + this.x + 10, BOARDY + this.y + (THINGSIZE/2) + 10);
|
2016-08-18 14:54:54 +10:00
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
*/
|
2016-08-18 14:54:54 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
// back to full opacity
|
2016-08-25 16:49:54 +10:00
|
|
|
if (!wipe.isactive()) {
|
|
|
|
ctx.globalAlpha = 1.0;
|
|
|
|
}
|
2016-08-18 14:54:54 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
/*
|
2016-08-19 17:46:39 +10:00
|
|
|
// path outline
|
2016-08-20 11:17:22 +10:00
|
|
|
if (inpath && this.state != "parade" && this.state != "explode") {
|
2016-08-18 14:54:54 +10:00
|
|
|
ctx.beginPath();
|
2016-08-19 17:46:39 +10:00
|
|
|
ctx.lineWidth = 1;
|
|
|
|
ctx.fillStyle = "black";
|
|
|
|
// outline it
|
2016-08-18 16:18:35 +10:00
|
|
|
if (pathvalid) {
|
|
|
|
ctx.strokeStyle = "green";
|
|
|
|
} else {
|
|
|
|
ctx.strokeStyle = "red";
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
ctx.rect(BOARDX + this.x, BOARDY + this.y, this.size, this.size);
|
2016-08-18 14:54:54 +10:00
|
|
|
ctx.stroke();
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
*/
|
2016-08-18 14:54:54 +10:00
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
|
|
|
|
2016-08-18 16:18:35 +10:00
|
|
|
this.issametype = function(otherthing) {
|
|
|
|
if (otherthing == undefined) return false;
|
|
|
|
if (otherthing.type == this.type) return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// return TRUE if we did something
|
2016-08-18 14:14:48 +10:00
|
|
|
this.snaptogrid = function() {
|
2016-08-25 16:49:54 +10:00
|
|
|
var moved = false;
|
|
|
|
var snaptox = Math.floor(this.gridx * GRIDSIZE + (GRIDSIZE/2) - (this.size/2));
|
|
|
|
var snaptoy = Math.floor(this.gridy * GRIDSIZE + (GRIDSIZE/2) - (this.size/2));
|
2016-08-26 10:31:09 +10:00
|
|
|
|
2016-08-27 13:48:41 +10:00
|
|
|
if (this.isanimating()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-26 10:31:09 +10:00
|
|
|
if (this.state != "fall" && this.state != "stop") {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
//var snapto = (GRIDSIZE + (GRIDSIZE/2) - (THINGSIZE/2);
|
|
|
|
//if (this.y % (GRIDSIZE + (GRIDSIZE/2) - (THINGSIZE/2)) != 0) {
|
2016-08-25 16:49:54 +10:00
|
|
|
//if (this.y % snapto != 0) {
|
|
|
|
if (this.y != snaptoy) {
|
|
|
|
this.y = snaptoy;
|
|
|
|
var moved = true;
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
2016-08-25 16:49:54 +10:00
|
|
|
if (this.x != snaptox) {
|
|
|
|
this.x = snaptox;
|
|
|
|
var moved = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return moved;
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
this.getstoppedbelowthing = function() {
|
2016-09-02 13:42:47 +10:00
|
|
|
var bt,i;
|
2016-08-18 14:14:48 +10:00
|
|
|
bt = getgridthing(this.gridx, this.gridy + 1);
|
|
|
|
if (bt && bt.state != "fall") {
|
|
|
|
return bt;
|
|
|
|
}
|
2016-09-02 13:42:47 +10:00
|
|
|
// look for things movng to the place below.
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
if (things[i] != this && things[i].state == "swapping" && things[i].path != undefined) {
|
|
|
|
var n;
|
|
|
|
for (n = 0; n < things[i].path.length; n++) {
|
|
|
|
var gx,gy;
|
|
|
|
gx = Math.floor(things[i].path[n].x / GRIDSIZE);
|
|
|
|
gy = Math.floor(things[i].path[n].y / GRIDSIZE);
|
|
|
|
// get grid coords
|
|
|
|
if (gx == this.gridx && gy == this.gridy + 1) {
|
|
|
|
return things[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
this.addabove = function() {
|
2016-08-18 14:14:48 +10:00
|
|
|
// add a new cat above us
|
2016-08-18 16:18:35 +10:00
|
|
|
things.push(new thing(this.gridx, "top", "random"));
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
this.kill = function() {
|
2016-08-18 14:14:48 +10:00
|
|
|
// kill ourselves
|
2016-08-31 13:55:35 +10:00
|
|
|
game.progress(this.type, 1);
|
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
var idx = things.indexOf(this);
|
|
|
|
things.splice(idx, 1);
|
|
|
|
}
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
this.updatexy = function() {
|
|
|
|
this.x = this.gridx * GRIDSIZE + (GRIDSIZE/2) - (THINGSIZE/2);
|
|
|
|
this.y = this.gridy * GRIDSIZE + (GRIDSIZE/2) - (THINGSIZE/2);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setgridxy = function(x,y) {
|
|
|
|
this.gridx = x;
|
|
|
|
this.gridy = y;
|
|
|
|
this.updatexy();
|
|
|
|
}
|
|
|
|
|
2016-08-30 17:19:28 +10:00
|
|
|
this.slap = function(toad) {
|
|
|
|
var origgx,origgy;
|
|
|
|
// remember cat loc
|
|
|
|
origgx = this.gridx;
|
|
|
|
origgy = this.gridy;
|
|
|
|
|
|
|
|
|
|
|
|
// add new object above cat location
|
|
|
|
//this.addabove();
|
|
|
|
// move cat to toad location
|
|
|
|
//this.setgridxy(toad.gridx,toad.gridy);
|
|
|
|
|
|
|
|
// add new object above toad location
|
|
|
|
toad.addabove();
|
|
|
|
|
|
|
|
// toad falls down, smashing everything under it
|
|
|
|
toad.state = "slapped";
|
|
|
|
|
|
|
|
// add "pow"
|
|
|
|
things.push(new thing(toad.gridx, toad.gridy, "pow"));
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
//game.progress("toad", 1);
|
2016-08-30 17:19:28 +10:00
|
|
|
|
|
|
|
console.log("slap");
|
|
|
|
}
|
|
|
|
|
|
|
|
this.attack = function(whitecat) {
|
|
|
|
var i,adj;
|
|
|
|
|
|
|
|
// add new object above cat location
|
|
|
|
//this.addabove();
|
|
|
|
// move cat to toad location
|
|
|
|
//this.setgridxy(toad.gridx,toad.gridy);
|
|
|
|
|
|
|
|
for (i = 0; i < MAXDIAGDIRS; i++) {
|
|
|
|
var newx,newy;
|
|
|
|
newx = whitecat.gridx + DIAGDIRXMOD[i];
|
|
|
|
newy = whitecat.gridy + DIAGDIRYMOD[i];
|
|
|
|
adj = getgridthing(newx, newy);
|
|
|
|
if (adj != undefined) {
|
|
|
|
adj.addabove();
|
|
|
|
adj.givepoints();
|
|
|
|
adj.startexplode();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// add "pow"
|
|
|
|
things.push(new thing(whitecat.gridx, whitecat.gridy, "pow"));
|
|
|
|
|
|
|
|
// whitecat itself goes too.
|
|
|
|
whitecat.addabove();
|
|
|
|
whitecat.startexplode();
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
//game.progress("whitecat", 1);
|
2016-08-30 17:19:28 +10:00
|
|
|
|
|
|
|
console.log("whitecat");
|
|
|
|
}
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
this.chomp = function(food) {
|
|
|
|
var origgx,origgy;
|
|
|
|
// remember cat loc
|
|
|
|
origgx = this.gridx;
|
|
|
|
origgy = this.gridy;
|
2016-08-20 11:17:22 +10:00
|
|
|
|
|
|
|
// add new object above cat location
|
|
|
|
this.addabove();
|
2016-08-19 17:46:39 +10:00
|
|
|
|
|
|
|
// move cat to food location
|
|
|
|
this.setgridxy(food.gridx,food.gridy);
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
// move food to cat location (so new object will
|
|
|
|
// be added in the correct column.
|
2016-08-20 11:17:22 +10:00
|
|
|
//food.setgridxy(origgx, origgy);
|
2016-08-19 17:46:39 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
// make food explode
|
|
|
|
//food.addabove();
|
|
|
|
//food.kill();
|
2016-08-30 14:55:26 +10:00
|
|
|
food.startexplode("chomp");
|
2016-08-19 17:46:39 +10:00
|
|
|
|
|
|
|
// mark that we've eaten something
|
2016-09-03 10:52:03 +10:00
|
|
|
if (this.type == "cat") {
|
|
|
|
this.sleepy = true;
|
|
|
|
}
|
2016-08-19 17:46:39 +10:00
|
|
|
|
|
|
|
console.log("chomp");
|
|
|
|
}
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
this.isanimating = function() {
|
|
|
|
if (this.type == "text") return true;
|
2016-08-31 15:19:51 +10:00
|
|
|
if (this.type == "firework") return true;
|
|
|
|
if (this.type == "bagpop") return true;
|
|
|
|
if (this.type == "brickpop") return true;
|
2016-09-02 13:42:47 +10:00
|
|
|
if (this.type == "curtainfall") return true;
|
2016-08-20 11:17:22 +10:00
|
|
|
if (this.state == "explode") return true;
|
2016-08-23 01:13:47 +10:00
|
|
|
if (this.state == "shrink") return true;
|
2016-08-20 11:17:22 +10:00
|
|
|
if (this.state == "parade") return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-09-02 13:42:47 +10:00
|
|
|
this.shredcurtain = function() {
|
|
|
|
var i,nshards = 7;
|
|
|
|
for (i = 0; i < nshards; i++) {
|
|
|
|
things.push(new thing(this.gridx, this.gridy, "curtainfall"));
|
|
|
|
}
|
|
|
|
|
|
|
|
this.givepoints();
|
|
|
|
this.addabove();
|
|
|
|
this.kill();
|
|
|
|
}
|
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
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--;
|
2016-09-02 11:48:48 +10:00
|
|
|
console.log(this.name + " hp is at " + this.hp);
|
2016-08-31 13:55:35 +10:00
|
|
|
if (this.hp <= 0) {
|
|
|
|
game.dirty = true; // need to redraw
|
2016-09-02 11:48:48 +10:00
|
|
|
if (this.type == "brick") {
|
|
|
|
this.breakbrick();
|
|
|
|
} else {
|
2016-09-02 13:42:47 +10:00
|
|
|
this.shredcurtain();
|
2016-09-02 11:48:48 +10:00
|
|
|
}
|
2016-08-31 13:55:35 +10:00
|
|
|
} else {
|
|
|
|
// add a slash from a random x/y to a random x/y
|
|
|
|
addslash(this.slashes, THINGSIZE, THINGSIZE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
this.startexplode = function(why) {
|
2016-08-31 13:55:35 +10:00
|
|
|
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;
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
|
|
|
|
2016-08-23 01:13:47 +10:00
|
|
|
this.startshrink = function() {
|
|
|
|
this.expcount=1;
|
|
|
|
this.expmax=SHRINKTICKS;
|
|
|
|
this.state = "shrink";
|
2016-08-30 14:55:26 +10:00
|
|
|
this.xspeed = 0;
|
|
|
|
this.yspeed = 0;
|
2016-08-23 01:13:47 +10:00
|
|
|
}
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
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;
|
2016-08-23 01:13:47 +10:00
|
|
|
if (pathdoor != undefined) {
|
|
|
|
// we're at a door. vanish.
|
|
|
|
this.pushpath(-1, -1);
|
|
|
|
} else {
|
|
|
|
// 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));
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
} else {
|
|
|
|
this.pushpath(curpath[nextidx].x, curpath[nextidx].y);
|
|
|
|
}
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
//console.log("Starting parade: " + this.name + " path len is [" + this.path.length + "]");
|
2016-08-20 11:17:22 +10:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
this.move = function() {
|
|
|
|
// not at bottom and nothing fixed below us?
|
|
|
|
var dofall = false;
|
|
|
|
var belowthing = null,atbottom = false;
|
|
|
|
|
2016-08-31 15:19:51 +10:00
|
|
|
if (this.type == "firework" && this.delay > 0) {
|
|
|
|
this.delay--;
|
2016-09-02 13:42:47 +10:00
|
|
|
} else if ((this.type == "bagpop") || (this.type == "brickpop") || (this.type == "firework") || (this.type == "curtainfall")) {
|
2016-08-30 14:55:26 +10:00
|
|
|
game.dirty = true; // need to redraw
|
|
|
|
|
|
|
|
// regular gravity
|
2016-08-31 15:19:51 +10:00
|
|
|
if (this.type == "firework") {
|
|
|
|
if (this.y >= SCREENH) {
|
|
|
|
atbottom = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((this.gridy >= GRIDH-1)) {
|
|
|
|
atbottom = true;
|
|
|
|
}
|
2016-08-30 14:55:26 +10:00
|
|
|
}
|
|
|
|
if (!atbottom) {
|
|
|
|
game.dirty = true; // need to redraw
|
|
|
|
// accelerate
|
|
|
|
this.yspeed += GRAVITY;
|
|
|
|
|
2016-08-31 15:19:51 +10:00
|
|
|
// remember previous positions
|
|
|
|
if (this.type == "firework") {
|
|
|
|
// add current position to trail
|
|
|
|
this.lastx.push(this.x);
|
|
|
|
this.lasty.push(this.y);
|
|
|
|
|
|
|
|
// remove old positions from trail
|
|
|
|
while (this.lastx.length >= FIREWORKTRAILLEN) {
|
|
|
|
this.lastx.splice(0, 1);
|
|
|
|
}
|
|
|
|
while (this.lasty.length >= FIREWORKTRAILLEN) {
|
|
|
|
this.lasty.splice(0, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
// move
|
|
|
|
this.y += this.yspeed;
|
|
|
|
this.x += this.xspeed;
|
|
|
|
|
|
|
|
// don't go below bottom of screen
|
2016-08-31 15:19:51 +10:00
|
|
|
if (this.type == "firework") {
|
|
|
|
if (this.y >= SCREENH) {
|
|
|
|
atbottom = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (this.y > GRIDSIZE * GRIDH) {
|
|
|
|
atbottom = true;
|
|
|
|
}
|
2016-08-30 14:55:26 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// calc new gridx / gridy
|
|
|
|
this.calcgridxy();
|
|
|
|
|
2016-08-31 15:19:51 +10:00
|
|
|
if (this.type != "firework") {
|
|
|
|
if ((this.gridy >= GRIDH-1)) {
|
|
|
|
atbottom = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// fade
|
|
|
|
if (this.type == "firework") {
|
|
|
|
this.opacity -= FIREWORKFADESPEED;
|
|
|
|
if (this.opacity <= 0) {
|
|
|
|
this.opacity = 0;
|
2016-08-30 14:55:26 +10:00
|
|
|
atbottom = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (atbottom) {
|
|
|
|
this.kill();
|
|
|
|
}
|
|
|
|
} else if (this.state == "explode") {
|
2016-08-22 19:52:15 +10:00
|
|
|
game.dirty = true; // need to redraw
|
2016-08-20 11:17:22 +10:00
|
|
|
this.expcount++;
|
|
|
|
if (this.expcount >= this.expmax) {
|
|
|
|
this.kill();
|
|
|
|
} else {
|
|
|
|
// get bigger
|
|
|
|
this.size += EXPLODEGAIN;
|
2016-08-30 17:19:28 +10:00
|
|
|
this.opacity -= this.expfadespeed;
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
if (this.opacity < 0) this.opacity = 0;
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
// adjust x/y
|
|
|
|
this.x = (this.gridx * GRIDSIZE) + (GRIDSIZE/2) - (this.size/2);
|
|
|
|
this.y = (this.gridy * GRIDSIZE) + (GRIDSIZE/2) - (this.size/2);
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
2016-08-25 20:01:45 +10:00
|
|
|
} else if (this.type == "text") {
|
|
|
|
game.dirty = true; // need to redraw
|
|
|
|
// slowly move up
|
|
|
|
this.y -= TEXTSPEED;
|
|
|
|
this.lifetime++;
|
|
|
|
if (this.lifetime >= TEXTTIME) {
|
|
|
|
this.opacity -= TEXTFADESPEED;
|
|
|
|
if (this.opacity <= 0) {
|
|
|
|
this.kill();
|
|
|
|
}
|
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
} else if (this.state == "shrink") {
|
2016-08-30 14:55:26 +10:00
|
|
|
var xcutoff;
|
2016-08-23 01:13:47 +10:00
|
|
|
game.dirty = true; // need to redraw
|
|
|
|
this.expcount++;
|
|
|
|
if (this.expcount >= this.expmax) {
|
|
|
|
this.kill();
|
|
|
|
} else {
|
|
|
|
// get smaller
|
|
|
|
this.size -= SHRINKLOSE;
|
|
|
|
|
|
|
|
if (this.size < 1) this.size == 1;
|
|
|
|
|
|
|
|
// adjust x/y
|
|
|
|
this.x = (this.gridx * GRIDSIZE) + (GRIDSIZE/2) - (this.size/2);
|
|
|
|
this.y = (this.gridy * GRIDSIZE) + (GRIDSIZE/2) - (this.size/2);
|
2016-08-30 14:55:26 +10:00
|
|
|
|
|
|
|
// going in to a bag ?
|
|
|
|
xcutoff = SCREENW - this.size*2;
|
|
|
|
if (this.x > xcutoff) {
|
|
|
|
this.x = xcutoff;
|
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
}
|
|
|
|
} else if ((this.state == "parade") || (this.state == "swapping")) {
|
2016-08-20 11:17:22 +10:00
|
|
|
// move towards next cell in path
|
|
|
|
var nextx = this.path[0].x;
|
|
|
|
var nexty = this.path[0].y;
|
|
|
|
var xdone = 0, ydone = 0;
|
2016-08-30 14:55:26 +10:00
|
|
|
var goingright = false;
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
game.dirty = true; // need to redraw
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-23 01:13:47 +10:00
|
|
|
// special case: door.
|
|
|
|
if ((nextx == -1) && (nexty == -1)) {
|
|
|
|
this.path = [];
|
|
|
|
this.startshrink();
|
2016-08-20 11:17:22 +10:00
|
|
|
} else {
|
2016-08-23 01:13:47 +10:00
|
|
|
if (this.x < nextx) {
|
2016-08-30 14:55:26 +10:00
|
|
|
goingright = true;
|
2016-08-23 01:13:47 +10:00
|
|
|
this.x += this.pathspeed;
|
2016-08-27 13:48:41 +10:00
|
|
|
if (this.x >= nextx) {
|
|
|
|
this.x = nextx;
|
|
|
|
xdone = true;
|
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
} else if (this.x > nextx) {
|
|
|
|
this.x -= this.pathspeed;
|
2016-08-27 13:48:41 +10:00
|
|
|
if (this.x <= nextx) {
|
|
|
|
this.x = nextx;
|
|
|
|
xdone = true;
|
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
} else {
|
|
|
|
xdone = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.y < nexty) {
|
|
|
|
this.y += this.pathspeed;
|
2016-08-27 13:48:41 +10:00
|
|
|
if (this.y >= nexty) {
|
|
|
|
this.y = nexty;
|
|
|
|
ydone = true;
|
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
} else if (this.y > nexty) {
|
|
|
|
this.y -= this.pathspeed;
|
2016-08-27 13:48:41 +10:00
|
|
|
if (this.y <= nexty) {
|
|
|
|
this.y = nexty;
|
|
|
|
ydone = true;
|
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
} else {
|
|
|
|
ydone = true;
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-23 01:13:47 +10:00
|
|
|
this.calcgridxy();
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-31 13:55:35 +10:00
|
|
|
// cat parade into a bag or wall?
|
2016-08-30 14:55:26 +10:00
|
|
|
if (this.state == "parade") {
|
|
|
|
var bag;
|
|
|
|
// hit a bag?
|
|
|
|
bag = getbagaty(this.gridy);
|
|
|
|
if (goingright && (this.gridx >= GRIDW) && (bag != undefined)) {
|
|
|
|
if (bag.cats < bag.capacity) {
|
|
|
|
this.path = [];
|
|
|
|
this.startshrink();
|
|
|
|
bag.cats++;
|
|
|
|
|
|
|
|
if (bag.cats >= bag.capacity) {
|
|
|
|
game.dirty = true; // need to redraw
|
|
|
|
game.addbagpop(bag.y);
|
|
|
|
}
|
|
|
|
}
|
2016-08-31 13:55:35 +10:00
|
|
|
} else {
|
|
|
|
var brick;
|
|
|
|
brick = gridxyhasthingtype(this.gridx, this.gridy, "brick");
|
|
|
|
if (brick != undefined) {
|
|
|
|
// parade cat explodes.
|
|
|
|
this.path = [];
|
|
|
|
this.startexplode();
|
|
|
|
|
|
|
|
brick.losehp();
|
|
|
|
}
|
2016-08-30 14:55:26 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-23 01:13:47 +10:00
|
|
|
// at destination?
|
|
|
|
if (xdone && ydone) {
|
|
|
|
this.poppath();
|
2016-08-30 14:55:26 +10:00
|
|
|
|
2016-09-02 11:48:48 +10:00
|
|
|
//console.log("poppath for " + this.name + " - new len is " + this.path.length);
|
2016-08-31 13:55:35 +10:00
|
|
|
|
2016-08-23 01:13:47 +10:00
|
|
|
// path finished?
|
|
|
|
if (this.path == undefined || this.path.length == 0) {
|
2016-08-31 13:55:35 +10:00
|
|
|
if (this.state == "parade" ){
|
2016-09-02 11:48:48 +10:00
|
|
|
//console.log("calling kill for parading " + this.type);
|
2016-08-23 01:13:47 +10:00
|
|
|
this.kill();
|
|
|
|
} else {
|
|
|
|
this.state = "stop";
|
|
|
|
}
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
|
|
|
}
|
2016-08-30 17:19:28 +10:00
|
|
|
} else if (this.state == "slapped") {
|
|
|
|
var below;
|
|
|
|
// fall, knocking things below down too
|
|
|
|
|
|
|
|
below = this.getstoppedbelowthing();
|
|
|
|
if (below) {
|
|
|
|
// anything below vanishes
|
|
|
|
below.addabove();
|
|
|
|
below.givepoints();
|
|
|
|
below.startexplode();
|
|
|
|
game.dirty = true; // need to redraw
|
|
|
|
}
|
|
|
|
if (!atbottom) {
|
|
|
|
game.dirty = true; // need to redraw
|
|
|
|
// accelerate
|
|
|
|
this.yspeed += GRAVITY;
|
|
|
|
|
|
|
|
// move
|
|
|
|
this.y += this.yspeed;
|
|
|
|
|
|
|
|
// don't go below bottom of screen
|
|
|
|
if (this.y > GRIDSIZE * GRIDH) {
|
|
|
|
//this.y = GRIDSIZE * GRIDH;
|
|
|
|
this.kill();
|
|
|
|
} else {
|
|
|
|
// calc new gridx / gridy
|
|
|
|
this.calcgridxy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
} else {
|
2016-09-03 10:52:03 +10:00
|
|
|
var below,willfall = false;
|
|
|
|
below = this.getstoppedbelowthing();
|
2016-08-20 11:17:22 +10:00
|
|
|
// regular gravity
|
|
|
|
if ((this.gridy >= GRIDH-1)) {
|
|
|
|
atbottom = true;
|
|
|
|
}
|
2016-09-03 10:52:03 +10:00
|
|
|
if (!atbottom && !below && this.canfall()) {
|
|
|
|
willfall = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (willfall) {
|
2016-08-22 19:52:15 +10:00
|
|
|
game.dirty = true; // need to redraw
|
2016-08-20 11:17:22 +10:00
|
|
|
// accelerate
|
|
|
|
this.yspeed += GRAVITY;
|
|
|
|
|
|
|
|
// move
|
|
|
|
this.y += this.yspeed;
|
|
|
|
|
2016-08-24 22:47:23 +10:00
|
|
|
this.state = "fall";
|
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
// don't go below bottom of screen
|
2016-08-24 22:47:23 +10:00
|
|
|
if (this.y > GRIDSIZE * GRIDH) {
|
|
|
|
//this.y = GRIDSIZE * GRIDH;
|
|
|
|
atbottom = true;
|
|
|
|
this.state = "stop";
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
|
|
|
|
// calc new gridx / gridy
|
|
|
|
this.calcgridxy();
|
2016-08-24 22:47:23 +10:00
|
|
|
|
|
|
|
if ((this.gridy >= GRIDH-1)) {
|
|
|
|
atbottom = true;
|
|
|
|
this.state = "stop";
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// hit something?
|
|
|
|
if (atbottom || this.getstoppedbelowthing()) {
|
|
|
|
// something below us.
|
|
|
|
|
|
|
|
// stop
|
|
|
|
this.yspeed = 0;
|
2016-08-18 14:14:48 +10:00
|
|
|
|
2016-08-20 11:17:22 +10:00
|
|
|
// snap to grid
|
2016-08-22 19:52:15 +10:00
|
|
|
if (this.snaptogrid()) {
|
|
|
|
game.dirty = true; // need to redraw
|
|
|
|
}
|
2016-08-20 11:17:22 +10:00
|
|
|
|
|
|
|
this.state = "stop";
|
|
|
|
}
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
2016-09-03 10:52:03 +10:00
|
|
|
|
|
|
|
this.enterbox = function(box) {
|
|
|
|
game.dirty = true;
|
|
|
|
|
|
|
|
box.boxfull = true;
|
|
|
|
box.catcol = this.catcol;
|
|
|
|
|
|
|
|
// this cat vanishes
|
|
|
|
this.addabove();
|
|
|
|
this.kill();
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
function mainloop() {
|
2016-08-18 14:14:48 +10:00
|
|
|
var x, height, gap, minHeight, maxHeight, minGap, maxGap;
|
2016-08-19 17:46:39 +10:00
|
|
|
var i;
|
2016-08-25 16:49:54 +10:00
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
requestAnimFrame(mainloop);
|
|
|
|
|
2016-08-19 17:46:39 +10:00
|
|
|
game.frameNo += 1;
|
2016-08-25 16:49:54 +10:00
|
|
|
if (wipe.isactive()) {
|
|
|
|
wipe.tick();
|
|
|
|
}
|
2016-08-20 15:12:32 +10:00
|
|
|
|
|
|
|
if (game.state == "title") {
|
2016-08-22 19:52:15 +10:00
|
|
|
game.clear();
|
2016-08-20 15:12:32 +10:00
|
|
|
game.drawtitle();
|
2016-08-25 16:49:54 +10:00
|
|
|
///game.setstate("levselect");
|
2016-08-27 12:25:17 +10:00
|
|
|
} else if (game.state == "loader") {
|
|
|
|
game.clear();
|
|
|
|
game.drawloader();
|
|
|
|
|
2016-09-08 14:15:46 +10:00
|
|
|
game.checkfont();
|
|
|
|
|
2016-08-27 12:25:17 +10:00
|
|
|
if (nimages >= maximages) {
|
2016-09-08 13:49:23 +10:00
|
|
|
// has font loaded?
|
2016-09-08 14:15:46 +10:00
|
|
|
if (game.fontloaded) {
|
2016-09-08 13:49:23 +10:00
|
|
|
game.setstate("title");
|
|
|
|
}
|
2016-08-27 12:25:17 +10:00
|
|
|
}
|
2016-08-20 15:12:32 +10:00
|
|
|
} else if (game.state == "help") {
|
2016-08-22 19:52:15 +10:00
|
|
|
game.clear();
|
|
|
|
game.drawhelp();
|
|
|
|
} else if (game.state == "levselect") {
|
|
|
|
game.clear();
|
|
|
|
game.drawlevselect();
|
|
|
|
} else if ((game.state == "running") || (game.state == "gameover") || (game.state == "levelcomplete")) {
|
2016-08-25 16:49:54 +10:00
|
|
|
var gridalpha = 1.0;
|
2016-08-20 15:12:32 +10:00
|
|
|
// move objects
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
things[i].move();
|
2016-08-20 11:17:22 +10:00
|
|
|
}
|
2016-08-25 16:49:54 +10:00
|
|
|
|
2016-08-29 19:24:29 +10:00
|
|
|
// move "turns left" bar towards its correct location.
|
|
|
|
game.moveturnsleftbar();
|
|
|
|
|
2016-08-25 16:49:54 +10:00
|
|
|
gridalpha = wipe.getval(1.0, "up", "down", 1.0);
|
|
|
|
ctx.globalAlpha = gridalpha;
|
2016-08-30 14:55:26 +10:00
|
|
|
if (game.dirty || wipe.isactive() || (game.screenflash > 0)) {
|
2016-08-22 19:52:15 +10:00
|
|
|
// clear
|
|
|
|
game.clear();
|
|
|
|
// draw grid
|
|
|
|
game.drawgrid();
|
2016-08-29 14:21:42 +10:00
|
|
|
// draw turns left
|
|
|
|
game.drawsides();
|
2016-08-22 19:52:15 +10:00
|
|
|
// draw non-animating objects
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
2016-08-31 15:19:51 +10:00
|
|
|
if (!things[i].isanimating() && things[i].type != "firework") {
|
2016-09-03 10:52:03 +10:00
|
|
|
things[i].draw(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// draw non-animating box tops
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
if (!things[i].isanimating() && things[i].type == "box") {
|
|
|
|
things[i].draw(1);
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-08-20 15:12:32 +10:00
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
// draw animating objects
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
2016-08-31 15:19:51 +10:00
|
|
|
if (things[i].isanimating() && things[i].type != "firework") {
|
2016-09-03 10:52:03 +10:00
|
|
|
things[i].draw(0);
|
|
|
|
if (things[i].type == "box") {
|
|
|
|
// draw top as well
|
|
|
|
things[i].draw(1);
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-08-20 15:12:32 +10:00
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
// draw top of canvas (score etc)
|
|
|
|
game.drawtop();
|
|
|
|
|
|
|
|
// draw bottom of canvas (goals)
|
|
|
|
game.drawbottom();
|
2016-08-20 11:17:22 +10:00
|
|
|
|
2016-09-02 11:48:48 +10:00
|
|
|
if (game.state == "gameover") {
|
|
|
|
// draw buttons
|
|
|
|
game.drawcontinuebutton();
|
|
|
|
} else if (game.state == "levelcomplete") {
|
2016-08-22 19:52:15 +10:00
|
|
|
// draw buttons
|
|
|
|
game.drawcontinuebutton();
|
2016-08-31 15:19:51 +10:00
|
|
|
// spawn new fireworks
|
|
|
|
if (countthingsoftype("firework") < (FIREWORKSHARDS*2)) {
|
|
|
|
game.addfirework();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-03 10:52:03 +10:00
|
|
|
// draw fireworks and box tops
|
2016-08-31 15:19:51 +10:00
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
if (things[i].type == "firework") {
|
2016-09-03 10:52:03 +10:00
|
|
|
things[i].draw(1);
|
2016-08-31 15:19:51 +10:00
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-08-21 09:32:57 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
|
|
|
|
// draw dragged arrow
|
|
|
|
game.drawpath();
|
2016-08-25 20:01:45 +10:00
|
|
|
|
|
|
|
// flash
|
|
|
|
game.drawflash();
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-08-25 16:49:54 +10:00
|
|
|
ctx.globalAlpha = 1.0;
|
2016-08-22 19:52:15 +10:00
|
|
|
game.dirty = false;
|
|
|
|
|
|
|
|
if (game.state == "levelcomplete") {
|
|
|
|
// make image bigger
|
|
|
|
game.zoomwinimg();
|
|
|
|
}
|
2016-08-19 17:46:39 +10:00
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
// check for game over and level over
|
2016-08-22 19:52:15 +10:00
|
|
|
if (game.state == "running") {
|
|
|
|
if (!thingsmoving()) {
|
2016-08-23 01:13:47 +10:00
|
|
|
var i;
|
|
|
|
if (pathdoor != undefined) {
|
|
|
|
// still a path door needing to be closed/destroyed?
|
|
|
|
pathdoor.givepoints();
|
|
|
|
pathdoor.addabove();
|
|
|
|
pathdoor.startshrink();
|
|
|
|
pathdoor = null;
|
2016-08-30 14:55:26 +10:00
|
|
|
} else if (matchthree()) {
|
|
|
|
// matched three things in a row?
|
|
|
|
// if so, don't finish level yet.
|
2016-08-23 01:13:47 +10:00
|
|
|
} else if (levelfinished()) {
|
2016-08-29 19:24:29 +10:00
|
|
|
// important: check for this BEFORE gameover.
|
|
|
|
// otherwise levels with turn limits won't work.
|
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
// record score
|
2016-09-05 14:22:21 +10:00
|
|
|
if (playerdata.levscore[curlevel] == null || score > playerdata.levscore[curlevel]) {
|
2016-08-22 19:52:15 +10:00
|
|
|
playerdata.setlevscore(curlevel, score);
|
|
|
|
}
|
|
|
|
|
|
|
|
game.setstate("levelcomplete");
|
2016-08-29 19:24:29 +10:00
|
|
|
|
2016-08-22 19:52:15 +10:00
|
|
|
} else if (!anyvalidmoves()) {
|
|
|
|
game.setstate("gameover");
|
2016-08-29 19:24:29 +10:00
|
|
|
} else if (game.turnsleft <= 0) {
|
|
|
|
game.setstate("gameover");
|
2016-08-23 01:13:47 +10:00
|
|
|
}
|
|
|
|
// mark things as not new
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
2016-09-04 11:47:42 +10:00
|
|
|
if ((things[i].gridy >= 0) && !things[i].isanimating()) things[i].isnew = false;
|
2016-08-23 01:13:47 +10:00
|
|
|
}
|
|
|
|
// suns move down once
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
2016-09-04 11:47:42 +10:00
|
|
|
if (things[i].type == "sunlight" &&
|
|
|
|
isonscreen(things[i].gridx, things[i].gridy) && !things[i].isnew &&
|
2016-08-23 01:13:47 +10:00
|
|
|
things[i].state != "swapping" && things[i].counter == 0) {
|
2016-08-31 13:55:35 +10:00
|
|
|
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) {
|
2016-08-23 01:13:47 +10:00
|
|
|
// at bottom - disappear
|
|
|
|
things[i].addabove();
|
2016-08-30 14:55:26 +10:00
|
|
|
things[i].startexplode("sun");
|
2016-08-31 13:55:35 +10:00
|
|
|
//game.progress("sun", 1);
|
2016-08-23 01:13:47 +10:00
|
|
|
} else {
|
2016-08-31 13:55:35 +10:00
|
|
|
// move down (swap with thing below us)
|
2016-08-23 01:13:47 +10:00
|
|
|
things[i].pushpath(things[i].x, things[i].y + GRIDSIZE);
|
|
|
|
things[i].state = "swapping";
|
|
|
|
things[i].counter = 1;
|
|
|
|
|
|
|
|
if (thingbelow != undefined && thingbelow.state != "swapping" &&
|
|
|
|
thingbelow.type != "sunlight") {
|
|
|
|
thingbelow.pushpath(things[i].x, things[i].y);
|
|
|
|
thingbelow.state = "swapping";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-22 19:52:15 +10:00
|
|
|
}
|
2016-08-23 01:13:47 +10:00
|
|
|
|
2016-08-20 15:12:32 +10:00
|
|
|
}
|
2016-08-20 12:27:15 +10:00
|
|
|
}
|
|
|
|
}
|
2016-08-18 14:14:48 +10:00
|
|
|
}
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
function canmatchthree(what) {
|
|
|
|
if (what.isanimating()) return false; // ignore moving things, though there shouldnt be any anyway
|
|
|
|
|
2016-09-04 11:47:42 +10:00
|
|
|
if (!isonscreen(what.gridx, what.gridy)) return false;
|
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
switch (what.type) {
|
|
|
|
case "llama": return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function isongrid(x, y) {
|
|
|
|
if (x >= 0 && x < GRIDW && y >= 0 && y < GRIDH) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function matchthreefrom(what, locdb) {
|
|
|
|
var setthings = [];
|
|
|
|
var n,gotmatch = false;
|
|
|
|
|
|
|
|
if (locdb == undefined) debug = false;
|
|
|
|
if (!canmatchthree(what)) return false;
|
2016-09-04 11:47:42 +10:00
|
|
|
|
2016-08-30 14:55:26 +10:00
|
|
|
if (what.matched) return false; // ignore things already in sets of 3
|
|
|
|
|
|
|
|
for (n = 0; n < MAXDIRS; n++) {
|
|
|
|
var gotone = true;
|
|
|
|
if (locdb) console.log("matchthreefrom() - checking " + DIRNAME[n]);
|
|
|
|
setthings = [];
|
|
|
|
setthings.push(what);
|
|
|
|
while ( gotone ) {
|
|
|
|
var newx,newy;
|
|
|
|
gotone = false;
|
|
|
|
newx = setthings[setthings.length-1].gridx + DIRXMOD[n];
|
|
|
|
newy = setthings[setthings.length-1].gridy + DIRYMOD[n];
|
|
|
|
if (isongrid(newx, newy)) {
|
|
|
|
newthing = getgridthing(newx, newy);
|
|
|
|
if (newthing != null) {
|
|
|
|
if (locdb) console.log(" -> " + newthing.type);
|
|
|
|
if (canmatchthree(newthing) &&
|
|
|
|
newthing.type == setthings[setthings.length-1].type) {
|
|
|
|
// matched
|
|
|
|
setthings.push(newthing);
|
|
|
|
gotone = true;
|
|
|
|
if (locdb) console.log(" -> matches!");
|
|
|
|
} else {
|
|
|
|
if (locdb) console.log(" doesn't match.");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (locdb) console.log(" nothing there.");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (locdb) console.log(" off grid.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (locdb) console.log("matched " + setthings.length);
|
|
|
|
if (setthings.length >= 3) {
|
|
|
|
var nn;
|
|
|
|
// matched!
|
|
|
|
for (nn = 0; nn < setthings.length; nn++) {
|
2016-08-31 13:55:35 +10:00
|
|
|
//console.log(" "+setthings[nn].name + " x=",setthings[nn].x + ",y=" + setthings[nn].y);
|
2016-08-30 14:55:26 +10:00
|
|
|
setthings[nn].matched = true;
|
|
|
|
}
|
|
|
|
gotmatch = true;
|
|
|
|
}
|
|
|
|
setthings = [];
|
|
|
|
}
|
|
|
|
return gotmatch;
|
|
|
|
}
|
|
|
|
|
|
|
|
function matchthree() {
|
|
|
|
var i,n;
|
|
|
|
var checklen = 3;
|
|
|
|
var matches = 0;
|
|
|
|
// for each grid pos, search n/s/e/w for matches of 3 the same.
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (matchthreefrom(things[i])) matches++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// clear anything which matched
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (things[i].matched) {
|
|
|
|
things[i].givepoints();
|
|
|
|
things[i].addabove();
|
|
|
|
things[i].startexplode("matchthree");
|
|
|
|
things[i].matched = false;
|
|
|
|
}
|
|
|
|
}
|
2016-09-03 10:52:03 +10:00
|
|
|
|
|
|
|
// also check for ambushes
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (!things[i].isanimating() && things[i].type == "llama" &&
|
|
|
|
isadjacenttotype(things[i], "box", null, null, true)) {
|
|
|
|
things[i].matched = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < things.length; i++) {
|
|
|
|
if (things[i].matched) {
|
|
|
|
things[i].matched = false;
|
|
|
|
|
|
|
|
// ambush!
|
|
|
|
things[i].givepoints();
|
|
|
|
things[i].addabove();
|
|
|
|
|
|
|
|
// add "pow"
|
|
|
|
things.push(new thing(things[i].gridx, things[i].gridy, "pow"));
|
|
|
|
|
|
|
|
things[i].kill();
|
|
|
|
|
|
|
|
game.progress("ambush", 1);
|
|
|
|
}
|
|
|
|
}
|
2016-08-30 14:55:26 +10:00
|
|
|
}
|
|
|
|
|
2016-08-21 09:32:57 +10:00
|
|
|
function levelfinished() {
|
|
|
|
var i;
|
|
|
|
// past last level!
|
|
|
|
if (curlevel >= game.levels.length) return false;
|
|
|
|
|
|
|
|
for (i = 0 ; i < game.levels[curlevel].goals.length; i++ ) {
|
|
|
|
if (game.levels[curlevel].goals[i].progress < game.levels[curlevel].goals[i].count) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-20 12:27:15 +10:00
|
|
|
function anyvalidmoves() {
|
|
|
|
var gotmoves = false;
|
|
|
|
var i;
|
|
|
|
|
|
|
|
if (things == undefined || things.length == 0) return false;
|
|
|
|
|
|
|
|
for (i = 0; i < things.length; i += 1) {
|
|
|
|
if (things[i].hasvalidmoves()) {
|
|
|
|
gotmoves = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return gotmoves;
|
|
|
|
}
|
|
|
|
|
2016-08-18 14:14:48 +10:00
|
|
|
//<button onmousedown="accelerate(-0.2)" onmouseup="accelerate(0.05)">ACCELERATE</button>
|
|
|
|
</script>
|
|
|
|
<br>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
|
|
|
|
|
2016-08-27 18:14:26 +10:00
|
|
|
<!-- vim: set syntax=javascript : -->
|