import { _decorator, Component, Prefab, Node, instantiate, Sprite, SpriteFrame, Label } from 'cc'; import { MissionData } from '../battle/MissionData'; import { DataSystem } from '../core/data/DataSystem'; import { Http, HttpResponseCode } from '../core/net/Http'; import { Window } from '../core/ui/window/Window'; import { ReportThinking } from '../ReportThinking'; import { PVPCardArray } from './PVPCardArray'; import { PVPHero } from './PVPHero'; import { PVPHeroUI } from './PVPHeroUI'; import { PVPHeroData, PVPLogic, PVPPage, PVPPageType } from './PVPLogic'; import { PVPResult } from './PVPResult'; const { ccclass, property } = _decorator; @ccclass('PVP') export class PVP extends Component { @property({ type: PVPCardArray, tooltip: "底部卡牌组" }) bottomCards: PVPCardArray; @property({ type: PVPCardArray, tooltip: "顶部卡牌组" }) topCards: PVPCardArray; @property({ type: [Node], tooltip: "移动坐标点集合" }) posArray: Array = []; @property({ type: Prefab, tooltip: "pvp英雄预制体" }) pvpHeroPrefab: Prefab; @property({ type: Prefab, tooltip: "pvp英雄UI预制体" }) pvpHeroUiPrefab: Prefab; @property({ type: Node, tooltip: "战斗层" }) battleLayer: Node; @property({ type: Sprite, tooltip: "八卦图" }) bagua: Sprite; @property({ type: [SpriteFrame], tooltip: "八卦图合集" }) baguaSpriteList: Array = []; @property({ type: Label, tooltip: "攻击加成文本" }) gjLabel: Label; @property({ type: Label, tooltip: "暴击加成文本" }) bjLabel: Label; @property({ type: PVPResult, tooltip: "结算界面" }) pvpResult: PVPResult; @property({ type: Http, tooltip: "http组件" }) http: Http; private g1: Array = []; private g2: Array = []; private key: number; private isWin: boolean = false; private pages: Array = []; private index = 0; private g1Node: Node; private g2Node: Node; private isSkip = false; start() { DataSystem.getData(MissionData).isInPvp = true; this.pvpResult.closehandler = this.close.bind(this); this.setData(this.getComponent(Window).params[0]); } onDestroy() { DataSystem.getData(MissionData).isInPvp = false; } public setData(data: { g1: Array, g2: Array, key: number, baseHit: number, buff: any }) { this.g1 = data.g1.concat(); this.g2 = data.g2.concat(); this.key = data.key; let logic = new PVPLogic(this.g1, this.g2, data.key, data.baseHit, data.buff); let logicData = logic.begin(); this.pages = logicData.pages.concat(); this.bagua.spriteFrame = this.baguaSpriteList[logic.fetterID]; this.gjLabel.string = `+ ${logic.g1Camp.attack / 100}%`; this.bjLabel.string = `+ ${logic.g1Camp.cri / 100}%`; this.isWin = logicData.winner == 1; this.bottomCards.setData(this.g1); this.topCards.setData(this.g2); ReportThinking.fight_pvp(this.g1.concat(), this.isWin); this.doBattle(this.index); } /** * 对战递归 * @param index 战报索引 */ private doBattle(index: number): void { if (this.isSkip) { return; } switch (this.pages[index].type) { case PVPPageType.intoBattle: this.intoBattle(this.pages[index]); break; case PVPPageType.attack: this.attack(this.pages[index]); break; case PVPPageType.die: this.die(this.pages[index]); break; case PVPPageType.end: this.end(this.pages[index]); break; } } /**加入战斗 */ private intoBattle(page: PVPPage): void { let uiNode = instantiate(this.pvpHeroUiPrefab); uiNode.setPosition(10000, 10000, 0); uiNode.setParent(this.battleLayer); this['g' + page.formID + 'Node'] = instantiate(this.pvpHeroPrefab); this['g' + page.formID + 'Node'].setPosition(this.posArray[page.formID == 1 ? 0 : 2].position); this['g' + page.formID + 'Node'].getComponent(PVPHero).setUI(uiNode.getComponent(PVPHeroUI)); this['g' + page.formID + 'Node'].getComponent(PVPHero).setData(this['g' + page.formID][0], page.formID == 1 ? -1 : 1, this.posArray[page.formID == 1 ? 1 : 3].position, this.actionComplete.bind(this)); this['g' + page.formID + 'Node'].setParent(this.battleLayer); } /**攻击 */ private attack(page: PVPPage): void { this['g' + page.formID + 'Node'].getComponent(PVPHero).attack(this['g' + (page.formID == 1 ? 2 : 1) + 'Node'], this.attackComplete.bind(this)); } /**死亡 */ private die(page: PVPPage): void { let node = this['g' + this.pages[this.index].formID + 'Node'] as Node; (this['g' + this.pages[this.index].formID] as Array).shift(); if (this.pages[this.index].formID == 1) { this.bottomCards.setData(this.g1); } else { this.topCards.setData(this.g2); } node.getComponent(PVPHero).die(this.actionComplete.bind(this)); } /**战斗结束 */ private async end(page: PVPPage) { let result = await this.http.send("/api/pvp/EndPVP", { isWin: this.isWin, key: this.key }) if (result && result.code == HttpResponseCode.Success && result.data) { this.pvpResult.node.active = true; this.pvpResult.setData(result.data); } } /**当攻击结束时 */ private attackComplete(): void { let node = this['g' + (this.pages[this.index].formID == 1 ? 2 : 1) + 'Node'] as Node; node.getComponent(PVPHero).onHit(this.pages[this.index].hit, this.actionComplete.bind(this)); } /**战报动作完成 */ private actionComplete(): void { this.index++; if (this.index < this.pages.length) { this.doBattle(this.index); } } /**跳过 */ private skip(): void { this.doBattle(this.pages.length - 1); this.isSkip = true; } private close(): void { this.node.getComponent(Window).close(); } } export class PVPCardData extends PVPHeroData { public url: string; constructor(id: number, lv: number, star: number, color: number, camp: number, url?: string) { super(id, lv, star, color, camp); this.url = url; } }