/*
 * @Author: ls
 * @Date: 2022-03-09 21:15:44
 * @LastEditTime: 2022-03-15 17:46:21
 * @LastEditors: ls
 * @Description: 蛋糕
 * @FilePath: \cake\assets\cake\scene\cake.ts
 */

import { MyCocosSceneComponent } from '../script/MyCocosSceneComponent';

let { ccclass, property } = cc._decorator;

@ccclass
export default class SceneComponent extends MyCocosSceneComponent {
	addPreloadImage() {
		// TODO 根据自己的配置预加载图片资源
		// this._imageResList.push({ url: this.data.pic_url });
	}
	addPreloadAudio() {
		// TODO 根据自己的配置预加载音频资源
		let length = this.data.questions.length;

		for (let index = 0; index < length; index++) {
			this._audioResList.push({ url: this.data.questions[index].audio });
		}
		this._audioResList.push({ url: this.data.guideAudio });
	}
	addPreloadAnima() {
		// let length = this.data.questions.length;
		// for (let index = 0; index < length; index++) {
		// 	this._animaResList.push({ url: this.data.questions[index].dragonBoneData.skeJsonData.url });
		// 	this._animaResList.push({ url: this.data.questions[index].dragonBoneData.texJsonData.url });
		// 	this._animaResList.push({ url: this.data.questions[index].dragonBoneData.texPngData.url });
		// }
	}

	onLoadEnd() {
		// TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考
		this.initData();
		this.initView();
		this.initListener();
	}

	_first = null; // 首次
	_curPage = null; // 第几题
	_results = null; // 题目结果
	_sounding = null; // 播放题干中

	_replaying = null; // 评测动画播放中

	_schedule_candle = null; // 蜡烛燃烧回调
	_timeout = null; // 倒计时

	initData() {
		// 所有全局变量 默认都是null
		this._first = true;
		this._curPage = 0;
		this._results = [];
		this._sounding = false;
		this._replaying = false;

		this._schedule_candle = null;
		this._timeout = 0;
	}

	initView() {
		this.initAdapter();

		this.initHome();

		this.resetGame();
	}

	initListener() {}

	/**
	 * 初始化适配
	 */
	initAdapter() {
		// 上
		let up = cc.find('up', this.node);
		up.x = 0;
		up.y = this.node.height / 2;

		// 下
		let down = cc.find('down', this.node);
		down.x = 0;
		down.y = -this.node.height / 2;

		// 左
		let left = cc.find('left', this.node);
		left.x = -this.node.width / 2;
		left.y = 0;

		// 右
		let right = cc.find('right', this.node);
		right.x = this.node.width / 2;
		right.y = 0;

		// 左上
		let left_up = cc.find('left_up', this.node);
		left_up.x = -this.node.width / 2;
		left_up.y = this.node.height / 2;

		// 左下
		let left_down = cc.find('left_down', this.node);
		left_down.x = -this.node.width / 2;
		left_down.y = -this.node.height / 2;

		// 右上
		let right_up = cc.find('right_up', this.node);
		right_up.x = this.node.width / 2;
		right_up.y = this.node.height / 2;

		// 右下
		let right_down = cc.find('right_down', this.node);
		right_down.x = this.node.width / 2;
		right_down.y = -this.node.height / 2;

		// 背景
		let bg = cc.find('bg', this.node);
		bg.scale = this._mapScaleMax;

		// 遮罩
		let mask = cc.find('mask', this.node);
		mask.scale = this._mapScaleMax;

		// 桌子
		let desktop = cc.find('down/desktop', this.node);
		desktop.width = this.node.width;
	}

	/**
	 * 显示开始游戏
	 */
	initHome() {
		// 显示遮罩
		let mask = cc.find('mask', this.node);
		mask.opacity = 255;
		mask.active = true;

		// 显示开始
		let play = cc.find('btn_play', this.node);
		play.once('click', this.play, this);
		play.active = true;

		// 显示标题
		let title = cc.find('left_up/title', this.node);
		title.active = true;
		let titleLabel = title.getChildByName('label').getComponent(cc.Label);
		let titleLabelOutline = title.getChildByName('label').getComponent(cc.LabelOutline);
		titleLabel.string = this.data.title;
		titleLabel.scheduleOnce(() => {
			titleLabelOutline.width = (titleLabel.actualFontSize / 48) * 6; // 下一帧执行,更新描边
		});
	}

	/**
	 * 重置游戏
	 */
	resetGame() {
		// 隐藏贴图(并初始化)
		let layout = cc.find('right_up/layout', this.node);
		layout.active = false;
		if (this._first) {
			this._first = false;
			this._results.length = 0;

			layout.removeAllChildren();
			let item = cc.find('right_up/item', this.node);
			if (this.data.questions.length) {
				for (let index = 0; index < this.data.questions.length; index++) {
					this._results.push(false);

					let tag = cc.instantiate(item);
					tag.parent = layout;
					tag.active = true;
				}
			}
		}

		// 隐藏选项
		let cake_select_01 = cc.find('right/cake_select_01', this.node);
		cake_select_01.active = false;
		let cake_select_02 = cc.find('right/cake_select_02', this.node);
		cake_select_02.active = false;
		// 隐藏选项描边
		let cake_select_side_01 = cc.find('right/cake_select_01/side', this.node);
		cake_select_side_01.active = false;
		let cake_select_side_02 = cc.find('right/cake_select_02/side', this.node);
		cake_select_side_02.active = false;

		// 隐藏蛋糕
		let cake = cc.find('down/cake', this.node);
		cake.active = false;
		let cake_style_01 = cc.find('down/cake/cake_style_01', this.node);
		cake_style_01.active = false;
		let cake_style_02 = cc.find('down/cake/cake_style_02', this.node);
		cake_style_02.active = false;
		let cake_style_03 = cc.find('down/cake/cake_style_03', this.node);
		cake_style_03.active = false;
		let cake_style_04 = cc.find('down/cake/cake_style_04', this.node);
		cake_style_04.active = false;
		let cake_style_05 = cc.find('down/cake/cake_style_05', this.node);
		cake_style_05.active = false;

		// 隐藏蜡烛
		let candle = cc.find('left_down/candle', this.node);
		candle.getComponent(cc.Sprite).spriteFrame = this.getSpriteFrame('candle_select'); // 设置蜡烛精灵
		candle.getComponent(cc.Sprite).fillRange = 1;
		cc.find('left_down/candle/cake_fire_ske', this.node).active = false;
		cc.find('left_down/candle/cake_timeout_ske', this.node).active = false;
		candle.active = false;

		// 隐藏提交
		let submit = cc.find('right_down/btn_submit', this.node);
		submit.active = false;
		// 隐藏喇叭
		let sound = cc.find('right_down/btn_sound', this.node);
		sound.active = false;
		// 隐藏碎渣
		let offscum = cc.find('right_down/offscum', this.node);
		offscum.active = false;

		// 隐藏come on
		let come_on = cc.find('come_on', this.node);
		come_on.active = false;
		// 隐藏nice try
		let nice_try = cc.find('nice_try', this.node);
		nice_try.active = false;
		// 隐藏全对
		let all_right = cc.find('all_right', this.node);
		all_right.active = false;

		// 隐藏评测
		let pc = cc.find('down/pc', this.node);
		pc.active = false;
		// 隐藏测评excellent
		let test_excellent = cc.find('test_excellent', this.node);
		test_excellent.active = false;
		// 隐藏测评nice try
		let test_nice_try = cc.find('test_nice_try', this.node);
		test_nice_try.active = false;
	}

	/**
	 * 初始化游戏
	 */
	initGame() {
		let problem = this.data.questions[this._curPage];

		// 隐藏开始
		let play = cc.find('btn_play', this.node);
		play.active = false;

		// 显示贴图
		let layout = cc.find('right_up/layout', this.node);
		layout.active = true;
		// 设置贴图蓝边
		let curTag = layout.children[this._curPage];
		if (curTag) {
			curTag.getChildByName('red').active = false;
			curTag.getChildByName('tag').active = false;
			curTag.getChildByName('bule').active = true;
		}

		this.playLocalAudio('enter');
		// 移入题干蛋糕
		let cake = cc.find('down/cake', this.node);
		cc.Tween.stopAllByTarget(cake);
		cake.x = this.node.width / 2 + 200;
		cake.active = true;
		cc.tween(cake).to(0.5, { x: 0 }).start();

		// 蛋糕底座显示完整单词
		let cake_base = cake.getChildByName('cake_base');
		cake_base.active = true;
		cake.getChildByName('cake_drop_down').active = false;
		cake_base.getChildByName('label').getComponent(cc.Label).string = problem.text;
		// 根据单词长度显示蛋糕
		for (let index = 0; index < problem.text.length - 1; index++) {
			let show_cake = cake.getChildByName(`cake_style_0${index + 1}`);
			show_cake.active = true;
			show_cake.getChildByName('label').getComponent(cc.Label).string = problem.text[index];
			show_cake.getChildByName('side').active = false;
		}

		// 移入选项蛋糕
		let cake_select_01 = cc.find('right/cake_select_01', this.node);
		let cake_select_02 = cc.find('right/cake_select_02', this.node);
		cc.Tween.stopAllByTarget(cake_select_01);
		cc.Tween.stopAllByTarget(cake_select_02);
		cake_select_01.x = 200;
		cake_select_02.x = 200;
		cake_select_01.y = 100;
		cake_select_02.y = -100;
		cake_select_01.active = true;
		cake_select_02.active = true;
		cc.tween(cake_select_01).to(0.5, { x: -200 }).start();
		cc.tween(cake_select_02).to(0.5, { x: -200 }).start();
		// 替换选项蛋糕spriteFrame
		let cake_select = cake.getChildByName(`cake_style_0${problem.text.length}`);
		cake_select_01.getComponent(cc.Sprite).spriteFrame = cake_select.getComponent(cc.Sprite).spriteFrame;
		cake_select_02.getComponent(cc.Sprite).spriteFrame = cake_select.getComponent(cc.Sprite).spriteFrame;
		// 替换选项蛋糕边spriteFrame
		let cake_select_side = cake_select.getChildByName('side');
		cake_select_01.getChildByName('side').getComponent(cc.Sprite).spriteFrame = cake_select_side.getComponent(cc.Sprite).spriteFrame;
		cake_select_02.getChildByName('side').getComponent(cc.Sprite).spriteFrame = cake_select_side.getComponent(cc.Sprite).spriteFrame;
		// 随机设置选项蛋糕
		let rand = Math.random();
		let right_select = rand > 0.5 ? '01' : '02';
		let wrong_select = rand > 0.5 ? '02' : '01';
		let cake_select_right = cc.find(`right/cake_select_${right_select}`, this.node);
		let cake_select_wrong = cc.find(`right/cake_select_${wrong_select}`, this.node);
		cake_select_right.getChildByName('label').getComponent(cc.Label).string = problem.rightLetter;
		cake_select_wrong.getChildByName('label').getComponent(cc.Label).string = problem.wrongLetter;
		cake_select_right.off('click');
		cake_select_wrong.off('click');

		// 渐隐遮罩
		let mask = cc.find('mask', this.node);
		cc.Tween.stopAllByTarget(mask);
		// mask.opacity = 255;
		let self = this;
		cc.tween(mask)
			.to(0.5, { opacity: 0 })
			.call(() => {
				self.playLocalAudio('enter');

				// 移除蜡烛燃烧回调
				if (self._schedule_candle) {
					self._timeout = 0;
					self.unschedule(this._schedule_candle);
					self._schedule_candle = null;
				}

				// 移入蜡烛
				let candle = cc.find('left_down/candle', self.node);
				let cake_fire = cc.find('left_down/candle/cake_fire_ske', self.node);
				let cake_timeout = cc.find('left_down/candle/cake_timeout_ske', self.node);
				cc.Tween.stopAllByTarget(candle);
				candle.x = -80;
				candle.active = true;
				cc.tween(candle).to(0.5, { x: 80 }).start();
				// 设置蓝色蜡烛
				candle.getComponent(cc.Sprite).spriteFrame = self.getSpriteFrame('candle_select');
				candle.getComponent(cc.Sprite).fillRange = 1;
				// 设置火焰燃烧状态
				cake_fire.y = 362;
				cake_timeout.y = 423;
				cake_fire.active = true;
				cake_timeout.active = false;

				// 播放题干音频
				self.playAudioByUrl(problem.audio, () => {
					console.log('题干音频播放完成');

					// 移入喇叭
					let sound = cc.find('right_down/btn_sound', self.node);
					cc.Tween.stopAllByTarget(sound);
					sound.x = 80;
					sound.active = true;
					cc.tween(sound).to(0.5, { x: -80 }).start();
					sound.on('click', () => {
						if (self._sounding) return;
						self._sounding = true;

						let open = cc.find('right_down/btn_sound/open', self.node);
						cc.Tween.stopAllByTarget(open);
						// open.opacity = 255;
						open.active = true;
						cc.tween(open).blink(10, 20).start();

						self.playAudioByUrl(problem.audio, () => {
							cc.Tween.stopAllByTarget(open);
							self._sounding = false;
							open.opacity = 255;
						});
					});

					self._timeout = problem.chooseWaitTime;
					// 蜡烛燃烧回调
					self._schedule_candle = function (dt) {
						self._timeout -= dt;
						let ratio = self._timeout / problem.chooseWaitTime;

						if (self._timeout < 0) {
							console.log('蜡烛燃尽');

							self.selectWrong();

							self.unschedule(self._schedule_candle);
							self._schedule_candle = null;
							cake_timeout.active = false;
							cake_fire.active = false;
							self._timeout = 0;
						} else if (ratio <= 0.2) {
							cake_fire.active = false;
							cake_timeout.active = true;
						}

						cake_fire.y = 362 - candle.height + candle.height * ratio;
						cake_timeout.y = 423 - candle.height + candle.height * ratio;
						candle.getComponent(cc.Sprite).fillRange = ratio;
					};
					// 蜡烛开始燃烧
					self.schedule(self._schedule_candle);

					cake_select_wrong.once(
						'click',
						() => {
							console.log('选择错误');

							// 选择错误
							self.selectWrong();
						},
						self,
					);
					cake_select_right.once(
						'click',
						() => {
							console.log('选择正确');

							// 显示选中蛋糕描边
							cake_select_right.getChildByName('side').active = true;

							// 获取目标蛋糕的相对位置
							let cake_style = cake.getChildByName(`cake_style_0${problem.text.length}`);
							let tarNodePos = cake_style.position;
							let tarWorldPos = cake.convertToWorldSpaceAR(cc.v2(tarNodePos));
							let tarRightPos = cake_select_right.parent.convertToNodeSpaceAR(tarWorldPos);
							// 移动选中蛋糕到目标位置
							cc.Tween.stopAllByTarget(cake_select_right);
							cc.tween(cake_select_right)
								.to(0.5, { position: cc.v3(tarRightPos), scale: cake_style.scale })
								.call(() => {
									cake_select_right.active = false;
									cake_select_right.scale = 0.8;
									cake_select_right.getChildByName('side').active = false;

									cake_style.active = true;
									cake_style.getChildByName('label').getComponent(cc.Label).string = problem.rightLetter;
									cake_style.getChildByName('side').active = true;
									let cake_drop_down = cake.getChildByName('cake_drop_down');
									cake_drop_down.y = tarNodePos.y + 50 * cake_style.scale;
									cake_drop_down.active = true;
									let dragonBones_cake_drop_down = cake_drop_down.getComponent(dragonBones.ArmatureDisplay);
									dragonBones_cake_drop_down.playAnimation('newAnimation', 1);

									self.playLocalAudio('right');
								})
								.start();

							// 移除错误选项点击事件
							cake_select_wrong.off('click');

							// 移出干扰选项蛋糕
							// cake_select_wrong.x = -200;
							cake_select_wrong.active = true;
							cc.Tween.stopAllByTarget(cake_select_wrong);
							cc.tween(cake_select_wrong)
								.to(0.5, { x: 200 })
								.call(() => {
									cake_select_wrong.active = false;
								})
								.start();

							self.selectRight();
						},
						self,
					);
				});
			})
			.start();
	}

	/**
	 * 开始游戏
	 */
	play() {
		this._curPage = 0;
		this.initGame();
	}

	startTest(value) {
		// 开始系统评测
		window['courseware'].startTest(value);
	}

	stopTest() {
		// 结束系统评测
		window['courseware'].stopTest((res) => {
			// 模拟数据
			// let res = '{"result":{"overall":100}}';

			let replay = cc.find('down/pc/frame/btn_replay', this.node);
			replay.off('click');
			replay.active = false;

			// 渐显遮罩
			let mask = cc.find('mask', this.node);
			mask.opacity = 0;
			mask.active = true;
			cc.Tween.stopAllByTarget(mask);
			cc.tween(mask).to(0.5, { opacity: 255 }).start();
			// TODO 文档未体现 移除蜡烛和提交
			// 移出提交
			let submit = cc.find('right_down/btn_submit', this.node);
			submit.off('click');
			// submit.x = -120;
			submit.active = true;
			cc.Tween.stopAllByTarget(submit);
			cc.tween(submit)
				.to(0.5, { x: 120 })
				.call(() => {
					submit.active = false;
				})
				.start();

			// 移除蜡烛燃烧回调
			if (this._schedule_candle) {
				this._timeout = 0;
				this.unschedule(this._schedule_candle);
				this._schedule_candle = null; // 移除蜡烛 schedule
			}
			// 移出蜡烛
			let candle = cc.find('left_down/candle', this.node);
			candle.active = true;
			// candle.x = 80;
			cc.Tween.stopAllByTarget(candle);
			cc.tween(candle).to(0.5, { x: -80 }).start();

			res = JSON.parse(res);
			if (res['result'].overall < 80) {
				this._results[this._curPage] = false;

				this.playLocalAudio('voice_test_nice_try');

				let layout = cc.find('right_up/layout', this.node);
				layout.active = true;
				let curTag = layout.children[this._curPage];

				if (curTag) {
					curTag.getChildByName('bule').active = false;
					curTag.getChildByName('tag').active = false;
					curTag.getChildByName('red').active = true;
				}
				// 移入测评nice try
				let test_nice_try = cc.find('test_nice_try', this.node);

				cc.Tween.stopAllByTarget(test_nice_try);
				test_nice_try.x = 0;
				test_nice_try.y = this.node.height * 0.5 + 400;
				test_nice_try.active = true;
				cc.Tween.stopAllByTarget(test_nice_try);
				cc.tween(test_nice_try)
					.to(0.7, { y: 0 }, { easing: 'backOut' })
					.delay(1)
					.to(0.3, { y: -this.node.height * 0.5 - 400 }, { easing: 'sineIn' })
					.call(() => {
						test_nice_try.active = false;
					})
					.start();

				// cc.tween(test_nice_try)
				// 	.to(0.5, { y: -this.node.height * 0.1 }, { easing: 'sineIn' })
				// 	.to(0.2, { y: 0 }, { easing: 'sineOut' })
				// 	.delay(1)
				// 	.to(0.3, { y: -this.node.height * 0.5 - 400 }, { easing: 'sineIn' })
				// 	.call(() => {
				// 		test_nice_try.active = true;
				// 	})
				// 	.start();
			} else {
				this._results[this._curPage] = true;

				this.playLocalAudio('voice_test_excellent');
				// 显示贴图
				let layout = cc.find('right_up/layout', this.node);
				layout.active = true;
				let curTag = layout.children[this._curPage];
				if (curTag) {
					curTag.getChildByName('bule').active = false;
					curTag.getChildByName('red').active = false;
					let tag = curTag.getChildByName('tag');
					tag.active = true;
					tag.opacity = 0;
					tag.scale = 0.5;
					cc.tween(tag).to(0.7, { opacity: 255, scale: 1.2 }).to(0.2, { scale: 1 }).start();
				}
				let test_excellent = cc.find('test_excellent', this.node);
				test_excellent.active = true;
				let dragonBones_test_excellent = test_excellent.getComponent(dragonBones.ArmatureDisplay);
				dragonBones_test_excellent.playAnimation('newAnimation', 1);
				dragonBones_test_excellent.off(dragonBones.EventObject.COMPLETE);
				dragonBones_test_excellent.once(dragonBones.EventObject.COMPLETE, () => {
					test_excellent.active = false;
				});
			}
			this.unschedule(this.completeGame);
			this.scheduleOnce(this.completeGame, 1);
		});
	}

	completeGame() {
		// 渐显遮罩
		let mask = cc.find('mask', this.node);
		mask.opacity = 255;
		mask.active = true;
		cc.Tween.stopAllByTarget(mask);
		cc.tween(mask)
			.to(0.5, { opacity: 0 })
			.call(() => {})
			.start();

		this.overTime();
	}

	selectRight() {
		let problem = this.data.questions[this._curPage];

		this.playLocalAudio('enter');

		// 移出喇叭
		let sound = cc.find('right_down/btn_sound', this.node);
		sound.off('click');
		// sound.x = -80;
		sound.active = true;
		cc.Tween.stopAllByTarget(sound);
		cc.tween(sound)
			.to(0.5, { x: 80 })
			.call(() => {
				sound.active = false;
			})
			.start();

		// 移除蜡烛燃烧回调
		if (this._schedule_candle) {
			this._timeout = 0;
			this.unschedule(this._schedule_candle);
			this._schedule_candle = null; // 移除蜡烛 schedule
		}

		// 移出蜡烛
		let candle = cc.find('left_down/candle', this.node);
		let cake_fire = cc.find('left_down/candle/cake_fire_ske', this.node);
		let cake_timeout = cc.find('left_down/candle/cake_timeout_ske', this.node);
		candle.active = true;
		// candle.x = 80;
		let self = this;
		cc.Tween.stopAllByTarget(candle);
		cc.tween(candle)
			.to(0.5, { x: -80 })
			.call(() => {
				candle.active = false;

				// 第二步 => 语音评测
				// 移入pc
				let pc = cc.find('down/pc', self.node);
				pc.x = 0;
				pc.y = self.node.height + 400;
				pc.active = true;
				cc.Tween.stopAllByTarget(pc);
				cc.tween(pc)
					.to(0.5, { y: 0 })
					.call(() => {
						cc.find('down/cake', this.node).active = false;

						// 移入提交
						let submit = cc.find('right_down/btn_submit', self.node);
						submit.off('click');
						// submit.x = 120;
						submit.active = true;
						cc.Tween.stopAllByTarget(submit);
						cc.tween(submit).to(0.5, { x: -120 }).start();

						// 移除蜡烛燃烧回调
						if (self._schedule_candle) {
							self._timeout = 0;
							self.unschedule(self._schedule_candle);
							self._schedule_candle = null; // 移除蜡烛 schedule
						}
						// 移入蜡烛
						candle.x = -80;
						candle.active = true;
						cc.Tween.stopAllByTarget(candle);
						cc.tween(candle).to(0.5, { x: 80 }).start();
						// 设置红色蜡烛
						candle.getComponent(cc.Sprite).spriteFrame = self.getSpriteFrame('candle_test');
						candle.getComponent(cc.Sprite).fillRange = 1;
						// 设置火焰燃烧状态
						cake_fire.y = 362;
						cake_timeout.y = 423;
						cake_fire.active = true;
						cake_timeout.active = false;

						// 播放骨骼动画
						let frame = cc.find('down/pc/frame', self.node);
						let replay = cc.find('down/pc/frame/btn_replay', self.node);
						replay.active = false;
						replay.on('click', () => {
							if (self._replaying) return;
							self.asyncLoadDragonBoneAnime(frame, problem.dragonBoneData).then((node: cc.Node) => {
								self._replaying = true;

								let dragonBones_test = node.getComponent(dragonBones.ArmatureDisplay);
								dragonBones_test.playAnimation('newAnimation', 1);
								dragonBones_test.off(dragonBones.EventObject.COMPLETE);
								dragonBones_test.once(dragonBones.EventObject.COMPLETE, () => {
									node.destroy();
									node = null;

									replay.active = true;
									self._replaying = false;
								});
							});
						});

						self.asyncLoadDragonBoneAnime(frame, problem.dragonBoneData).then((node: cc.Node) => {
							let dragonBones_test = node.getComponent(dragonBones.ArmatureDisplay);
							dragonBones_test.playAnimation('newAnimation', 1);
							dragonBones_test.off(dragonBones.EventObject.COMPLETE);
							dragonBones_test.once(dragonBones.EventObject.COMPLETE, () => {
								node.destroy();
								node = null;

								replay.active = true;
							});
						});

						// 播放语音评测引导音频
						self.playAudioByUrl(self.data.guideAudio, () => {
							// 开始评测
							this.startTest(problem.text);

							self._timeout = problem.testWaitTime;

							// 蜡烛燃烧回调
							self._schedule_candle = function (dt) {
								self._timeout -= dt;
								let ratio = self._timeout / problem.testWaitTime;

								if (self._timeout < 0) {
									self.unschedule(self._schedule_candle);
									self._schedule_candle = null;
									cake_timeout.active = false;
									cake_fire.active = false;
									self._timeout = 0;

									console.log('蜡烛燃尽');
									self.stopTest();
								} else if (ratio <= 0.2) {
									cake_fire.active = false;
									cake_timeout.active = true;
								}

								cake_fire.y = 362 - candle.height + candle.height * ratio;
								cake_timeout.y = 423 - candle.height + candle.height * ratio;
								candle.getComponent(cc.Sprite).fillRange = ratio;
							};
							// 蜡烛开始燃烧
							self.schedule(self._schedule_candle);

							submit.once('click', () => {
								console.log('点击提交=');
								// 移除蜡烛燃烧回调
								if (self._schedule_candle) {
									self._timeout = 0;
									self.unschedule(self._schedule_candle);
									self._schedule_candle = null; // 移除蜡烛 schedule
								}

								self.stopTest();
							});
						});
					})
					.start();
			})
			.start();
	}

	selectWrong() {
		this.playLocalAudio('error');
		// 隐藏选项蛋糕
		let cake_select_01 = cc.find('right/cake_select_01', this.node);
		let cake_select_02 = cc.find('right/cake_select_02', this.node);
		cake_select_01.off('click');
		cake_select_02.off('click');
		cake_select_01.active = false;
		cake_select_02.active = false;
		// 显示渣渣
		let offscum = cc.find('right_down/offscum', this.node);
		offscum.active = true;
		// 贴图变红
		let layout = cc.find('right_up/layout', this.node);
		let curTag = layout.children[this._curPage];
		if (curTag) {
			curTag.getChildByName('bule').active = false;
			curTag.getChildByName('tag').active = false;
			curTag.getChildByName('red').active = true;
		}

		// 移出喇叭
		let sound = cc.find('right_down/btn_sound', this.node);
		sound.off('click');
		sound.active = true;
		// sound.x = -80;
		sound.off('click');
		cc.Tween.stopAllByTarget(sound);
		cc.tween(sound)
			.to(0.5, { x: 80 })
			.call(() => {
				sound.active = false;
			})
			.start();

		// 移除蜡烛燃烧回调
		if (this._schedule_candle) {
			this._timeout = 0;
			this.unschedule(this._schedule_candle);
			this._schedule_candle = null; // 移除蜡烛 schedule
		}

		// 移出蜡烛
		let candle = cc.find('left_down/candle', this.node);
		candle.active = true;
		// candle.x = 80;
		cc.Tween.stopAllByTarget(candle);
		cc.tween(candle)
			.to(0.5, { x: -80 })
			.call(() => {
				candle.active = false;
				this._results[this._curPage] = false;

				this.overTime();
			})
			.start();
	}

	overTime() {
		if (this._curPage === this.data.questions.length - 1) {
			// 总结
			let numRight = 0;
			for (let index = 0; index < this._results.length; index++) {
				if (this._results[index]) numRight++;
			}
			if (numRight === this._results.length) {
				this.allRight();
			} else {
				if (numRight / this._results.length < 0.6) {
					this.comeOn();
				} else {
					this.niceTry();
				}
			}
		} else {
			// 开始下一题
			this._curPage++;

			this.resetGame();

			// 移出pc
			let pc = cc.find('down/pc', this.node);
			if (pc.active) {
				// pc.x = 0;
				cc.Tween.stopAllByTarget(pc);
				cc.tween(pc)
					.to(0.5, { x: -this.node.width / 2 - 400, active: true })
					.call(() => {
						pc.active = false;
					})
					.start();
			}

			this.initGame();
		}
	}

	comeOn() {
		let pc = cc.find('down/pc', this.node);
		if (pc.active) {
			this.playLocalAudio('game_over_came_on');
			let come_on = cc.find('come_on', this.node);
			cc.Tween.stopAllByTarget(come_on);
			come_on.x = 0;
			come_on.y = this.node.height * 0.5 + 400;
			come_on.active = true;
			cc.tween(come_on)
				.to(0.7, { y: 0 }, { easing: 'backOut' })
				.delay(1)
				.to(0.3, { y: -this.node.height * 0.5 - 400 }, { easing: 'sineIn' })
				.call(() => {
					come_on.active = true;
				})
				.start();
		} else {
			// TODO 文档未体现

			// 移入pc
			cc.Tween.stopAllByTarget(pc);
			pc.x = 0;
			pc.y = this.node.height + 400;
			pc.active = true;
			cc.tween(pc)
				.to(0.5, { y: 0 })
				.call(() => {
					cc.find('down/cake', this.node).active = false;

					this.playLocalAudio('game_over_came_on');
					let come_on = cc.find('come_on', this.node);
					cc.Tween.stopAllByTarget(come_on);
					come_on.x = 0;
					come_on.y = this.node.height * 0.5 + 400;
					come_on.active = true;
					cc.tween(come_on)
						.to(0.7, { y: 0 }, { easing: 'backOut' })
						.delay(1)
						.to(0.3, { y: -this.node.height * 0.5 - 400 }, { easing: 'sineIn' })
						.call(() => {
							come_on.active = true;
						})
						.start();
				})
				.start();
		}

		// cc.tween(come_on)
		// 	.to(0.5, { y: -this.node.height * 0.1 }, { easing: 'sineIn' })
		// 	.to(0.2, { y: 0 }, { easing: 'sineOut' })
		// 	.delay(1)
		// 	.to(0.3, { y: -this.node.height * 0.5 - 400 }, { easing: 'sineIn' })
		// 	.call(() => {
		// 		come_on.active = true;
		// 	})
		// 	.start();
	}

	niceTry() {
		let pc = cc.find('down/pc', this.node);
		if (pc.active) {
			this.playLocalAudio('game_over_nice_try');

			let nice_try = cc.find('nice_try', this.node);
			cc.Tween.stopAllByTarget(nice_try);
			nice_try.x = 0;
			nice_try.y = this.node.height * 0.5 + 400;
			nice_try.active = true;
			cc.tween(nice_try)
				.to(0.7, { y: 0 }, { easing: 'backOut' })
				.delay(1)
				.to(0.3, { y: -this.node.height * 0.5 - 400 }, { easing: 'sineIn' })
				.call(() => {
					nice_try.active = true;
				})
				.start();
		} else {
			// TODO 文档未体现

			// 移入pc
			cc.Tween.stopAllByTarget(pc);
			pc.x = 0;
			pc.y = this.node.height + 400;
			pc.active = true;
			cc.tween(pc)
				.to(0.5, { y: 0 })
				.call(() => {
					cc.find('down/cake', this.node).active = false;

					this.playLocalAudio('game_over_nice_try');
					let nice_try = cc.find('nice_try', this.node);
					cc.Tween.stopAllByTarget(nice_try);
					nice_try.x = 0;
					nice_try.y = this.node.height * 0.5 + 400;
					nice_try.active = true;
					cc.tween(nice_try)
						.to(0.7, { y: 0 }, { easing: 'backOut' })
						.delay(1)
						.to(0.3, { y: -this.node.height * 0.5 - 400 }, { easing: 'sineIn' })
						.call(() => {
							nice_try.active = true;
						})
						.start();
				})
				.start();
		}

		// cc.tween(nice_try)
		// 	.to(0.5, { y: -this.node.height * 0.1 }, { easing: 'sineIn' })
		// 	.to(0.2, { y: 0 }, { easing: 'sineOut' })
		// 	.delay(1)
		// 	.to(0.3, { y: -this.node.height * 0.5 - 400 }, { easing: 'sineIn' })
		// 	.call(() => {
		// 		nice_try.active = true;
		// 	})
		// 	.start();
	}

	allRight() {
		let pc = cc.find('down/pc', this.node);
		if (pc.active) {
			this.playLocalAudio('all_right');

			let all_right = cc.find('all_right', this.node);
			all_right.active = true;

			let dragonBones_all_right = all_right.getComponent(dragonBones.ArmatureDisplay);
			dragonBones_all_right.playAnimation('newAnimation', 1);
			dragonBones_all_right.off(dragonBones.EventObject.COMPLETE);
			dragonBones_all_right.once(dragonBones.EventObject.COMPLETE, () => {
				all_right.active = false;
			});
		} else {
			// TODO 文档未体现
			this.playLocalAudio('all_right');

			// 移入pc
			cc.Tween.stopAllByTarget(pc);
			pc.x = 0;
			pc.y = this.node.height + 400;
			pc.active = true;
			cc.tween(pc)
				.to(0.5, { y: 0 })
				.call(() => {
					cc.find('down/cake', this.node).active = false;

					let all_right = cc.find('all_right', this.node);
					all_right.active = true;

					let dragonBones_all_right = all_right.getComponent(dragonBones.ArmatureDisplay);
					dragonBones_all_right.playAnimation('newAnimation', 1);
					dragonBones_all_right.off(dragonBones.EventObject.COMPLETE);
					dragonBones_all_right.once(dragonBones.EventObject.COMPLETE, () => {
						all_right.active = false;
					});
				})
				.start();
		}
	}

	onDestroy() {
		let all_right = cc.find('all_right', this.node);
		let dragonBones_all_right = all_right.getComponent(dragonBones.ArmatureDisplay);
		dragonBones_all_right.off(dragonBones.EventObject.COMPLETE);
	}

	playLocalAudio(audioName) {
		let audio = cc.find(`Canvas/res/audio/${audioName}`).getComponent(cc.AudioSource);
		return new Promise((resolve, reject) => {
			let id = cc.audioEngine.playEffect(audio.clip, false);
			cc.audioEngine.setFinishCallback(id, () => {
				resolve(id);
			});
		});
	}

	getSpriteFrame(resName) {
		let sf = cc.find('Canvas/res/img/' + resName).getComponent(cc.Sprite).spriteFrame;
		return sf;
	}

	/**
	 * 等比缩放
	 * @param imgWidth 图片宽
	 * @param imgHeight 图片高
	 * @param containerWidth 容器(目标)宽
	 * @param containerHeight 容器(目标)高
	 * @returns
	 */
	imgScaling(imgWidth, imgHeight, containerWidth, containerHeight) {
		let [
			// 用于设定图片的宽和高
			tempWidth,
			tempHeight,
		] = [undefined, undefined];

		try {
			imgWidth = parseFloat(imgWidth);
			imgHeight = parseFloat(imgHeight);
			containerWidth = parseFloat(containerWidth);
			containerHeight = parseFloat(containerHeight);
		} catch (error) {
			throw new Error('抱歉，我只接收数值类型或者可以转成数值类型的参数');
		}

		if (imgWidth > 0 && imgHeight > 0) {
			// 原图片宽高比例 大于 指定的宽高比例，这就说明了原图片的宽度必然 > 高度
			if (imgWidth / imgHeight >= containerWidth / containerHeight) {
				if (imgWidth > containerWidth) {
					tempWidth = containerWidth;
					// 按原图片的比例进行缩放
					tempHeight = (imgHeight * containerWidth) / imgWidth;
				} else {
					// 按照图片的大小进行缩放
					tempWidth = imgWidth;
					tempHeight = imgHeight;
				}
			} else {
				// 原图片的高度必然 > 宽度
				if (imgHeight > containerHeight) {
					tempHeight = containerHeight;
					// 按原图片的比例进行缩放
					tempWidth = (imgWidth * containerHeight) / imgHeight;
				} else {
					// 按原图片的大小进行缩放
					tempWidth = imgWidth;
					tempHeight = imgHeight;
				}
			}
		}

		return { tempWidth, tempHeight };
	}

	/**
	 * 异步加载 DragonBone
	 * @param node
	 * @param param
	 * @returns
	 */
	async asyncLoadDragonBoneAnime(node, { skeJsonData: { url: skeJsonDataUrl }, texJsonData: { url: texJsonDataUrl }, texPngData: { url: texPngDataUrl } }) {
		if (!texPngDataUrl || !texJsonDataUrl || !texPngDataUrl || texPngDataUrl == '' || texJsonDataUrl == '' || texPngDataUrl == '') {
			return;
		}

		return new Promise((resolve, reject) => {
			if (node.animaNode) {
				node.animaNode.removeFromParent();
			}
			const animaNode = new cc.Node();
			animaNode.name = 'animaNode';
			animaNode.parent = node;
			animaNode.active = true;
			node.animaNode = animaNode;

			const dragonDisplay = animaNode.addComponent(dragonBones.ArmatureDisplay);

			const loadTexture = new Promise((resolve, reject) => {
				cc.assetManager.loadRemote(texPngDataUrl, (error, texture) => {
					if (error) {
						reject(error);
					}
					resolve(texture);
				});
			});

			const loadTexJsonData = new Promise((resolve, reject) => {
				cc.assetManager.loadAny({ url: texJsonDataUrl }, (error, atlasJson) => {
					if (error) {
						reject(error);
					}
					resolve(atlasJson);
				});
			});

			const loadSkeJsonData = new Promise((resolve, reject) => {
				cc.assetManager.loadAny({ url: skeJsonDataUrl }, (error, dragonBonesJson) => {
					if (error) {
						reject(error);
					}
					resolve(dragonBonesJson);
				});
			});

			Promise.all([loadTexture, loadTexJsonData, loadSkeJsonData]).then(([texture, atlasJson, dragonBonesJson]) => {
				const atlas = new dragonBones.DragonBonesAtlasAsset();
				atlas.atlasJson = JSON.stringify(atlasJson);
				// @ts-ignore
				atlas.texture = texture;

				const asset = new dragonBones.DragonBonesAsset();
				asset.dragonBonesJson = JSON.stringify(dragonBonesJson);

				dragonDisplay.dragonAtlasAsset = atlas;
				dragonDisplay.dragonAsset = asset;

				// @ts-ignore
				let armatureNames = dragonBonesJson.armature.map((data) => data.name);

				if (armatureNames.length > 0) {
					dragonDisplay.armatureName = armatureNames[0];
				}
				resolve(animaNode);
			});
		});
	}
}
