167 lines
4.8 KiB
JavaScript
167 lines
4.8 KiB
JavaScript
import { BlockTypeEnum } from "../Blocks/blockTypeEnum";
|
|
import { Constants } from "../constants";
|
|
import { Map } from "../Graphics/Map/map";
|
|
import { Tank } from "../Tanks/tank";
|
|
import { SoundEnum, SoundManager } from "./soundManager";
|
|
|
|
export class CollisionManager {
|
|
/**
|
|
* @type {Map}
|
|
*/
|
|
_map;
|
|
|
|
/**
|
|
* @type {Tank}
|
|
*/
|
|
_mainTank;
|
|
|
|
/**
|
|
* @type {Tank[]}
|
|
*/
|
|
_aiTanks = [];
|
|
|
|
|
|
/**
|
|
* @param {SoundManager} soundManager
|
|
*/
|
|
constructor(soundManager) {
|
|
this.soundManager = soundManager;
|
|
}
|
|
|
|
|
|
attachMap(map) {
|
|
this._map = map;
|
|
}
|
|
|
|
setMainTank(tank) {
|
|
this._mainTank = tank;
|
|
}
|
|
|
|
addNewAITank(tank) {
|
|
if (tank)
|
|
this._aiTanks.push(tank);
|
|
}
|
|
|
|
deleteFromAITank(tank) {
|
|
this._aiTanks = this._aiTanks.filter(t => tank.x != t.x && tank.y != t.y);
|
|
}
|
|
|
|
checkCollisionForTank(xMin, xMax, yMin, yMax, tank) {
|
|
if (!this._map)
|
|
return false;
|
|
|
|
return (this._checkTankCollision(xMin, xMax, yMin, yMax, tank) != null) ||
|
|
(this._checkBoundaries(xMin, xMax, yMin, yMax) != null) ||
|
|
(this._checkBlockCollision(xMin, xMax, yMin, yMax, false) != null);
|
|
}
|
|
|
|
|
|
checkCollisionForShots(xMin, xMax, yMin, yMax, direction, tank) {
|
|
if (!this._map)
|
|
return false;
|
|
|
|
let blockColl = this._checkBlockCollision(xMin, xMax, yMin, yMax, true);
|
|
|
|
if (blockColl) {
|
|
for (let blockInfo of Array.from(blockColl)) {
|
|
blockInfo.block.resolveAttack(blockInfo.boxId, direction);
|
|
|
|
switch(blockInfo.block.getType()) {
|
|
case BlockTypeEnum.Brick:
|
|
this.soundManager.playSound(SoundEnum.BrickCollision);
|
|
break;
|
|
case BlockTypeEnum.Iron:
|
|
this.soundManager.playSound(SoundEnum.SteelCollision);
|
|
break;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (this._checkBoundaries(xMin, xMax, yMin, yMax) != null)
|
|
return true;
|
|
|
|
let collTank = this._checkTankCollision(xMin, xMax, yMin, yMax, tank);
|
|
|
|
if (collTank && collTank.id != tank.id) {
|
|
collTank.isDestroyed = true;
|
|
this.soundManager.playSound(SoundEnum.Explosion);
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
_checkTankCollision(xMin, xMax, yMin, yMax, tank) {
|
|
let tanks = [this._mainTank].concat(this._aiTanks).filter(t => t !== tank);
|
|
|
|
for (let tankToCheck of tanks) {
|
|
let box = tankToCheck.getCollisionBox();
|
|
if (this.intersect(xMin, xMax, yMin, yMax, box.minX, box.maxX, box.minY, box.maxY)) return tankToCheck;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
_checkBoundaries(xMin, xMax, yMin, yMax) {
|
|
const tilesize = Constants.TILE_SIZE.getValue();
|
|
|
|
if (xMin < 0 || yMin < 0 || xMax > this._map.width * tilesize || yMax > this._map.height * tilesize)
|
|
return [];
|
|
return null;
|
|
}
|
|
|
|
_checkBlockCollision(xMin, xMax, yMin, yMax, isShot) {
|
|
const blocksToCheck = this._getAllElementsOfMapOn(xMin, xMax, yMin, yMax);
|
|
const tilesize = Constants.TILE_SIZE.getValue();
|
|
let blockColl = new Set();
|
|
|
|
for (let i = 0; i < blocksToCheck.length; i++) {
|
|
if (isShot && blocksToCheck[i].block.getType() == BlockTypeEnum.River)
|
|
continue;
|
|
|
|
let boxes = blocksToCheck[i].block.getAllBoxes();
|
|
let x = blocksToCheck[i].xPos;
|
|
let y = blocksToCheck[i].yPos;
|
|
|
|
for (let j = 0; j < boxes.length; j++) {
|
|
const box = boxes[j];
|
|
if (this.intersect(xMin, xMax, yMin, yMax, x * tilesize + box.getXMin(), x * tilesize + box.getXMax(),
|
|
y * tilesize + box.getYMin(), y * tilesize + box.getYMax())) blockColl.add({block:blocksToCheck[i].block, boxId:j});
|
|
}
|
|
}
|
|
|
|
if (blockColl.size != 0){
|
|
return blockColl.values();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
_getAllElementsOfMapOn(xMin, xMax, yMin, yMax) {
|
|
const tilesize = Constants.TILE_SIZE.getValue();
|
|
let elements = [];
|
|
|
|
for (let x = 0; x < this._map.width; x++) {
|
|
for (let y = 0; y < this._map.height; y++) {
|
|
if (this.intersect(xMin, xMax, yMin, yMax, x * tilesize, (x + 1) * tilesize, y * tilesize, (y + 1) * tilesize))
|
|
elements.push({
|
|
block: this._map.getElement(x, y),
|
|
xPos: x,
|
|
yPos: y
|
|
});
|
|
}
|
|
}
|
|
|
|
return elements;
|
|
}
|
|
|
|
intersect(xMin, xMax, yMin, yMax, anXMin, anXMax, anYMin, anYMax) {
|
|
return (xMin <= anXMax && xMax >= anXMin) &&
|
|
(yMin <= anYMax && yMax >= anYMin);
|
|
}
|
|
|
|
|
|
} |