300 lines
9.6 KiB
TypeScript
300 lines
9.6 KiB
TypeScript
import { _decorator, Component, Node } from 'cc';
|
|
import { NodeBase } from '../../base/NodeBase';
|
|
import { EventTouch, Vec3 } from 'cc';
|
|
import { GameGlobalData } from '../../global/GameGlobalData';
|
|
import { UmLog } from '../../../../cc-common/cc-util/UmLog';
|
|
import { ColliderObject } from '../../base/ColliderObject';
|
|
import { Collider2D } from 'cc';
|
|
import { ShootingBase } from '../bullet/ShootingBase';
|
|
import { EACTIVE_SKILL_TYPE, EPHYSIC_GROUP, GameDefine } from '../../config/GameDefine';
|
|
import { LayoutManager } from '../LayoutManager';
|
|
import { HeroDataInfo } from '../../global/GameInterface';
|
|
import { BulletBase } from '../bullet/BulletBase';
|
|
import { Color } from 'cc';
|
|
import { UmUtil } from '../../../../cc-common/cc-util/UmUtil';
|
|
import { Sprite } from 'cc';
|
|
import { math } from 'cc';
|
|
import { UmClientEvent } from '../../../../cc-common/cc-util/UmOneToMultiListener';
|
|
import { Label } from 'cc';
|
|
import { RigidBody2D } from 'cc';
|
|
const { ccclass, property } = _decorator;
|
|
|
|
@ccclass('HeroBase')
|
|
export class HeroBase extends NodeBase {
|
|
@property(ColliderObject) colliderObject: ColliderObject = null!;
|
|
@property(ColliderObject) sensor: ColliderObject = null!;
|
|
@property(RigidBody2D) rigibodyComponent: RigidBody2D = null!;
|
|
|
|
@property(ShootingBase) shooting: ShootingBase = null!;
|
|
@property(Sprite) theme: Sprite = null!;
|
|
@property(Label) skillLabel: Label = null!;
|
|
|
|
originPoint = new Vec3();
|
|
isShootEnable = false;
|
|
listEnemyTarget: Node[] = new Array();
|
|
listEnemyContact = new Map<string, any>;
|
|
currentColor: math.Color;
|
|
effectColor: Color = Color.GREEN;
|
|
specialSkill = -1;
|
|
countImmuneDamageUsing: number = 0;
|
|
TWEEN_TAG = 1001;
|
|
isDestroying = false;
|
|
|
|
get isImmuneDamage(): boolean
|
|
{
|
|
return this.countImmuneDamageUsing > 0;
|
|
}
|
|
|
|
protected onLoad(): void {
|
|
this.TWEEN_TAG = UmUtil.getRandomInt(100000, Number.MAX_SAFE_INTEGER);
|
|
this.isDestroying = false;
|
|
}
|
|
|
|
protected start(): void {
|
|
UmClientEvent.on(GameDefine.EVENT_START_USE_SPECIAL_SKILL, this.onStartUseSpecialSkill.bind(this));
|
|
UmClientEvent.on(GameDefine.EVENT_END_USE_SPECIAL_SKILL, this.onEndUseSpecialSkill.bind(this));
|
|
|
|
UmClientEvent.on(GameDefine.EVENT_START_USE_ACTIVE_SKILL, this.onStartUseActiveSkill.bind(this));
|
|
UmClientEvent.on(GameDefine.EVENT_END_USE_ACTIVE_SKILL, this.onEndUseActiveSkill.bind(this));
|
|
|
|
this.isShootEnable = true;
|
|
this.registerColliderContact();
|
|
this.registerSensor();
|
|
this.loadDataAndDisplay();
|
|
this.currentColor = new Color(this.theme.color);
|
|
this.skillLabel.string = "";
|
|
|
|
}
|
|
|
|
protected onDestroy(): void {
|
|
UmClientEvent.off(GameDefine.EVENT_START_USE_SPECIAL_SKILL, this.onStartUseSpecialSkill.bind(this));
|
|
UmClientEvent.off(GameDefine.EVENT_END_USE_SPECIAL_SKILL, this.onEndUseSpecialSkill.bind(this));
|
|
|
|
UmClientEvent.off(GameDefine.EVENT_START_USE_ACTIVE_SKILL, this.onStartUseActiveSkill.bind(this));
|
|
UmClientEvent.off(GameDefine.EVENT_END_USE_ACTIVE_SKILL, this.onEndUseActiveSkill.bind(this));
|
|
}
|
|
|
|
|
|
onStartUseSpecialSkill(skillId: number)
|
|
{
|
|
UmLog.log("onStartUseSpecialSkill => ", skillId);
|
|
this.specialSkill = skillId;
|
|
this.skillLabel.string = `USE SKILL_${skillId}`;
|
|
}
|
|
|
|
onEndUseSpecialSkill() {
|
|
UmLog.log("onEndUseSpecialSkill");
|
|
this.specialSkill = -1;
|
|
this.skillLabel.string = "";
|
|
}
|
|
|
|
get heroData(): HeroDataInfo
|
|
{
|
|
return GameGlobalData.Instance.heroData.getHeroData();
|
|
}
|
|
|
|
loadDataAndDisplay() {
|
|
LayoutManager.instance.GameUI.getHeroHPBar().setMaxHPBar(this.heroData.hp);
|
|
}
|
|
|
|
protected registerColliderContact() {
|
|
this.colliderObject.registerBeginContact(this.onBeginContact.bind(this), true);
|
|
this.colliderObject.registerEndContact(this.onEndContact.bind(this), 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();
|
|
}
|
|
|
|
getTouchPointInParentNode(touchPoint): Vec3 {
|
|
return this.node.parent?.getNodeTransform().convertToNodeSpaceAR(touchPoint.toVec3());
|
|
}
|
|
|
|
onBeginContact(a: Collider2D, b: Collider2D) {
|
|
var bGroup = b.group;
|
|
// UmLog.log("HERO | onBeginContact = " + GameDefine.getPhysicGroupName(a.group), " vs ", GameDefine.getPhysicGroupName(bGroup));
|
|
if (b.group == Number(EPHYSIC_GROUP.SENSOR)) return;
|
|
|
|
if (b.group == Number(EPHYSIC_GROUP.ENEMY))
|
|
{
|
|
this.onEnemyStartContact(b.node);
|
|
return;
|
|
}
|
|
|
|
if (bGroup == Number(EPHYSIC_GROUP.BULLET_ENEMY)) {
|
|
this.onBulletContact(b.node);
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
onEndContact(a: Collider2D, b: Collider2D) {
|
|
if (b.group == Number(EPHYSIC_GROUP.ENEMY)) {
|
|
this.onEnemyEndContact(b.node);
|
|
return;
|
|
}
|
|
}
|
|
|
|
onSensorBegin(a: Collider2D, b: Collider2D) {
|
|
var bGroup = b.group;
|
|
// UmLog.log("HERO | onSensor Begin = " + GameDefine.getPhysicGroupName(a.group), " vs ", GameDefine.getPhysicGroupName(b.group));
|
|
if (bGroup != EPHYSIC_GROUP.ENEMY) return;
|
|
this.addEnemyTarget(b.node);
|
|
}
|
|
|
|
onSensorEnd(a: Collider2D, b: Collider2D) {
|
|
var bGroup = b.group;
|
|
// UmLog.log("HERO | onSensor End = " + GameDefine.getPhysicGroupName(a.group), " vs ", GameDefine.getPhysicGroupName(b.group));
|
|
GameDefine.getPhysicGroupName(bGroup);
|
|
if (bGroup != EPHYSIC_GROUP.ENEMY) return;
|
|
this.removeEnemyTarget(b.node);
|
|
}
|
|
|
|
protected update(dt: number): void {
|
|
if (!GameGlobalData.Instance.isStatePlay()) return;
|
|
if (this.isShootEnable)
|
|
{
|
|
var targetNode = this.findShootTarget();
|
|
this.shoot(targetNode);
|
|
}
|
|
|
|
this.calculateHitMeleeDamageUpdate(dt);
|
|
}
|
|
|
|
calculateHitMeleeDamageUpdate(dt: number)
|
|
{
|
|
//override
|
|
}
|
|
|
|
|
|
shoot(targetNode)
|
|
{
|
|
if (!targetNode) return;
|
|
this.shooting.shooting(this.node, targetNode, this.heroData.shooting, this.specialSkill);
|
|
}
|
|
|
|
addEnemyTarget(enemy: Node) {
|
|
UmLog.log("addEnemyTarget => ", enemy.name);
|
|
this.listEnemyTarget.push(enemy);
|
|
}
|
|
|
|
removeEnemyTarget(enemy: Node) {
|
|
UmLog.log("removeEnemyTarget => ", enemy.name);
|
|
if (!this.listEnemyTarget?.length) return;
|
|
let index = -1;
|
|
for (var i = 0; i < this.listEnemyTarget.length; i++) {
|
|
if (this.listEnemyTarget[i] && this.listEnemyTarget[i] == enemy)
|
|
{
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (index < 0) return;
|
|
this.listEnemyTarget.splice(index, 1);
|
|
}
|
|
|
|
findShootTarget(): Node {
|
|
// UmLog.log("FINE => ", this.listEnemyTarget.length);
|
|
var min_distance = Number.MAX_VALUE;
|
|
var heroPoint = this.node.worldPosition;
|
|
var targetNode: Node = null;
|
|
|
|
if (!this.listEnemyTarget.length) return null;
|
|
|
|
for (var i = 0; i < this.listEnemyTarget.length; i++) {
|
|
var point = this.listEnemyTarget[i].worldPosition;
|
|
var check_distance = Vec3.distance(heroPoint, point);
|
|
if (check_distance < min_distance)
|
|
{
|
|
min_distance = check_distance;
|
|
targetNode = this.listEnemyTarget[i];
|
|
}
|
|
}
|
|
|
|
return targetNode;
|
|
}
|
|
|
|
onEnemyStartContact(enemy: Node)
|
|
{
|
|
this.listEnemyContact.set(enemy.name, {enemy: enemy, time: 0});
|
|
}
|
|
|
|
onEnemyEndContact(enemy: Node) {
|
|
this.listEnemyContact.delete(enemy.name);
|
|
if (this.isImmuneDamage) return;
|
|
}
|
|
|
|
onBulletContact(bullet: Node) {
|
|
var bulletComp = bullet.parent.getComponent(BulletBase);
|
|
var damage = bulletComp?.damage | 0;
|
|
|
|
bulletComp?.destroyNode();
|
|
this.effectColor = bulletComp.getColor();
|
|
|
|
this.onHitDamage(damage);
|
|
}
|
|
|
|
onHitDamage(damage: number)
|
|
{
|
|
if (this.isImmuneDamage || !damage) return;
|
|
this.runHitEffect();
|
|
var hpBar = LayoutManager.instance.GameUI.getHeroHPBar();
|
|
hpBar?.decreaseHP(damage);
|
|
|
|
if (hpBar?.currentHP <= 0) {
|
|
this?.destroyNode();
|
|
LayoutManager.instance.GameUI.showGameLose();
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
setEnableRigibody(isEnable: boolean) {
|
|
if (this.rigibodyComponent)
|
|
this.rigibodyComponent.enabled = isEnable;
|
|
}
|
|
|
|
public destroyNode() {
|
|
if (this.isDestroying) return;
|
|
this.isDestroying = true;
|
|
//must destroy on thread
|
|
this.scheduleOnce(() => {
|
|
this.setEnableRigibody(false);
|
|
this.node?.destroy();
|
|
}, 0);
|
|
}
|
|
|
|
onStartUseActiveSkill(tag: number, manaUsed: number) {
|
|
UmLog.log("HERO => onStartUseActiveSkill");
|
|
this.countImmuneDamageUsing += (tag != Number(EACTIVE_SKILL_TYPE.SKILL_2)) ? 1 : 0;
|
|
this.shooting?.enableActiveSkill(tag, this.node);
|
|
}
|
|
|
|
onEndUseActiveSkill(tag: number, manaUsed: number) {
|
|
UmLog.log("HERO => onEndUseActiveSkill");
|
|
this.countImmuneDamageUsing -= (tag != Number(EACTIVE_SKILL_TYPE.SKILL_2)) ? 1 : 0;
|
|
this.countImmuneDamageUsing = Math.max(0, this.countImmuneDamageUsing);
|
|
}
|
|
|
|
|
|
}
|
|
|