import { EventHandler, EventTouch, find, instantiate, JsonAsset, Prefab, random, Sprite, SpriteFrame, SystemEventType, tween, UITransform, Vec2, Vec3 } from 'cc'; import { _decorator, Component, Node } from 'cc'; import { Http } from '../core/net/Http'; import { ResourcesUtils } from '../core/resourceManager/ResourcesUtils'; import { WindowManager } from '../core/ui/window/WindowManager'; import { WindowOpenMode } from '../core/ui/window/WindowOpenMode'; import { GeometryUtils } from '../core/utils/GeometryUtils'; import { Log } from '../core/utils/Log'; import { Random } from '../core/utils/Random'; import { ConfigData } from '../Data/ConfigData'; import { g } from '../Data/g'; import { GetTenfold } from '../Windows/GetTenfold'; import { Role } from './Role'; const { ccclass, property } = _decorator; /** * 神将控制器 * @author SS */ @ccclass('RoleController') export class RoleController extends Component { @property({ tooltip: "当角色可以出售", type: EventHandler }) public onCanSell: EventHandler; @property({ type: Node, tooltip: "角色组" }) roleGroup: Node; @property({ type: [Node], tooltip: "角色底" }) roleBgList: Node[] = []; @property({ tooltip: "角色预制体根目录" }) public rolePrefabPath = ''; @property({ tooltip: "画布", type: Node }) public canvas: Node; @property({ type: Node, tooltip: "出售按钮" }) sellButton: Node; @property({ type: Http, tooltip: "Http服务" }) http: Http; private rolesData = []; /**游戏场可显示神将节点 */ private roles: Array = []; /**最大显示神将数 */ private max: number = 12; /**当前选中的主角 */ private currentRole: Role; /**当前选中的主角开始位置 */ private beginTouchPoint: Vec2; /**当前选中的主角开始世界位置 */ private beginRoleWorldPosition: Vec3; /**目标的主角 */ private targetRole: Role; /**当前选中角色的位置索引 */ private _currentRoleIndex: number = -1; /**目标位置的索引 */ private targetRoleIndex: number = -1; /**是否已经拖动到出售按钮 */ private isMoveIn: boolean = false; /**开始移动 */ private startMove: boolean = false; start() { for (let i = 0; i < this.max; i++) { this.roles.push(null); this.rolesData.push(false); } let generals = g.gameData.getMyLocalData(g.userData.id).myLocalGenerals; for (let i = 0; i < generals.length; i++) { if (generals[i].index != -1) { this.createRole({ lv: generals[i].generalLv, index: generals[i].index, type: createType.Start }); } } !this.canvas && (this.canvas = find("Canvas")); this.canvas.on(SystemEventType.TOUCH_START, this.onTouchBegin, this); this.canvas.on(SystemEventType.TOUCH_END, this.onTouchEnd, this); this.canvas.on(SystemEventType.TOUCH_CANCEL, this.onTouchEnd, this); this.canvas.on(SystemEventType.TOUCH_MOVE, this.onTouchMove, this); } update() { if (g.gameData.hasSellGeneral) { g.gameData.hasSellGeneral = false; this.targetRoleIndex = -1; this.currentRoleIndex = -1; let role = this.roles[g.gameData.sellGeneralData.index]; if (role) { this.deleteRole(role, g.gameData.sellGeneralData.index, g.gameData.sellGeneralData.lv); this.checkNowRole(); g.gameData.saveLocalData(); } else { Log.warn('本地神将数据异常'); } } if (g.gameData.cancleSellGeneral) { g.gameData.cancleSellGeneral = false; this.targetRoleIndex = -1; this.currentRoleIndex = -1; let role = this.roles[g.gameData.sellGeneralData.index]; if (role) { role.node.worldPosition = this.beginRoleWorldPosition; } } if (g.gameData.isAddRole) { g.gameData.isAddRole = false; this.checkNowRole(); } } private currentTouchId = -1; private async onTouchBegin(e: EventTouch) { if (g.gameData.isBuying) { return; } if (this.currentTouchId != -1 && this.currentTouchId != e.touch.getID()) { return; } if (WindowManager.getWindowList().length > 0) { console.log("当前打开窗口数:::::" + WindowManager.getWindowList().length); return; } if (this._currentRoleIndex != -1 || this.targetRoleIndex != -1) { return; } this.currentRole = this.findRole(e.getUILocation()); if (this.currentRole) { g.gameData.isMoveing = true; let currentindex = this.currentRoleIndex; if (this.currentTouchId == - 1) { this.currentTouchId = e.touch.getID(); } this.beginTouchPoint = e.getUILocation(); this.currentRole.node.setSiblingIndex(this.roleGroup.children.length - 1); this.beginRoleWorldPosition = this.currentRole.node.worldPosition.clone(); let img: SpriteFrame = await ResourcesUtils.load("Roles/" + this.currentRole.generalBaseData.lv + "/spriteFrame", SpriteFrame, this.node); console.log("测试currentRoleIndex:::::" + this.currentRoleIndex); console.log(this.roleBgList[currentindex]); if (currentindex != -1) { let roleBg = this.roleBgList[currentindex].getChildByName("roleGray"); roleBg.getComponent(Sprite).spriteFrame = img; roleBg.active = true; } this.startMove = true; } } private async onTouchEnd(e: EventTouch) { if (this.currentTouchId != e.touch.getID() || WindowManager.getWindowList().length > 0) { return; } this.currentTouchId = -1; if (this.currentRole) { if (this.isMoveIn) {//出售 await WindowManager.open("Prefabs/Windows/SellGeneralWindow", WindowOpenMode.CloseAndAdd, { index: this.currentRoleIndex, lv: this.currentRole.generalLv, generalName: this.currentRole.generalBaseData.name }); g.gameData.isMoveing = false; } else { this.targetRole = this.findRole(e.getUILocation()); if (this.targetRole) {//目标位置有角色判断能否合与 if (this.currentRole.generalBaseData.lv == this.targetRole.generalBaseData.lv) {//可以合成 await this.promotionRole(); } else {//不可合成,互换位置 let temp = this.targetRole.node.worldPosition.clone(); this.targetRole.node.worldPosition = this.beginRoleWorldPosition; this.currentRole.node.worldPosition = temp; let Temprole = this.roles[this.currentRoleIndex]; this.roles[this.currentRoleIndex] = this.roles[this.targetRoleIndex]; this.roles[this.targetRoleIndex] = Temprole; g.gameData.updateLocalGeneral(this.currentRoleIndex, this.targetRoleIndex); this.currentRoleIndex = -1; this.targetRoleIndex = -1; g.gameData.isMoveing = false; } } else {//没有目标角色则移动位置 let roleBg = this.findNode(e.getUILocation()); if (roleBg) { this.currentRole.node.position = roleBg.position; this.roles[this.targetRoleIndex] = this.roles[this.currentRoleIndex]; this.rolesData[this.targetRoleIndex] = true; this.roles[this.currentRoleIndex] = null; this.rolesData[this.currentRoleIndex] = false; g.gameData.updateLocalGeneral(this.currentRoleIndex, this.targetRoleIndex); } else { this.currentRole.node.worldPosition = this.beginRoleWorldPosition; } g.gameData.isMoveing = false; this.currentRoleIndex = -1; this.targetRoleIndex = -1; } } this.onCanSell.emit([]); } } private onTouchMove(e: EventTouch) { if (WindowManager.getWindowList().length) { if (this.currentRole) { this.generalReset(); return; } } if (this.currentTouchId != e.touch.getID()) { return; } if (this.currentRole) { if (this.startMove) { this.startMove = false; this.onCanSell.emit([1]); } this.currentRole.node.worldPosition = this.beginRoleWorldPosition.clone().add(GeometryUtils.V2ToV3(e.getUILocation().subtract(this.beginTouchPoint))); if (this.changeMoveToSell(e)) { if (!this.isMoveIn) { this.onCanSell.emit([2]); } this.isMoveIn = true; } else { if (this.isMoveIn) { this.onCanSell.emit([1]); } this.isMoveIn = false; } } } private findRole(point: Vec2) { for (let i = 0; i < this.roles.length; i++) { const role = this.roles[i]; if (role && role.node.getComponent(UITransform) && role.node.getComponent(UITransform).isHit(point)) { if (role != this.currentRole) { if (this.currentRole) { this.targetRoleIndex = i; } else { this.currentRoleIndex = i; } return role; } } } return null; } private findNode(point: Vec2) { for (let i = 0; i < this.roleBgList.length; i++) { const node = this.roleBgList[i]; if (node && node.getComponent(UITransform).isHit(point) && this.currentRoleIndex != i) { this.targetRoleIndex = i; return node; } } return null; } /** * 检测是否移动到出售按钮 **/ private changeMoveToSell(e: EventTouch) { // let offX = this.currentRole.node.position.x + this.currentRole.getComponent("roleImg").node.getComponent(UITransform).width + e.getLocationX(); // let offY = this.currentRole.node.position.y + this.currentRole.getComponent("roleImg").node.getComponent(UITransform).height + e.getLocationY(); // this.currentRole.getbo // if (this.sellButton.getComponent(UITransform).isHit(new Vec2(offX, offY))) { if (this.sellButton.getComponent(UITransform).isHit(e.getUILocation())) { return true; } return false; } /** * 神将合成 */ public async promotionRole() { if (ConfigData.configMap.get("systemConfig").maxMixLv <= this.currentRole.generalBaseData.lv) { WindowManager.showTips("合成失败"); this.generalReset(); return; } let result = await this.http.send("/api/general/GeneralMix", { generalLv: this.currentRole.generalBaseData.lv }); if (!result.code) { if (!result.data) { this.generalReset(); } else { g.gameData.buyLv = result.data.buyLv; g.gameData.buyPrice = result.data.buyPrice; g.userData.money = result.data.newMoney; // g.userData.moneyPower10 = result.data.newMoneyPower10; g.userData.lv = (result.data.generalLv + 1) > g.userData.lv ? result.data.generalLv + 1 : g.userData.lv; this.deleteRole(this.currentRole, this.currentRoleIndex, result.data.generalLv); this.currentRoleIndex = -1; this.deleteRole(this.targetRole, this.targetRoleIndex, result.data.generalLv, createType.Mix); this.createRole({ lv: result.data.generalLv + 1, index: this.targetRoleIndex, type: createType.Mix }); g.gameData.isMoveing = false; g.gameData.openRecommend && this.checkMixRedPacket(); } } else { this.generalReset(); if (result.code == 105) { g.gameData.needSyncMoney = true; } else { WindowManager.showTips(g.CodeMsg[result.code]); } } } private generalReset() { if (this.currentRole) { this.currentRole.node.worldPosition = this.beginRoleWorldPosition; g.gameData.isMoveing = false; this.currentRoleIndex = -1; this.targetRoleIndex = -1; } } /** * 创建新角色 * @param data 角色数据 * @returns */ public async createRole(data) { let index = data.index == - 1 ? this.getFreeIndex() : data.index;//如果是合成创建有固定位置,购买或增送按顺序排列 this.rolesData[index] = true; g.gameData.addMyLocalGenral(index, data.lv); let preFabsData = await ResourcesUtils.load(this.rolePrefabPath, null, this.node); let targetPosition = this.roleBgList[index].position; var roleNode = instantiate(preFabsData); let role = roleNode.getComponent(Role); role.setData(data); this.roles[index] = role; roleNode.parent = this.roleGroup; if (data.type == createType.Start) { roleNode.position = new Vec3(targetPosition.x, targetPosition.y, 0); this.scheduleOnce(() => { roleNode.getComponent(Role).play(); }, Math.random()); return; } else if (data.type == createType.Buy) { roleNode.setPosition(this.beginPosition()); roleNode.setScale(new Vec3(0.3, 0.3, 0.3)); this.playBuyEffect(roleNode, new Vec3(targetPosition.x, targetPosition.y, 0)); } else if (data.type == createType.Mix) {//合成 roleNode.setScale(new Vec3(0.3, 0.3, 0.3)); roleNode.position = new Vec3(targetPosition.x, targetPosition.y, 0); this.playMixEffect(roleNode); this.checkNowRole(); } else if (data.type == createType.Reward) {//播放特效 roleNode.position = new Vec3(targetPosition.x, targetPosition.y, 0); role.getComponent(Role).playPrize(); this.scheduleOnce(() => { this.checkNowRole(); }, 0.8); } } private playBuyEffect(role: Node, v3: Vec3) { tween(role).to(0.2, { position: v3, scale: new Vec3(1, 1, 1) }).call(() => { g.gameData.isBuying = false; role.getComponent(Role).play(); }).start(); } private playMixEffect(role: Node) { tween(role).to(0.2, { scale: new Vec3(1, 1, 1) }).call(() => { this.targetRoleIndex = -1; role.getComponent(Role).play(); }).start(); } private async deleteRole(role: Role, index: number, lv: number, type: number = -1) { if (role) { if (role.generalLv == lv) { g.gameData.deleteMyLocalGenral(index, lv); this.roleGroup.removeChild(role.node); role.destroy(); if (type != createType.Mix) { this.roles[index] = null; this.rolesData[index] = false; } } else { WindowManager.showTips("数据异常"); } } } public onAttackLoss(generals: Array) { for (let j = 0; j < this.roles.length; j++) {//优先删除显示的神将 if (this.roles[j] && generals.indexOf(this.roles[j].generalLv) != -1) { generals.splice(generals.indexOf(this.roles[j].generalLv), 1); this.deleteRole(this.roles[j], j, this.roles[j].generalLv); } } for (let i = 0; i < generals.length; i++) {//删除未显示的神将 g.gameData.deleteMyLocalGenral(-1, generals[i]); } g.gameData.saveLocalData(); } /** * 创建角色初始坐标 * @returns */ private beginPosition(): Vec3 { let transFrom = this.roleGroup.getComponent(UITransform); let clampX = 0; let clampY = this.roleGroup.getPosition().y + transFrom.height - 200; return new Vec3(clampX, -clampY, 0); } /**获取空位索引 */ private getFreeIndex(): number { for (let i = 0; i < this.rolesData.length; i++) { if (!this.rolesData[i] && i != this.targetRoleIndex) { return i; } } return -1; } /**当前选中的位置索引 */ private get currentRoleIndex(): number { return this._currentRoleIndex; } /**当前选中的位置索引 */ private set currentRoleIndex(value: number) { if (value == -1) { this.currentRole = null; if (this._currentRoleIndex != -1) { this.roleBgList[this._currentRoleIndex].getChildByName("roleGray").active = false; } if (this.targetRoleIndex != -1) { this.roleBgList[this.targetRoleIndex].getChildByName("roleGray").active = false; } } else { this.roleBgList[value].getChildByName("roleGray").active = true; } this._currentRoleIndex = value; } /**检测未显示的神将 */ private checkNowRole() { let generals = g.gameData.getMyLocalData(g.userData.id).myLocalGenerals; for (let i = 0; i < generals.length; i++) { let targetIndex = this.getFreeIndex(); let index = generals[i].index; let lv = generals[i].generalLv; if (targetIndex == -1) { return; } if (generals[i].index == -1) { g.gameData.deleteMyLocalGenral(index, lv); g.gameData.isPlayPrizeRoleAnim = true; this.createRole({ index: targetIndex, lv: lv, type: createType.Reward }); return; } } } private myRandom: Random; private checkMixRedPacket() { this.myRandom || (this.myRandom = (new Random(null))); if (this.myRandom.value <= 0.2) { WindowManager.open('Prefabs/Each/MixRedPacket', WindowOpenMode.NotCloseAndAdd); } } } /**购买,合成,初始 ,奖励*/ export enum createType { Buy, Mix, Start, Reward }