super-hero/assets/cc-game/scripts/game_play/hero/HeroBase.ts

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);
}
}