Win checking
This commit is contained in:
parent
d2df62cdbe
commit
9c0aad2e75
|
|
@ -59,6 +59,14 @@ export default class Player extends Character {
|
|||
return this.inventory.find(i => i.type === ItemType.WEAPON_ROCKET_LAUNCHER);
|
||||
}
|
||||
|
||||
get keys() {
|
||||
return this.inventory.find(i => i.type === ItemType.ITEM_KEYS);
|
||||
}
|
||||
|
||||
get fuel() {
|
||||
return this.inventory.find(i => i.type === ItemType.ITEM_FUEL);
|
||||
}
|
||||
|
||||
public heal(player: Player) {
|
||||
player.health += this.healingAmount;
|
||||
}
|
||||
|
|
@ -77,11 +85,11 @@ export default class Player extends Character {
|
|||
return false;
|
||||
}
|
||||
|
||||
public hasItem(item: Item | null | undefined): boolean {
|
||||
public hasItem(item: Item | ItemTypeImage | null | undefined): boolean {
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
const itemIndex = this.inventory.findIndex(i => i === item);
|
||||
const itemIndex = this.inventory.findIndex(i => i === item || i.type === item);
|
||||
|
||||
return itemIndex >= 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import Entity from "./entity";
|
||||
import type Item from "./item";
|
||||
|
||||
import planks from './assets/items/planks.jpg';
|
||||
import { ItemType } from "./item";
|
||||
|
||||
export enum TileType {
|
||||
NORMAL,
|
||||
|
|
@ -69,7 +68,7 @@ export default class Tile extends Entity {
|
|||
y += (Number(this.top < doorway.top) - Number(doorway.top < this.top)) * 0.5;
|
||||
}
|
||||
|
||||
ctx.drawImage(planks, x - 0.2, y - 0.2, 0.4, 0.4);
|
||||
ctx.drawImage(ItemType.ITEM_PLANKS, x - 0.2, y - 0.2, 0.4, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,15 +20,21 @@ export default class TileMap extends Entity {
|
|||
private state = GameState.NORMAL;
|
||||
private availableTiles: Tile[] = [];
|
||||
|
||||
public keysFound = false;
|
||||
public fuelFound = false;
|
||||
public bossKilled = false;
|
||||
public readonly foundPlayers: Set<Player>;
|
||||
|
||||
constructor(
|
||||
position: [number, number],
|
||||
private mapSize: number,
|
||||
private tileSize: number,
|
||||
private spinner: Spinner,
|
||||
position: [number, number],
|
||||
private mapSize: number,
|
||||
private tileSize: number,
|
||||
private spinner: Spinner,
|
||||
numPlayers: number = 2,
|
||||
) {
|
||||
super(position, [mapSize * tileSize, mapSize * tileSize]);
|
||||
this.players = shuffle(Object.values(Players)).slice(0, numPlayers);
|
||||
this.foundPlayers = new Set(this.players);
|
||||
this.startTile = this.createMap();
|
||||
this.findAvailableTiles();
|
||||
}
|
||||
|
|
@ -237,8 +243,10 @@ export default class TileMap extends Entity {
|
|||
} else if (item instanceof Player) {
|
||||
tile.removeItem(item);
|
||||
this.players.push(item);
|
||||
this.foundPlayers.add(item);
|
||||
} else if (item.isBoss && this.player.removeItem(this.player.rocketLauncher)) {
|
||||
tile.killEnemy();
|
||||
this.bossKilled = true;
|
||||
} else if (item.isEnemy) {
|
||||
this.state = GameState.FIGHT;
|
||||
break;
|
||||
|
|
@ -246,6 +254,14 @@ export default class TileMap extends Entity {
|
|||
alert(`Unknown item found: ${item}`);
|
||||
}
|
||||
}
|
||||
if (tile.type === TileType.END) {
|
||||
if (this.player.removeItem(this.player.fuel)) {
|
||||
this.fuelFound = true;
|
||||
}
|
||||
if (this.player.removeItem(this.player.keys)) {
|
||||
this.keysFound = true;
|
||||
}
|
||||
}
|
||||
if (this.state === GameState.NORMAL) {
|
||||
this.nextPlayer();
|
||||
}
|
||||
|
|
@ -325,6 +341,18 @@ export default class TileMap extends Entity {
|
|||
private nextPlayer() {
|
||||
this.spinner.stop();
|
||||
this.currentPlayerIdx = (this.currentPlayerIdx + 1) % this.players.length;
|
||||
if (this.win) {
|
||||
const endTile = this.tiles.findLast(t => t.type === TileType.END);
|
||||
if (endTile) {
|
||||
for (const player of this.players) {
|
||||
const path = Pathfinding.findPath(player.tile, endTile);
|
||||
player.moveTo(endTile, path);
|
||||
}
|
||||
}
|
||||
setTimeout(alert, 2000, "🎉🎉🎉 ПОБЕДА! 🚗 🎉🎉🎉");
|
||||
} else if (this.currentPlayerIdx === 0) {
|
||||
// TODO zombies turn
|
||||
}
|
||||
}
|
||||
|
||||
private killEnemy() {
|
||||
|
|
@ -339,6 +367,28 @@ export default class TileMap extends Entity {
|
|||
this.setNormalState();
|
||||
}
|
||||
|
||||
private get win() {
|
||||
if (!this.keysFound || !this.fuelFound || !this.bossKilled) {
|
||||
return false;
|
||||
}
|
||||
const endTiles = this.tiles.filter(t => t.type === TileType.END);
|
||||
for (const tile of endTiles) {
|
||||
if (tile.items.length !== 0) return false;
|
||||
}
|
||||
for (const player of Object.values(Players)) {
|
||||
if (!this.foundPlayers.has(player)) return false;
|
||||
if (player.isDead) continue;
|
||||
|
||||
if (endTiles.every((tile) => {
|
||||
const path = Pathfinding.findPath(player.tile, tile);
|
||||
return path.length === 0;
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected draw(ctx: CanvasRenderingContext2D): void {
|
||||
ctx.scale(1 / this.width, 1 / this.height);
|
||||
|
||||
|
|
@ -363,6 +413,46 @@ export default class TileMap extends Entity {
|
|||
ctx.strokeStyle = 'yellow';
|
||||
|
||||
ctx.strokeRect(this.player.tile.centerX - w / 2, this.player.tile.centerY - w / 2, w, w);
|
||||
|
||||
let x = this.width + this.tileSize / 2 + 10;
|
||||
let y = this.height - this.tileSize / 2;
|
||||
for (const player of Object.values(Players)) {
|
||||
this.drawItem(ctx, player.type, x, y, w, this.foundPlayers.has(player));
|
||||
x += this.tileSize;
|
||||
}
|
||||
|
||||
x = this.width + this.tileSize / 2 + 10;
|
||||
y = this.height - 3 * this.tileSize / 2;
|
||||
for (const [item, found] of zip(
|
||||
[ItemType.ITEM_KEYS, ItemType.ITEM_FUEL, ItemType.ENEMY_BOSS],
|
||||
[this.keysFound, this.fuelFound, this.bossKilled],
|
||||
)) {
|
||||
this.drawItem(ctx, item, x, y, w, found);
|
||||
x += this.tileSize;
|
||||
}
|
||||
|
||||
x = this.width + this.tileSize / 2 + 10;
|
||||
y = this.height - 5 * this.tileSize / 2;
|
||||
for (const tile of this.tiles) {
|
||||
if (tile.type !== TileType.END) continue;
|
||||
|
||||
this.drawItem(ctx, ItemType.ENEMY_ZOMBIE, x, y, w, tile.items.length === 0);
|
||||
x += this.tileSize;
|
||||
}
|
||||
}
|
||||
|
||||
private drawItem(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
img: HTMLImageElement,
|
||||
x: number, y: number, w: number,
|
||||
found: boolean,
|
||||
) {
|
||||
ctx.drawImage(img, x - w / 2, y - w / 2, w, w);
|
||||
|
||||
if (!found) {
|
||||
ctx.fillStyle = `rgba(255, 255, 255, 0.6)`;
|
||||
ctx.fillRect(x - w / 2, y - w / 2, w, w);
|
||||
}
|
||||
}
|
||||
|
||||
public update(dt: number) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue