Custom snake sprite
This commit is contained in:
parent
d7ada21496
commit
93bd24e757
2 changed files with 135 additions and 14 deletions
|
@ -175,7 +175,12 @@ export class Game {
|
||||||
if (this.onEat && typeof this.onEat === "function")
|
if (this.onEat && typeof this.onEat === "function")
|
||||||
this.onEat(this.score);
|
this.onEat(this.score);
|
||||||
}
|
}
|
||||||
t.type = tiles.SNAKE;
|
if (!i)
|
||||||
|
t.type = tiles.HEAD;
|
||||||
|
else if (i === this.snake.body.length-1)
|
||||||
|
t.type = tiles.TAIL;
|
||||||
|
else
|
||||||
|
t.type = tiles.BODY;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -189,7 +194,7 @@ export class Game {
|
||||||
|
|
||||||
for (const l of this.world)
|
for (const l of this.world)
|
||||||
for (const t of l)
|
for (const t of l)
|
||||||
if (t.type === tiles.SNAKE)
|
if (t.type === tiles.HEAD || t.type === tiles.BODY || t.type === tiles.TAIL)
|
||||||
t.type = tiles.EMPTY;
|
t.type = tiles.EMPTY;
|
||||||
|
|
||||||
this.updateSnake();
|
this.updateSnake();
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import {Game} from "./Game.js";
|
import {Game} from "./Game.js";
|
||||||
|
import {directions} from "./Snake.js";
|
||||||
|
|
||||||
|
|
||||||
export class Tile {
|
export class Tile {
|
||||||
/**
|
/**
|
||||||
|
@ -42,20 +44,20 @@ export class Tile {
|
||||||
this.game.ctx.fillRect(...canvasPos, ...size);
|
this.game.ctx.fillRect(...canvasPos, ...size);
|
||||||
this.game.ctx.globalCompositeOperation = "source-over";
|
this.game.ctx.globalCompositeOperation = "source-over";
|
||||||
|
|
||||||
|
const pxsize = Math.round(size[0]/12);
|
||||||
|
const width = canvasPos[0];
|
||||||
|
const height = canvasPos[1];
|
||||||
|
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case tiles.EMPTY:
|
case tiles.EMPTY:
|
||||||
this.game.ctx.strokeStyle = "#999999";
|
this.game.ctx.strokeStyle = "#999999";
|
||||||
this.game.ctx.rect(...canvasPos, ...size);
|
this.game.ctx.rect(...canvasPos, ...size);
|
||||||
break;
|
break;
|
||||||
case tiles.APPLE:
|
case tiles.APPLE:
|
||||||
let pxsize = Math.round(size[0]/12);
|
|
||||||
if (!pxsize) {
|
if (!pxsize) {
|
||||||
this.game.ctx.fillStyle = "#ff0000";
|
this.game.ctx.fillStyle = "#ff0000";
|
||||||
this.game.ctx.fillRect(...canvasPos, ...size);
|
this.game.ctx.fillRect(...canvasPos, ...size);
|
||||||
} else {
|
} else {
|
||||||
let width = canvasPos[0];
|
|
||||||
let height = canvasPos[1];
|
|
||||||
|
|
||||||
this.game.ctx.fillStyle = "#00ffff";
|
this.game.ctx.fillStyle = "#00ffff";
|
||||||
this.game.ctx.fillRect(width+pxsize, height+pxsize, 10*pxsize, 10*pxsize);
|
this.game.ctx.fillRect(width+pxsize, height+pxsize, 10*pxsize, 10*pxsize);
|
||||||
|
|
||||||
|
@ -89,22 +91,134 @@ export class Tile {
|
||||||
this.game.ctx.fillRect(width+i*pxsize, height+7*pxsize, pxsize, pxsize);
|
this.game.ctx.fillRect(width+i*pxsize, height+7*pxsize, pxsize, pxsize);
|
||||||
|
|
||||||
this.game.ctx.globalCompositeOperation = "destination-out";
|
this.game.ctx.globalCompositeOperation = "destination-out";
|
||||||
this.game.ctx.fillRect(width+1*pxsize, height+1*pxsize, pxsize, pxsize);
|
for (const [i,j] of [[1,1],[10,1],[1,10],[10,10]])
|
||||||
this.game.ctx.fillRect(width+10*pxsize, height+1*pxsize, pxsize, pxsize);
|
this.game.ctx.fillRect(width+i*pxsize, height+j*pxsize, pxsize, pxsize);
|
||||||
this.game.ctx.fillRect(width+1*pxsize, height+10*pxsize, pxsize, pxsize);
|
|
||||||
this.game.ctx.fillRect(width+10*pxsize, height+10*pxsize, pxsize, pxsize);
|
|
||||||
this.game.ctx.globalCompositeOperation = "source-over";
|
this.game.ctx.globalCompositeOperation = "source-over";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case tiles.SNAKE:
|
case tiles.HEAD:
|
||||||
this.game.ctx.fillStyle = "#00ff5f";
|
if (!pxsize) {
|
||||||
this.game.ctx.fillRect(...canvasPos, ...size);
|
this.game.ctx.fillStyle = "#00ff5f";
|
||||||
|
this.game.ctx.fillRect(...canvasPos, ...size);
|
||||||
|
} else {
|
||||||
|
this.rotate(canvasPos, size);
|
||||||
|
this.game.ctx.fillStyle = "#FF4294";
|
||||||
|
this.game.ctx.fillRect(width + 6 * pxsize, height + pxsize, 6 * pxsize, 10 * pxsize);
|
||||||
|
this.game.ctx.fillRect(width + 4 * pxsize, height + 2 * pxsize, 6 * pxsize, 8 * pxsize);
|
||||||
|
this.game.ctx.fillRect(width + 2 * pxsize, height + 3 * pxsize, 6 * pxsize, 6 * pxsize);
|
||||||
|
this.game.ctx.fillRect(width + pxsize, height + 5 * pxsize, pxsize, 2 * pxsize);
|
||||||
|
this.game.ctx.fillStyle = "#000000";
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width + 6 * pxsize, height, pxsize * 6, pxsize);
|
||||||
|
this.game.ctx.fillRect(width + 6 * pxsize, height + 11 * pxsize, pxsize * 6, pxsize);
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width + 4 * pxsize, height + pxsize, pxsize * 2, pxsize);
|
||||||
|
this.game.ctx.fillRect(width + 4 * pxsize, height + 10 * pxsize, pxsize * 2, pxsize);
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width + 2 * pxsize, height + 2 * pxsize, pxsize * 2, pxsize);
|
||||||
|
this.game.ctx.fillRect(width + 2 * pxsize, height + 9 * pxsize, pxsize * 2, pxsize);
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width + pxsize, height + 7 * pxsize, pxsize, pxsize * 2);
|
||||||
|
this.game.ctx.fillRect(width + pxsize, height + 3 * pxsize, pxsize, pxsize * 2);
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width, height + 5 * pxsize, pxsize, pxsize * 2);
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width + 6 * pxsize, height + 4 * pxsize, pxsize * 4, pxsize);
|
||||||
|
this.game.ctx.fillRect(width + 6 * pxsize, height + 7 * pxsize, pxsize * 4, pxsize);
|
||||||
|
this.game.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case tiles.BODY:
|
||||||
|
if (!pxsize) {
|
||||||
|
this.game.ctx.fillStyle = "#0d5317";
|
||||||
|
this.game.ctx.fillRect(...canvasPos, ...size);
|
||||||
|
} else {
|
||||||
|
this.rotate(canvasPos, size);
|
||||||
|
this.game.ctx.fillStyle = "#FF4294";
|
||||||
|
this.game.ctx.fillRect(width, height, 12*pxsize, 12*pxsize);
|
||||||
|
this.game.ctx.fillStyle = "#000000";
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width, height, pxsize*12, pxsize);
|
||||||
|
this.game.ctx.fillRect(width, height+11*pxsize, pxsize*12, pxsize);
|
||||||
|
|
||||||
|
for (const [i,j] of [[1,1],[1,9],[2,3],[2,7],[3,5],[5,1],[5,9],[6,3],[6,7],[7,5],[9,1],[9,9],[10,3],[10,7],[11,5]])
|
||||||
|
this.game.ctx.fillRect(width+i*pxsize, height+j*pxsize, pxsize, pxsize*2);
|
||||||
|
|
||||||
|
this.game.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case tiles.TAIL:
|
||||||
|
if (!pxsize) {
|
||||||
|
this.game.ctx.fillStyle = "#efff00";
|
||||||
|
this.game.ctx.fillRect(...canvasPos, ...size);
|
||||||
|
} else {
|
||||||
|
this.rotate(canvasPos, size);
|
||||||
|
this.game.ctx.fillStyle = "#FF4294";
|
||||||
|
this.game.ctx.fillRect(width, height+pxsize, pxsize, 10*pxsize);
|
||||||
|
this.game.ctx.fillRect(width+pxsize, height+2*pxsize, pxsize, 8*pxsize);
|
||||||
|
this.game.ctx.fillRect(width+2*pxsize, height+3*pxsize, 2*pxsize, 6*pxsize);
|
||||||
|
this.game.ctx.fillRect(width+4*pxsize, height+4*pxsize, 3*pxsize, 4*pxsize);
|
||||||
|
this.game.ctx.fillRect(width+7*pxsize, height+5*pxsize, 4*pxsize, 2*pxsize);
|
||||||
|
this.game.ctx.fillStyle = "#000000";
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width, height, pxsize, pxsize);
|
||||||
|
this.game.ctx.fillRect(width, height+11*pxsize, pxsize, pxsize);
|
||||||
|
this.game.ctx.fillRect(width+pxsize, height+pxsize, pxsize, pxsize);
|
||||||
|
this.game.ctx.fillRect(width+pxsize, height+10*pxsize, pxsize, pxsize);
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width+2*pxsize, height+2*pxsize, 2*pxsize, pxsize);
|
||||||
|
this.game.ctx.fillRect(width+2*pxsize, height+9*pxsize, 2*pxsize, pxsize);
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width+4*pxsize, height+3*pxsize, 3*pxsize, pxsize);
|
||||||
|
this.game.ctx.fillRect(width+4*pxsize, height+8*pxsize, 3*pxsize, pxsize);
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width+7*pxsize, height+4*pxsize, 4*pxsize, pxsize);
|
||||||
|
this.game.ctx.fillRect(width+7*pxsize, height+7*pxsize, 4*pxsize, pxsize);
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width+11*pxsize, height+5*pxsize, pxsize, 2*pxsize);
|
||||||
|
this.game.ctx.fillRect(width+5*pxsize, height+5*pxsize, pxsize, 2*pxsize);
|
||||||
|
this.game.ctx.fillRect(width, height+4*pxsize, pxsize, 4*pxsize);
|
||||||
|
|
||||||
|
this.game.ctx.fillRect(width+pxsize, height+3*pxsize, pxsize, pxsize);
|
||||||
|
this.game.ctx.fillRect(width+pxsize, height+8*pxsize, pxsize, pxsize);
|
||||||
|
this.game.ctx.fillRect(width+4*pxsize, height+4*pxsize, pxsize, pxsize);
|
||||||
|
this.game.ctx.fillRect(width+4*pxsize, height+7*pxsize, pxsize, pxsize);
|
||||||
|
this.game.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.game.ctx.stroke();
|
this.game.ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDirection() {
|
||||||
|
const np = this.game.snake.body[this.game.snake.body.findIndex(([x,y]) => x === this.x && y === this.y)-1];
|
||||||
|
const d = [this.x, this.y].map((n, i) => -(n - np[i]));
|
||||||
|
|
||||||
|
return Object.values(directions).find(([x, y]) => d[0] === x && d[1] === y);
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate(canvasPos, size) {
|
||||||
|
const cx = canvasPos[0] + 0.5 * size[0];
|
||||||
|
const cy = canvasPos[1] + 0.5 * size[1];
|
||||||
|
|
||||||
|
this.game.ctx.translate(cx, cy);
|
||||||
|
switch (this.type === tiles.HEAD? this.game.lastDirection : this.getDirection()) {
|
||||||
|
case directions.UP:
|
||||||
|
this.game.ctx.rotate(Math.PI / 2);
|
||||||
|
break;
|
||||||
|
case directions.DOWN:
|
||||||
|
this.game.ctx.rotate(-Math.PI / 2);
|
||||||
|
break;
|
||||||
|
case directions.RIGHT:
|
||||||
|
this.game.ctx.rotate(-Math.PI);
|
||||||
|
break;
|
||||||
|
case directions.LEFT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.game.ctx.translate(-cx, -cy);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the tile position on the canvas
|
* Get the tile position on the canvas
|
||||||
* @returns {[int, int]}
|
* @returns {[int, int]}
|
||||||
|
@ -135,5 +249,7 @@ export class InvalidTileOption extends Error {
|
||||||
export const tiles = {
|
export const tiles = {
|
||||||
EMPTY: "empty",
|
EMPTY: "empty",
|
||||||
APPLE: "apple",
|
APPLE: "apple",
|
||||||
SNAKE: "snake"
|
HEAD: "head",
|
||||||
|
BODY: "body",
|
||||||
|
TAIL: "tail"
|
||||||
};
|
};
|
||||||
|
|
Reference in a new issue