2022-12-20 12:37:56 +00:00
|
|
|
import { BoxCollider2D, Component, Material, randomRange, Sprite, Vec3, _decorator } from "cc";
|
2022-11-28 11:19:04 +00:00
|
|
|
import { ISignal } from "../../../Services/EventSystem/ISignal";
|
|
|
|
import { Signal } from "../../../Services/EventSystem/Signal";
|
2022-12-19 13:24:29 +00:00
|
|
|
import { delay } from "../../../Services/Utils/AsyncUtils";
|
2022-12-12 11:46:17 +00:00
|
|
|
import { EnemySettings } from "../../Data/GameSettings";
|
2022-11-28 11:19:04 +00:00
|
|
|
import { UnitHealth } from "../UnitHealth";
|
2022-12-05 14:13:42 +00:00
|
|
|
import { EnemyMovementType } from "./EnemyMovementType";
|
2022-11-28 11:19:04 +00:00
|
|
|
|
2022-11-08 18:45:57 +00:00
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
|
|
|
@ccclass("Enemy")
|
2022-12-05 11:19:46 +00:00
|
|
|
export class Enemy extends Component {
|
2022-12-19 13:24:29 +00:00
|
|
|
@property(BoxCollider2D) private collider: BoxCollider2D;
|
|
|
|
@property(Sprite) private sprite: Sprite;
|
2022-12-20 07:44:26 +00:00
|
|
|
@property(Material) private defaultMaterial: Material;
|
2022-12-19 13:24:29 +00:00
|
|
|
@property(Material) private whiteMaterial: Material;
|
2022-11-08 18:45:57 +00:00
|
|
|
|
2022-12-12 11:46:17 +00:00
|
|
|
private deathEvent: Signal<Enemy> = new Signal<Enemy>();
|
2022-12-13 17:56:00 +00:00
|
|
|
private lifetimeEndedEvent: Signal<Enemy> = new Signal<Enemy>();
|
2022-12-12 11:46:17 +00:00
|
|
|
|
2022-12-20 12:02:57 +00:00
|
|
|
private id: string;
|
2022-12-05 14:13:42 +00:00
|
|
|
private movementType: EnemyMovementType;
|
2022-12-13 17:56:00 +00:00
|
|
|
private health: UnitHealth;
|
2022-12-12 11:46:17 +00:00
|
|
|
private damage: number;
|
2022-12-07 09:47:46 +00:00
|
|
|
private speedX: number;
|
|
|
|
private speedY: number;
|
2022-12-13 17:56:00 +00:00
|
|
|
private lifetimeLeft: number;
|
|
|
|
|
|
|
|
private xpReward: number;
|
|
|
|
private goldReward: number;
|
2022-12-20 12:37:56 +00:00
|
|
|
private healthPotionRewardChance: number;
|
2022-12-23 08:52:26 +00:00
|
|
|
private magnetRewardChance: number;
|
|
|
|
private chestRewardChance: number;
|
2022-11-08 18:45:57 +00:00
|
|
|
|
2022-12-19 15:24:52 +00:00
|
|
|
private endOfLifetimeTriggered = false;
|
|
|
|
|
2022-12-12 11:46:17 +00:00
|
|
|
public setup(position: Vec3, settings: EnemySettings): void {
|
2022-12-20 12:02:57 +00:00
|
|
|
this.id = settings.id;
|
2022-12-12 11:46:17 +00:00
|
|
|
this.movementType = <EnemyMovementType>settings.moveType;
|
|
|
|
this.health = new UnitHealth(settings.health);
|
|
|
|
this.damage = settings.damage;
|
|
|
|
this.speedX = randomRange(settings.speed / 2, settings.speed);
|
|
|
|
this.speedY = randomRange(settings.speed / 2, settings.speed);
|
2022-12-13 17:56:00 +00:00
|
|
|
this.lifetimeLeft = settings.lifetime;
|
|
|
|
|
|
|
|
this.xpReward = settings.xpReward;
|
|
|
|
this.goldReward = settings.goldReward;
|
2022-12-20 12:37:56 +00:00
|
|
|
this.healthPotionRewardChance = settings.healthPotionRewardChance;
|
2022-12-23 08:52:26 +00:00
|
|
|
this.magnetRewardChance = settings.magnetRewardChance;
|
|
|
|
this.chestRewardChance = settings.chestRewardChance;
|
2022-12-12 11:46:17 +00:00
|
|
|
|
2022-11-16 11:26:20 +00:00
|
|
|
this.node.setWorldPosition(position);
|
|
|
|
this.node.active = true;
|
2022-12-19 13:24:29 +00:00
|
|
|
|
|
|
|
this.health.HealthPointsChangeEvent.on(this.animateHurt, this);
|
2022-12-19 15:24:52 +00:00
|
|
|
this.endOfLifetimeTriggered = false;
|
2022-11-08 18:45:57 +00:00
|
|
|
}
|
|
|
|
|
2022-12-20 12:02:57 +00:00
|
|
|
public get Id(): string {
|
|
|
|
return this.id;
|
|
|
|
}
|
|
|
|
|
2022-12-05 14:13:42 +00:00
|
|
|
public get MovementType(): EnemyMovementType {
|
|
|
|
return this.movementType;
|
|
|
|
}
|
|
|
|
|
2022-11-08 18:45:57 +00:00
|
|
|
public get Collider(): BoxCollider2D {
|
|
|
|
return this.collider;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get Damage(): number {
|
2022-12-12 11:46:17 +00:00
|
|
|
return this.damage;
|
2022-11-08 18:45:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public get Health(): UnitHealth {
|
|
|
|
return this.health;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get DeathEvent(): ISignal<Enemy> {
|
|
|
|
return this.deathEvent;
|
|
|
|
}
|
|
|
|
|
2022-12-19 13:24:29 +00:00
|
|
|
public get XPReward(): number {
|
|
|
|
return this.xpReward;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get GoldReward(): number {
|
|
|
|
return this.goldReward;
|
|
|
|
}
|
|
|
|
|
2022-12-20 12:37:56 +00:00
|
|
|
public get HealthPotionRewardChance(): number {
|
|
|
|
return this.healthPotionRewardChance;
|
|
|
|
}
|
|
|
|
|
2022-12-23 08:52:26 +00:00
|
|
|
public get MagnetRewardChance(): number {
|
|
|
|
return this.magnetRewardChance;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get ChestRewardChance(): number {
|
|
|
|
return this.chestRewardChance;
|
|
|
|
}
|
|
|
|
|
2022-12-13 17:56:00 +00:00
|
|
|
public get LifetimeEndedEvent(): ISignal<Enemy> {
|
|
|
|
return this.lifetimeEndedEvent;
|
|
|
|
}
|
|
|
|
|
2022-11-08 18:45:57 +00:00
|
|
|
public dealDamage(points: number): void {
|
|
|
|
this.health.damage(points);
|
|
|
|
if (!this.health.IsAlive) {
|
|
|
|
this.deathEvent.trigger(this);
|
|
|
|
}
|
|
|
|
}
|
2022-11-14 15:35:47 +00:00
|
|
|
|
2022-12-13 17:56:00 +00:00
|
|
|
public gameTick(move: Vec3, deltaTime: number): void {
|
2022-11-14 15:35:47 +00:00
|
|
|
const newPosition: Vec3 = this.node.worldPosition;
|
2022-12-07 09:47:46 +00:00
|
|
|
newPosition.x += move.x * this.speedX * deltaTime;
|
|
|
|
newPosition.y += move.y * this.speedY * deltaTime;
|
2022-11-14 15:35:47 +00:00
|
|
|
|
2022-12-19 15:24:52 +00:00
|
|
|
if (move.x < 0) {
|
|
|
|
this.sprite.node.setScale(-1, 1, 1);
|
2022-12-31 11:53:49 +00:00
|
|
|
} else if (0 < move.x) {
|
2022-12-19 15:24:52 +00:00
|
|
|
this.sprite.node.setScale(1, 1, 1);
|
|
|
|
}
|
|
|
|
|
2022-11-14 15:35:47 +00:00
|
|
|
this.node.setWorldPosition(newPosition);
|
2022-12-13 17:56:00 +00:00
|
|
|
|
|
|
|
if (0 < this.lifetimeLeft) {
|
|
|
|
this.lifetimeLeft -= deltaTime;
|
|
|
|
if (this.lifetimeLeft <= 0) {
|
|
|
|
this.lifetimeEndedEvent.trigger(this);
|
2022-12-19 15:24:52 +00:00
|
|
|
} else if (this.lifetimeLeft <= 2) {
|
|
|
|
this.animateEndOfLifetime();
|
2022-12-13 17:56:00 +00:00
|
|
|
}
|
|
|
|
}
|
2022-11-14 15:35:47 +00:00
|
|
|
}
|
2022-12-19 13:24:29 +00:00
|
|
|
|
2022-12-19 15:24:52 +00:00
|
|
|
private async animateEndOfLifetime(): Promise<void> {
|
|
|
|
if (this.endOfLifetimeTriggered) return;
|
|
|
|
|
|
|
|
this.endOfLifetimeTriggered = true;
|
|
|
|
|
|
|
|
while (this.node.active) {
|
|
|
|
this.sprite.node.active = false;
|
|
|
|
await delay(200);
|
|
|
|
|
|
|
|
this.sprite.node.active = true;
|
|
|
|
await delay(200);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-19 13:24:29 +00:00
|
|
|
private async animateHurt(): Promise<void> {
|
|
|
|
this.sprite.material = this.whiteMaterial;
|
|
|
|
await delay(100);
|
|
|
|
this.sprite.material = this.defaultMaterial;
|
|
|
|
}
|
2022-11-08 18:45:57 +00:00
|
|
|
}
|