// Learn cc.Class:
//  - https://docs.cocos.com/creator/manual/en/scripting/class.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

// import { getSprNode } from "./util";
import { getSprNode, playAudioByUrl, getScaleRateBy2Node, localPosTolocalPos, randomSortByArr, loadDragonBones, playAudio, showTrebleFirework, delayCall, removeFromArr, showBtnAnima, asyncDelay, RandomInt, jellyShake} from "./util";

cc.Class({
	extends: cc.Component,

	properties: {
		baseWidth: {
			default: 1280,
			type: cc.Integer
		},
		baseHeight: {
			default: 720,
			type: cc.Integer
		}
	},

	onLoad() {
		cc.debug.setDisplayStats(false);
		this.initSceneData();
		this.initSize();
	},

	initSceneData() {
		this._imageResList = [];
		this._audioResList = [];
		this._animaResList = [];
	},



	_designSize: null,
	_frameSize: null,
	_mapScaleMin: null,
	_mapScaleMax: null,
	_cocosScale: null,
	canvas: null,
	initSize() {


		// 注意cc.winSize只有在适配后(修改fitHeight/fitWidth后)才能获取到正确的值,因此使用cc.getFrameSize()来获取初始的屏幕大小
		let screen_size = cc.view.getFrameSize().width / cc.view.getFrameSize().height
		let design_size = cc.Canvas.instance.designResolution.width / cc.Canvas.instance.designResolution.height
		let f = screen_size >= design_size

		cc.Canvas.instance.fitHeight = f
		cc.Canvas.instance.fitWidth = !f

		const frameSize = cc.view.getFrameSize();
		this._frameSize = frameSize;

		this._designSize = cc.view.getDesignResolutionSize();

		let sx = cc.winSize.width / frameSize.width;
		let sy = cc.winSize.height / frameSize.height;
		this._cocosScale = Math.min(sx, sy);

		sx = frameSize.width / this._designSize.width;
		sy = frameSize.height / this._designSize.height;
		this._mapScaleMin = Math.min(sx, sy) * this._cocosScale;
		this._mapScaleMax = Math.max(sx, sy) * this._cocosScale;

		this.canvas = cc.find('Canvas');


		// cc.log('cc.Canvas: ', cc.Canvas);
	},

	isTeacher: null,
	serverAllUser: null,
	start() {
		let getData = this.getData.bind(this);
		if (window && window.courseware) {
			getData = window.courseware.getData;
		}
		getData((data, aspect) => {

			if (window['air']?.airClassInfo?.user?.classRole == 'tea') {
        this.isTeacher = true;
      }
			if (aspect) {
        console.log('aspect : ', aspect);
        this.serverAllUser = aspect.all_user;
				this.initPageData(aspect);
      }

			console.log('data:', data);
			this.data = data || this.getDefaultData();

			this.preloadItem()
		})
	},

	// 用于存储公共数据 当翻页时清空 
	pageData: null, 
	initPageData(aspect) {
		const pageDataStr = aspect?.page_aspect?.pagedata;
		if (!pageDataStr) {
			this.pageData = {};
		} else {
			this.pageData = JSON.parse(pageDataStr);
		}
		console.log('this.pageData: ', this.pageData);
	},

	setPageData(key, value) {
		this.pageData[key] = value;
		this.sendPageData();
	},

	getPageData(key) {
		if (this.pageData && this.pageData[key]) {
			return this.pageData[key];
		}
	},

	sendPageData() {

		const data = this.pageData;
		if (window && window.courseware) {
			let storePageAspect = window.courseware.storePageAspect;
			if (storePageAspect) {
				storePageAspect(data);
				console.log('storePageAspect : ', data);
			}
		}
	},

	_imageResList: null,
	_audioResList: null,
	_animaResList: null,
	preloadItem() {
		// this.addPreloadImage();
		// this.addPreloadAudio();
		// this.addPreloadAnima();
		this.preload();
	},

	getData(func) {
		func(this.getDefaultData());
	},

	getDefaultData() {
		const dataJson = '{"customAction":{"type":"text","changeStart":[["color","#ff00ff"],["size","30px"]],"changeEnd":[["color","#ffffff"],["size","33px"]],"changeTime":"0.5","pic_url":"http://staging-teach.cdn.ireadabc.com/071c713ba8b0bc9c6399a42ac8811082.png","text":"aaaa"},"bgItem":{"url":"http://staging-teach.cdn.ireadabc.com/c2cb9a9f65af3b853e57a22a6602e481.png","rect":{"x":209.51,"y":0,"width":851.97,"height":479}},"hotZoneItemArr":[{"id":"1614839864479","index":0,"audio_url":"http://staging-teach.cdn.ireadabc.com/32258b839eca32b6ccf94f3dd6c86e0c.mp3","itemType":"rect","fontScale":0.99296875,"imgScale":1,"mapScale":0.99296875,"gIdx":"2","rect":{"x":554.19,"y":138.28,"width":76.37,"height":72.85}},{"id":"1614840901996","index":1,"pic_url":"http://staging-teach.cdn.ireadabc.com/c8abf7383d65bcbdba8f390785cece60.png","itemType":"pic","fontScale":0.99296875,"imgScale":0.4963768115942029,"mapScale":0.99296875,"gIdx":"1","rect":{"x":699.35,"y":162.22,"width":137,"height":137}},{"id":"1614840912007","index":2,"audio_url":"http://staging-teach.cdn.ireadabc.com/85cff126986f5cc11b05e95181da5869.mp3","itemType":"text","fontScale":0.99296875,"imgScale":1,"mapScale":0.99296875,"gIdx":"3","actionData_3":{"type":"text","changeStart":[],"changeEnd":[],"changeTime":0.3,"changeOption":[["fontColor","#00ffff","#00ffff"],["fontSize","100","100"],["opacity","0","100"]],"text":"dddddg","audio_url":"http://staging-teach.cdn.ireadabc.com/5285e1e88a26a08783757e9c43a8653f.mp3"},"rect":{"width":371.17,"height":99.3,"x":306.63,"y":8.14}},{"id":"1614842879059","index":3,"audio_url":"http://staging-teach.cdn.ireadabc.com/cd8daa8b4d8ff707b3a3680e80bc4761.mp3","itemType":"rect","fontScale":0.99296875,"imgScale":1,"mapScale":0.99296875,"skeJsonData":{"url":"http://staging-teach.cdn.ireadabc.com/c5c80dbe4df2fe619f67b4d8a99d15c8.json","name":"a_ske.json"},"texJsonData":{"url":"http://staging-teach.cdn.ireadabc.com/df141aa05ea55b3835ef2ebfc6685d48.json","name":"a_tex.json"},"texPngData":{"url":"http://staging-teach.cdn.ireadabc.com/adbfe4292df235154c88737fe22cdba0.png","name":"a_tex.png"},"gIdx":"0","rect":{"x":111.27,"y":277.23,"width":76.31,"height":76.31}},{"id":"1614932660076","index":4,"itemType":"pic","fontScale":0.99296875,"imgScale":1.134480587666508,"mapScale":0.99296875,"gIdx":"4","actionData_4":{"type":"pic","skeJsonData":{},"texJsonData":{},"texPngData":{},"changeStart":[],"changeEnd":[],"changeTime":0.3,"changeOption":[["scale","1"],["opacity","50","100"]],"pic_url":"http://staging-teach.cdn.ireadabc.com/97eb28e4c023f92efde4310d590be985.png","audio_url":"http://staging-teach.cdn.ireadabc.com/c693181b18d5b8e018cdd0dbbd8a8466.mp3"},"rect":{"x":715.92,"y":310,"width":110.04,"height":144.08}},{"id":"1616741577774","index":5,"itemType":"rect","fontScale":0.99296875,"imgScale":1,"mapScale":0.99296875,"gIdx":"5","actionData_5":{"type":"anima","skeJsonData":{"url":"http://staging-teach.cdn.ireadabc.com/c5c80dbe4df2fe619f67b4d8a99d15c8.json","name":"a_ske.json"},"texJsonData":{"url":"http://staging-teach.cdn.ireadabc.com/df141aa05ea55b3835ef2ebfc6685d48.json","name":"a_tex.json"},"texPngData":{"url":"http://staging-teach.cdn.ireadabc.com/adbfe4292df235154c88737fe22cdba0.png","name":"a_tex.png"},"changeStart":[],"changeEnd":[],"changeTime":0.3,"changeOption":[["scale","1"],["opacity","0","100"]],"audio_url":"http://staging-teach.cdn.ireadabc.com/c693181b18d5b8e018cdd0dbbd8a8466.mp3"},"rect":{"x":11.48,"y":7,"width":147.01,"height":147.01}}],"title":"Look and Say","title_audio_url":"http://staging-teach.cdn.ireadabc.com/85cff126986f5cc11b05e95181da5869.mp3"}';
		const data1 = JSON.parse(dataJson);
		return data1;

	},

	preload() {
		const preloadArr = this._imageResList.concat(this._audioResList).concat(this._animaResList);
		cc.assetManager.loadAny(preloadArr, null, null, (err, data) => {
			// console.log(' preload data, ', data);

			this.loadEnd();
			this.addServerListener();
			if (window && window["air"]) {
				window["air"].hideAirClassLoading();
			}
		});
	},

	addPreloadImage() {
	
		if (this.data.bgItem) {
			this._imageResList.push({ url: this.data.bgItem.url });
		}
		if (!this.data.hotZoneItemArr) {
			return;
		}
		this.data.hotZoneItemArr.forEach((item) => {
			if (item.pic_url) {
				this._imageResList.push({ url: item.pic_url });
			}
		})
	},

	addPreloadAudio() {

		this._audioResList.push({url: this.data.title_audio_url || ''});
		
		if (!this.data.hotZoneItemArr) {
			return;
		}
		this.data.hotZoneItemArr.forEach((item) => {
			this._audioResList.push({url: item.audio_url});
		})

	},

	addPreloadAnima() {
		if (!this.data.hotZoneItemArr) {
			return;
		}
		this.data.hotZoneItemArr.forEach((item) => {
			if (item.skeJsonData) {
				this._animaResList.push({ url: item.skeJsonData.url || '' });
				this._animaResList.push({ url: item.texJsonData.url || ''});
				this._animaResList.push({ url: item.texPngData.url || ''});
			}
		})
	},


	loadEnd() {
		this.initData();
		this.initView();
		// this.initListener();
		// this.initMusic();
	},

	initMusic() {
		cc.assetManager.loadRemote(this.data.bg_audio_url, (err, clip) => {
			cc.audioEngine.setMusicVolume(0.3);
			const audioID = cc.audioEngine.playMusic(clip, true);
		});
	},


	isDebug: null,

	treeType: null,
	treeTypeArr: null,
	typeIndex: null,

	btnArr: null,
	fruitArr: null,
	modelLevel: null,
	initData() {

		this.isDebug = true;

		this.isTeacher = true;

		this.treeTypeArr = ['apple', 'banana', 'orange'];
		this.typeIndex = 0;

		this.treeType = this.treeTypeArr[0];


		// this.btnArr = [];
		// this.fruitArr = [];

		// this.modelLevel = 1;
		this.initAudioEffect();
	},

	bgClip: null,
	walkClip: null,
	appearClip: null,
	magicClip: null,
	realFruitClip: null,
	popClip: null,
	btnStarClip: null,
	stripClip: null,
	goodjobClip: null,
	clickClip: null,
	tipClip: null,
	finishClip: null,

	appleClip: null,
	bananaClip: null,
	orangeClip: null,

	appleSentenceClip: null,
	bananaSentenceClip: null,
	orangeSentenceClip: null,

	appleGroupClip: null,
	bananaGroupClip: null,
	orangeGroupClip: null,
	initAudioEffect() {
		this.bgClip = cc.find('Canvas/res/audio/bg').getComponent(cc.AudioSource).clip;
		this.walkClip = cc.find('Canvas/res/audio/walk').getComponent(cc.AudioSource).clip;
		this.appearClip = cc.find('Canvas/res/audio/fruit_appear').getComponent(cc.AudioSource).clip;
		this.magicClip = cc.find('Canvas/res/audio/magic_appear').getComponent(cc.AudioSource).clip;
		this.realFruitClip = cc.find('Canvas/res/audio/real_fruit').getComponent(cc.AudioSource).clip;
		this.btnStarClip = cc.find('Canvas/res/audio/btn_star').getComponent(cc.AudioSource).clip;
		this.popClip = cc.find('Canvas/res/audio/pop').getComponent(cc.AudioSource).clip;
		this.stripClip = cc.find('Canvas/res/audio/strip').getComponent(cc.AudioSource).clip;
		this.goodjobClip = cc.find('Canvas/res/audio/goodjob').getComponent(cc.AudioSource).clip;
		this.clickClip = cc.find('Canvas/res/audio/click').getComponent(cc.AudioSource).clip;
		this.tipClip = cc.find('Canvas/res/audio/tip').getComponent(cc.AudioSource).clip;
		this.finishClip = cc.find('Canvas/res/audio/finish').getComponent(cc.AudioSource).clip;
		
	
		this.appleClip = cc.find('Canvas/res/audio/apple').getComponent(cc.AudioSource).clip;
		this.bananaClip = cc.find('Canvas/res/audio/banana').getComponent(cc.AudioSource).clip;
		this.orangeClip = cc.find('Canvas/res/audio/orange').getComponent(cc.AudioSource).clip;
		
		this.appleSentenceClip = cc.find('Canvas/res/audio/sentence_apples').getComponent(cc.AudioSource).clip;
		this.bananaSentenceClip = cc.find('Canvas/res/audio/sentence_bananas').getComponent(cc.AudioSource).clip;
		this.orangeSentenceClip = cc.find('Canvas/res/audio/sentence_oranges').getComponent(cc.AudioSource).clip;


		this.appleGroupClip = [];
		this.appleGroupClip[0] = cc.find('Canvas/res/audio/drop_group/apple1').getComponent(cc.AudioSource).clip;
		this.appleGroupClip[1] = cc.find('Canvas/res/audio/drop_group/apple2').getComponent(cc.AudioSource).clip;
		this.appleGroupClip[2] = cc.find('Canvas/res/audio/drop_group/apple3').getComponent(cc.AudioSource).clip;

		this.bananaGroupClip = [];
		this.bananaGroupClip[0] = cc.find('Canvas/res/audio/drop_group/banana1').getComponent(cc.AudioSource).clip;
		this.bananaGroupClip[1] = cc.find('Canvas/res/audio/drop_group/banana2').getComponent(cc.AudioSource).clip;
		this.bananaGroupClip[2] = cc.find('Canvas/res/audio/drop_group/banana3').getComponent(cc.AudioSource).clip;

		this.orangeGroupClip = [];
		this.orangeGroupClip[0] = cc.find('Canvas/res/audio/drop_group/orange1').getComponent(cc.AudioSource).clip;
		this.orangeGroupClip[1] = cc.find('Canvas/res/audio/drop_group/orange2').getComponent(cc.AudioSource).clip;
		this.orangeGroupClip[2] = cc.find('Canvas/res/audio/drop_group/orange3').getComponent(cc.AudioSource).clip;

	},

	playBgMusic() {
		playAudio(this.bgClip, () => {
			this.playBgMusic();
		})
	},


	sendServerEvent(key, data) {

		if (this.isDebug) {
			this.addServerListenerTest(key, data);
			return;
		}

    const c = window.courseware;
		if (c) {
			c.sendEvent(key, data);
		}
  },


	addServerListener() {

		console.log(' in addServerListener');

		const c = window.courseware;
		if (!c) {
			return;
		}
		
	

		if (this.isTeacher) {
			c.onEvent('add_fruit', (data, next) => {
				console.log('in add_fruit : ', data);
				this.addFruit(data.send_data);
				next();
			});
	
			c.onEvent('add_bomb', (data, next) => {
				console.log('in add_bomb: ', data);
				this.addBomb(data.send_data);
				next();
			});

			c.onEvent('touch_fruit', (data, next) => {
				console.log('in touch_fruit: ', data);
				this.serverTouchFruit(data.data_id);
				next();
			});
	
			c.onEvent('touch_bomb', (data, next) => {
				console.log('in touch_bomb: ', data);
				this.serverTouchBomb(data.data_id);
				next();
			});

		} else {

			c.onEvent('click_level', (data, next) => {
				console.log('in click_level: ', data);
				this.clickLevelBtn(data.level, true);
				next();
			});

			c.onEvent('game_end', (data, next) => {
				console.log('in game_end: ', data);
				this.gameEnd(true);
				next();
			});
			
		}
	
		
	


	},

	addServerListenerTest(event, data) {
		

		console.log('event: ', event)
		console.log('data: ', data)

		switch(event) {
			case 'fruit_panel_sound_click':
				this.fruitPanelSoundClick();
				break;
			case 'sentence_panel_sound_click':
				this.sentencePanelSoundClick();
				break;
			case 'word_layer_sound_click':
				this.wordLayerSoundClick();
				break;
			case 'sentence_layer_sound_click':
				this.sentenceLayerSoundClick();
				break;
			case 'fruit_panel_speak_click':
				this.fruitPanelSpeakClick();
				break;
			case 'sentence_panel_speak_click':
				this.sentencePanelSpeakClick();
				break;
				
				
				
						
		}
	},



	initView() {

		this.initBg();
		this.initTree();
		this.initNextBtn();
		this.initRole();
		this.initMagicBasket();


		this.setCurStopX();
		this.roleMove();

		// this.initTeacherBtn();
		// this.initTi();
		// this.setLevel(1);

		// this.countDown();


		this.initTitle();

		this.initWordLayer();
		this.initSentenceLayer();

		this.initGoodJobLayer();

		this.initEndLayer();



		// this.showGoodJob();
		// this.showEndMask();

		this.playBgMusic();

		cc.debug.setDisplayStats(true);




	},

	initTitle() {

		const title = getSprNode('bg_title');
		title.scale = this._mapScaleMin;
		title.anchorX = 0;
		title.anchorY = 1;
		title.x = - this.canvas.width / 2 + 20 * this._mapScaleMin;
		title.y = this.canvas.height / 2 - 20 * this._mapScaleMin;
		this.canvas.addChild(title)

		if (this.isTeacher) {
			const chineseBtn = getSprNode('btn_chinese');
			chineseBtn.scale = this._mapScaleMin;
			chineseBtn.x = this.canvas.width / 2 - (20 + chineseBtn.width / 2) * this._mapScaleMin;
			chineseBtn.y = this.canvas.height / 2 - (20 + chineseBtn.height / 2 ) * this._mapScaleMin;
			this.canvas.addChild(chineseBtn)
	
			chineseBtn.on(cc.Node.EventType.TOUCH_START, () => {
				showBtnAnima(chineseBtn);
	
				if (this.tipClipId) {
					cc.audioEngine.stop(this.tipClipId)
				}
				this.tipClipId = playAudio(this.tipClip);
			})
		}
	
	},



	bgGround: null,
	bgBack: null,
	bgSky: null,
	groundMinX: null,
	initBg() {
			
		const bgGround = cc.find("Canvas/bg_ground");
		bgGround.scale = this.canvas.width * 3 / bgGround.width;
		bgGround.x = -this.canvas.width / 2;
		bgGround.y = -this.canvas.height / 2;
		this.bgGround = bgGround;
		this.groundMinX = -this.bgGround.width * this.bgGround.scaleX + this.canvas.width / 2;

		// bgGround.scale *= 0.5;

		const bgBack = cc.find("Canvas/bg_back");
		bgBack.scale = bgGround.scale
		bgBack.x = -this.canvas.width / 2;
		bgBack.y = -this.canvas.height / 2;
		this.bgBack = bgBack;

		const backOffX = -500 * bgBack.scale;
		bgBack.speedRate = (bgBack.width + backOffX * 2) / bgBack.width
		bgBack.x += backOffX;
		// console.log('	bgBack.speedRate: ', 	bgBack.speedRate);

		const bgSky = cc.find("Canvas/bg_sky");
		bgSky.scaleX = bgGround.scaleX;
		bgSky.scaleY = this.canvas.height / bgSky.height;
		bgSky.x = -this.canvas.width / 2;
		bgSky.y = -this.canvas.height / 2;
		this.bgSky = bgSky;

		// const camera = cc.find("Canvas/Main Camera")
		// camera.x += this.canvas.width * 2;
	},



	role: null,
	roleBaseX: null,
	initRole() {

		const resDragonBone = cc.find("Canvas/res/anima/role")
		const role = cc.instantiate(resDragonBone)	

		const dragonDisplay = role.getComponent(dragonBones.ArmatureDisplay);
		dragonDisplay.playAnimation('normal', 1);

		role.anima = dragonDisplay;
		role.anchorY = 0;
		role.x = -100; 
		role.y = 300;
		// role.scale = 1 / this.bgGround.scale
		this.bgGround.addChild(role, 1000);

		this.role = role;

		this.roleBaseX = this.canvas.width / 4;

		// const role = getSprNode('role')
		// role.anchorY = 0;
		// role.x = -100; 
		// role.y = 100;
		// this.bgGround.addChild(role, 1000);
		// this.role = role;
	},

	curMagicBasket: null,
	initMagicBasket() {

		const mbNode = new cc.Node();
		this.role.addChild(mbNode);
		mbNode.x = 180;
		mbNode.y = -100;

		const magicBasket = getSprNode("icon_magicbasket");
		this.curMagicBasket = magicBasket;
		mbNode.addChild(magicBasket);

		const baseY = mbNode.y;
		const time = 1.5;
		const line = 30;
		cc.tween(mbNode)
			.to(time, {y: baseY + line}, {easing: "sineInOut"})
			.to(time, {y: baseY}, {easing: "sineInOut"})
			.union()
			.repeatForever()
			.start();
	},

	wordLayer: null,
	curSmallBasket: null,
	wordLayerSoundBtn: null,
	initWordLayer() {

		const wordLayer = new cc.Node();
		this.wordLayer = wordLayer;
		this.canvas.addChild(wordLayer, 20);

		const bgBlack = getSprNode("bg_black");
		bgBlack.scaleX = this.canvas.width / bgBlack.width;
		bgBlack.scaleY = this.canvas.height / bgBlack.height;
		wordLayer.addChild(bgBlack);


		const bg = getSprNode("bg_word");
		bg.scale = this._mapScaleMin;
		wordLayer.addChild(bg);
		wordLayer.bg = bg;
		bg.y += 100 * this._mapScaleMin;


		const realFruit = cc.instantiate(this.curRealFruit);
		realFruit.scale = this._mapScaleMin * 1.5;
		realFruit.x = -430;
		realFruit.y = -10;
		bg.addChild(realFruit);
		wordLayer.realFruit = realFruit;


		const text = this.getWordLayerText();
		bg.addChild(text);
		text.x = -60;
		wordLayer.text = text;

		const baseY = text.y + text.height / 2 - 20;
		for (let i=0 ;i<3 ;i++) {
			const stripBg = getSprNode("bg_strip");
			stripBg.x = 230;
			stripBg.y = baseY - stripBg.height / 2 - i * 85;
			bg.addChild(stripBg);
			const strip = getSprNode("strip_" + (3-i));
			stripBg.addChild(strip);
			strip.scaleX = 0;
			strip.anchorX = 0;
			strip.x = -stripBg.width / 2;


			const star = this.getEmptyStar(3-i);
			star.x = stripBg.x + 170;
			star.y = stripBg.y;
			bg.addChild(star)
			const fillStar = this.getFillStar(3-i);
			fillStar.x = star.x;
			fillStar.y = star.y;
			fillStar.opacity = 0;
			bg.addChild(fillStar);

			wordLayer['strip_' + (3-i)] = strip;
			wordLayer['star_' + (3-i)] = fillStar;
		}
		

		const sound_1 = cc.find("Canvas/res/anima/sound_1")
		const soundIcon = cc.instantiate(sound_1)	
		bg.addChild(soundIcon);
		soundIcon.x = -230;
		soundIcon.y = 170;


		soundIcon.addComponent(cc.Button)
		soundIcon.on("click", () => {
			this.sendServerEvent("word_layer_sound_click", {});
		});

		const anima = soundIcon.getComponent(cc.Animation);
		soundIcon.anima = anima;
		this.wordLayerSoundBtn = soundIcon;



		const basket = getSprNode("basket_small/icon_basket");
		bg.addChild(basket);
		basket.x = 540;
		basket.y = -190
		this.curSmallBasket = basket;

		this.initBottomTi(wordLayer);

		this.wordLayer.active = false;
	},

	wordLayerSoundClick() {

		const soundIcon = this.wordLayerSoundBtn;

		if (soundIcon.isClicked) {
			return;
		}
		soundIcon.isClicked = true;

		const anima = soundIcon.anima;
		anima.play("sound_1");

		playAudio(this.curFruit.clip, () => {
			soundIcon.isClicked = false;
			anima.play("sound_1", 0);
			anima.sample("sound_1");
			anima.stop();
		})
	},


	sentenceLayer: null,
	initSentenceLayer() {

		const sentenceLayer = new cc.Node();
		this.sentenceLayer = sentenceLayer;
		this.canvas.addChild(sentenceLayer, 20);

		const bgBlack = getSprNode("bg_black");
		bgBlack.scaleX = this.canvas.width / bgBlack.width;
		bgBlack.scaleY = this.canvas.height / bgBlack.height;
		sentenceLayer.addChild(bgBlack);


		const bg = getSprNode("bg_sentence");
		bg.scale = this._mapScaleMin;
		sentenceLayer.addChild(bg);
		sentenceLayer.bg = bg;

		const basket = getSprNode("basket_big/icon_basket");
		bg.addChild(basket)
		basket.x = -450;
		this.curBigBasket = basket;


		const text = this.getSentenceLayerText();
		bg.addChild(text);
		text.x = -60;
		sentenceLayer.text = text;

		const baseX = 255;
		const baseY = text.y + text.height / 2 - 5;
		for (let i=0 ;i<3 ;i++) {
			const stripBg = getSprNode("bg_strip");
			stripBg.x = baseX;
			stripBg.y = baseY - stripBg.height / 2 - i * 85;
			bg.addChild(stripBg);
			const strip = getSprNode("strip_" + (3-i));
			stripBg.addChild(strip);
			strip.scaleX = 0;
			strip.anchorX = 0;
			strip.x = -stripBg.width / 2;


			const star = this.getEmptyStar(3-i);
			star.x = stripBg.x + 170;
			star.y = stripBg.y;
			bg.addChild(star)
			const fillStar = this.getFillStar(3-i);
			fillStar.x = star.x;
			fillStar.y = star.y;
			fillStar.opacity = 0;
			bg.addChild(fillStar);

			sentenceLayer['strip_' + (3-i)] = strip;
			sentenceLayer['star_' + (3-i)] = fillStar;
		}
		

		const sound_1 = cc.find("Canvas/res/anima/sound_1")
		const soundIcon = cc.instantiate(sound_1)	
		bg.addChild(soundIcon);
		soundIcon.x = -230;
		soundIcon.y = 170;

		soundIcon.addComponent(cc.Button)
		soundIcon.on("click", () => {

			this.sentenceLayerSoundClick();
			this.sendServerEvent("sentence_layer_sound_click", {});
		})

		const anima = soundIcon.getComponent(cc.Animation);
		soundIcon.anima = anima;
		this.sentenceLayerSoundBtn = soundIcon;

		this.initBottomTi(sentenceLayer);

		this.sentenceLayer.active = false;
	},

	sentenceLayerSoundClick() {

		const soundIcon = this.sentenceLayerSoundBtn;

		if (soundIcon.isClicked) {
			return;
		}
		soundIcon.isClicked = true;

		const anima = soundIcon.anima;
		anima.play("sound_1");

		playAudio(this.curSentenceClip, () => {
			soundIcon.isClicked = false;
			anima.play("sound_1", 0);
			anima.sample("sound_1");
			anima.stop();
		})
	},

	goodJobLayer: null,
	initGoodJobLayer() {
		const goodJobLayer = new cc.Node();
		this.canvas.addChild(goodJobLayer);

		const bgBlack = getSprNode("bg_black")
		bgBlack.scaleX = this.canvas.width / bgBlack.width;
		bgBlack.scaleY = this.canvas.height / bgBlack.height;
		goodJobLayer.addChild(bgBlack);

		this.goodJobLayer = goodJobLayer;
		this.goodJobLayer.active = false;
	},



	initBottomTi(bg) {


		const ti = getSprNode("bg_ti");
		ti.scale = this._mapScaleMin;
		ti.anchorY = 0;
		ti.y = -this.canvas.height / 2;
		bg.addChild(ti);


		let baseX = 155;
		let disW = 180;
		const goodBtn = getSprNode("btn_good");
		ti.addChild(goodBtn);
		goodBtn.y = ti.height / 2 - 20;
		goodBtn.x = baseX;
		const star1 = getSprNode("btn_star_1");
		goodBtn.addChild(star1);
		star1.y = 24;
		goodBtn.star = star1;
		goodBtn.starNum = 1;

		const greatBtn = getSprNode("btn_great");
		ti.addChild(greatBtn);
		greatBtn.x = baseX + disW;
		greatBtn.y = goodBtn.y;
		const star2 = getSprNode("btn_star_2");
		greatBtn.addChild(star2);
		star2.y = star1.y
		greatBtn.star = star2;
		greatBtn.starNum = 2;

		const perfectBtn = getSprNode("btn_perfect");
		ti.addChild(perfectBtn);
		perfectBtn.x = baseX + disW * 2;
		perfectBtn.y = goodBtn.y;
		const star3 = getSprNode("btn_star_3");
		perfectBtn.addChild(star3);
		star3.y = star1.y
		perfectBtn.star = star3;
		perfectBtn.starNum = 3;

		bg.tiBtnArr = [goodBtn, greatBtn, perfectBtn];

		this.addTiBtnListener(goodBtn);
		this.addTiBtnListener(greatBtn);
		this.addTiBtnListener(perfectBtn);

		// if (!this.isTeacher) {
		// 	ti.active = false;
		// }
	},

	addTiBtnListener(btn) {
		
		btn.on(cc.Node.EventType.TOUCH_START, () => {
	
			showBtnAnima(btn);
			
			if (btn.isClicked) {
				return;
			}
			btn.isClicked = true;

			cc.tween(btn.star)
				.to(0.3, {opacity: 0}, {easing: "cubicIn"})
				.call(() => {
					if (this.wordLayer.active) {
						this.showWordLayerStar(btn.starNum);
						this.addSmallBasketFruit();
					} else {
						this.showSentenceLayerStar(btn.starNum);
						this.addBigBasketFruit();
					}

				})
				.start();

			playAudio(this.stripClip);
			playAudio(this.btnStarClip);

		})
	},

	showWordLayerStar(starNum) {
		const fillStar = this.wordLayer['star_' + starNum];
		cc.tween(fillStar)
			.to(0.5, {opacity: 255}, {easing: "cubicOut"})
			.start();

		const strip = this.wordLayer['strip_' + starNum];
		cc.tween(strip)
			.to(0.5, {scaleX: 1}, {easing: "cubicOut"})
			.call(() => {
				this.checkHideWordLayer();
			})
			.start();
	},

	showSentenceLayerStar(starNum) {
		const fillStar = this.sentenceLayer['star_' + starNum];
		cc.tween(fillStar)
			.to(0.5, {opacity: 255}, {easing: "cubicOut"})
			.start();

		const strip = this.sentenceLayer['strip_' + starNum];
		cc.tween(strip)
			.to(0.5, {scaleX: 1}, {easing: "cubicOut"})
			.call(() => {
				this.checkHideSentenceLayer();
			})
			.start();
	},


	smallBasketFruitCount: null,
	addSmallBasketFruit() {
		if (!this.smallBasketFruitCount) {
			this.smallBasketFruitCount = 1;
		}

		if (this.smallBasketFruitCount > 3) {
			return;
		}

		let resName;
		switch(this.treeType) {
			case this.treeTypeArr[0]:
				resName = "basket_small/icon_basket_1_" + this.smallBasketFruitCount;
				break;
			case this.treeTypeArr[1]:
				resName = "basket_small/icon_basket_2_" + this.smallBasketFruitCount;
				break;
			case this.treeTypeArr[2]:
				resName = "basket_small/icon_basket_3_" + this.smallBasketFruitCount;
				break;
						

		}

		console.log("resName: ", resName);

		const oldBasket = this.curSmallBasket;
		const newBasket = getSprNode(resName);
		newBasket.parent = oldBasket.parent;
		newBasket.x = oldBasket.x;
		newBasket.y = oldBasket.y;

		this.curSmallBasket = newBasket;
		this.smallBasketFruitCount ++;

		this.changePicAnima(oldBasket, newBasket);
	},

	bigBasketFruitCount: null,
	curBigBasket: null,
	addBigBasketFruit() {
		if (!this.bigBasketFruitCount) {
			this.bigBasketFruitCount = 1;
		}

		if (this.bigBasketFruitCount > 3) {
			return;
		}

		let resName;
		switch(this.treeType) {
			case this.treeTypeArr[0]:
				resName = "basket_big/icon_basket_1_" + this.bigBasketFruitCount;
				break;
			case this.treeTypeArr[1]:
				resName = "basket_big/icon_basket_2_" + this.bigBasketFruitCount;
				break;
			case this.treeTypeArr[2]:
				resName = "basket_big/icon_basket_3_" + this.bigBasketFruitCount;
				break;

		}

		console.log("resName: ", resName);

		const oldBasket = this.curBigBasket;
		const newBasket = getSprNode(resName);
		newBasket.parent = oldBasket.parent;
		newBasket.x = oldBasket.x;
		newBasket.y = oldBasket.y;

		this.curBigBasket = newBasket;
		this.bigBasketFruitCount ++;

		
		this.changePicAnima(oldBasket, newBasket);
	},


	changePicAnima(oldPic, newPic) {

		newPic.opacity = 0;
		
		this.showDropFruitAnima(newPic, () => {
			this.changePicAnimaStart(oldPic, newPic);
		});

	},

	changePicAnimaStart(oldPic, newPic) {

		newPic.opacity = 0;

		const changeTime = 0.5;
		cc.tween(newPic) 
			.to(changeTime, {opacity: 255}, {easing: "cubicOut"})
			.call(() => {

				cc.tween(oldPic)
					.to(changeTime, {opacity: 0})
					.call(() => {
						oldPic.removeFromParent();
					})
					.start();
			})
			.start();

	},


	showDropFruitAnima(pic, cb) {

		let resName;
		switch(this.treeType) {
			case this.treeTypeArr[0]:
				resName = "icon_apple"
				break;
			case this.treeTypeArr[1]:
				resName = "icon_banana"
				break;
			case this.treeTypeArr[2]:
				resName = "icon_orange"
				break;
		}

		const time = 0.7;
		const maxLen = pic.width * pic.scaleX * 0.33;
		for (let i=0; i<2; i++) {
			const fruit = getSprNode(resName);
			fruit.scale = maxLen / fruit.width;
			fruit.angle = Math.random() * 360;
			fruit.x = pic.x + Math.random() * 60 - 30;
			fruit.y = pic.y + Math.random() * 60 - 30 + 200;
			fruit.parent = pic.parent;
			fruit.opacity = 0;

			const delayTime = 0.1 + i * Math.random() * 0.3;
			cc.tween(fruit)
				.delay(delayTime)
				.to(time, {y: pic.y}, {easing: "cubicIn"})
				.call(() => {
					fruit.removeFromParent();
				})
				.start()

			
			cc.tween(fruit)
				.delay(delayTime)
				.to(time * 0.1, {opacity: 255})
				.to(time * 0.9, {opacity: 0}, {easing: "cubicIn"})
				.start();

		}

		delayCall(0.8, () => {
			cb();
		})
	},

	checkHideWordLayer() {

		console.log('this.wordLayer: ', this.wordLayer);
		for( let i=1; i<=3; i++) {
			const star = this.wordLayer['star_' + i];
			if (star.opacity == 0) {
				return;
			}
		}


		console.log(' hidelayer ');
		this.hideLayerLayer(this.wordLayer);
	},

	hideLayerLayer(layer) {

		if (layer.isHide) {
			return;
		}
		layer.isHide = true;

		cc.tween(layer)
			.delay(1)
			.to(0.5, {opacity: 0}, {easing: "cubicIn"})
			.call(() => {
				layer.active = false;
				this.checkEnterNextTree();
			})
			.start();
	},

	checkHideSentenceLayer() {
		for( let i=1; i<=3; i++) {
			const star = this.sentenceLayer['star_' + i];
			if (star.opacity == 0) {
				return;
			}
		}

		this.hideLayerLayer(this.sentenceLayer);
	},


	getEmptyStar(num) {
		const emptyStarResName = 'icon_empty_star_' + num;
		const star = getSprNode(emptyStarResName);
		star.anchorX = 0;
		return star;
	},

	getFillStar(num) {
		const fillStarResName = 'icon_fill_star_' + num;
		const star = getSprNode(fillStarResName);
		star.anchorX = 0;
		return star;
	},

	getWordLayerText() {

		let resName;
		switch(this.treeType) {
			case this.treeTypeArr[0]:
				resName = "text_apple"
				break;
			case this.treeTypeArr[1]:
				resName = "text_banana"
				break;
			case this.treeTypeArr[2]:
				resName = "text_orange"
				break;
		}

		const wordLayerText = getSprNode(resName);
		return wordLayerText;
	},

	getSentenceLayerText() {
		let resName;
		switch(this.treeType) {
			case this.treeTypeArr[0]:
				resName = "text_apples"
				break;
			case this.treeTypeArr[1]:
				resName = "text_bananas";
				break;
			case this.treeTypeArr[2]:
				resName = "text_oranges";
				break;
		}

		const text = getSprNode(resName);
		return text;
	},


	isShowEndLayer: null,
	curStopX: null,
	curFruit: null,
	jumpTimes: null,
	curGroupClip: null,
	curSentenceClip: null,
	setCurStopX() {

		this.jumpTimes = 0;

		switch(this.treeType) {
			case this.treeTypeArr[0]:
				this.curStopX = this.apple.x - 300;
				this.curFruit = this.apple;
				this.curRealFruit = this.realApple;
				this.curGroupClip = this.appleGroupClip;
				this.curSentenceClip = this.appleSentenceClip;
				break;
			
			case this.treeTypeArr[1]:
				this.curStopX = this.banana.x - 300;
				this.curFruit = this.banana;
				this.curRealFruit = this.realBanana;
				this.curGroupClip = this.bananaGroupClip;
				this.curSentenceClip = this.bananaSentenceClip;

				break;

			case this.treeTypeArr[2]:
				this.curStopX = this.orange.x - 300;
				this.curFruit = this.orange;
				this.curRealFruit = this.realOrange;
				this.curGroupClip = this.orangeGroupClip;
				this.curSentenceClip = this.orangeSentenceClip;

				break;
			
			default:
				this.curStopX = this.bgGround.width + this.role.width * this.role.scaleX;
				this.isShowEndLayer = true;
				break;
		}
	},

	showFruit() {

		const time = 0.7
		cc.tween(this.curFruit)
			.to(time, {opacity: 255, y: this.role.y - 130}, {easing: "cubicIn"})
			.call(() => {
				this.fruitJump();
			})
			.start()

		playAudio(this.appearClip);
		
	},

	fruitJump() {

		


		const audioTime = this.curGroupClip[0].duration;
		console.log('audioTime: ', audioTime)
		// var actionJump = cc.jumpBy(audioTime * 2, cc.v2(100, 0), 140 - this.jumpTimes * 35, 1);
		var actionJump = cc.jumpBy(audioTime * 2, cc.v2(100, 0), 140, 1);
		const callFunc = cc.callFunc(() => {
			this.jumpTimes ++
			if (this.jumpTimes < 3) {
				this.fruitJump();
			} else {
				this.fruitJumpEnd();
			}
		})

		cc.tween(this.curFruit)
			.to(audioTime, {scale: this.curFruit.scale * 1.3}, {easing: "sineInOut"})
			.start();

		const seq = cc.sequence(actionJump, callFunc);
		this.curFruit.runAction(seq);
		
		playAudio(this.curGroupClip[this.jumpTimes]);

	},

	fruitJumpEnd() {
		this.showFruitMagic();
	},

	showFruitMagic() {
		const fruitMagic = getSprNode("icon_magiccircle")
		this.curFruit.addChild(fruitMagic);
		fruitMagic.scale = 0;

		cc.tween(fruitMagic)
			.by(1, {angle: 180})
			.repeatForever()
			.start();

		cc.tween(fruitMagic)
			.to(0.5, {scale: 1}, {easing: "sineOut"})
			.start();

		const time = 1;
		cc.tween(this.curFruit)
			.to(time, {y: this.curFruit.y + 50}, {easing: "cubicInOut"})
			.call(() => {
				this.showFruitPanel();
			})
			.start();

		playAudio(this.magicClip);
	},


	curFruitPanel: null,
	showFruitPanel() {
		const fruitPanel = this.getFruitPanel();
		fruitPanel.x = this.curFruit.x;
		fruitPanel.y = this.curFruit.y;
		fruitPanel.parent = this.curFruit.parent;
		fruitPanel.anchorX = 1;
		fruitPanel.zIndex = 1000;
		fruitPanel.scale = 0;
		this.curFruitPanel = fruitPanel;

		this.changeRealFruit();
		this.showTi(2);


		// fruitPanel.zIndex = 1000;
	},

	changeRealFruit() {

		cc.tween(this.curFruit)
		.to(0.4, {scale: 0}, {easing: "cubicIn"})
		.call(() => {

			cc.tween(this.curFruitPanel)
				.to(0.9, {scale: this._mapScaleMin}, {easing: "elasticOut"})
				.call(() => {

					this.playSentenceAudio();
				})
				.start();

				delayCall(0.2, () => {
					playAudio(this.realFruitClip)
				})
		})
		.start();
	},

	curSentencePanel: null,
	showSentencePanel() {
		const sentencePanel = this.getSentencePanel();
		sentencePanel.anchorX = 0;
		sentencePanel.anchorY = 0;
		sentencePanel.scale = 0;
		sentencePanel.x = 60;
		sentencePanel.y = 80;
		this.curSentencePanel = sentencePanel;

		this.role.addChild(sentencePanel);

		cc.tween(sentencePanel)
			.to(0.5, {scale: 1}, {easing: "cubicOut"})
			.start();

	},

	playSentenceAudio() {
		this.roleSpeak();
		this.showSentencePanel();

		playAudio(this.curSentenceClip, () => {
			this.roleIdle();
		})
	
	},


	sentencePanelSoundBtn: null,
	sentencePanelSpeakBtn: null,
	getSentencePanel() {
		let resName;
		switch(this.treeType) {
			case this.treeTypeArr[0]:
				resName = "bg_ilike_apple";
				break;
			case this.treeTypeArr[1]:
				resName = "bg_ilike_banana";
				break;
			case this.treeTypeArr[2]:
				resName = "bg_ilike_orange";
				break;
		}
		const panel = getSprNode(resName);


		const sound_1 = cc.find("Canvas/res/anima/sound_1")
		const soundIcon = cc.instantiate(sound_1)	
		panel.addChild(soundIcon);
		soundIcon.x = 70;
		soundIcon.y = panel.height + 10;

		soundIcon.addComponent(cc.Button)
		soundIcon.on("click", () => {
			this.sendServerEvent("sentence_panel_sound_click", {});
		})

		const anima = soundIcon.getComponent(cc.Animation);
		soundIcon.anima = anima;
		this.sentencePanelSoundBtn = soundIcon;


		const speakIcon = getSprNode("btn_speak");
		speakIcon.anchorX = 0;
		speakIcon.x = panel.width - 20;
		speakIcon.y = panel.height - 20;
		panel.addChild(speakIcon);

		panel.speakIcon = speakIcon;


		speakIcon.addComponent(cc.Button);
		speakIcon.on("click", () => {

			this.sendServerEvent("sentence_panel_speak_click");

		});
		this.sentencePanelSpeakBtn = speakIcon;

		return panel;

	},

	sentencePanelSpeakClick() {

		const speakIcon = this.sentencePanelSpeakBtn;

		if (speakIcon.isClicked) {
			return;
		}

		speakIcon.isClicked = true;

		this.resetSentenceLayer();
		this.showSentenceLayer();

		cc.tween(speakIcon)
			.to(0.3, {opacity: 0}, {easing:"cubicOut"})
			.call(() => {
				speakIcon.active = false;
			})
			.start();
	},


	sentencePanelSoundClick() {

		const soundIcon = this.sentencePanelSoundBtn;
		if (soundIcon.isClicked) {
			return;
		}
		soundIcon.isClicked = true;

		this.roleSpeak();
		const anima = soundIcon.anima;
		anima.play("sound_1");

		playAudio(this.curSentenceClip, () => {
			soundIcon.isClicked = false;
			anima.play("sound_1", 0);
			anima.sample("sound_1");
			anima.stop();
			this.roleIdle();
		})

		this.addMagicBasketFruit()
	},


	magciBasketFruitCount: null,
	addMagicBasketFruit() {
		if (!this.magciBasketFruitCount) {
			this.magciBasketFruitCount = 1;
		}
		
		if (this.magciBasketFruitCount > 6) {
			return;
		}

		let resName;
		switch(this.treeType) {
			case this.treeTypeArr[0]:
				resName = "magic_basket/apple" + this.magciBasketFruitCount;
				break;
			case this.treeTypeArr[1]:
				resName = "magic_basket/banana" + this.magciBasketFruitCount;
				break;
			case this.treeTypeArr[2]:
				resName = "magic_basket/orange" + this.magciBasketFruitCount;
				break;
						

		}

		console.log("resName: ", resName);

		const oldBasket = this.curMagicBasket;
		const newBasket = getSprNode(resName);
		newBasket.parent = oldBasket.parent;
		newBasket.x = oldBasket.x;
		newBasket.y = oldBasket.y;

		this.curMagicBasket = newBasket;

		this.magciBasketFruitCount ++;


		this.changePicAnima(oldBasket, newBasket);
	},

	resetMagicBasket() {

		if (this.typeIndex == 2) {
			return;
		}

		const oldBasket = this.curMagicBasket;
		const newBasket = getSprNode("icon_magicbasket");
		newBasket.parent = oldBasket.parent;
		newBasket.x = oldBasket.x;
		newBasket.y = oldBasket.y;

		this.curMagicBasket = newBasket;

		this.magciBasketFruitCount = 1;

		oldBasket.zIndex = 10;
		this.changePicAnimaStart(oldBasket, newBasket);
	},


	fruitPanelSoundBtn: null,
	fruitPanelSpeakBtn: null,
	getFruitPanel() {
		let resName;
		let speakIconOffX = 0;
		switch(this.treeType) {
			case this.treeTypeArr[0]:
				resName = "bg_apple_panel"
				break;
			case this.treeTypeArr[1]:
				resName = "bg_banana_panel"
				speakIconOffX = -75;
				break;
			case this.treeTypeArr[2]:
				resName = "bg_orange_panel"
				break;
		}
		const panel = getSprNode(resName);

		const realFruit = this.curRealFruit;
		panel.addChild(realFruit);

		const sound_1 = cc.find("Canvas/res/anima/sound_1")
		const soundIcon = cc.instantiate(sound_1)	
		panel.addChild(soundIcon);
		soundIcon.x = -270;
		soundIcon.y = 60;
		soundIcon.addComponent(cc.Button)
		soundIcon.on("click", () => {
			this.sendServerEvent("fruit_panel_sound_click", {})
		})

		const anima = soundIcon.getComponent(cc.Animation);
		soundIcon.anima = anima;
		soundIcon.realFruit = realFruit;
		this.fruitPanelSoundBtn = soundIcon;


		const speakIcon = getSprNode("btn_speak");
		speakIcon.anchorX = 0;
		speakIcon.x = speakIcon.width / 2 + speakIconOffX;
		speakIcon.y = speakIcon.height / 4;
		panel.addChild(speakIcon);

		panel.speakIcon = speakIcon;

		speakIcon.addComponent(cc.Button);
		speakIcon.on("click", () => {

			this.sendServerEvent("fruit_panel_speak_click")
		});

		this.fruitPanelSpeakBtn = speakIcon;

		return panel;
	},

	fruitPanelSpeakClick() {

		const speakIcon = this.fruitPanelSpeakBtn;

		if (speakIcon.isClicked) {
			return;
		}
		speakIcon.isClicked = true;

		this.resetWordLayer();
		this.showWordLayer();


		cc.tween(speakIcon)
			.to(0.3, {opacity: 0}, {easing:"cubicOut"})
			.call(() => {
				speakIcon.active = false;
			})
			.start();
	},


	fruitPanelSoundClick() {

		const soundIcon = this.fruitPanelSoundBtn;

		if (soundIcon.isClicked) {
			return;
		}
		soundIcon.isClicked = true;

		const anima = soundIcon.anima;
		anima.play("sound_1");

		jellyShake(soundIcon.realFruit);

		playAudio(this.curFruit.clip, () => {
			soundIcon.isClicked = false;
			anima.play("sound_1", 0);
			anima.sample("sound_1");
			anima.stop();
		})

	},



	resetWordLayer() {

		this.smallBasketFruitCount = 1;
		
		const layer = this.wordLayer;
		const bg = layer.bg;

		layer.realFruit.removeFromParent();

		layer.isHide = false;

		const realFruit = cc.instantiate(this.curRealFruit);
		realFruit.scale = this._mapScaleMin * 1.5;
		realFruit.x = -430;
		realFruit.y = -10;
		bg.addChild(realFruit);
		layer.realFruit = realFruit;


		layer.text.removeFromParent();

		const text = this.getWordLayerText();
		bg.addChild(text);
		text.x = -60;
		layer.text = text;
		

		for (let i=0 ;i<3 ;i++) {
		
			layer['strip_' + (3-i)].scaleX = 0;
			layer['star_' + (3-i)].opacity = 0;
		}
		

		console.log(' aaa bb ');
		this.curSmallBasket.removeFromParent();

		const basket = getSprNode("basket_small/icon_basket");
		bg.addChild(basket);
		basket.x = 540;
		basket.y = -190
		this.curSmallBasket = basket;

		const btnArr = this.wordLayer.tiBtnArr;
		console.log('btnArr: ', this.btnArr);
		for (let i=0; i<btnArr.length; i++) {
			btnArr[i].star.opacity = 255;
			btnArr[i].isClicked = false;
		}
	},

	showWordLayer() {

		this.wordLayer.active = true;
		this.wordLayer.opacity = 0;

		cc.tween(this.wordLayer)
			.to(0.7, {opacity: 255}, {easing: "cubicOut"})
			.start();

		playAudio(this.popClip);
	},

	showSentenceLayer() {
		this.sentenceLayer.active = true;
		this.sentenceLayer.opacity = 0;

		cc.tween(this.sentenceLayer)
			.to(0.7, {opacity: 255}, {easing: "cubicOut"})
			.start();	

		playAudio(this.popClip);
	},

	resetSentenceLayer() {

		this.bigBasketFruitCount = 1;
		
		const layer = this.sentenceLayer;
		const bg = layer.bg;

		this.curBigBasket.removeFromParent();

		layer.isHide = false;

		const basket = getSprNode("basket_big/icon_basket");
		bg.addChild(basket)
		basket.x = -450;
		this.curBigBasket = basket;


		layer.text.removeFromParent();

		const text = this.getSentenceLayerText();
		bg.addChild(text);
		text.x = -60;
		layer.text = text;

		for (let i=0 ;i<3 ;i++) {
		
			layer['strip_' + (3-i)].scaleX = 0;
			layer['star_' + (3-i)].opacity = 0;
		}
		

		const btnArr = layer.tiBtnArr;
		for (let i=0; i<btnArr.length; i++) {
			btnArr[i].star.opacity = 255;
			btnArr[i].isClicked = false;
		}
	},



	curWalkAudioId: null,
	playWalkAudio() {
		this.curWalkAudioId = playAudio(this.walkClip, () => {
			if (this.role.isMoving) {
				this.playWalkAudio();
			}
		})
	},

	stopWalkAudio() {

		console.log('in curWalkAudioId: ', this.curWalkAudioId)
		cc.audioEngine.stop(this.curWalkAudioId);

	},

	roleMove() {


		this.role.speedX = 3.2;
		this.role.isMoving = true;
		this.role.anima.playAnimation("walk", -1)


		this.playWalkAudio();
		
	},

	roleIdle() {

		this.role.isMoving = false;
		this.role.anima.playAnimation("normal", -1)

		this.stopWalkAudio();
	},

	roleSpeak() {

		this.role.isMoving = false;
		this.role.anima.playAnimation("speak", -1)

		this.stopWalkAudio();
	},


	checkEnterNextTree() {
		if (this.curFruitPanel.speakIcon.active) {
			return;
		}
		if (this.curSentencePanel.speakIcon.active) {
			return;
		}

		// if (this.typeIndex >= 2) {
		// 	return;
		// }


		this.hideFruitPanel();
		this.hideSentencePanel();
		// this.resetMagicBasket();

		delayCall(0.4, () => {
			this.showGoodJob();
			this.showTi(3);
		})

		playAudio(this.goodjobClip);

		this.hideCurTi();

		// this.enterNextTree(this.treeTypeArr[this.typeIndex]);
	},

	showGoodJob() {
		let resName;
		switch(this.treeType) {
			case this.treeTypeArr[0]:
				resName = "good_job/bg_goodjob_1";
				break;
			case this.treeTypeArr[1]:
				resName = "good_job/bg_goodjob_2";
				break;
			case this.treeTypeArr[2]:
				resName = "good_job/bg_goodjob_3";
				break;
		}

		const goodJobLayer = this.goodJobLayer;
		goodJobLayer.active = true;
		goodJobLayer.opacity = 0;

		const showLayerTime = 0.4;
		const showIconTime = 1.2;
		const delayTime = 1;

		cc.tween(goodJobLayer)
			.to(showLayerTime, {opacity: 255})
			.delay(showIconTime)
			.delay(delayTime)
			.to(showLayerTime, {opacity: 0})
			.call(() => {
				goodJobLayer.active = false;
				if (this.typeIndex > 1) {
					this.enterNextTree();
				} else {
					this.showNextBtn();
				}
			})
			.start();

		if (goodJobLayer.icon) {
			goodJobLayer.icon.removeFromParent();
			goodJobLayer.icon = null;
		}
		const goodJob = getSprNode(resName);
		goodJobLayer.addChild(goodJob);
		goodJob.scale = 0;
		goodJobLayer.icon = goodJob;

		cc.tween(goodJob)
			.delay(showLayerTime)
			.to(showIconTime, {scale: this._mapScaleMin}, {easing: "elasticOut"})
			.start();


		const p = goodJob.position;

		this.showOneFirework(p, this.canvas, cc.find('paperBase').children, 300, 500, 30, 1);

	},


	enterNextTree() {

		this.hideCurTi();
		this.hideNextBtn();

		this.resetMagicBasket();

		this.typeIndex ++;
		const type = this.treeTypeArr[this.typeIndex];

		this.treeType = type;
		this.setCurStopX();
		this.roleMove();
	},

	hideFruitPanel() {
		cc.tween(this.curFruitPanel)
			.to(0.3, {opacity: 0})
			.call(() => {
				this.curFruitPanel.removeFromParent();
			})
			.start();
	},

	hideSentencePanel() {
		cc.tween(this.curSentencePanel)
		.to(0.3, {opacity: 0})
		.call(() => {
			this.curSentencePanel.removeFromParent();
		})
		.start();
	},


	endLayer: null,
	initEndLayer() {

		const node = new cc.Node();
		this.canvas.addChild(node, 40);
		node.active = false;
		this.endLayer = node;


		const endBg = getSprNode('finish/bg_finish');
		node.addChild(endBg);
		endBg.scale = this._mapScaleMax;


		const resDragonBone = cc.find("Canvas/res/anima/clamphands")
		const clamphands = cc.instantiate(resDragonBone)	
	

		const dragonDisplay = clamphands.getComponent(dragonBones.ArmatureDisplay);
		// dragonDisplay.on(dragonBones.EventObject.COMPLETE, () => {
		// })
		dragonDisplay.playAnimation('clamphands', -1);


		clamphands.scale = this._mapScaleMin;
		clamphands.x = -this.canvas.width / 2 + clamphands.width / 2 * this._mapScaleMin;
		clamphands.y = -this.canvas.height / 2 + clamphands.height / 2 * this._mapScaleMin;
		node.addChild(clamphands);
	},


	showEndMask() {
	
		const bgBlack = getSprNode("black")
		bgBlack.scaleX = this.canvas.width / bgBlack.width;
		bgBlack.scaleY = this.canvas.height / bgBlack.height;
		this.canvas.addChild(bgBlack, 41);
		bgBlack.opacity = 0;
		
		const time = 1;
		cc.tween(bgBlack)
			.to(time, {opacity: 255}, {easing: "cubicIn"})
			.call(() => {
				this.endLayer.active = true;
			})
			.to(time / 2, {opacity: 0}, {easing: "sineOut"})
			.call(() => {
				this.showEndLayer();
			})
			.start()
	},


	showEndLayer() {
		console.log('show end layer');

		const endBg = this.endLayer;
		endBg.height = this.canvas.height;
		endBg.active = true;
		
		const endIcon = getSprNode("finish/bg_finish_icon")
		endIcon.scale = 0;
		endIcon.x = 200 * this._mapScaleMin;
		endIcon.y = -50 * this._mapScaleMin;
		endBg.addChild(endIcon, 1);

		cc.tween(endIcon)
			.to(1, {scale: this._mapScaleMin}, {easing: "elasticOut"})
			.start();

		const bgLight = getSprNode("finish/bg_light");
		bgLight.scale = this._mapScaleMin;
		endBg.addChild(bgLight);
		bgLight.x = endIcon.x;
		bgLight.y = endIcon.y;

		cc.tween(bgLight)
			.to(0.3, {opacity: 255})
			.start();

		cc.tween(bgLight)
			.by(10, {angle: 360})
			.repeatForever()
			.start();


			// const p = bgLight.position;
			// p.x = 0;
			// p.y = this.canvas.height / 4;

		this.showOneFirework(bgLight.position, endBg, cc.find('paperBase').children, 400, 600, 30);

		playAudio(this.finishClip);

	},




	async showOneFirework(pos, parentNode, nodeList, w, h, n, timeRate=1) {

		for (let i = 0; i < 3; i++) {
				this.showFirework(pos, parentNode, nodeList, w, h, n, timeRate);
				await asyncDelay(0.1);
		}
	},

	showFirework(pos, parentNode, nodeList, width = 200, height = 500, number = 30, timeRate=1) {
			for (let i = 0; i < number; i++) {
					const quad = this.createQuads(pos, parentNode, nodeList);
					const targetX = RandomInt(width / 2, -width / 2);
					const targetY = RandomInt(height);

					cc.tween(quad)
							.by(0.5 * timeRate, { x: targetX })
							.by((2 + 2 *  Math.random()) * timeRate, { x: targetX * 2 })
							.start();

					cc.tween(quad)
							.by(0.5 * timeRate, { y: targetY }, { easing: 'quadOut' })
							.to((3 + 2 * Math.random()) * timeRate, { y: -parentNode.height * 2 }, { easing: 'quadIn' })
							.removeSelf()
							.start();

					cc.tween(quad)
							.delay(1  * timeRate)
							.to((0.5 + 2 * Math.random()) * timeRate , { opacity: 0 })
							.start();
			}
	},

	createQuads(pos, parentNode, nodeList) {
			const quadBase = cc.instantiate(nodeList[RandomInt(nodeList.length)]);
			console.log('nodeList', nodeList);
			console.log('quadBase', quadBase);
			quadBase.x = pos.x;
			quadBase.y = pos.y;
			quadBase.z = pos.z;
			quadBase.angle = RandomInt(180);
			quadBase.parent = parentNode;

			const quad = quadBase.getChildByName('quad');
			quad.x = 0;
			quad.y = 0;
			quad.angle = RandomInt(180);

			const paper = quad.getChildByName('paper');
			paper.scaleX = Math.random() * 0.8 + 0.2;
			paper.scaleY = Math.random() * 0.8 + 0.2;

			quadBase.scaleX = Math.random();
			cc.tween(quadBase)
					.to((1 - quadBase.scaleX) * 0.3, { scaleX: 1 })
					.call(() => {
							const time = Math.random() * 0.2;
							cc.tween(quadBase)
									.to(0.1 + time, { scaleX: -1 })
									.to(0.1 + time, { scaleX: 1 })
									.union()
									.repeatForever()
									.start();
					})
					.start();


			return quadBase;
	},


	curTi: null,
	showTi(id) {
		const ti = getSprNode("bg_ti_" + id)
		this.canvas.addChild(ti);
		ti.y = -this.canvas.height / 2;
		ti.anchorY = 0;
		ti.opacity = 0;
		ti.scale = this._mapScaleMin;

		this.curTi = ti;

		cc.tween(ti)
			.to(0.5, {opacity: 255}, {easing: "cubicOut"})
			.start();
		
		if (!this.isTeacher) {
			ti.active = false;
		}
	},

	hideCurTi() {

		cc.tween(this.curTi)
			.to(0.5, {opacity: 0}, {easing: "cubitOut"})
			.start();
	},




















	countNum: null,
	countDown() {

		const dateTime = this.getPageData('dateTime');
		if (dateTime) {
			//已经倒数过  直接开始
			this.gameStart();
			return;
		}

		
		if (!this.countNum) {
			this.countNum = 3;
			playAudio(this.countDownClip);

		}

		const countSpr = getSprNode("text_" + this.countNum);
		countSpr.scale = this._mapScaleMin;
		this.canvas.addChild(countSpr, 30)
		countSpr.opacity = 0;


		cc.tween(countSpr)
			.to(0.2, {opacity: 255}, {easing: "cubicOut"})
			.delay(0.8)
			.to(0.2, {opacity: 0}, {easing: "cubicOut"})
			.call(() => {
				countSpr.removeFromParent();
			})
			.start();

		delayCall(1, () => {
			this.countNum --;
			if (this.countNum > 0) {
				this.countDown();
			} else {
				this.gameStart();
			}
		})
	},

	gameStart() {

		this.initKnife();

		if (this.isTeacher) {
			// 老师统计结束时间
			this.setGameEndTime();

		} else {
			// 学生控制加水果
			this.addItem();
		}
	
	},

	setGameEndTime() {

		let time = 60;
		let dateTime = this.getPageData('dateTime');
		if (dateTime) {
			const subTime = (new Date().getTime() - dateTime) / 1000;
			time -= subTime;
			if (time < 0 || time > 60) {
				time = 0;
			}
		} else {
			dateTime = new Date().getTime();
			this.setPageData('dateTime', dateTime);
		}

		console.log('time: ', time);

		delayCall(time, () => {
			this.gameEnd();
		})
	},
	

	addItem() {
		if (this.isGameEnd) {
			return;
		}

		if (Math.random() < 0.1) {
			this.addBomb();
		} else {
			this.addFruit();
		}

		
		const time = this.canvas.height / (this.baseSpeed * 200);
		delayCall(time, () => {
			this.addItem();
		})

	},

	 addBomb(data=null) {

		const bomb = this.getBomb(data);
		this.fruitArr.push(bomb);
		
		if (!this.isTeacher) {
			this.sendServerEvent("add_bomb", {send_data: bomb.data});
		}

		// if (!data) {
		// 	// 不是server发来的
		// 	removeFromArr(this.fruitArr, bomb);
		// 	bomb.removeFromParent();
		// 	this.sendServerEvent("add_bomb", {send_data: bomb.data});
		// }

	},

	addFruit(data=null) {

		const fruit = this.getFruit(data);
		this.fruitArr.push(fruit);


		if (!this.isTeacher) {
			this.sendServerEvent("add_fruit", {send_data: fruit.data});
		}

		// if (!data) {
		// 	removeFromArr(this.fruitArr, fruit);
		// 	fruit.removeFromParent();
		// 	this.sendServerEvent("add_fruit", {send_data: fruit.data});
		// }
	

	},

	getBomb(data = null) {
		const node = getSprNode("icon_bomb");

		const maxW = this.canvas.width - 300 * this._mapScaleMin;

		if (!data) {
			data = {};
			data.xRandom = Math.random();
			data.sRandom =  Math.random();
			data.id = new Date().getTime();
		}
		node.x =  -maxW / 2 + data.xRandom * maxW;
		node.y = this.canvas.height / 2 + 300 / 2 * this._mapScaleMin;
		// node.angle = -30 + Math.random() * 60;
		node.scale = (0.7 + data.sRandom  * 0.3) * this._mapScaleMin;
		this.canvas.addChild(node);

		node.data = data;

		this.addBombListener(node);
		this.setFruitSpeed(node);

		return node;
	},

	getFruit(data=null) {
	
		if (!data) {
			data = {};
			data.xRandom = Math.random();
			data.rRandom = Math.random();
			data.sRandom = Math.random();
			data.speedRandom = Math.random();
			data.id = new Date().getTime();
			data.fruitId = 1 + Math.floor(Math.random() * 7);
		}

		const id = data.fruitId 

		
		const maxW = this.canvas.width - 300 * this._mapScaleMin;
		const node = new cc.Node();
		node.x = -maxW / 2 + data.xRandom * maxW;
		node.y = this.canvas.height / 2 + 300 / 2 * this._mapScaleMin;
		node.angle = data.rRandom * 360;
		node.scale = (0.7 +  data.sRandom * 0.3) * this._mapScaleMin;
		this.canvas.addChild(node);

		node.speedR = -0.25 + data.speedRandom * 0.5

		node.id = id;
		node.data = data;


		const icon = getSprNode("fruit/" + id + "_icon");
		node.addChild(icon);
		node.icon = icon;

		const iconLeft = getSprNode("fruit/" + id + "_icon_l")
		node.addChild(iconLeft, 1);
		node.iconLeft = iconLeft;
		iconLeft.active = false;

		const iconRight = getSprNode("fruit/" + id + "_icon_r")
		node.addChild(iconRight, 1);
		node.iconRight = iconRight;
		iconRight.active = false;

		const iconPop = getSprNode("fruit/" + id + "_pop")
		node.addChild(iconPop)
		node.iconPop = iconPop;
		iconPop.active = false;
		
		this.addFruitListener(node);
		this.setFruitSpeed(node);

		return node;

	},

	addFruitListener(fruit) {

		const icon = fruit.icon;
		icon.on(cc.Node.EventType.TOUCH_START, () => {
			console.log('touch fruit');
			if (fruit.isPop) {
				return;
			}
			if (this.isStopUpdate) {
				return;
			}

			if (this.isTeacher) {
				return;
			}
		
			this.touchFruit(fruit);
		});
	},



	serverTouchFruit(dataId) {
		const arr = this.fruitArr;
		for (let i=0; i<arr.length; i++) {
			if (arr[i]?.data?.id == dataId) {
				this.touchFruit(arr[i], true);
				break;
			}
		}
	},
	touchFruit(fruit, isServer=false) {

		if (!isServer && !this.isTeacher) {
			this.sendServerEvent('touch_fruit', {data_id: fruit.data.id})
			// return;
		}

		this.knifeOnFruit(fruit);
		this.showScore(fruit);
		this.fruitPop(fruit);

	},

	addBombListener(bomb) {

		bomb.on(cc.Node.EventType.TOUCH_START, () => {
			console.log('touch bomb');
			if (bomb.isPop) {
				return;
			}
			if (this.isStopUpdate) {
				return;
			}

			this.touchBomb(bomb);
			
		});
	},


	serverTouchBomb(dataId) {
		const arr = this.fruitArr;
		for (let i=0; i<arr.length; i++) {
			if (arr[i]?.data?.id == dataId) {
				this.touchBomb(arr[i], true);
				break;
			}
		}
	},
	touchBomb(bomb, isServer=false) {

		if (!isServer && !this.isTeacher) {
			this.sendServerEvent('touch_bomb', {data_id: bomb.data.id} );
			// return;
		}

		this.knifeOnFruit(bomb);
		this.showBombAnima(bomb);

	},

	isStopUpdate: null,
	showBombAnima(bomb) {

		this.isStopUpdate = true;
		bomb.isPop = true;

		const bgBlack = getSprNode("bg_black")
		bgBlack.scaleX = this.canvas.width / bgBlack.width * 1.5;
		bgBlack.scaleY = this.canvas.height / bgBlack.height * 1.5;
		this.canvas.addChild(bgBlack, 41);
		
		const bgBlackLight = getSprNode("bg_blacklight");
		bgBlackLight.scaleX = 1 /	bgBlack.scaleX * this._mapScaleMax
		bgBlackLight.scaleY = 1 /	bgBlack.scaleY * this._mapScaleMax
		bgBlack.addChild(bgBlackLight);

		const resDragonBone = cc.find("Canvas/res/anima/bomb")
		const magic = cc.instantiate(resDragonBone)	

		const dragonDisplay = magic.getComponent(dragonBones.ArmatureDisplay);
		dragonDisplay.on(dragonBones.EventObject.COMPLETE, () => {
			cc.tween(bgBlack)
				.to(0.5, {opacity: 0})
				.call(() => {
					bgBlack.removeFromParent();
					magic.removeFromParent();
				})
				.start();

				if (!this.isGameEnd) {
					this.isStopUpdate = false;
				}
		})
		dragonDisplay.playAnimation('bomb', 1);

		magic.x = bomb.x;
		magic.y = bomb.y;
		magic.scale = bomb.scale;

		this.canvas.addChild(magic, 42);
		// magic.parent = this.canvas;
		this.removeBomb(bomb);

		delayCall(0.55, () => {
			this.shakeScreen();
			playAudio(this.popClip);
		})

	},

	shakeScreen() {

		const camera = cc.find("Canvas/Main Camera")

		const time = 0.4;
		const rate = -2;
		cc.tween(camera)
			.to(time / 4 / 2, {x: 12 * rate, y: 12 * rate}, {easing: "sineInOut"})
			.to(time / 4, {x: -8 * rate, y: -8 * rate}, {easing: "sineInOut"})
			.to(time / 4, {x: 5 * rate, y: 5 * rate}, {easing: "sineInOut"})
			.to(time / 4, {x: -1 * rate, y: -1 * rate}, {easing: "sineInOut"})
			.to(time / 4, {x: 0 * rate, y: 0 * rate}, {easing: "sineInOut"})
			.start();
	},


	removeBomb(bomb) {
		removeFromArr(this.fruitArr, bomb);
		bomb.removeFromParent();
	},


	knifeOnFruit(fruit) {
		this.knife.x = fruit.x + 30 * this._mapScaleMin;
		this.knife.y = fruit.y;
	},
	

	fruitPop(fruit) {

		playAudio(this.fruitClip);

		removeFromArr(this.fruitArr, fruit);
		fruit.isPop = true;

		const rTween = fruit.tween;
		if (rTween) {
			rTween.stop();
		}
		fruit.speedR = 0;

		const tmpAngle = fruit.angle % 360;

		fruit.icon.active = false;
		const iconLeft = fruit.iconLeft;
		const iconRight = fruit.iconRight;
		const iconPop = fruit.iconPop;

		iconLeft.active = true;
		iconRight.active = true;
		iconPop.active = true;


		fruit.angle = 0;
		iconLeft.angle = 43;
		iconRight.angle = 43;

		const knifeLight = getSprNode('bg_knifelight');
		knifeLight.angle = 30;
		knifeLight.x = 20
		knifeLight.y = 25
		iconPop.addChild(knifeLight);

		knifeLight.scale = 0;
		cc.tween(knifeLight)
			.to(0.3, {scale: 1}, {easing: "cubicOut"})
			.delay(0.2)
			.to(0.3, {opacity: 0})
			.start();


		var actionTo = cc.jumpTo(1.5, cc.v2(-300 + Math.random() * 100, -300), 270 + Math.random() * 100, 1);
		iconLeft.runAction(actionTo);

		var actionTo = cc.jumpTo(1.5, cc.v2(300 + Math.random() * 100, -300), 270 + Math.random() * 100, 1);
		iconRight.runAction(actionTo);


		if (fruit.id == 2) {
				iconRight.anchorX = 0.75;
		}
		if (fruit.id == 5) {
			iconLeft.anchorY = 0.25;
			iconRight.anchorY = 0.25;
		}


		const leftAngleSpeed = tmpAngle * 0.5;
		const rightAngleSpeed = -tmpAngle * 0.5; 
		cc.tween(iconLeft)
			.by(1, {angle: leftAngleSpeed})
			.repeatForever()
			.start();

		cc.tween(iconRight)
			.by(1, {angle: rightAngleSpeed})
			.repeatForever()
			.start();

		iconPop.opacity = 0;
		cc.tween(iconPop)
			.to(0.7, {opacity: 255}, {easing: "expoOut"})
			.delay(0.2)
			.to(0.5, {opacity: 0}, {easing: "cubicIn"})
			.start();



		cc.tween(iconRight)
			.to(1.5, {opacity: 0}, {easing: "cubicIn"})
			.start();

		cc.tween(iconLeft)
			.to(1.5, {opacity: 0}, {easing: "cubicIn"})
			.call(() => {
				fruit.removeFromParent();
			})
			.start();

	},

	showScore(fruit) {
		playAudio(this.scoreClip);
		const score = getSprNode('text_10');
		score.opacity = 0;
		this.canvas.addChild(score);

		score.x = fruit.x;
		score.y = fruit.y;

		cc.tween(score)
			.by(0.5, {opacity: 255, y: 120 * this._mapScaleMin}, {easing: "cubicOut"})
			.delay(0.5)
			.to(0.3, {opacity: 0}, {easing: "sineIn"})
			.call(() => {
				score.removeFromParent();
			})
			.start();
	},






	knife: null,
	initKnife() {
		const knife = getSprNode("icon_knife");
		knife.x = 300 * this._mapScaleMin;
		knife.y = - 200 * this._mapScaleMin;
		knife.zIndex = 40;
		knife.anchorY = 0.75;
		knife.anchorX = 0.15;
		this.canvas.addChild(knife);

		knife.opacity = 0;
		cc.tween(knife)
			.to(0.3, {opacity: 255})
			.start();

		this.knife = knife;
	},


	ti: null,
	initTi() {
		const ti = getSprNode("bg_ti");
		ti.scale = this._mapScaleMin;
		ti.anchorX = 0;
		ti.anchorY = 0;
		ti.x = -this.canvas.width / 2 + 10 * this._mapScaleMin;
		ti.y = -this.canvas.height / 2 + 30 * this._mapScaleMin;
		this.canvas.addChild(ti, 51);

		this.ti = ti;

		if (!this.isTeacher) {
			this.ti.active = false;
		}
	},

	initTeacherBtn() {
		const btnNode = new cc.Node();
		btnNode.scale = this._mapScaleMin;
		btnNode.parent = this.canvas;
		btnNode.zIndex = 60;

		btnNode.x = this.canvas.width / 2 - 520 * this._mapScaleMin;
		btnNode.y = -this.canvas.height / 2 + 70 * this._mapScaleMin;


		const disW = 10;
		const btnLv1 = getSprNode("btn_easy1");
		btnLv1.x = btnLv1.width / 2;
		btnNode.addChild(btnLv1);
		btnLv1.level = 1;
		const btnLv1Light = getSprNode("btn_easy2");
		btnLv1Light.x = btnLv1.x;
		btnNode.addChild(btnLv1Light);
		btnLv1Light.opacity = 0;
		this.addBtnListener(btnLv1, btnLv1Light);

		const btnLv2 = getSprNode("btn_medium1");
		btnLv2.x = btnLv1.x + btnLv1.width / 2 + disW + btnLv2.width / 2;
		btnNode.addChild(btnLv2);
		btnLv2.level = 2;
		const btnLv2Light = getSprNode("btn_medium2");
		btnLv2Light.x = btnLv2.x;
		btnNode.addChild(btnLv2Light);
		btnLv2Light.opacity = 0;
		this.addBtnListener(btnLv2, btnLv2Light);


		const btnLv3 = getSprNode("btn_hard1");
		btnLv3.x = btnLv2.x + btnLv2.width / 2 + disW + btnLv3.width / 2;
		btnNode.addChild(btnLv3);
		btnLv3.level = 3;
		const btnLv3Light = getSprNode("btn_hard2");
		btnLv3Light.x = btnLv3.x;
		btnNode.addChild(btnLv3Light);
		btnLv3Light.opacity = 0;
		this.addBtnListener(btnLv3, btnLv3Light);

		this.btnArr = [btnLv1, btnLv2, btnLv3];

		if (!this.isTeacher) {
			btnLv1.active = false;
			btnLv2.active = false;
			btnLv3.active = false;
			btnLv1Light.active = false;
			btnLv2Light.active = false;
			btnLv3Light.active = false;
		}

	},


	addBtnListener(btn, btnLight) {
	
		btn.light = btnLight;

		if (!this.isTeacher) {
			return;
		}

		btn.addComponent(cc.Button);
		btn.on('click', () => {
			this.clickLevelBtn(btn.level);
		})
	},


	clickLevelBtn(level, isServer=false) {
		if (!isServer && this.isTeacher) {
			this.sendServerEvent("click_level", {level});
			// return;
		}
		this.setLevel(level);
		this.hideTi();
	},

	setLevel(level) {
		for (let i=0; i<this.btnArr.length; i++) {
			if (this.btnArr[i].level == level) {

				this.changeBtn(this.btnArr[i]);
				this.modelLevel = this.btnArr[i].level;
				this.setBaseSpeed();
				return;
			}
		}
	},


	changeBtn(btn) {

		if (btn.opacity != 0) {

			this.hideAllBtn();

			btn.opacity = 0;
			btn.light.opacity = 255;
		} 

		
	},

	hideTi() {
		if (this.ti) {
			const ti = this.ti;
			cc.tween(ti)
				.to(0.3, {opacity: 0}, {easing: "cubicIn"})
				.call(() => {
					ti.removeFromParent()
				})
				.start();

			this.ti = null;
		}
	},

	hideAllBtn() {
		for (let i=0; i<this.btnArr.length; i++) {
			this.btnArr[i].opacity = 255;
			this.btnArr[i].light.opacity = 0;
		}
	},

	baseSpeed: null,
	setBaseSpeed(level=null) {
		if (!level) {
			level = this.modelLevel;
		}
		this.baseSpeed = 1 + level * 1;
	},

	setFruitSpeed(fruit) {
		fruit.speedY = this.baseSpeed;
	},

	updateFruit() {


		const fruitArr = this.fruitArr;
		if (!fruitArr) {
			return;
		}
		for (let i=0; i<fruitArr.length; i++) {
			fruitArr[i].y -= fruitArr[i].speedY;
			fruitArr[i].angle += fruitArr[i].speedR;
		}

		for (let i=0; i<fruitArr.length; i++) {
			const fruit = fruitArr[i]
			if (fruit) {
				if (fruit.y <= -this.canvas.height) {
					this.fruitArr.splice(i, 1);
					fruit.removeFromParent();
					i --;
					console.log('remove one fruit');
				}
			}

		}
	},


	checkRoleStop() {
		if (this.role.x >= this.curStopX) {

			this.roleIdle();

			if (this.isShowEndLayer) {

				this.showEndMask();
			} else {
				this.showFruit();
			}

		}
	},



	updateRole() {
		if (!this.role) {
			return;
		}
		if (this.role.isMoving) {

			this.role.x += this.role.speedX;

			if (this.role.x > this.roleBaseX && this.bgGround.x > this.groundMinX ) {
				this.bgGround.x -= this.role.speedX * this.bgGround.scaleX;
				this.bgBack.x -= this.role.speedX * this.bgGround.scaleX * this.bgBack.speedRate;
			}
			
			this.checkRoleStop();
		}
	},

	update() {

		this.updateRole();

		// if (this.isStopUpdate) {
		// 	return;
		// }
		// this.updateFruit();
	},






	initListener() {

		const canvas = cc.find('Canvas');
		
		let downFlag = false;



		const touchStart = (e) => {
			this.canvasTouchStart(e);
			console.log('touch start');

			if (canvas.hasEventListener(cc.Node.EventType.MOUSE_DOWN)) {
				canvas.off(cc.Node.EventType.MOUSE_DOWN, mouseDown)
			}
		}


		const mouseDown = (e) => {
			if (!downFlag) {
				return;
			}
			this.canvasTouchStart(e);
			console.log('mouse down');

			if (canvas.hasEventListener(cc.Node.EventType.TOUCH_MOVE)) {
				canvas.off(cc.Node.EventType.TOUCH_MOVE, touchMove)
				this.removeHtmlCanvasListener('touchmove');
			}
		}


		const touchMove = (e) => {
			this.canvasTouchMove(e);
			console.log('touch move');

			if (canvas.hasEventListener(cc.Node.EventType.MOUSE_MOVE)) {
				canvas.off(cc.Node.EventType.MOUSE_MOVE, mouseMove)
			}
		}

		const mouseMove = (e) => {
			if (!downFlag) {
				return;
			}
			this.canvasTouchMove(e);
			console.log('mouse move');

			if (canvas.hasEventListener(cc.Node.EventType.TOUCH_MOVE)) {
				canvas.off(cc.Node.EventType.TOUCH_MOVE, touchMove)
				this.removeHtmlCanvasListener('touchmove');
			}
		}

		const touchEnd = (e) => {
		
			downFlag = false;
			this.canvasTouchEnd(e);

			if (canvas.hasEventListener(cc.Node.EventType.MOUSE_UP)) {
				canvas.off(cc.Node.EventType.MOUSE_UP, mouseUp)
			}
			if (canvas.hasEventListener(cc.Node.EventType.MOUSE_LEAVE)) {
				canvas.off(cc.Node.EventType.MOUSE_LEAVE, mouseUp)
			}
			this.removeHtmlTouchEnd();
		}

		const mouseUp = (e) => {
	
			downFlag = false;

			this.canvasTouchEnd(e);

			if (canvas.hasEventListener(cc.Node.EventType.TOUCH_END)) {
				canvas.off(cc.Node.EventType.TOUCH_END, touchEnd)
			}
			if (canvas.hasEventListener(cc.Node.EventType.TOUCH_CANCEL)) {
				canvas.off(cc.Node.EventType.TOUCH_CANCEL, touchEnd)
			}
		}
		


		canvas.on(cc.Node.EventType.TOUCH_START, touchStart)
		canvas.on(cc.Node.EventType.MOUSE_DOWN, mouseDown)

		canvas.on(cc.Node.EventType.TOUCH_MOVE, touchMove)
		canvas.on(cc.Node.EventType.MOUSE_MOVE, mouseMove)

		canvas.on(cc.Node.EventType.TOUCH_END, touchEnd)
		canvas.on(cc.Node.EventType.TOUCH_CANCEL, touchEnd)
		canvas.on(cc.Node.EventType.MOUSE_UP, mouseUp)

	},

	canvasTouchStart(e) {


		const pos = e.getLocation();
		this.knife.x = pos.x - e.currentTarget.width / 2;
		this.knife.y = pos.y - e.currentTarget.height / 2;

	},

	canvasTouchMove(e) {

		const pos = e.getLocation();
		this.knife.x = pos.x - e.currentTarget.width / 2;
		this.knife.y = pos.y - e.currentTarget.height / 2;

	},

	canvasTouchEnd(e) {

		if (!this._curShowItem) {
			return;
		}

		this._curShowItem = null;
	},



	removeHtmlCanvasListener(type) {
		// const canvasHtml = document.querySelector('canvas');
		// canvasHtml.addEventListener(type, (e) => {})
	},
	

	removeHtmlTouchEnd() {
		// const canvasHtml = document.querySelector('canvas');
		// canvasHtml.removeEventListener('touchend', this.htmlCanvasTouchendFunc, this);
	},


	isGameEnd: null,
	gameEnd(isServer=false) {

		if (!isServer && this.isTeacher) {
			this.sendServerEvent('game_end', {});
			// return;
		}

		this.isGameEnd = true
		this.isStopUpdate = true;

		playAudio(this.endClip);

		const goodJob = getSprNode('text_good-job')
		// goodJob.scale = this._mapScaleMin;
		this.canvas.addChild(goodJob, 70);

		goodJob.scale = 0;
		cc.tween(goodJob)
			.to(0.7, {scale: this._mapScaleMin}, {easing: "elasticOut"})
			.start();

	},



















	showSound() {

		this.showPanel1();

		playAudio(this.tip1Clip, () => {
			this.tip1ShowEnd();
		});
	},

	tip1ShowEnd() {

		this.showMagic();
		playAudio(this.tip2Clip, () => {
			this.tip2ShowEnd();
		});

	},

	tip2ShowEnd() {
		this.showBtn();

		this.showPanel2();
		
	},

	panel1: null,
	showPanel1() {
		if (!this.isTeacher) {
			return;
		}

		const panel1 = getSprNode("bg_ti1")
		panel1.scale = this._mapScaleMin;
		panel1.parent = cc.find("Canvas")
		panel1.zIndex = 20;
		panel1.anchorY = 0;
		panel1.y = - this.canvas.height / 2;
		// panel1.opacity = 0;
		this.panel1 = panel1;

		panel1.baseY = panel1.y;
		panel1.y -= panel1.height / 2 * panel1.scaleY;
		
		cc.tween(panel1)
			.to(1, {y: panel1.baseY}, {easing: "cubicOut"})
			.start();

		// cc.tween(panel1)
		// 	.to(0.3, {opacity: 255})
		// 	.start();
	},

	panel2: null,
	showPanel2() {
		if (!this.isTeacher) {
			return;
		}
		const panel2 = getSprNode("bg_ti2")
		panel2.scale = this._mapScaleMin;
		panel2.parent = cc.find("Canvas")
		panel2.zIndex = 30;
		panel2.anchorY = 0;
		panel2.y = - this.canvas.height / 2;
		panel2.opacity = 0;
		this.panel2 = panel2;

		cc.tween(this.panel1)
			.delay(0.3)
			.to(0.3, {opacity: 0})
			.start();

		cc.tween(panel2)
			.to(0.3, {opacity: 255})
			.start();
	},

	showMagic() {
		console.log("in showMagic");

		const resDragonBone = cc.find("Canvas/res/anima/magic")
		const magic = cc.instantiate(resDragonBone)	



		const dragonDisplay = magic.getComponent(dragonBones.ArmatureDisplay);
		dragonDisplay.on(dragonBones.EventObject.COMPLETE, () => {
			dragonDisplay.playAnimation('spinturn', -1);
		})
		dragonDisplay.playAnimation('appear', 1);


		magic.parent = cc.find("Canvas/bg_door");


		// const magic = getSprNode("bg_magic");
		// magic.scale = 0;
		// magic.parent = cc.find("Canvas/bg_door");
		// magic.zIndex = 10;

		// cc.tween(magic)
		// 	.to(2.5, {scale: this._mapScaleMin}, {easing: "cubicOut"})
		// 	.start();

		// cc.tween(magic)
		// 	.by(1, {angle: 120})
		// 	.repeatForever()
		// 	.start();

		playAudio(this.magicAppearClip);
	},


	btn: null,
	_showBtn() {
		console.log("in showBtn");
		const btn = getSprNode("btn_go")
		btn.parent = this.canvas
		btn.zIndex = 50;
		btn.scale = this._mapScaleMin;
		btn.x = 230 * this._mapScaleMin
		btn.y = -this.canvas.height / 2 + 230 * this._mapScaleMin;

		btn.addComponent(cc.Button)
		btn.on("click", () => {

			this.sendServerEvent('btn_click')
		
		})
		
		// btn.y = - this.canvas.height / 2;
		btn.opacity = 0;
		this.btn = btn;

		cc.tween(btn)
			.to(0.5, {opacity: 255})
			.start();

		this.showHand();
	},

	btnClick() {

		if (this.btn.opacity == 0) {
			return;
		}
		this.btn.opacity = 0
		playAudio(this.btnClip);
		playAudio(this.tip3Clip);

	},


	initSmog() {

		this.addSmog(-this.canvas.width / 1.5, false);
		this.addSmog(-this.canvas.width / 2, false);
		this.addSmog(-this.canvas.width / 2 + this.canvas.width / 3, false);
		this.addSmog(-this.canvas.width / 2 + this.canvas.width / 3 * 2);

		// const parent = cc.find("Canvas");
		// let smog;

		// smog = getSprNode("bg_smog")
		// parent.addChild(smog);

		// smog.scale = this._mapScaleMin * (0.5 + Math.random() * 0.7);
		// smog.x = px;
		// smog.y = -240 + Math.random() * 80;

		// if (Math.random() > 0.5) {
		// 	smog.scaleX *= -1;	
		// }
	
		// let time = 20;
	
		// cc.tween(smog)
		// 	.to(time, {x: this.canvas.width})
		// 	.call(() => {
		// 		this.smogArr.push(smog);
		// 	})
		// 	.start()

	},

	addSmog(px, isCreateNext = true) {

		const parent = cc.find("Canvas/bg_door");
		let smog;

		if (this.smogArr.length > 0) {
			smog = this.smogArr.pop();
		} else {
			smog = getSprNode("bg_smog")
			parent.addChild(smog);

		}



		smog.scale = this._mapScaleMin * (0.5 + Math.random() * 0.7);
		smog.x = px;
		smog.y = -140 + Math.random() * 80;
		smog.zIndex = 10;
		if (Math.random() > 0.5) {
			smog.scaleX *= -1;	
		}

		let time = 30 + Math.random() * 10;
	
		cc.tween(smog)
			.to(time, {x: this.canvas.width})
			.call(() => {
				this.smogArr.push(smog);
			})
			.start()


		if (isCreateNext) {
			delayCall(time / 10 + time / 10 * Math.random(), () => {
				this.addSmog(-this.canvas.width);
			})
		}


	},

	nextBtn: null,
	initNextBtn() {
		const nextBtn = getSprNode("btn_next");
		this.bgGround.addChild(nextBtn, 20)
		nextBtn.x = - this.bgGround.x - this.canvas.width / 2 +  this.canvas.width / this.bgGround.scaleX - 100;
		nextBtn.y = 150;
		nextBtn.scale = this._mapScaleMin;
		this.nextBtn = nextBtn;

		nextBtn.active = false;

		nextBtn.addComponent(cc.Button)
		nextBtn.on("click", () => {
			if (nextBtn.isClicked) {
				return;
			}
			nextBtn.isClicked = true;

			this.enterNextTree();

			playAudio(this.clickClip)
		})

		this.initHand(nextBtn);
		// nextBtn.y = -100;
	},


	initHand(btn) {
		console.log("in showHand");

		const hand1 = getSprNode("icon_hand1")
		hand1.parent = btn;
		hand1.x = 70;
		hand1.y = -80;

		const hand2 = getSprNode("icon_hand2")
		hand2.parent = btn;
		hand2.x = hand1.x;
		hand2.y = hand1.y;
		hand2.opacity = 0;
		
		btn.hand1 = hand1;
		btn.hand2 = hand2;

		// this.showHandAnima();


	},

	showNextBtn() {
		const btn = this.nextBtn;
		// if (!btn.active) {

		btn.active = true;

		btn.opacity = 0;
		cc.tween(btn)
			.to(0.5, {opacity: 255}, {easing: "cubicOut"})
			.start();

		btn.x = - this.bgGround.x - this.canvas.width / 2 +  this.canvas.width / this.bgGround.scaleX - 100;
		btn.isClicked = false;
		// }

		this.showHandAnima(btn)
	},

	showHandAnima(btn) {

		const hand1 = btn.hand1;
		const hand2 = btn.hand2;

		if (hand1.opacity == 0) {
			const delayTime = 0.2;

			cc.tween(btn)
				.delay(delayTime)
				.call(() => {
					hand1.opacity = 255;
					hand2.opacity = 0;
					this.showHandAnima(btn);
				})
				.start();
				
		} else {
			const delayTime = 0.5;
			cc.tween(btn)
			.delay(delayTime)
			.call(() => {
				hand1.opacity = 0;
				hand2.opacity = 255;
				this.showHandAnima(btn);
			})
			.start();
		}
	},

	hideNextBtn() {
		cc.tween(this.nextBtn)
			.to(0.3, {opacity: 0}, {easing: "cubicIn"})
			.call(() => {
				this.nextBtn.active = false;
			})
			.start();
	},

	initTree() {

		this.initAppleTree();
		this.initBananaTree()
		this.initOrangeTree()
	},

	apple: null,
	realApple: null,
	initAppleTree() {

		const parent = cc.find("Canvas/bg_ground");
		const tmpX = 0;
		const tmpY = 0;
		const rate = 1.15;
		const treeDataArr = [
			[tmpX + 108 * rate, tmpY + 238, 0.9],
			[tmpX + 332 * rate, tmpY + 238, 0.7],
			[tmpX + 556 * rate, tmpY + 197, 1],
			[tmpX + 783 * rate, tmpY + 227, 0.6],
			[tmpX + 968 * rate, tmpY + 217, 0.77],
		]




		for (let i=0; i<treeDataArr.length; i++) {
			const treeData = treeDataArr[i];

			const appleTree = getSprNode("bg_appletree");
			appleTree.x = treeData[0];
			appleTree.y = treeData[1];
			appleTree.scale = treeData[2];
			appleTree.anchorY = 0;

			parent.addChild(appleTree, 999 - appleTree.y);
			this.addTreeAnima(appleTree);

			if (appleTree.scale == 1) {

				const apple = getSprNode("icon_apple")
				apple.x = appleTree.x;
				apple.y = appleTree.y + appleTree.height / 2;
				apple.parent = appleTree.parent;
				apple.zIndex = appleTree.zIndex;
				apple.opacity = 0;
				apple.scale = 50 / apple.width;
				this.apple = apple;

				apple.clip = this.appleClip;

				const realApple = getSprNode("icon_realapple")
				this.realApple = realApple;
			}
		}
	},

	banana: null,
	realBanana: null,
	initBananaTree() {

		const parent = cc.find("Canvas/bg_ground");
		const tmpX = this.bgGround.width / 3 + 90;
		const tmpY = 40;
		const rate = 1.3;

		const treeDataArr = [
			[tmpX + 54 * rate, tmpY + 202, 0.78],
			[tmpX + 240 * rate, tmpY + 150, 0.86],
			[tmpX + 447 * rate, tmpY + 145, 1],
			[tmpX + 569 * rate, tmpY + 198, 0.7],
			[tmpX + 672 * rate, tmpY + 200, 0.58],
			[tmpX + 803 * rate, tmpY + 170, 0.8],
		]



		for (let i=0; i<treeDataArr.length; i++) {
			const treeData = treeDataArr[i];

			const bananaTree = getSprNode("bg_bananatree");
			bananaTree.x = treeData[0];
			bananaTree.y = treeData[1];
			bananaTree.scale = treeData[2];
			bananaTree.anchorY = 0;

			parent.addChild(bananaTree, 999 - bananaTree.y);
			this.addTreeAnima(bananaTree);

			if (bananaTree.scale == 1) {

				const fruit = getSprNode("icon_banana")
				fruit.x = bananaTree.x;
				fruit.y = bananaTree.y + bananaTree.height / 2;
				fruit.parent = bananaTree.parent;
				fruit.zIndex = bananaTree.zIndex;
				fruit.opacity = 0;
				fruit.scale = 50 / fruit.width;
				this.banana = fruit;

				fruit.clip = this.bananaClip;

				const realBanana = getSprNode("icon_realbanana")
				this.realBanana = realBanana;
			}
		}
	},

	orange: null,
	realOrange: null,
	initOrangeTree() {

		const parent = cc.find("Canvas/bg_ground");
		const tmpX = this.bgGround.width / 3 * 2;
		const tmpY = 0;
		const rate = 1.05;
		const treeDataArr = [
			[tmpX + 147 * rate, tmpY + 228, 0.77],
			[tmpX + 349 * rate, tmpY + 199, 0.72],
			[tmpX + 602 * rate, tmpY + 178, 1],
			[tmpX + 848 * rate, tmpY + 240, 0.54],
			[tmpX + 1047 * rate, tmpY + 201, 0.8],
		]


		for (let i=0; i<treeDataArr.length; i++) {
			const treeData = treeDataArr[i];

			const orangeTree = getSprNode("bg_orangetree");
			orangeTree.x = treeData[0];
			orangeTree.y = treeData[1];
			orangeTree.scale = treeData[2];
			orangeTree.anchorY = 0;

			parent.addChild(orangeTree, 999 - orangeTree.y);
			this.addTreeAnima(orangeTree);

			if (orangeTree.scale == 1) {

				const fruit = getSprNode("icon_orange")
				fruit.x = orangeTree.x;
				fruit.y = orangeTree.y + orangeTree.height / 2;
				fruit.parent = orangeTree.parent;
				fruit.zIndex = orangeTree.zIndex;
				fruit.opacity = 0;
				fruit.scale = 50 / fruit.width;
				this.orange = fruit;

				fruit.clip = this.orangeClip;

				const realOrange = getSprNode("icon_realorange")
				this.realOrange = realOrange;
			}
		}
	},




	addTreeAnima(tree) {

		const wind = 1  + Math.random() * 1

		const shakeLine = 8 * wind;
		const time = 4 * wind;

		cc.tween(tree)
			.to(time / 3 / 2, {skewX: 0.3 * shakeLine}, {easing: "sineInOut"})
			.to(time / 3 / 1.2, {skewX: -0.1 * shakeLine}, {easing: "sineInOut"})
			.to(time / 3, {skewX: 0.05 * shakeLine}, {easing: "sineInOut"})
			.to(time / 3, {skewX: 0 * shakeLine}, {easing: "sineInOut"})

			.start()

		delayCall(time + Math.random() * 1.5, () => {
			this.addTreeAnima(tree);
		})

	},


	




	initHotZone() {
		this.initHotZoneBg();
	},


	hotZoneBg: null,
	initHotZoneBg() {
		this.hotZoneBg = new cc.Node();
		this.hotZoneBg.name = 'hotZoneBg';
		this.hotZoneBg.parent = cc.find('Canvas');
		// this.hotZoneBg.zIndex = 4;

		const titleH = 107 * this._mapScaleMin + 11 * 2

		if (!this.data.bgItem) {
			return;
		}

		cc.loader.load({url: this.data.bgItem.url}, (err, img) => {

			// this.addMask(this.hotZoneBg);

			this.hotZoneBg.width = img.width;
			this.hotZoneBg.height = img.height;

			// const tmpS = 640 / 720;
			// let subNum = 720 - 640;
			// const frameSize = cc.view.getFrameSize();
			// const winSize = cc.winSize;

			// console.log('this.hotZoneBg.box: ', this.hotZoneBg.getBoundingBox());
			// console.log('let visiSize=cc.director.getVisibleSize();: ', cc.view.getVisibleSize());
			// console.log('lframeSize: ', frameSize);

			// let sx = frameSize.width / this._designSize.width;
			// let sy = frameSize.height / this._designSize.height;
			// const mapS = Math.min(sx, sy);
			// // const sy = canvas.height * tmpS / box.height;



			//  sx = frameSize.width * this._cocosScale / img.width;
			//  sy = (frameSize.height * this._cocosScale - subNum * mapS * this._cocosScale) / img.height;


			const sprNode = new cc.Node();
			sprNode.name = 'bgItemSpr'
			var sf = new cc.SpriteFrame(img);
			// const spr = this.hotZoneBg.addComponent(cc.Sprite);
			const spr = sprNode.addComponent(cc.Sprite);
			spr.spriteFrame = sf
			sprNode.width = this.hotZoneBg.width;
			sprNode.height = this.hotZoneBg.height;
			sprNode.parent = this.hotZoneBg;
			window['bg'] =sprNode 


			const sx = this.canvas.width / this.hotZoneBg.width;
			const sy = (this.canvas.height - titleH) / this.hotZoneBg.height;
			const s = Math.min(sx, sy);
			this.hotZoneBg.scale = s;
			
			// this.hotZoneBg.y = -frameSize.height / 2 * this._cocosScale + this.hotZoneBg.height / 2 * this.hotZoneBg.scaleY + (subNum * mapS * this._cocosScale);
			this.hotZoneBg.y = 0 - titleH / 2 ;
			// console.log('this.hotZoneBg.y', this.hotZoneBg.y);




			// this.data.bgItem.isShowDebugLine = true;
			this.initHotZoneItem();


	
		});

	},

	initHotZoneItem() {
		this.data.hotZoneItemArr.forEach((item) => {
			// console.log('item.gIdx: ', item.gIdx);
			switch (item.gIdx) {
				case "0":
					this.setOneAnimaSmall(item);
					break;
				case "1":
					this.setOnePic(item);
					break;
				case "2":
					this.setOneRect(item);
					break;
				case "3":
				case "4":
				case "5":
					this.setOneAction(item);
					break;
					
			
				default:
					break;
			}

		});

	},


	addMask(node) {
		const mask = node.addComponent(cc.Mask);
		mask.type = cc.Mask.Type.RECT;
	},

	setOneAction(data) {



		const rate =  (this.hotZoneBg.scale * this.hotZoneBg.width) / this.data.bgItem.rect.width;
		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		this.hotZoneBg.addChild(rectNode);

		const ctx = rectNode.addComponent(cc.Graphics);
		// 红色矩形
		ctx.lineWidth = 4;
		ctx.strokeColor = cc.Color.BLACK;
		ctx.fillColor = cc.Color.WHITE.setA(100);

		const scale = rate / this.hotZoneBg.scaleY ;

		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
		rectNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;
		const {x, y, width, height} = rectNode;
		rectNode.anchorX = rectNode.anchorY = 0;

		if (this.data.bgItem.isShowDebugLine) {
			ctx.rect(0, 0, rectNode.width, rectNode.height);
		}
		ctx.stroke();
		ctx.fill();



		console.log('setOneAction ~~ data: ', data)
		const actionData = data['actionData_' + data.gIdx];
		if (!actionData) {
			return;
		}
		if (actionData.type == 'text') {
			const label = this.setOneActionText(rectNode, actionData);
			label.node.scale = scale * data.fontScale;

			// label.overflow = cc.Label.Overflow.NONE;
			// label.node.setContentSize(new cc.Size(0, lineHeight));
			label["_forceUpdateRenderData"](true);
		
			
		} else if (actionData.type == 'pic') {

			const pic = this.setOneActionPic(rectNode, actionData);

		} else if (actionData.type == 'anima') {

			const anima = this.setOneActionAnima(rectNode, actionData);
		}
	},

	setOneActionText(rectNode, actionData) {


		const labelNode = new cc.Node();
		labelNode.parent = rectNode;
		const label = labelNode.addComponent(cc.Label);

		label.font = cc.find('Canvas/res/font/aharoni').getComponent(cc.Label).font;
		label.string = actionData.text;
		// label.string = `<size=${size}><color=#751e00>${this.curGroup.title }</color></size>`
		// label.lineHeight = size;
		// label.horizontalAlign = cc.macro.TextAlignment.LEFT
		// labelNode.anchorX = 0;
		// labelNode.anchorY = 1
		labelNode.color = cc.Color.BLACK;


		const opArr = actionData.changeOption
		// console.log('opArr', opArr);


		const tweenArr = [];

		for (let i = 0; i < opArr.length; i++ ) {

			const opData = opArr[i];
			console.log('opArr[0]', opArr[i])
			if (opData[0] == 'fontColor') {
				const color = new cc.Color();
				cc.Color.fromHEX(color, opData[1] );
				labelNode.color = color;

			} else if (opData[0] == 'opacity') {
				// console.log('opData: ', opData)
				labelNode.opacity = Number( opData[1] / 100 * 255 ) + 0.1;
				// console.log(labelNode.opacity);
				tweenArr.push({item: labelNode , option: `{"${opData[0]}" : ${opData[2] / 100 * 255}}`, optionName: opData[0]},)

			} else {
				label[opData[0]] = opData[1];
				tweenArr.push({item: label, option: `{"${opData[0]}" : ${opData[2]}}`, optionName: opData[0]})

			}
		}


		if (actionData.audio_url) {
			cc.assetManager.loadRemote(actionData.audio_url, (err, audioClip) => {
				labelNode.audioClip = audioClip;
			});
		}


		label.lineHeight = label.fontSize;

		labelNode.y += rectNode.height / 2;
		labelNode.x += rectNode.width / 2;
		

		rectNode.addComponent(cc.Button);
		rectNode.on('click', () => {

			if (labelNode.audioClip) {
				cc.audioEngine.stopAllEffects();
				cc.audioEngine.playEffect(labelNode.audioClip, false, 0.8);
			}

			if (labelNode.isClicked) {
				// return;
			}
			labelNode.isClicked = true;

			// const j = JSON.stringify({'fontSize': 500});
			// console.log('j: ', JSON.parse('{"fontSize":500}'));

			for (let i=0; i<tweenArr.length; i++) {
				const tweenData = tweenArr[i];

				// JSON.parse(tweenData.option)

				// console.log( JSON.parse(tweenData.option) );

				if (tweenData.optionName == 'opacity') {
					console.log('~~~ ',  tweenData.item[tweenData.optionName] );
					// tweenData.item[tweenData.optionName] = tweenData.item[tweenData.optionName] + 1

					cc.tween(tweenData.item)
						.to(actionData.changeTime,  JSON.parse(tweenData.option) )
						.start();
				}
				

			}

			// cc.tween({})
			// 	.to(5, { scale: (Math.random() - 0.5) + 1})
			// 	.start();

		});

		// labelNode.opacity = 255;

		return label;
	},

	setOneActionPic(rectNode, actionData) {

		console.log('setOneActionPic actionData: ', actionData)
		const picNode = new cc.Node();
		rectNode.addChild(picNode);

		cc.loader.load({url: actionData.pic_url}, (err, img) => {

			const spr = picNode.addComponent(cc.Sprite);
			spr.spriteFrame = new cc.SpriteFrame(img)

			picNode.y += rectNode.height / 2;
			picNode.x += rectNode.width / 2;

			picNode.scaleX = rectNode.width / picNode.width;
			picNode.scaleY = rectNode.height / picNode.height;

			const opArr = actionData.changeOption	
			const tweenArr = [];
	
			for (let i = 0; i < opArr.length; i++ ) {
	
				const opData = opArr[i];
				console.log('opData: ~~~ ', opData);

				if (opData[0] == 'opacity') {
					picNode.opacity = Number( opData[1] / 100 * 255 ) + 0.1;
					console.log(picNode.opacity);
					tweenArr.push({item: picNode , option: `{"${opData[0]}" : ${opData[2] / 100 * 255}}`, optionName: opData[0]},)
	
				}  else {
					// picNode[opData[0]] = Number(opData[1]);
					// tweenArr.push({item: picNode, option: `{"${opData[0]}" : ${opData[2]}}`, optionName: opData[0]})
				}

	
				if (actionData.audio_url) {
					cc.assetManager.loadRemote(actionData.audio_url, (err, audioClip) => {
						rectNode.audioClip = audioClip;
					});
				}
				

				rectNode.addComponent(cc.Button);
				rectNode.on('click', () => {

					if (rectNode.audioClip) {
						cc.audioEngine.stopAllEffects();
						cc.audioEngine.playEffect(rectNode.audioClip, false, 0.8);
					}
		
					if (rectNode.isClicked) {
						// return;
					}
					rectNode.isClicked = true;

					for (let i=0; i<tweenArr.length; i++) {
						const tweenData = tweenArr[i];
		
						if (tweenData.optionName == 'opacity') {
							cc.tween(tweenData.item)
								.to(actionData.changeTime,  JSON.parse(tweenData.option) )
								.start();
						}
					}
		
				});
			}

		});
	},

	setOneActionAnima(rectNode, actionData) {


		const animaNode = new cc.Node();
		rectNode.addChild(animaNode);

		if (actionData.audio_url) {
			cc.assetManager.loadRemote(actionData.audio_url, (err, audioClip) => {
				rectNode.audioClip = audioClip;
			});
		}

		const data = actionData;

		const dragonDisplay = animaNode.addComponent(dragonBones.ArmatureDisplay);
		if (!data.texPngData) {
			return
		}



		const image = data.texPngData.url//"http://staging-teach.cdn.ireadabc.com/5a0c5af3e952acd0ac83a6e5c6f03ff1.png";
		const ske = data.skeJsonData.url//"http://staging-teach.cdn.ireadabc.com/bd825dcceea298d1146be8067ae3d17f.json";
		const atlas = data.texJsonData.url//"http://staging-teach.cdn.ireadabc.com/246f8991b729fa3e5a7f4802de828efa.json";
		cc.loader.load(image, (error, texture) => {

			cc.loader.load({url: atlas, type: 'txt'}, (error, atlasJson) => {

				cc.loader.load({url: ske, type: 'txt'}, (error, dragonBonesJson) => {

					const atlas = new dragonBones.DragonBonesAtlasAsset();
					atlas.atlasJson = atlasJson;
					atlas.texture = texture;

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

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


					let json = JSON.parse(asset.dragonBonesJson);
					let armatures = json["armature"];
					let armatureNames = [];
					for (let i = 0; i < armatures.length; i++) {
						armatureNames.push(armatures[i].name);
					}
					// console.log('armatureNames: ', armatureNames);

					let animationNames = [];

					if (armatureNames.length > 0) {
						let defaultArmatureName = armatureNames[0];
						dragonDisplay.armatureName = defaultArmatureName;
						// let animationNames = dragonDisplay.getAnimationNames(defaultArmatureName);
						let defaultArmature = armatures[0];
						let animations = defaultArmature.animation;
						for (let i = 0; i < animations.length; i++) {
							animationNames.push(animations[i].name);
						}

						// rectNode.addComponent(cc.Button);
						// rectNode.on('click', () => {
						// 	if (rectNode.isClicked) {
						// 		// return;
						// 	}
						// 	rectNode.isClicked = true;
						// 	console.log('clicked');

						// 	if (rectNode.audioClip) {
						// 		cc.audioEngine.stopAllEffects();
						// 		cc.director.emit('STOP_ALL_AUDIO')
						// 		cc.audioEngine.playEffect(rectNode.audioClip, false, 0.8);
						// 	}

						// 	if (animationNames.length > 0) {
						// 		dragonDisplay.playAnimation(animationNames[0], 1);
						// 	}
						// });
					}


					// animaNode.x = rectNode.x + rectNode.width / 2;
					// animaNode.y = rectNode.y + rectNode.height / 2;

					// const sx = rectNode.width / animaNode.width;
					// const sy = rectNode.height / animaNode.height;
					// const scale = Math.min(sx, sy);
					// animaNode.scale = scale;
					


			


					animaNode.y += rectNode.height / 2;
					animaNode.x += rectNode.width / 2;

					animaNode.scaleX = rectNode.width / animaNode.width;
					animaNode.scaleY = rectNode.height / animaNode.height;
		
					const opArr = actionData.changeOption	
					const tweenArr = [];
			
					for (let i = 0; i < opArr.length; i++ ) {
			
						const opData = opArr[i];
						console.log('opData: ~~~ ', opData);
		
						if (opData[0] == 'opacity') {
							animaNode.opacity = Number( opData[1] / 100 * 255 ) + 0.1;
							console.log(animaNode.opacity);
							tweenArr.push({item: animaNode , option: `{"${opData[0]}" : ${opData[2] / 100 * 255}}`, optionName: opData[2] == null ? '' : opData[0]},)
			
						}  else {
							// animaNode[opData[0]] = Number(opData[1]);
							// tweenArr.push({item: animaNode, option: `{"${opData[0]}" : ${opData[2]}}`, optionName: opData[2] == null ? '' : opData[0]})
						}
		
			
						if (actionData.audio_url) {
							cc.assetManager.loadRemote(actionData.audio_url, (err, audioClip) => {
								rectNode.audioClip = audioClip;
							});
						}
						
		
						rectNode.addComponent(cc.Button);
						rectNode.on('click', () => {
		
							if (rectNode.audioClip) {
								cc.audioEngine.stopAllEffects();
								cc.audioEngine.playEffect(rectNode.audioClip, false, 0.8);
							}
				
							if (rectNode.isClicked) {
								// return;
							}
							rectNode.isClicked = true;
		
							for (let j=0; j<tweenArr.length; j++) {
								const tweenData = tweenArr[j];
				
								console.log('tweenData: ', tweenData);

								if (tweenData.optionName) {

									cc.tween(tweenData.item)
										.to(actionData.changeTime,  JSON.parse(tweenData.option))
										.start();

								}

							}
						
							if (animationNames.length > 0) {
								dragonDisplay.playAnimation(animationNames[0], 1);
							}
				
						});
					}
		
					
				});
			});
		});

	},
	



	setOneAnimaSmall(data) {


		const rate = (this.hotZoneBg.scale * this.hotZoneBg.width) / this.data.bgItem.rect.width;

		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		this.hotZoneBg.addChild(rectNode);


		const ctx = rectNode.addComponent(cc.Graphics);
		// 红色矩形
		ctx.lineWidth = 4;
		ctx.strokeColor = cc.Color.BLACK;
		ctx.fillColor = cc.Color.WHITE.setA(100);

		const scale = rate / this.hotZoneBg.scaleY;

		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
		rectNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;

		rectNode.anchorX = rectNode.anchorY = 0;


		if (this.data.bgItem.isShowDebugLine) {
			ctx.rect(0, 0, rectNode.width, rectNode.height);
		}
		ctx.stroke();
		ctx.fill();




		const animaNode = new cc.Node();
		animaNode.name = 'anima_' + data.index;
		this.hotZoneBg.addChild(animaNode);



		if (data.audio_url) {
			cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
				animaNode.audioClip = audioClip;
			});
		}


		const dragonDisplay = animaNode.addComponent(dragonBones.ArmatureDisplay);
		if (!data.texPngData) {
			return
		}
		
		const image = data.texPngData.url//"http://staging-teach.cdn.ireadabc.com/5a0c5af3e952acd0ac83a6e5c6f03ff1.png";
		const ske = data.skeJsonData.url//"http://staging-teach.cdn.ireadabc.com/bd825dcceea298d1146be8067ae3d17f.json";
		const atlas = data.texJsonData.url//"http://staging-teach.cdn.ireadabc.com/246f8991b729fa3e5a7f4802de828efa.json";
		cc.loader.load(image, (error, texture) => {

			cc.loader.load({url: atlas, type: 'txt'}, (error, atlasJson) => {

				cc.loader.load({url: ske, type: 'txt'}, (error, dragonBonesJson) => {

					const atlas = new dragonBones.DragonBonesAtlasAsset();
					atlas.atlasJson = atlasJson;
					atlas.texture = texture;

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

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

					

					let json = JSON.parse(asset.dragonBonesJson);
					let armatures = json["armature"];
					// console.log('armatures: ', armatures);
					let armatureNames = [];
					for (let i = 0; i < armatures.length; i++) {
						armatureNames.push(armatures[i].name);
					}
					// console.log('armatureNames: ', armatureNames);
					if (armatureNames.length > 0) {
						let defaultArmatureName = armatureNames[0];
						dragonDisplay.armatureName = defaultArmatureName;
						// let animationNames = dragonDisplay.getAnimationNames(defaultArmatureName);
						let defaultArmature = armatures[0];
						let animations = defaultArmature.animation;
						let animationNames = [];
						for (let i = 0; i < animations.length; i++) {
							animationNames.push(animations[i].name);
						}

						rectNode.addComponent(cc.Button);
						rectNode.on('click', () => {
							if (rectNode.isClicked) {
								// return;
							}
							rectNode.isClicked = true;
							console.log('clicked');

							if (animaNode.audioClip) {
								cc.audioEngine.stopAllEffects();
								cc.director.emit('STOP_ALL_AUDIO')
								cc.audioEngine.playEffect(animaNode.audioClip, false, 0.8);
							}

							if (animationNames.length > 0) {
								dragonDisplay.playAnimation(animationNames[0], 1);
							}
						});
					}


					animaNode.x = rectNode.x + rectNode.width / 2;
					animaNode.y = rectNode.y + rectNode.height / 2;

					const sx = rectNode.width / animaNode.width;
					const sy = rectNode.height / animaNode.height;
					const scale = Math.min(sx, sy);
					animaNode.scale = scale;
					
				});
			});
		});

	},


	setOnePic(data) {
		const rate = (this.hotZoneBg.scale * this.hotZoneBg.width) / this.data.bgItem.rect.width;

		const picNode = new cc.Node();
		picNode.name= 'pic' + data.index;
		picNode.data = data;
		this.hotZoneBg.addChild(picNode);

		cc.loader.load({url: data.pic_url}, (err, img) => {

			const spr = picNode.addComponent(cc.Sprite);
			spr.spriteFrame = new cc.SpriteFrame(img)

			const scale = rate / this.hotZoneBg.scaleY;

			picNode.width = data.rect.width * scale;
			picNode.height = data.rect.height * scale;
			picNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
			picNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;

			picNode.anchorX = picNode.anchorY = 0;

			if (data.audio_url) {
				this.addPicAudio(picNode);
			}

		});

	},

	setOneRect(data) {
		const rate = (this.hotZoneBg.scale * this.hotZoneBg.width) / this.data.bgItem.rect.width;

		const rectNode = new cc.Node();
		rectNode.name = 'rect' + data.index;
		this.hotZoneBg.addChild(rectNode);


		const ctx = rectNode.addComponent(cc.Graphics);
		// 红色矩形
		ctx.lineWidth = 4;
		ctx.strokeColor = cc.Color.BLACK;
		ctx.fillColor = cc.Color.WHITE.setA(100);

		const scale = rate / this.hotZoneBg.scaleY;
		// console.log('scale: ', scale);
		// console.log('scale2: ', scale / data.mapScale);


		rectNode.width = data.rect.width * scale;
		rectNode.height = data.rect.height * scale;
		rectNode.x = -this.hotZoneBg.width / 2 + data.rect.x * scale;
		rectNode.y = this.hotZoneBg.height / 2 - data.rect.height * scale - data.rect.y * scale;
		// rectNode.scale = 1 / data.mapScale;

		rectNode.anchorX = rectNode.anchorY = 0;


		if (this.data.bgItem.isShowDebugLine) {
			ctx.rect(0, 0, rectNode.width, rectNode.height);
		}
		ctx.stroke();
		ctx.fill();

		// console.log('```data: ', data)


		if (data.audio_url) {
			cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
				rectNode.audioClip = audioClip;
			});
		}

		rectNode.addComponent(cc.Button);
		rectNode.on('click', () => {
			if (rectNode.isClicked) {
				// return;
			}
			rectNode.isClicked = true;
			console.log('clicked');

			if (rectNode.audioClip) {
				cc.audioEngine.stopAllEffects();
				cc.audioEngine.playEffect(rectNode.audioClip, false, 0.8);
			}
		});


	},

	addPicAudio(picNode) {
		const data = picNode.data;
		
		cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
			picNode.audioClip = audioClip;
		});

		picNode.addComponent(cc.Button);
		picNode.on('click', () => {
				if (picNode.audioClip) {
					cc.audioEngine.stopAllEffects();
					cc.audioEngine.playEffect(picNode.audioClip, false, 0.8);
				}
		});
	},


});
