import GameConfig from "../GameConfig"; import GameMgr, { Sound } from "../GameMgr"; import Block from "./game_page/Block"; import BlockLong from "./game_page/BlockLong"; const {ccclass, property} = cc._decorator; @ccclass export default class GamePage extends cc.Component { @property({type: cc.Prefab}) block_prefab: cc.Prefab = null; @property({type: cc.Node}) blocks_node: cc.Node = null; @property({type: dragonBones.ArmatureDisplay}) collision1s: dragonBones.ArmatureDisplay[] = []; @property({type: dragonBones.ArmatureDisplay}) collision2s: dragonBones.ArmatureDisplay[] = []; @property({type: cc.Node}) road_lights: cc.Node[] = []; @property({type: cc.Sprite}) keys: cc.Sprite[] = []; @property({type: cc.Node}) key_checks: cc.Node[] = []; @property({type: cc.SpriteFrame}) keys_on: cc.SpriteFrame[] = []; @property({type: cc.SpriteFrame}) keys_out: cc.SpriteFrame[] = []; @property({type: BlockLong}) block_long: BlockLong = null; @property({type: dragonBones.ArmatureDisplay}) font_glown: dragonBones.ArmatureDisplay = null; @property({type: cc.Label}) double_hit: cc.Label = null; @property({type: cc.Font}) double_hit_fonts: cc.Font[] = []; //连击数 hitCount: number = 0; //成功击中的节拍数 hitBeat: number = 0; //已经消失的节拍数 overBeat: number = 0; //开始时间 startTime: number; music: cc.AudioClip; music_id: number; beats_index: number = 0; beats: number[]; beats_long: number[]; static instance: GamePage; onLoad() { GamePage.instance = this; window.game_page = this; window.game_all_hit = () => { this.hitBeat = this.beats.length; }; window.game_acc_finish = () => { this.overBeat = this.beats.length; this.gameOver(); }; this.music = GameMgr.instance.song; this.beats = GameMgr.instance.beats; this.initBlockPool(5); for (let collision of this.collision1s) { collision.addEventListener(dragonBones.EventObject.COMPLETE, () => { collision.node.active = false; }); } for (let i = 0; i < this.key_checks.length; i++) { this.key_checks[i].on(cc.Node.EventType.TOUCH_START, () => { this.onRoad(i); }); this.key_checks[i].on(cc.Node.EventType.TOUCH_END, () => { this.outRoad(i); }); this.key_checks[i].on(cc.Node.EventType.TOUCH_CANCEL, () => { this.outRoad(i); }); } //初始化发光动画监听 this.font_glown.addEventListener(dragonBones.EventObject.START, () => { this.font_glown.node.opacity = 255; }); this.font_glown.addEventListener(dragonBones.EventObject.COMPLETE, () => { this.font_glown.node.opacity = 0; }); } onDestroy() { window.game_page = null; } start() { // //剔除紧密的节拍,控制节拍间最小间隔 // let beat_min_interval = GameConfig.song_star_limit_beat_min_interval[GameConfig.song_infos[GameMgr.instance.song_id].stars]; // for (let i = 1; i < this.beats.length; i++) { // if (this.beats[i] == undefined) { // break; // } // while (this.beats[i] != undefined && this.beats[i] - this.beats[i - 1] < beat_min_interval) { // this.beats.splice(i, 1); // } // } //动态设立长节拍触发点 this.beats_long = JSON.parse(JSON.stringify(this.beats)); // let var_time = 0; // let record_indexes = []; // for (let i = 1; i < this.beats_long.length; i++) { // let last_time = this.beats_long[i - 1]; // if (var_time > GameConfig.beat_long_interval) { // // this.beats_long[i - 1] = -1; // var_time = 0; // record_indexes.push(i - 1); // } // var_time += this.beats_long[i] - last_time; // } // //新增需求,长条出现1~2次就好,那就取两次 // let beat_long_indexes = []; // if (record_indexes.length >= 3) { // let record_pos1 = Math.floor(record_indexes.length * 1 / 3); // let record_pos2 = Math.floor(record_indexes.length * 2 / 3); // beat_long_indexes.push(record_indexes[record_pos1]); // beat_long_indexes.push(record_indexes[record_pos2]); // } else { // beat_long_indexes = record_indexes; // } // for (let beat_long_index of beat_long_indexes) { // this.beats_long[beat_long_index] = -1; // } this.startTime = Date.now(); let first_time = this.beats[0] - GameConfig.block_come_time; if (first_time < 0) { for (let i = 0; i < this.beats.length; i++) { let beat = this.beats[i]; if (beat - GameConfig.block_come_time < 0) { this.scheduleOnce(() => { this.addBlock(beat); this.beats_index++; }, (beat - GameConfig.block_come_time) - first_time); } else { break; } } this.scheduleOnce(() => { this.music_id = cc.audioEngine.playMusic(this.music, false); }, -first_time); } else { this.music_id = cc.audioEngine.playMusic(this.music, false); } } update() { if (this.music_id > -1) { let music_progress_time = cc.audioEngine.getCurrentTime(this.music_id); let beat_long = this.beats_long[this.beats_index]; if (beat_long < 0) {//当前节拍触发长条 if (this.beats[this.beats_index] - music_progress_time <= GameConfig.long_come_time) { let count = 0; let first_beat = this.beats[this.beats_index]; for (let i = this.beats_index; i < this.beats.length; i++) { let d_value = this.beats[i] - first_beat // 退出时间x2,能够让长条退场过程中不会出现别的方块 if (d_value <= GameConfig.long_idle_time + GameConfig.long_out_time * 2) { this.beats_index++; count++; } else { break; } } if (count > 0) { this.block_long.initCount = count; this.block_long.count = count; this.block_long.release(); } } } else { while (this.beats_index < this.beats.length && this.beats[this.beats_index] - music_progress_time <= GameConfig.block_come_time) { this.addBlock(this.beats[this.beats_index]); this.beats_index++; } } } } block_pool: cc.NodePool = new cc.NodePool(); initBlockPool(count: number) { for (let i = 0; i < count; ++i) { let block = cc.instantiate(this.block_prefab); this.block_pool.put(block); } } getBlock(): cc.Node { let block = null; if (this.block_pool.size() > 0) { block = this.block_pool.get(); } else { block = cc.instantiate(this.block_prefab); } return block; } putBlock(block: cc.Node) { this.block_pool.put(block); } addBlock(beat: number) { let node = this.getBlock(); this.blocks_node.addChild(node); node.getComponent(Block).init(beat); } /** * 拳击袋攻击次数统计,用于计算卡路里 */ checkHit_count: number = 0; /** * 拳击袋专用接口-不区分打击方向 */ checkHit() { this.checkHit_count++; let index = -1; if (this.block_long.canHit) { index = this.block_long.index; } else { let block = this.findBestBlock(); if (block) { index = block.index; } } if (index > -1) { this.key_checks[index].emit(cc.Node.EventType.TOUCH_START); this.scheduleOnce(() => { this.key_checks[index].emit(cc.Node.EventType.TOUCH_END); }, 0.05); } } /**拳袋专用接口2-区分打击方向 */ checkHit2(index: number) { this.key_checks[index].emit(cc.Node.EventType.TOUCH_START); this.scheduleOnce(() => { this.key_checks[index].emit(cc.Node.EventType.TOUCH_END); }, 0.05); } /**寻找最佳的击打方块,目前是以离检测区域中点最近的为佳 */ findBestBlock(index?: number): Block { let bestBlock = null; let deltaY = 1 << 12; let end_center_y = (GameConfig.end_line_y + GameConfig.fianl_line_y) / 2; for (let node of this.blocks_node.children) { if(node.y > GameConfig.end_line_y+150) continue; if(node.y < GameConfig.end_line_y-150) continue; let block = node.getComponent(Block); if ((index == undefined || block.index == index) && block.existTime > 0.5) { let dy = Math.abs(node.y - end_center_y); if (dy < deltaY) { bestBlock = block; deltaY = dy; } } } return bestBlock; } checkHitRoad(index: number) { let blockExplode = this.findBestBlock(index); if (blockExplode instanceof Block) { if (blockExplode.canHit(index)) { this.hit(); this.countHitBeat(1); } blockExplode.addCollision(); return; } //长条击打检测 if (this.block_long.canHit && index == this.block_long.index) { this.hit(); if (this.block_long.count > 0) { this.countHitBeat(1); } this.block_long.count--; let c: dragonBones.ArmatureDisplay = this.collision2s[this.block_long.index]; c.node.active = true; let config = GameConfig.collision_configs[this.block_long.index]; c.node.setPosition(config.posX_long, config.posY_long); c.node.setScale(config.scaleX, config.scaleY); c.playAnimation("02", 1); } } onRoad(index: number) { this.keys[index].spriteFrame = this.keys_on[index]; this.road_lights[index].active = true; this.checkHitRoad(index); } outRoad(index: number) { this.keys[index].spriteFrame = this.keys_out[index]; this.road_lights[index].active = false; } miss() { //新增,需求说连击不要断 // this.hitCount = 0; } hit() { this.hitCount++; let targetScale = [12, 7.5]; let targetScaleStartRate = 0.2; let targetScaleEndRate = 0.25; this.double_hit.node.opacity = 255; this.double_hit.node.setScale(targetScale[0] * targetScaleStartRate, targetScale[1] * targetScaleStartRate); this.double_hit.string = this.hitCount.toString(); this.double_hit.font = this.double_hit_fonts[1]; this.double_hit.node.stopAllActions(); this.double_hit.node.runAction(cc.sequence( cc.scaleTo(0.1, targetScale[0], targetScale[1]), cc.scaleTo(0.1, targetScale[0] * targetScaleEndRate, targetScale[1] * targetScaleEndRate), cc.callFunc(() => { this.double_hit.font = this.double_hit_fonts[0]; }), cc.delayTime(0.23), cc.fadeOut(0.23) )); this.font_glown.timeScale = 2; this.font_glown.playAnimation("01", 1); // GameMgr.instance.playEffect(Sound.hit_effect); } countHitBeat(plus_value: number) { this.hitBeat += plus_value; } countOverBeat(plus_value: number) { this.overBeat += plus_value; if (this.overBeat == this.beats.length) { this.gameOver(); } } gameOver() { cc.audioEngine.stopMusic(); this.scheduleOnce(() => { GameMgr.instance.addPage(GameMgr.instance.settle_page); }, 0.5); } back() { if (GameMgr.instance.debug) { alert("如需重复测试,请关闭网页重新打开!") return; } this.node.destroy(); GameMgr.instance.playEffect(Sound.button_effect); GameMgr.instance.addPage(GameMgr.instance.main_page); } }