import { _decorator, Component, EventKeyboard, EventTouch, input, Input, KeyCode, Node, ParticleSystem, Tween, tween, Vec3, } from 'cc'; import GameState from '../Enum/GameState'; import TimeConfig from '../Enum/TimeConfig'; import GameEvent from '../Events/GameEvent'; import { EventManger } from '../Manager/EventManger'; import { GameManager } from '../Manager/GameManager'; import Utils from '../Utilities'; const { ccclass, property } = _decorator; @ccclass('TutorialController') export class TutorialController extends Component { @property({ type: Node, visible: true }) private _tapL: Node; @property({ type: Node, visible: true }) private _tapR: Node; @property({ type: ParticleSystem, visible: true }) private _tapLEffect: ParticleSystem; @property({ type: ParticleSystem, visible: true }) private _tapREffect: ParticleSystem; private _timer = 0; private _showed = false; private _canShow = true; private _playing = false; protected onLoad(): void { this.node.on(Input.EventType.TOUCH_START, this.onTouchStart, this); input.on(Input.EventType.KEY_UP, this.onKeyInputUpStart, this); EventManger.instance.on(GameEvent.GameStateChange, this.onGameStateChange, this); } protected start() { this.playTutorial(); } protected update(dt: number): void { if (!this._playing) return; this._timer += dt; if (!this._showed && this._timer > TimeConfig.Tutorial) { this._showed = true; this.playTutorial(); } } private onGameStateChange(state: GameState) { switch (state) { case GameState.Playing: this._playing = true; break; case GameState.GameOver: case GameState.End: this._playing = false; this._canShow = false; break; default: this._canShow = true; break; } } private async playTutorial() { if (this._canShow) { this._tapL.setActive(true); this._tapR.setActive(true); this._tapLEffect.setNodeActive(true); this._tapREffect.setNodeActive(true); tween(this._tapL) .call(() => this._tapLEffect.clear()) .to(0.5, { position: new Vec3(-470, -500), scale: new Vec3(0.9, 0.9) }, { easing: 'quintOut' }) .to(0.5, { position: new Vec3(-470, -550), scale: Vec3.ONE }, { easing: 'sineOut' }) .call(() => this._tapLEffect.play()) .union() .repeatForever() .start(); await Utils.delay(0.5); tween(this._tapR) .call(() => this._tapREffect.clear()) .to(0.5, { position: new Vec3(470, -500), scale: new Vec3(0.9, 0.9) }, { easing: 'quintOut' }) .to(0.5, { position: new Vec3(470, -550), scale: Vec3.ONE }, { easing: 'sineOut' }) .call(() => this._tapREffect.play()) .union() .repeatForever() .start(); } } private stopTutorial() { Tween.stopAllByTarget(this._tapL); Tween.stopAllByTarget(this._tapR); this._timer = 0; this._showed = false; this._tapLEffect.setNodeActive(false); this._tapREffect.setNodeActive(false); this._tapL.setActive(false); this._tapR.setActive(false); } private startGame() { this.stopTutorial(); this.node.off(Input.EventType.TOUCH_START, this.onTouchStart, this); input.off(Input.EventType.KEY_UP, this.onKeyInputUpStart, this); this.node.on(Input.EventType.TOUCH_START, this.onTouch, this); input.on(Input.EventType.KEY_UP, this.onKeyInputUp, this); GameManager.instance.play(); } private onTouch(event: EventTouch) { this.stopTutorial(); } private onTouchStart(event: EventTouch) { this.startGame(); } private onKeyInputUpStart(event: EventKeyboard) { switch (event.keyCode) { case KeyCode.KEY_A: case KeyCode.ARROW_LEFT: case KeyCode.KEY_D: case KeyCode.ARROW_RIGHT: this.startGame(); break; default: break; } } private onKeyInputUp(event: EventKeyboard) { switch (event.keyCode) { case KeyCode.KEY_A: case KeyCode.ARROW_LEFT: case KeyCode.KEY_D: case KeyCode.ARROW_RIGHT: this.stopTutorial(); break; default: break; } } }