*create different levels with goals
*display goals at bottom of screen *implement progress() to earn progress towards goals *go to next level after meeting all goals
This commit is contained in:
parent
5cc296e61f
commit
b0f3ec030c
289
cat.html
289
cat.html
|
@ -36,9 +36,22 @@ var overdesc = "";
|
|||
var curpath = [];
|
||||
var pathdir = -1;
|
||||
var pathvalid = false;
|
||||
var curlevel = 1;
|
||||
|
||||
var lastmx = -1, lastmy = -1;
|
||||
|
||||
|
||||
// goal types
|
||||
|
||||
|
||||
var GOALVERB = {
|
||||
'food': 'Eat',
|
||||
'points': 'Earn',
|
||||
'parades': 'Form',
|
||||
'llamas': 'Clear',
|
||||
'cats': 'Clear',
|
||||
};
|
||||
|
||||
var MAXDIRS = 4;
|
||||
var DIRXMOD = [ 0, 1, 0, -1 ];
|
||||
var DIRYMOD = [ -1, 0, 1, 0 ];
|
||||
|
@ -60,6 +73,8 @@ var HELPARROWSIZE=15;
|
|||
var HELPTITLESIZE = 18;
|
||||
var HELPTEXTSIZE = 12;
|
||||
|
||||
var GOALTEXTSIZE = 16;
|
||||
|
||||
var TITLETEXTSIZE = 36;
|
||||
var TITLECREDITTEXTSIZE = 16;
|
||||
var TITLESTARTTEXTSIZE = 26;
|
||||
|
@ -357,6 +372,7 @@ function startGame() {
|
|||
loadimage('title', 'images/title.png');
|
||||
|
||||
game.init();
|
||||
game.initlevels();
|
||||
|
||||
window.addEventListener('load', game.init, false);
|
||||
window.addEventListener('resize', game.resize, false);
|
||||
|
@ -507,6 +523,24 @@ function addcommas(num) {
|
|||
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
}
|
||||
|
||||
function drawcross(x, y, x2, y2, col, width) {
|
||||
// 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();
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -547,11 +581,10 @@ function drawarrowhead(ctx, x1, y1, x2, y2, col, size) {
|
|||
}
|
||||
|
||||
var game = {
|
||||
|
||||
|
||||
ratio: null,
|
||||
curw: null,
|
||||
curh: null,
|
||||
levels: null,
|
||||
|
||||
canvas : document.createElement("canvas"),
|
||||
|
||||
|
@ -638,22 +671,84 @@ var game = {
|
|||
|
||||
|
||||
initgamevars : function() {
|
||||
score = 0;
|
||||
},
|
||||
|
||||
initlevelvars : function() {
|
||||
// kill any existing objects
|
||||
clearthings();
|
||||
|
||||
score = 0;
|
||||
overdesc = "";
|
||||
curpath = [];
|
||||
pathdir = -1;
|
||||
pathvalid = false;
|
||||
},
|
||||
|
||||
start : function() {
|
||||
var x,y;
|
||||
this.frameNo = 0;
|
||||
// goal1type goal1count goal2type goal2count etc...
|
||||
addlevel : function () {
|
||||
var i,mylevel,idx;
|
||||
mylevel = new Object();
|
||||
mylevel.goals = new Array();
|
||||
for (i = 0 ; i < arguments.length; i += 2) {
|
||||
idx = mylevel.goals.push(new Object()) - 1;
|
||||
mylevel.goals[idx].type = arguments[i];
|
||||
mylevel.goals[idx].count = arguments[i+1];
|
||||
mylevel.goals[idx].progress = 0;
|
||||
}
|
||||
this.levels.push(mylevel);
|
||||
},
|
||||
|
||||
this.initgamevars();
|
||||
// earn progress towards goals
|
||||
progress : function(type, amt) {
|
||||
var i;
|
||||
|
||||
// past last level!
|
||||
if (curlevel >= game.levels.length) return false;
|
||||
|
||||
console.log("progress()");
|
||||
for (i = 0 ; i < this.levels[curlevel].goals.length; i++ ) {
|
||||
console.log("this goal type is " + this.levels[curlevel].goals[i].type);
|
||||
if (this.levels[curlevel].goals[i].type == type) {
|
||||
this.levels[curlevel].goals[i].progress += amt;
|
||||
if (this.levels[curlevel].goals[i].progress >= this.levels[curlevel].goals[i].count) {
|
||||
this.levels[curlevel].goals[i].progress = this.levels[curlevel].goals[i].count;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
initlevels : function ( ) {
|
||||
var mylevel,i,n;
|
||||
|
||||
console.log("doing level init");
|
||||
this.levels = [];
|
||||
this.addlevel(); // dummy level with 0 goals
|
||||
this.addlevel("food", 10);
|
||||
this.addlevel("points", 200);
|
||||
|
||||
/*
|
||||
for (i = 0; i < this.levels.length; i++) {
|
||||
console.log("Level " + (i+1) + " goals:");
|
||||
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);
|
||||
}
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
nextlevel : function() {
|
||||
curlevel++;
|
||||
|
||||
this.initlevelvars();
|
||||
this.populategrid();
|
||||
|
||||
this.state = "running";
|
||||
},
|
||||
|
||||
populategrid : function() {
|
||||
var i;
|
||||
while (!anyvalidmoves()) {
|
||||
var m;
|
||||
clearthings();
|
||||
|
@ -673,6 +768,17 @@ var game = {
|
|||
things[i].gridy -= GRIDH;
|
||||
things[i].updatexy();
|
||||
}
|
||||
},
|
||||
|
||||
startgame : function() {
|
||||
var x,y;
|
||||
this.frameNo = 0;
|
||||
|
||||
this.initgamevars();
|
||||
this.initlevelvars();
|
||||
this.populategrid();
|
||||
|
||||
curlevel = 1;
|
||||
|
||||
this.state = "running";
|
||||
},
|
||||
|
@ -689,12 +795,22 @@ var game = {
|
|||
this.context.clearRect(0, 0, this.canvas.width-1, BOARDY-1);
|
||||
|
||||
if (game.state == "running") {
|
||||
var y1 = 6;
|
||||
var y2 = 32;
|
||||
|
||||
// show level
|
||||
this.context.font = "16pt Futura";
|
||||
this.context.textAlign = "center";
|
||||
this.context.textBaseline = "top";
|
||||
this.context.fillStyle = "#00aaee";
|
||||
this.context.fillText("Level " + curlevel, SCREENW/2, y1);
|
||||
|
||||
// show score
|
||||
this.context.font = "16pt Futura";
|
||||
this.context.textAlign = "left";
|
||||
this.context.textBaseline = "top";
|
||||
this.context.fillStyle = "white";
|
||||
this.context.fillText("Score: " + addcommas(score), 16, 16);
|
||||
this.context.fillText("Score: " + addcommas(score), 16, y2);
|
||||
|
||||
switch (thingsmoving()) {
|
||||
case "parade":
|
||||
|
@ -720,17 +836,135 @@ var game = {
|
|||
this.context.textAlign = "right";
|
||||
this.context.textBaseline = "top";
|
||||
this.context.fillStyle = col;
|
||||
this.context.fillText(texttodraw, SCREENW-16, 16);
|
||||
this.context.fillText(texttodraw, SCREENW-16, y2);
|
||||
}
|
||||
} else if (game.state == "gameover") {
|
||||
this.context.textAlign = "center";
|
||||
this.context.textBaseline = "top";
|
||||
shadowtext(this.context, "GAME OVER", 20, "red", SCREENW / 2, 5);
|
||||
shadowtext(this.context, "Final Score: " + addcommas(score), 16, "white", SCREENW / 2, 35);
|
||||
} 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);
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
drawbottom : function() {
|
||||
var bx = 0,by = BOARDY + GRIDH*GRIDSIZE + 15;
|
||||
var bw = SCREENW, bh = SCREENH - by;
|
||||
var x,y,ctx;
|
||||
var margin = 10;
|
||||
var indent = 50;
|
||||
var boxindent = 20;
|
||||
ctx = this.context;
|
||||
|
||||
if (game.state == "running") {
|
||||
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");
|
||||
|
||||
// clear
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(bx, by, bw, bh);
|
||||
|
||||
//outline
|
||||
ctx.strokeStyle = "cyan";
|
||||
ctx.lineWidth = 5;
|
||||
ctx.beginPath();
|
||||
ctx.rect(bx+(borderwidth/2), by+(borderwidth/2), bw-(borderwidth/2), bh-(borderwidth/2));
|
||||
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;
|
||||
|
||||
if (this.levels[curlevel].goals[n].progress >= this.levels[curlevel].goals[n].count) {
|
||||
goalmet = true;
|
||||
}
|
||||
|
||||
if (goalmet) {
|
||||
goalcol = "#00ddff";
|
||||
} else {
|
||||
goalcol = "#aaee00";
|
||||
}
|
||||
|
||||
// goal name
|
||||
var goaltext = GOALVERB[this.levels[curlevel].goals[n].type] + " " +
|
||||
this.levels[curlevel].goals[n].count + " " +
|
||||
this.levels[curlevel].goals[n].type;
|
||||
|
||||
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";
|
||||
shadowtext(ctx, progtext, GOALTEXTSIZE,goalcol, SCREENW-indent, y);
|
||||
|
||||
// checkbox
|
||||
var boxsize = texth-8;
|
||||
var boxx = x+boxindent;
|
||||
var boxy = y + texth/2 - boxsize/2;
|
||||
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) {
|
||||
//drawcross(boxx,boxy, boxx+boxsize-1, boxy+boxsize-1, goalcol, 2);
|
||||
var tickleftx = boxx + boxsize/4;
|
||||
var ticklefty = boxy + boxsize/2;
|
||||
var tickbasex = boxx + boxsize/2;
|
||||
var tickbasey = boxy+boxsize-boxsize/8;
|
||||
var tickrightx = boxx + boxsize - boxsize/5;
|
||||
var tickrighty = boxy + boxsize/8;
|
||||
drawline(ctx, tickleftx,ticklefty, tickbasex, tickbasey, goalcol, 2);
|
||||
drawline(ctx, tickbasex, tickbasey, tickrightx, tickrighty, goalcol, 2);
|
||||
}
|
||||
|
||||
y += texth;
|
||||
}
|
||||
} else {
|
||||
// past last level
|
||||
ctx.textAlign = "left";
|
||||
ctx.textBaseline = "top";
|
||||
shadowtext(ctx, "(none)", GOALTEXTSIZE,goaltitlecol, x+indent, y);
|
||||
}
|
||||
} else if (game.state == "levelcomplete") {
|
||||
this.context.textAlign = "center";
|
||||
this.context.textBaseline = "bottom";
|
||||
shadowtext(this.context, "Tap for next level", TITLESTARTTEXTSIZE, "#00dd00", SCREENW / 2, by + bh/2);
|
||||
}
|
||||
},
|
||||
|
||||
drawtitle : function() {
|
||||
var ratio,w,h;
|
||||
var img = image['title'];
|
||||
|
@ -1079,6 +1313,8 @@ var game = {
|
|||
if (ch == 'a') {
|
||||
console.log("ending game");
|
||||
game.state = "gameover";
|
||||
} else if (ch == 'n') {
|
||||
game.state = "levelcomplete";
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1123,7 +1359,11 @@ var game = {
|
|||
} else if (game.state == "title") {
|
||||
game.setstate("help");
|
||||
} else if (game.state == "help") {
|
||||
game.start();
|
||||
game.startgame();
|
||||
} else if (game.state == "levelcomplete") {
|
||||
// TODO : show help for this level
|
||||
// TODO: start next levle
|
||||
game.nextlevel();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1275,6 +1515,7 @@ var game = {
|
|||
curpath.splice(0, 1);
|
||||
}
|
||||
}
|
||||
game.progress("parades", 1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1483,16 +1724,20 @@ function thing(gridx, gridy, type, text) {
|
|||
var points = 0;
|
||||
if (this.type == "food") {
|
||||
points = FOODPOINTS;
|
||||
game.progress("food", 1);
|
||||
} else if (this.type == "llama") {
|
||||
points = LLAMAPOINTS;
|
||||
game.progress("llamas", 1);
|
||||
} else if (this.type == "cat") {
|
||||
if (this.eaten == true) {
|
||||
points = SLEEPYCATPOINTS;
|
||||
} else {
|
||||
points = CATPOINTS;
|
||||
}
|
||||
game.progress("cats", 1);
|
||||
}
|
||||
score += points;
|
||||
game.progress("points", points);
|
||||
|
||||
// add animation
|
||||
things.push(new thing(this.gridx, this.gridy, "text", "+" + points));
|
||||
|
@ -1915,21 +2160,39 @@ function mainloop() {
|
|||
things[i].draw();
|
||||
}
|
||||
}
|
||||
// hide top of canvads
|
||||
// draw top of canvas (score etc)
|
||||
game.drawtop();
|
||||
|
||||
// draw bottom of canvas (goals)
|
||||
game.drawbottom();
|
||||
|
||||
// draw dragged arrow
|
||||
game.drawpath();
|
||||
|
||||
// check for valid moves
|
||||
// check for game over and level over
|
||||
if (!thingsmoving()) {
|
||||
if (!anyvalidmoves()) {
|
||||
if (levelfinished()) {
|
||||
game.state = "levelcomplete";
|
||||
} else if (!anyvalidmoves()) {
|
||||
game.state = "gameover";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function anyvalidmoves() {
|
||||
var gotmoves = false;
|
||||
var i;
|
||||
|
|
40
todo
40
todo
|
@ -29,20 +29,36 @@ phone fixes as per http://www.html5rocks.com/en/mobile/touch/
|
|||
|
||||
https://www.smashingmagazine.com/2012/10/design-your-own-mobile-game/
|
||||
|
||||
*put commas in score
|
||||
*create diff levels with goals
|
||||
*display goals at bottom of screen
|
||||
*implement progress() to earn progress towards goals
|
||||
*go to next level after meeting all goals
|
||||
|
||||
different levels with goals
|
||||
eat x cheese
|
||||
get x parades
|
||||
get x llamas
|
||||
break x obstacles
|
||||
get x goats
|
||||
etc.
|
||||
later levels have multiple goals
|
||||
implement level-specific help text
|
||||
when starting a levle, go to 'help text' state if it has one.
|
||||
if not, just start the level
|
||||
|
||||
use the bottom of the screen to show level goals
|
||||
(make current 'help text' the text for level 1)
|
||||
|
||||
title screen -> level select
|
||||
Level selection screen
|
||||
grid of numbers for each level
|
||||
1 2 3 4 5
|
||||
6 7 8 9 10
|
||||
...etc
|
||||
|
||||
scrolling background of cat paws ?
|
||||
|
||||
|
||||
custom thing chance ratios for each level
|
||||
1: no llamas
|
||||
2: no llamas
|
||||
3: llamas
|
||||
|
||||
better level complete animation
|
||||
zoom in random cat picture?
|
||||
|
||||
|
||||
title screen -> level select -> help -> startgame
|
||||
|
||||
certain levels have help screens (ie. lev 1 is initial help)
|
||||
|
||||
|
@ -50,6 +66,8 @@ remember which level you're up to
|
|||
|
||||
after each level, show cat picture.
|
||||
|
||||
complex goal: form x parades of length y
|
||||
|
||||
|
||||
sounds:
|
||||
chomp
|
||||
|
|
Loading…
Reference in New Issue