import { _decorator, CCInteger, Collider2D, Component, Contact2DType, EventHandler, tween, Vec2, Animation, Vec3, AudioClip, } from 'cc'; import Utilities from '../Utilities'; import { Ball } from './Ball'; import TimeConfig from '../Enum/TimeConfig'; import { EventManger } from '../Manager/EventManger'; import GameEvent from '../Events/GameEvent'; import { CameraController } from '../Environments/CameraController'; import { SoundManager } from '../Manager/SoundManager'; const { ccclass, property } = _decorator; @ccclass('Cannon') export class Cannon extends Component { @property({ type: Collider2D, visible: true }) private _collider: Collider2D; @property({ type: Animation, visible: true }) private _animation: Animation; @property({ type: CCInteger, visible: true }) private _force = 30; @property({ type: AudioClip, visible: true }) private _soundFx: AudioClip; @property({ type: EventHandler, visible: true }) private onDone: EventHandler[] = []; protected onLoad(): void { this._collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this); EventManger.instance.on(GameEvent.BallOut, this.onBallOut, this); } private async onBeginContact(self: Collider2D, other: Collider2D) { const ball = other.getComponent(Ball); this._collider.enabled = false; if (ball) { ball.setActiveRigi(false); tween(ball.node).to(0.1, { worldPosition: this.node.worldPosition }).start(); await Utilities.delay(TimeConfig.DelayCannonFire); CameraController.instance.shake(0.2); this._animation.play(); ball.setActiveRigi(true); ball.throwBall(new Vec2(0, this._force)); SoundManager.instance.playSfx(this._soundFx); await Utilities.delay(TimeConfig.DelayCannonDone); tween(this._collider.node).to(0.5, { scale: Vec3.ZERO }, { easing: 'backIn' }).start(); EventHandler.emitEvents(this.onDone, ball); } } private onBallOut() { tween(this._collider.node) .to(0.5, { scale: Vec3.ONE }, { easing: 'backOut', onComplete: () => (this._collider.enabled = true) }) .start(); } }