2021-06-05 15:21:59 +02:00

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);
}
}