2022-12-20 10:27:51 +00:00
|
|
|
import { Collider2D, Contact2DType, Node } from "cc";
|
|
|
|
import { ISignal } from "../../Services/EventSystem/ISignal";
|
|
|
|
import { Signal } from "../../Services/EventSystem/Signal";
|
2022-11-08 18:45:57 +00:00
|
|
|
import { GameTimer } from "../../Services/GameTimer";
|
2022-12-20 10:27:51 +00:00
|
|
|
import { GroupType } from "../GroupType";
|
2022-12-23 08:22:22 +00:00
|
|
|
import { Item } from "../Items/Item";
|
2022-12-20 10:27:51 +00:00
|
|
|
import { ItemManager } from "../Items/ItemManager";
|
2022-12-21 10:30:21 +00:00
|
|
|
import { Projectile } from "../Projectile/Projectile";
|
2022-11-28 11:19:04 +00:00
|
|
|
import { Enemy } from "../Unit/Enemy/Enemy";
|
2022-12-20 10:27:51 +00:00
|
|
|
import { Player } from "../Unit/Player/Player";
|
2022-11-08 18:45:57 +00:00
|
|
|
|
|
|
|
export class PlayerCollisionSystem {
|
|
|
|
private playerContacts: Collider2D[] = [];
|
|
|
|
private collisionTimer: GameTimer;
|
|
|
|
|
|
|
|
private groupToResolver: Map<number, (collider: Collider2D) => void> = new Map<number, (collider: Collider2D) => void>();
|
|
|
|
|
2022-12-20 10:27:51 +00:00
|
|
|
private itemPickedUpEvent = new Signal<Node>();
|
|
|
|
|
|
|
|
public constructor(private player: Player, collisionDelay: number, private itemManager: ItemManager) {
|
2022-11-08 18:45:57 +00:00
|
|
|
this.player = player;
|
|
|
|
|
|
|
|
player.Collider.on(Contact2DType.BEGIN_CONTACT, this.onPlayerContactBegin, this);
|
|
|
|
player.Collider.on(Contact2DType.END_CONTACT, this.onPlayerContactEnd, this);
|
|
|
|
|
|
|
|
this.collisionTimer = new GameTimer(collisionDelay);
|
|
|
|
|
|
|
|
this.groupToResolver.set(GroupType.ENEMY, this.resolveEnemyContact.bind(this));
|
2022-12-21 10:30:21 +00:00
|
|
|
this.groupToResolver.set(GroupType.ENEMY_PROJECTILE, this.resolveEnemyProjectileContact.bind(this));
|
2022-12-23 08:22:22 +00:00
|
|
|
this.groupToResolver.set(GroupType.ITEM, this.resolveItemContact.bind(this));
|
2022-11-08 18:45:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public gameTick(deltaTime: number): void {
|
|
|
|
this.collisionTimer.gameTick(deltaTime);
|
|
|
|
if (this.collisionTimer.tryFinishPeriod()) {
|
|
|
|
this.resolveAllContacts();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-20 10:27:51 +00:00
|
|
|
public get ItemPickedUpEvent(): ISignal<Node> {
|
|
|
|
return this.itemPickedUpEvent;
|
|
|
|
}
|
|
|
|
|
2022-11-08 18:45:57 +00:00
|
|
|
private onPlayerContactBegin(_selfCollider: Collider2D, otherCollider: Collider2D): void {
|
|
|
|
this.playerContacts.push(otherCollider);
|
|
|
|
this.resolveContact(otherCollider);
|
|
|
|
}
|
|
|
|
|
|
|
|
private onPlayerContactEnd(_selfCollider: Collider2D, otherCollider: Collider2D): void {
|
|
|
|
const index: number = this.playerContacts.indexOf(otherCollider);
|
|
|
|
if (index != -1) {
|
|
|
|
this.playerContacts.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private resolveAllContacts(): void {
|
|
|
|
for (let i = 0; i < this.playerContacts.length; i++) {
|
|
|
|
this.resolveContact(this.playerContacts[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private resolveContact(otherCollider: Collider2D): void {
|
2023-01-02 10:14:44 +00:00
|
|
|
if (!this.player.Health.IsAlive) return;
|
|
|
|
|
2022-11-08 18:45:57 +00:00
|
|
|
if (this.groupToResolver.has(otherCollider.group)) {
|
|
|
|
this.groupToResolver.get(otherCollider.group)(otherCollider);
|
|
|
|
} else {
|
|
|
|
console.log("Collided with undefined group: " + otherCollider.group);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private resolveEnemyContact(enemyCollider: Collider2D): void {
|
|
|
|
const damage: number = enemyCollider.node.getComponent(Enemy).Damage;
|
|
|
|
console.log("Collided with enemy: Damage: " + damage);
|
|
|
|
this.player.Health.damage(damage);
|
|
|
|
}
|
2022-11-16 11:26:20 +00:00
|
|
|
|
2022-12-21 10:30:21 +00:00
|
|
|
private resolveEnemyProjectileContact(enemyCollider: Collider2D): void {
|
|
|
|
const projectile = enemyCollider.node.getComponent(Projectile);
|
|
|
|
const damage: number = projectile.Damage;
|
|
|
|
projectile.pierce();
|
|
|
|
console.log("Collided with enemy projectile: Damage: " + damage);
|
|
|
|
|
|
|
|
this.player.Health.damage(damage);
|
|
|
|
}
|
|
|
|
|
2022-12-23 08:22:22 +00:00
|
|
|
private resolveItemContact(xpCollider: Collider2D): void {
|
|
|
|
console.log("Collided with item");
|
|
|
|
this.itemManager.pickupItem(xpCollider.node.getComponent(Item));
|
2022-12-20 12:37:56 +00:00
|
|
|
}
|
2022-11-08 18:45:57 +00:00
|
|
|
}
|