208 lines
6.9 KiB
JavaScript
208 lines
6.9 KiB
JavaScript
import { Tileset } from "../Graphics/Tileset/tileset"
|
|
import { Tank } from "../Tanks/tank";
|
|
import { Constants } from "../constants"
|
|
import { BlockTypeEnum } from "../Blocks/blockTypeEnum"
|
|
import { MapParser } from "../Graphics/Map/mapParser";
|
|
import { CollisionManager } from "./collisionManager";
|
|
import { AITankManager } from "./../Tanks/aiTankManager";
|
|
import { DirectionEnum } from "../Tanks/directionEnum";
|
|
import { SoundEnum, SoundManager } from "./soundManager";
|
|
|
|
import $ from 'jquery';
|
|
import { isThursday } from "date-fns";
|
|
|
|
export class GameField {
|
|
|
|
/**
|
|
*
|
|
* @param {number} width
|
|
* @param {number} height
|
|
* @param {CanvasRenderingContext2D} ctx
|
|
* @param {HTMLCanvasElement} canvas
|
|
*/
|
|
constructor(width = 512, height = 512, ctx, canvas) {
|
|
this.height = height;
|
|
this.width = width + 100;
|
|
this.ctx = ctx;
|
|
this.canvas = canvas;
|
|
this.tileset = null;
|
|
this.map = null;
|
|
|
|
this.soundManager = new SoundManager();
|
|
|
|
this.collisionManager = new CollisionManager(this.soundManager);
|
|
this.tank = new Tank(Constants.PLAYER_TANK_ID_IMAGE.getValue(), 0, 18 * 16, this.collisionManager);
|
|
this.aiTanks = new AITankManager(this.collisionManager);
|
|
this.collisionManager.setMainTank(this.tank);
|
|
|
|
this.lastRequest = null;
|
|
}
|
|
|
|
//add all tiles here!
|
|
async setupTileset() {
|
|
this.tileset = new Tileset("nesBattle.png");
|
|
|
|
//Bricks
|
|
this.tileset.addTile(512, 0, 32, 32, BlockTypeEnum.Brick);
|
|
|
|
//Metal
|
|
this.tileset.addTile(512, 32, 32, 32, BlockTypeEnum.Iron);
|
|
|
|
//Eagle
|
|
this.tileset.addTile(608, 64, 32, 32, BlockTypeEnum.Eagle);
|
|
this.tileset.addTile(640, 64, 32, 32, BlockTypeEnum.DestroyedEagle);
|
|
|
|
//River
|
|
this.tileset.addTile(512, 64, 32, 32, BlockTypeEnum.River);
|
|
|
|
//Forest
|
|
this.tileset.addTile(544, 64, 32, 32, BlockTypeEnum.Forest);
|
|
|
|
//Tank
|
|
this.tileset.addTile(0, 2, 28, 30, Constants.PLAYER_TANK_ID_IMAGE.getValue() + DirectionEnum.Up.getValue());
|
|
this.tileset.addTile(64, 0, 28, 28, Constants.PLAYER_TANK_ID_IMAGE.getValue() + DirectionEnum.Left.getValue());
|
|
this.tileset.addTile(128, 0, 28, 28, Constants.PLAYER_TANK_ID_IMAGE.getValue() + DirectionEnum.Down.getValue());
|
|
this.tileset.addTile(192, 0, 28, 28, Constants.PLAYER_TANK_ID_IMAGE.getValue() + DirectionEnum.Right.getValue());
|
|
|
|
//Enemy tank
|
|
this.tileset.addTile(256, 2, 28, 30, 200 + DirectionEnum.Up.getValue());
|
|
this.tileset.addTile(320, 0, 28, 28, 200 + DirectionEnum.Left.getValue());
|
|
this.tileset.addTile(386, 0, 28, 28, 200 + DirectionEnum.Down.getValue());
|
|
this.tileset.addTile(452, 0, 28, 28, 200 + DirectionEnum.Right.getValue());
|
|
|
|
this.tileset.addTile(512, 8 * 32, 32, 32, BlockTypeEnum.Explosion1);
|
|
this.tileset.addTile(544, 8 * 32, 32, 32, BlockTypeEnum.Explosion2);
|
|
this.tileset.addTile(576, 8 * 32, 32, 32, BlockTypeEnum.Explosion3);
|
|
|
|
await this.tileset.loadAll();
|
|
}
|
|
|
|
async prepareGame(level) {
|
|
if (!this.tileset) {
|
|
await this.setupTileset();
|
|
}
|
|
|
|
this.map = await new MapParser().getMap(level, this.tileset);
|
|
this.canvas.height = this.height;
|
|
this.canvas.width = this.width;
|
|
this.collisionManager.attachMap(this.map);
|
|
this.aiTanks.setCount(this.map._enemiesCount);
|
|
}
|
|
|
|
async play(level, firstTime) {
|
|
this.ctx.clearRect(0, 0, this.width, this.height);
|
|
this.tank.deathCount = 20;
|
|
this.tank.isDestroyed = false;
|
|
this.tank.x = Constants.TANK_DEFAULT_SPAWN_X.getValue();
|
|
this.tank.y = Constants.TANK_DEFAULT_SPAWN_Y.getValue();
|
|
this.aiTanks._activeTanks = [];
|
|
this.collisionManager._aiTanks = [];
|
|
|
|
$(".loading").show();
|
|
$(".text-loading").show();
|
|
$(".start-level-button").hide();
|
|
await this.prepareGame(level);
|
|
if (this.map == null) {
|
|
this.prepareGame(1);
|
|
}
|
|
$(".text-loading").hide();
|
|
$(".start-level-button").show();
|
|
|
|
if (firstTime) {
|
|
$(".start-level-button").on("click", () => {
|
|
$(".loading").hide();
|
|
this.soundManager.playSound(SoundEnum.GameStart);
|
|
requestAnimationFrame(() => this.gameLoop());
|
|
})
|
|
}
|
|
else {
|
|
$(".loading").hide();
|
|
requestAnimationFrame(() => this.gameLoop());
|
|
}
|
|
|
|
}
|
|
|
|
lose() {
|
|
this.soundManager.playSound(SoundEnum.GameOver);
|
|
requestAnimationFrame(() => this.drawFieldRecursive())
|
|
setTimeout(() => {
|
|
cancelAnimationFrame(this.lastRequest);
|
|
this.lastRequest = undefined;
|
|
this.play(1, false);
|
|
}, 2000);
|
|
}
|
|
|
|
win() {
|
|
cancelAnimationFrame(this.lastRequest);
|
|
this.lastRequest = undefined;
|
|
setTimeout(() => { this.play(this.map.mapLevel + 1, false); }, 2000);
|
|
}
|
|
|
|
|
|
async gameLoop() {
|
|
if (this.map.getEagle().isDestroyed()) {
|
|
this.lose();
|
|
return;
|
|
}
|
|
|
|
if (this.aiTanks.isAllTanksDied()) {
|
|
this.win();
|
|
return;
|
|
}
|
|
|
|
if (this.tank.canBeErased()) {
|
|
this.lose();
|
|
return;
|
|
}
|
|
|
|
this.drawField();
|
|
|
|
this.lastRequest = requestAnimationFrame(() => this.gameLoop());
|
|
}
|
|
|
|
drawFieldRecursive() {
|
|
this.drawField();
|
|
this.lastRequest = requestAnimationFrame(() => this.drawFieldRecursive());
|
|
}
|
|
|
|
drawField() {
|
|
let lateDraw = [];
|
|
|
|
for (let x = 0; x < this.map.width; x += 1) {
|
|
for (let y = 0; y < this.map.height; y += 1) {
|
|
this.ctx.fillStyle = "black";
|
|
this.ctx.fillRect(x * Constants.TILE_SIZE.getValue(), y * Constants.TILE_SIZE.getValue(),
|
|
Constants.TILE_SIZE.getValue(), Constants.TILE_SIZE.getValue());
|
|
|
|
let element = this.map.getElement(x, y);
|
|
if (element.getType() == BlockTypeEnum.Forest) {
|
|
lateDraw.push({ element, x, y });
|
|
} else {
|
|
element.draw(this.ctx, x * Constants.TILE_SIZE.getValue(), y * Constants.TILE_SIZE.getValue());
|
|
}
|
|
}
|
|
}
|
|
|
|
this.tank.draw(this.tileset, this.ctx);
|
|
|
|
this.aiTanks.drawAllTanks(this.tileset, this.ctx);
|
|
|
|
for (let el of lateDraw) {
|
|
el.element.draw(this.ctx, el.x * Constants.TILE_SIZE.getValue(), el.y * Constants.TILE_SIZE.getValue());
|
|
}
|
|
|
|
this.drawPanel();
|
|
|
|
}
|
|
|
|
drawPanel() {
|
|
this.ctx.fillStyle = "black";
|
|
this.ctx.fillRect(this.width - 90, 0, 90, 100);
|
|
|
|
this.ctx.font = "20px VT323, sans-serif";
|
|
this.ctx.fillStyle = "white";
|
|
this.ctx.fillText("Level: " + this.map.mapLevel, this.width - 90, 20);
|
|
this.ctx.fillText("Tanks: " + this.aiTanks._count, this.width - 90, 50);
|
|
}
|
|
|
|
} |