super-hero/assets/cc-game/scripts/game_play/enemy/EnemyBase.ts

263 lines
8.4 KiB
TypeScript

import { Collider2D, Vec3 } from 'cc';
import { _decorator, Component, Node } from 'cc';
import { UmUtil } from '../../../../cc-common/cc-util/UmUtil';
import { ColliderObject } from '../../base/ColliderObject';
import { UmLog } from '../../../../cc-common/cc-util/UmLog';
import { GameDefine, EPHYSIC_GROUP, EACTIVE_SKILL_TYPE, ENEMY_TYPE, EATTACK_TYPE } from '../../config/GameDefine';
import { BulletBase } from '../bullet/BulletBase';
import { LayoutManager } from '../LayoutManager';
import { Sprite } from 'cc';
import { Color } from 'cc';
import { ShootingBase } from '../bullet/ShootingBase';
import { GameGlobalData } from '../../global/GameGlobalData';
import { EnemyDataInfo, ShootingDataInfo } from '../../global/GameInterface';
import { ActiveSkillBase } from '../hero/ActiveSkillBase';
import { Enum } from 'cc';
import { UmClientEvent } from '../../../../cc-common/cc-util/UmOneToMultiListener';
import { RigidBody2D } from 'cc';
import { Label } from 'cc';
import { CircleCollider2D } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('EnemyBase')
export class EnemyBase extends Component {
@property(ColliderObject) colliderObject: ColliderObject = null!;
@property(ColliderObject) sensor: ColliderObject = null!;
@property(RigidBody2D) rigibodyComponent: RigidBody2D = null!;
@property(Sprite) theme: Sprite = null!;
@property(ShootingBase) shooting: ShootingBase = null!;
@property({ type: Enum(ENEMY_TYPE) }) public enemyType: ENEMY_TYPE = ENEMY_TYPE.MELEE;
@property({ type: Enum(EATTACK_TYPE) }) public attackType: EATTACK_TYPE = EATTACK_TYPE.MELEE
@property(Label) txtName: Label = null!;
isShootEnable = false;
isDestroying = false;
isCheckedWin = false;
currentColor: Color;
effectColor: Color = Color.GREEN;
heroTarget: Node;
dmg = 5;
moveSpeed = 50;
range = 5;
hp = 1000;
dataConfig: any = null;
atkCooldown: number = 1;
visualRange: number = 5;
TWEEN_TAG = 1001;
setEnemyData(data) {
// No: data["no"],
// Name_Id: data["nameid"],
// Group: data["group"],
// Visual_Name: data["visualname"],
// Atk: data["atk"],
// Hp: data["hp"],
// AtkSpeed: data["atkspeed"],
// Exp: data["exp"],
// MoveSpeed: data["movespeed"],
// AtkRange: data["atkrange"],
// AtkCoolDown: data["atkcooldown"],
// VisualRange: data["visualrange"],
// SkillDmg: data["Skilldmg"],
// SkillEffect: data["skilleffect"],
this.dataConfig = data;
this.enemyType = GameDefine.getEnemyType(data?.Group) || this.enemyType;
this.attackType = GameDefine.getAttackType(this.enemyType) || this.attackType;
this.dmg = data?.Atk || this.dmg;
this.moveSpeed = data?.MoveSpeed || this.moveSpeed;
this.range = data?.AtkRange || this.range;
this.hp = data?.Hp || this.hp;
this.atkCooldown = data?.AtkCoolDown || this.atkCooldown;
this.visualRange = data?.VisualRange || this.visualRange;
this.txtName.string = data?.Name_Id + "|" + this.dmg.toString();
this.updateSensorRange();
UmLog.log(JSON.stringify(data));
}
updateSensorRange()
{
this.sensor.collider.getComponent(CircleCollider2D).radius = GameDefine.SQUARE_UNIT * this.visualRange;
}
protected onLoad(): void {
this.setEnableRigibody(false);
this.TWEEN_TAG = UmUtil.getRandomInt(100000, Number.MAX_SAFE_INTEGER);
}
start(): void {
this.setEnableRigibody(true);
this.registerColliderContact();
this.registerSensor();
// this.loadDataAndDisplay();
this.isShootEnable = true;
this.currentColor = new Color(this.theme.color);
}
setEnableRigibody(isEnable: boolean)
{
if (this.rigibodyComponent)
this.rigibodyComponent.enabled = isEnable;
}
protected registerColliderContact() {
this.colliderObject.registerBeginContact(this.onBeginContact.bind(this), true);
this.colliderObject.registerEndContact(null, true);
}
protected offColliderContact() {
this.colliderObject.offContact();
}
protected registerSensor() {
this.sensor.registerBeginContact(this.onSensorBegin.bind(this), false);
this.sensor.registerEndContact(this.onSensorEnd.bind(this), false);
}
protected offSensor() {
this.sensor.offContact();
}
loadDataAndDisplay()
{
LayoutManager.instance.GameUI.getBossHPBar().setMaxHPBar(100);
}
onBeginContact(a: Collider2D, b: Collider2D) {
var bGroup = b.group;
// UmLog.log("BOSS | Contact Begin = " + GameDefine.getPhysicGroupName(a.group), " vs ", GameDefine.getPhysicGroupName(bGroup));
if (bGroup == Number(EPHYSIC_GROUP.ENEMY)) return;
if (bGroup == Number(EPHYSIC_GROUP.BULLET_HERO)) {
this.onBulletContact(b.node);
return;
}
if (bGroup == Number(EPHYSIC_GROUP.ACTIVE_SKILL)) {
this.onHeroActiveSkillContact(b.node);
return;
}
}
onSensorBegin(a: Collider2D, b: Collider2D) {
var bGroup = b.group;
// UmLog.log("BOSS |onSensor Begin = " + GameDefine.getPhysicGroupName(a.group), " vs ", GameDefine.getPhysicGroupName(b.group));
if (bGroup != EPHYSIC_GROUP.HERO) return;
this.heroTarget = b.node;
}
onSensorEnd(a: Collider2D, b: Collider2D) {
var bGroup = b.group;
// UmLog.log("BOSS | onSensor End = " + GameDefine.getPhysicGroupName(a.group), " vs ", GameDefine.getPhysicGroupName(b.group));
GameDefine.getPhysicGroupName(bGroup);
if (bGroup != EPHYSIC_GROUP.HERO) return;
this.heroTarget = null;
}
public destroyNode() {
if (this.isDestroying) return;
this.isDestroying = true;
//must destroy on thread
this.scheduleOnce(() => {
this.setEnableRigibody(false);
this.node?.destroy();
}, 0);
}
onBulletContact(bullet: Node) {
var bulletComp = bullet.parent.getComponent(BulletBase);
if (!bulletComp) return;
var damage = bulletComp?.damage | 0;
this.effectColor = bulletComp.getColor();
this.hitDamage(damage);
bulletComp?.destroyNode();
}
onHeroActiveSkillContact(skill: Node) {
UmLog.log("onHeroActiveSkillContact => ", skill.name);
var skillComp = skill.getComponent(ActiveSkillBase);
if (!skillComp) return;
if (skillComp.skillType != Number(EACTIVE_SKILL_TYPE.SKILL_2)) return;
var damage = skillComp?.dmg | 0;
this.effectColor = skillComp.getColor();
this.hitDamage(damage);
}
hitDamage(damage: number)
{
var hpBar = LayoutManager.instance.GameUI.getBossHPBar();
hpBar.decreaseHP(damage);
if (hpBar.currentHP <= 0) {
this.checkWin();
this?.destroyNode();
}
this.runHitEffect();
}
checkWin()
{
//override at extent
}
runHitEffect() {
this.theme.color = this.effectColor;
UmUtil.stopAllTweenTag(this.TWEEN_TAG);
UmUtil.delay(this.node, 0.2, () => {
this.theme.color = this.currentColor;
}, this.TWEEN_TAG);
}
// shooting => { "AtkRange": 5, "AtkCoolDown": 1, "AtkSpeed": 30, "Damage": 10, "AoERange": 0, "AoEDmg": 0 }
get ShootingDataConfig(): ShootingDataInfo {
var shootingData: ShootingDataInfo = {
AtkRange: this.dataConfig.AtkRange,
AtkCoolDown: this.dataConfig.AtkCoolDown,
AtkSpeed: this.dataConfig.AtkSpeed,
Damage: this.dataConfig.Atk,
AoERange: this.dataConfig.AoERange,
AoEDmg: this.dataConfig.AoEDmg,
};
return shootingData;
}
protected update(dt: number): void {
if (!GameGlobalData.Instance.isStatePlay()) return;
if (!this.isShootEnable) return;
var targetShoot = this.findShootTargetPoint();
if (!targetShoot) return;
this.shooting.shooting(this.node, targetShoot, this.ShootingDataConfig);
}
findShootTargetNode(): Node
{
return this.heroTarget;
}
findShootTargetPoint(): Vec3 {
var point = this.node.worldPosition;
point = UmUtil.plusTwoVector3(point, new Vec3(0, -10, 0));
return point;
}
}