mirror of
https://github.com/Sheldan/canvas.git
synced 2026-01-01 23:07:47 +00:00
survivors: fixing drops being duplicated (sometimes)
adding item container system to not edit the list while iterating over
This commit is contained in:
@@ -1,16 +1,16 @@
|
|||||||
import {Enemy} from "./Enemies.ts";
|
import {Enemy} from "./Enemies.ts";
|
||||||
import {Player} from "./Player.ts";
|
import {Player} from "./Player.ts";
|
||||||
import {Projectile, ProjectileStats} from "./projectile.ts";
|
import {Projectile } from "./projectile.ts";
|
||||||
import {Vector} from "./base.ts";
|
import {Vector} from "./base.ts";
|
||||||
import type {Drop, Placeable} from "./interfaces.ts";
|
import type {Drop, Placeable} from "./interfaces.ts";
|
||||||
|
|
||||||
export class World {
|
export class World {
|
||||||
private _enemies: Enemy[] = [];
|
private _enemies: ObjectContainer<Enemy> = new ObjectContainer<Enemy>()
|
||||||
private _projectiles: Projectile[] = [];
|
private _projectiles: ObjectContainer<Projectile> = new ObjectContainer<Projectile>();
|
||||||
private _drops: Drop[] = [];
|
private _drops: ObjectContainer<Drop> = new ObjectContainer<Drop>();
|
||||||
private _player: Player;
|
private _player: Player;
|
||||||
private _ctx: CanvasRenderingContext2D;
|
private readonly _ctx: CanvasRenderingContext2D;
|
||||||
private _size: Vector
|
private _size: Vector;
|
||||||
|
|
||||||
constructor(player: Player, ctx: CanvasRenderingContext2D, size: Vector) {
|
constructor(player: Player, ctx: CanvasRenderingContext2D, size: Vector) {
|
||||||
this._player = player;
|
this._player = player;
|
||||||
@@ -19,26 +19,42 @@ export class World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enemiesAct() {
|
enemiesAct() {
|
||||||
this._enemies.forEach(enemy => enemy.act())
|
this._enemies.items.forEach(enemy => enemy.act())
|
||||||
this._projectiles.forEach(projectile => projectile.act())
|
this._enemies.clean()
|
||||||
this._drops.forEach(drop => drop.act())
|
this._projectiles.items.forEach(projectile => projectile.act())
|
||||||
|
this._projectiles.clean()
|
||||||
|
this._drops.items.forEach(drop => drop.act())
|
||||||
|
this._drops.clean()
|
||||||
}
|
}
|
||||||
|
|
||||||
draw() {
|
draw() {
|
||||||
this._enemies.forEach(enemy => enemy.draw(this._ctx))
|
this._enemies.items.forEach(enemy => enemy.draw(this._ctx))
|
||||||
this._drops.forEach(drop => drop.draw(this._ctx))
|
this._drops.items.forEach(drop => drop.draw(this._ctx))
|
||||||
this._projectiles.forEach(projectile => projectile.draw(this._ctx))
|
this._projectiles.items.forEach(projectile => projectile.draw(this._ctx))
|
||||||
this._player.draw(this._ctx);
|
this._player.draw(this._ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
addProjectile(projectile: Projectile) {
|
addProjectile(projectile: Projectile) {
|
||||||
this._projectiles.push(projectile)
|
this._projectiles.add(projectile)
|
||||||
}
|
}
|
||||||
|
|
||||||
addDrop(drop: Drop) {
|
addDrop(drop: Drop) {
|
||||||
this._drops.push(drop)
|
this._drops.add(drop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeDrop(drop: Drop) {
|
||||||
|
this._drops.scheduleRemoval(drop)
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEnemy(enemy: Enemy) {
|
||||||
|
this._enemies.scheduleRemoval(enemy)
|
||||||
|
}
|
||||||
|
|
||||||
|
removeProjectile(projectile: Projectile) {
|
||||||
|
this._projectiles.scheduleRemoval(projectile)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
movePlayer(vector: Vector) {
|
movePlayer(vector: Vector) {
|
||||||
this._player.position.x += vector.x;
|
this._player.position.x += vector.x;
|
||||||
this._player.position.y += vector.y;
|
this._player.position.y += vector.y;
|
||||||
@@ -48,26 +64,11 @@ export class World {
|
|||||||
this._player.position.y = Math.max(this._player.getSize(), this._player.position.y)
|
this._player.position.y = Math.max(this._player.getSize(), this._player.position.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
removeDrop(drop: Drop) {
|
|
||||||
this._drops = this._drops.filter(item => item !== drop)
|
|
||||||
}
|
|
||||||
|
|
||||||
removeProjectile(projectile: Projectile) {
|
|
||||||
this._projectiles = this._projectiles.filter(item => item !== projectile)
|
|
||||||
}
|
|
||||||
|
|
||||||
removeEnemy(enemy: Enemy) {
|
|
||||||
this._enemies = this._enemies.filter(item => item !== enemy)
|
|
||||||
}
|
|
||||||
|
|
||||||
maxValue() {
|
maxValue() {
|
||||||
return Math.max(this.size.x, this.size.y)
|
return Math.max(this.size.x, this.size.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
get enemies(): [Enemy] {
|
|
||||||
return this._enemies;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
get size(): Vector {
|
get size(): Vector {
|
||||||
return this._size;
|
return this._size;
|
||||||
@@ -78,7 +79,7 @@ export class World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addEnemy(enemy: Enemy) {
|
addEnemy(enemy: Enemy) {
|
||||||
this._enemies.push(enemy)
|
this._enemies.add(enemy)
|
||||||
}
|
}
|
||||||
|
|
||||||
randomPlace(): Vector {
|
randomPlace(): Vector {
|
||||||
@@ -96,7 +97,7 @@ export class World {
|
|||||||
getClosestTargetToButNotArray(point: Vector, placeAbles?: [Placeable | undefined], range?: number): [number, Placeable | undefined] | undefined {
|
getClosestTargetToButNotArray(point: Vector, placeAbles?: [Placeable | undefined], range?: number): [number, Placeable | undefined] | undefined {
|
||||||
let currentTarget;
|
let currentTarget;
|
||||||
let currentDistance = Number.MAX_SAFE_INTEGER;
|
let currentDistance = Number.MAX_SAFE_INTEGER;
|
||||||
this._enemies.forEach(enemy => {
|
this._enemies.items.forEach(enemy => {
|
||||||
if(placeAbles && placeAbles.indexOf(enemy) !== -1) {
|
if(placeAbles && placeAbles.indexOf(enemy) !== -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -117,4 +118,36 @@ export class World {
|
|||||||
get player(): Player {
|
get player(): Player {
|
||||||
return this._player;
|
return this._player;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ObjectContainer<T> {
|
||||||
|
private _items: T[] = [];
|
||||||
|
private _itemsToRemove: T[] = [];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._items = []
|
||||||
|
this._itemsToRemove = []
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleRemoval(item: T) {
|
||||||
|
this._itemsToRemove.push(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
clean() {
|
||||||
|
this._itemsToRemove.forEach(value => this.remove(value))
|
||||||
|
this._itemsToRemove = []
|
||||||
|
}
|
||||||
|
|
||||||
|
private remove(itemToRemove: T) {
|
||||||
|
this._items = this._items.filter(item => item !== itemToRemove)
|
||||||
|
}
|
||||||
|
|
||||||
|
add(item: T) {
|
||||||
|
this._items.push(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get items(): T[] {
|
||||||
|
return this._items;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,6 @@ export class MoneyDrop extends BasicDrop {
|
|||||||
drop.worth = 1;
|
drop.worth = 1;
|
||||||
drop.size = 1;
|
drop.size = 1;
|
||||||
drop._color = 'orange';
|
drop._color = 'orange';
|
||||||
world.addDrop(drop)
|
|
||||||
return drop;
|
return drop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {Vector} from "./base.ts";
|
|||||||
import {BasicEnemy, ContainerEnemy, Enemy, HealthEnemy, ShootingEnemy} from "./Enemies.ts";
|
import {BasicEnemy, ContainerEnemy, Enemy, HealthEnemy, ShootingEnemy} from "./Enemies.ts";
|
||||||
import {HUD} from "./ui.ts";
|
import {HUD} from "./ui.ts";
|
||||||
import {HomingPistol, Pistol} from "./weapons.ts";
|
import {HomingPistol, Pistol} from "./weapons.ts";
|
||||||
|
import {MoneyDrop} from "./drop.ts";
|
||||||
|
|
||||||
|
|
||||||
let hud: HUD;
|
let hud: HUD;
|
||||||
@@ -107,7 +108,6 @@ docReady(function () {
|
|||||||
world = new World(player, ctx, new Vector(window.innerWidth, window.innerHeight));
|
world = new World(player, ctx, new Vector(window.innerWidth, window.innerHeight));
|
||||||
state = new WorldState();
|
state = new WorldState();
|
||||||
|
|
||||||
ShootingEnemy.spawnShootingEnemy(world, new Vector(350, 350))
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
BasicEnemy.spawnBasicEnemy(world)
|
BasicEnemy.spawnBasicEnemy(world)
|
||||||
ShootingEnemy.spawnShootingEnemy(world)
|
ShootingEnemy.spawnShootingEnemy(world)
|
||||||
|
|||||||
Reference in New Issue
Block a user