Enemy spawners

This commit is contained in:
Martin 2022-12-05 12:19:46 +01:00
parent 772a5cc7e0
commit 8aa7ee6f2e
12 changed files with 104 additions and 28 deletions

View File

@ -59,7 +59,6 @@ export class GameBootstrapper extends Component {
this.player.node,
settings.player.haloLauncher
);
this.haloProjectileLauncher.upgrade();
this.horizontalProjectileLauncher = new WaveProjectileLauncher(
this.horizontalProjectileLauncherComponent,
@ -67,7 +66,6 @@ export class GameBootstrapper extends Component {
[new Vec2(-1, 0), new Vec2(1, 0)],
settings.player.horizontalLauncher
);
this.horizontalProjectileLauncher.upgrade();
this.diagonalProjectileLauncher = new WaveProjectileLauncher(
this.diagonalProjectileLauncherComponent,
@ -75,7 +73,6 @@ export class GameBootstrapper extends Component {
[new Vec2(-0.5, -0.5), new Vec2(0.5, -0.5)],
settings.player.diagonalLauncher
);
this.diagonalProjectileLauncher.upgrade();
new PlayerProjectileCollisionSystem([this.haloProjectileLauncher, this.horizontalProjectileLauncher, this.diagonalProjectileLauncher]);

View File

@ -0,0 +1,22 @@
import { GameTimer } from "../../../Services/GameTimer";
import { roundToOneDecimal } from "../../../Services/Utils/MathUtils";
import { EnemySpawner } from "./EnemySpawner";
import { EnemyType } from "./EnemyType";
export class CircularEnemySpawner {
private spawnTimer: GameTimer = new GameTimer(10);
public constructor(private enemySpawner: EnemySpawner, private enemiesToSpawn: number, private enemyType: EnemyType) {}
public gameTick(deltaTime: number): void {
this.spawnTimer.gameTick(deltaTime);
if (this.spawnTimer.tryFinishPeriod()) {
const angle: number = (2 * Math.PI) / this.enemiesToSpawn;
for (let i = 0; i < this.enemiesToSpawn; i++) {
const posX: number = roundToOneDecimal(Math.sin(angle * i)) * 500;
const posY: number = roundToOneDecimal(Math.cos(angle * i)) * 500;
this.enemySpawner.spawnNewEnemy(posX, posY);
}
}
}
}

View File

@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "2e8e236a-fcdd-4995-aaff-be8802488d8c",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@ -6,7 +6,7 @@ import { UnitHealth } from "../UnitHealth";
const { ccclass, property } = _decorator;
@ccclass("Enemy")
export class Enemy extends Component implements IDamageDealing {
export class Enemy extends Component {
@property(BoxCollider2D) public collider: BoxCollider2D;
private health: UnitHealth = new UnitHealth(1);
@ -15,7 +15,7 @@ export class Enemy extends Component implements IDamageDealing {
public setup(position: Vec3): void {
this.health = new UnitHealth(1);
this.speed = randomRange(0.5, 1);
this.speed = randomRange(40, 90);
this.node.setWorldPosition(position);
this.node.active = true;
}
@ -51,7 +51,3 @@ export class Enemy extends Component implements IDamageDealing {
this.node.setWorldPosition(newPosition);
}
}
export interface IDamageDealing {
Damage: number;
}

View File

@ -1,8 +1,11 @@
import { Component, Node, _decorator } from "cc";
import { XPSpawner } from "../../XP/XPSpawner";
import { CircularEnemySpawner } from "./CircularEnemySpawner";
import { Enemy } from "./Enemy";
import { EnemyMover } from "./EnemyMover";
import { EnemySpawner } from "./EnemySpawner";
import { EnemyType } from "./EnemyType";
import { InvididualEnemySpawner as IndividualEnemySpawner } from "./InvididualEnemySpawner";
const { ccclass, property } = _decorator;
@ccclass("EnemyManager")
@ -12,30 +15,39 @@ export class EnemyManager extends Component {
private enemyMover: EnemyMover;
private individualEnemySpawner: IndividualEnemySpawner;
private circularEnemySpawner: CircularEnemySpawner;
public init(targetNode: Node): void {
this.enemyMover = new EnemyMover(targetNode);
this.enemySpawner.init(targetNode);
this.enemySpawner.EnemyAddedEvent.on(this.onEnemyAdded, this);
this.enemySpawner.enemyRemovedEvent.on(this.onRemoveEnemy, this);
this.individualEnemySpawner = new IndividualEnemySpawner(this.enemySpawner, EnemyType.Basic);
this.circularEnemySpawner = new CircularEnemySpawner(this.enemySpawner, 20, EnemyType.Basic);
this.xpSpawner.init();
}
public gameTick(deltaTime: number): void {
this.enemySpawner.gameTick(deltaTime);
this.individualEnemySpawner.gameTick(deltaTime);
this.circularEnemySpawner.gameTick(deltaTime);
this.enemyMover.gameTick(deltaTime);
}
private onEnemyAdded(enemy: Enemy): void {
enemy.DeathEvent.on(this.onEnemyDied, this);
this.enemyMover.addEnemy(enemy);
}
private onEnemyDied(enemy: Enemy): void {
enemy.DeathEvent.off(this.onEnemyDied);
this.xpSpawner.spawnXp(enemy.node.worldPosition, 1);
}
private onRemoveEnemy(enemy: Enemy): void {
this.enemyMover.removeEnemy(enemy);
}
}

View File

@ -22,7 +22,7 @@ export class EnemyMover {
this.enemies.forEach((enemy) => {
let direction: Vec3 = new Vec3();
direction = Vec3.subtract(direction, this.targetNode.worldPosition, enemy.node.worldPosition);
enemy.moveBy(direction.multiplyScalar(deltaTime).normalize());
enemy.moveBy(direction.normalize().multiplyScalar(deltaTime));
});
}
}

View File

@ -1,7 +1,6 @@
import { Component, Prefab, randomRange, Vec3, _decorator, Node } from "cc";
import { Component, Node, Prefab, Vec3, _decorator } from "cc";
import { ISignal } from "../../../Services/EventSystem/ISignal";
import { Signal } from "../../../Services/EventSystem/Signal";
import { GameTimer } from "../../../Services/GameTimer";
import { ObjectPool } from "../../../Services/ObjectPool";
import { Enemy } from "./Enemy";
@ -12,34 +11,30 @@ export class EnemySpawner extends Component {
@property(Prefab) private enemies: Prefab[] = [];
public enemyAddedEvent: Signal<Enemy> = new Signal<Enemy>();
public enemyRemovedEvent: Signal<Enemy> = new Signal<Enemy>();
private enemyPool: ObjectPool<Enemy>;
private spawnTimer: GameTimer;
private targetNode: Node;
public init(targetNode: Node): void {
this.targetNode = targetNode;
this.enemyPool = new ObjectPool(this.enemies[0], this.node, 5, "Enemy");
this.spawnTimer = new GameTimer(1);
}
public gameTick(deltaTime: number): void {
this.spawnTimer.gameTick(deltaTime);
if (this.spawnTimer.tryFinishPeriod()) {
this.spawnNewEnemy();
}
this.enemyPool = new ObjectPool(this.enemies[0], this.node, 50, "Enemy");
}
public get EnemyAddedEvent(): ISignal<Enemy> {
return this.enemyAddedEvent;
}
private spawnNewEnemy(): void {
public get EnemyRemovedEvent(): ISignal<Enemy> {
return this.enemyRemovedEvent;
}
public spawnNewEnemy(positionX: number, positionY: number): void {
const enemy = this.enemyPool.borrow();
const spawnPosition = new Vec3();
spawnPosition.x = this.targetNode.worldPosition.x + randomRange(-300, 300);
spawnPosition.y = this.targetNode.worldPosition.y + randomRange(-800, 800);
spawnPosition.x = this.targetNode.worldPosition.x + positionX;
spawnPosition.y = this.targetNode.worldPosition.y + positionY;
enemy.setup(spawnPosition);
enemy.DeathEvent.on(this.returnEnemyToPool, this);
@ -50,5 +45,7 @@ export class EnemySpawner extends Component {
private returnEnemyToPool(enemy: Enemy): void {
enemy.DeathEvent.off(this.returnEnemyToPool);
this.enemyPool.return(enemy);
this.enemyRemovedEvent.trigger(enemy);
}
}

View File

@ -0,0 +1,3 @@
export enum EnemyType {
Basic = "Basic"
}

View File

@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "8db8a72b-543d-4566-8900-7701372634e3",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@ -0,0 +1,18 @@
import { randomRange } from "cc";
import { GameTimer } from "../../../Services/GameTimer";
import { randomPositiveOrNegative } from "../../../Services/Utils/MathUtils";
import { EnemySpawner } from "./EnemySpawner";
import { EnemyType } from "./EnemyType";
export class InvididualEnemySpawner {
private spawnTimer: GameTimer = new GameTimer(1);
public constructor(private enemySpawner: EnemySpawner, enemyType: EnemyType) {}
public gameTick(deltaTime: number): void {
this.spawnTimer.gameTick(deltaTime);
if (this.spawnTimer.tryFinishPeriod()) {
const posX: number = randomRange(300, 600) * randomPositiveOrNegative();
const posY: number = randomRange(300, 600) * randomPositiveOrNegative();
this.enemySpawner.spawnNewEnemy(posX, posY);
}
}
}

View File

@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "46674857-f5ad-4112-8b5d-c19879117904",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@ -1,3 +1,7 @@
export function roundToOneDecimal(num: number): number {
return Math.round(num * 10) / 10;
}
export function randomPositiveOrNegative(): number {
return Math.random() < 0.5 ? 1 : -1;
}