2023-10-31 02:34:12 +08:00
|
|
|
import { _decorator,Node } from "cc";
|
2023-10-23 18:56:01 +08:00
|
|
|
import GBaseMode from "../GBaseMode";
|
|
|
|
import { GTactical } from "../entity/GTactical";
|
|
|
|
import { Prefab } from "cc";
|
|
|
|
import { instantiate } from "cc";
|
|
|
|
import { Vec2 } from "cc";
|
2023-10-30 02:34:11 +08:00
|
|
|
import { GRoleUtil } from "../entity/GRole";
|
2023-11-01 02:01:35 +08:00
|
|
|
import GRoleDefault from "../base/role/GRoleDefault";
|
2023-11-04 05:56:28 +08:00
|
|
|
import { v3 } from "cc";
|
2023-12-13 19:33:57 +08:00
|
|
|
import { TB } from "../../config/data/schema";
|
2023-11-21 01:57:40 +08:00
|
|
|
import JNFrameTime from "../../../../extensions/ngame/assets/ngame/sync/frame/game/time/JNFrameTime";
|
|
|
|
import GBattleModeManager from "../GBattleModeManager";
|
|
|
|
import { app, TD } from "../../App";
|
|
|
|
import { GPVPStart } from "../../action/PVPAction";
|
|
|
|
import { PlayerPetOV } from "../../consts/API";
|
2023-12-05 01:43:43 +08:00
|
|
|
import GPetAttribute from "../base/values/attribute/role/GPetAttribute";
|
2023-12-23 19:00:53 +08:00
|
|
|
import { GModeEvent } from "./GMode";
|
2023-10-23 18:56:01 +08:00
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
|
|
|
//PVP 角色
|
|
|
|
export enum GPVPModePlayerEnum{
|
|
|
|
PLAYER, //玩家
|
|
|
|
ENEMY, //敌人
|
|
|
|
}
|
|
|
|
|
|
|
|
//PVP 玩家信息
|
|
|
|
export interface GPVPModePlayerInfo{
|
|
|
|
//阵法
|
|
|
|
tactical: GTactical;
|
|
|
|
//宠物列表
|
2023-12-05 01:43:43 +08:00
|
|
|
roles: PlayerPetOV[];
|
2023-10-23 18:56:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PVP 模式
|
|
|
|
*/
|
|
|
|
@ccclass('GPVPMode')
|
2023-11-21 01:57:40 +08:00
|
|
|
export default class GPVPMode extends GBaseMode<{},GPVPStart>{
|
2023-10-23 18:56:01 +08:00
|
|
|
|
|
|
|
@property(Prefab)
|
|
|
|
rolePrefab: Prefab = null;
|
2023-10-31 02:34:12 +08:00
|
|
|
|
|
|
|
@property(Node)
|
|
|
|
objects: Node = null;
|
2023-10-23 18:56:01 +08:00
|
|
|
|
|
|
|
//玩家信息
|
2023-10-26 03:06:44 +08:00
|
|
|
playerInfo: GPVPModePlayerInfo;
|
2023-10-23 18:56:01 +08:00
|
|
|
//敌方信息
|
2023-10-26 03:06:44 +08:00
|
|
|
enemyInfo: GPVPModePlayerInfo;
|
2023-10-23 18:56:01 +08:00
|
|
|
|
|
|
|
//玩家宠物
|
2023-11-01 02:01:35 +08:00
|
|
|
playerRoles: GRoleDefault[] = [];
|
2023-10-23 18:56:01 +08:00
|
|
|
//敌方宠物
|
2023-11-01 02:01:35 +08:00
|
|
|
enemyRoles: GRoleDefault[] = [];
|
2023-10-23 18:56:01 +08:00
|
|
|
|
|
|
|
//玩家位置
|
|
|
|
playerPos: Vec2 = new Vec2(-400,0);
|
|
|
|
//敌方位置
|
|
|
|
enemyPos: Vec2 = new Vec2(400,0);
|
|
|
|
|
2023-11-21 01:57:40 +08:00
|
|
|
//是否结束游戏
|
|
|
|
isEndGame:boolean = false;
|
|
|
|
|
2023-10-31 02:34:12 +08:00
|
|
|
get scene():Node{
|
|
|
|
return this.objects;
|
|
|
|
}
|
|
|
|
|
2023-10-26 03:06:44 +08:00
|
|
|
onLoad(){
|
2023-11-21 01:57:40 +08:00
|
|
|
|
|
|
|
//整理GPVPStart数据
|
|
|
|
//宠物Id列表
|
|
|
|
let leftTactical:number[] = JSON.parse(this.data.leftTactical);
|
|
|
|
let rightTactical:number[] = JSON.parse(this.data.rightTactical);
|
|
|
|
|
|
|
|
//宠物列表
|
2023-12-05 01:43:43 +08:00
|
|
|
let leftTbs:PlayerPetOV[] = [];
|
|
|
|
let rightTbs:PlayerPetOV[] = [];
|
2023-11-21 01:57:40 +08:00
|
|
|
|
2023-12-05 01:43:43 +08:00
|
|
|
//整理宠物信息
|
2023-11-21 01:57:40 +08:00
|
|
|
for (let index = 0; index < leftTactical.length; index++) {
|
|
|
|
const petId = leftTactical[index];
|
2023-12-05 01:43:43 +08:00
|
|
|
leftTbs[index] = null;
|
|
|
|
|
2023-11-21 01:57:40 +08:00
|
|
|
if(petId != 0){
|
|
|
|
let pet:PlayerPetOV = JSON.parse(this.data.leftPets[petId]);
|
2023-12-05 01:43:43 +08:00
|
|
|
if(pet && pet.petId)
|
|
|
|
leftTbs[index] = pet;
|
2023-11-21 01:57:40 +08:00
|
|
|
}
|
|
|
|
}
|
2023-12-05 01:43:43 +08:00
|
|
|
|
2023-11-21 01:57:40 +08:00
|
|
|
for (let index = 0; index < rightTactical.length; index++) {
|
|
|
|
const petId = rightTactical[index];
|
2023-12-05 01:43:43 +08:00
|
|
|
rightTbs[index] = null;
|
|
|
|
|
2023-11-21 01:57:40 +08:00
|
|
|
if(petId != 0){
|
|
|
|
let pet:PlayerPetOV = JSON.parse(this.data.leftPets[petId]);
|
2023-12-05 01:43:43 +08:00
|
|
|
if(pet && pet.petId)
|
|
|
|
rightTbs[index] = pet;
|
2023-11-21 01:57:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.playerInfo = { tactical: GTactical.getTactical().setOffset(this.playerPos), roles: leftTbs };
|
|
|
|
this.enemyInfo = { tactical: GTactical.getTactical(true).setOffset(this.enemyPos), roles: rightTbs };
|
|
|
|
|
2023-10-26 03:06:44 +08:00
|
|
|
super.onLoad();
|
|
|
|
}
|
|
|
|
|
2023-10-23 18:56:01 +08:00
|
|
|
|
|
|
|
onSyncInitSuccess(): void {
|
2023-10-30 02:34:11 +08:00
|
|
|
|
2023-11-04 05:56:28 +08:00
|
|
|
//调整相机
|
2023-12-10 00:58:43 +08:00
|
|
|
this.camera.enabled = true;
|
2023-11-04 05:56:28 +08:00
|
|
|
let camreaPos = this.camera.node.worldPosition;
|
2023-11-20 18:25:50 +08:00
|
|
|
this.camera.node.worldPosition = v3(0,800,camreaPos.z)
|
2023-10-23 18:56:01 +08:00
|
|
|
|
|
|
|
//初始化战斗
|
|
|
|
console.log("GPVPMode 模式初始化");
|
|
|
|
|
2023-11-21 01:57:40 +08:00
|
|
|
//生成宠物
|
|
|
|
this.playerInfo.roles.forEach((info,index) => info && this.onGenRole(GPVPModePlayerEnum.PLAYER,index+1,info))
|
|
|
|
this.enemyInfo.roles.forEach((info,index) => info && this.onGenRole(GPVPModePlayerEnum.ENEMY,index+1,info))
|
2023-10-23 18:56:01 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//生成角色
|
2023-12-05 01:43:43 +08:00
|
|
|
onGenRole(type: GPVPModePlayerEnum,index:number,info:PlayerPetOV) {
|
2023-10-23 18:56:01 +08:00
|
|
|
|
2023-11-01 02:01:35 +08:00
|
|
|
let tactical = this.getInfo(type).tactical;
|
2023-10-23 18:56:01 +08:00
|
|
|
let pos:Vec2 = this.getInfo(type).tactical.getPosition(index);
|
|
|
|
if(!pos) return;
|
|
|
|
let role = instantiate(this.rolePrefab);
|
2023-11-01 02:01:35 +08:00
|
|
|
let entity = role.getComponent(GRoleDefault);
|
|
|
|
//初始化
|
2023-12-05 01:43:43 +08:00
|
|
|
entity.onInit(type,TD.TbGRole.get(info.petTbId),tactical,index);
|
2023-11-01 02:01:35 +08:00
|
|
|
|
|
|
|
//绑定寻敌
|
|
|
|
entity.onQueryEunmy = () => {
|
|
|
|
return this.getEnumy(entity,type);
|
|
|
|
}
|
|
|
|
|
2023-11-21 01:57:40 +08:00
|
|
|
//绑定受击回调
|
|
|
|
entity.addHitCallback(this.onHitBack.bind(this));
|
|
|
|
//绑定死亡回调
|
|
|
|
entity.addKillBackEvent(this.onRoleKillBack.bind(this))
|
|
|
|
|
2023-12-05 01:43:43 +08:00
|
|
|
//添加宠物属性
|
|
|
|
entity.onEffectiveValue(new GPetAttribute(info));
|
|
|
|
|
2023-11-01 02:01:35 +08:00
|
|
|
this.addGObject(entity,tactical.getPosition(index));
|
2023-10-24 02:32:06 +08:00
|
|
|
this.getOnesRole(type).push(entity);
|
2023-10-23 18:56:01 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//获取配置
|
|
|
|
getInfo(type: GPVPModePlayerEnum): GPVPModePlayerInfo {
|
|
|
|
if(type == GPVPModePlayerEnum.PLAYER) return this.playerInfo;
|
|
|
|
if(type == GPVPModePlayerEnum.ENEMY) return this.enemyInfo;
|
|
|
|
}
|
|
|
|
|
2023-10-24 02:32:06 +08:00
|
|
|
//获取阵营角色
|
2023-11-01 02:01:35 +08:00
|
|
|
getOnesRole(type: GPVPModePlayerEnum):GRoleDefault[]{
|
2023-10-24 02:32:06 +08:00
|
|
|
if(type == GPVPModePlayerEnum.PLAYER) return this.playerRoles;
|
|
|
|
if(type == GPVPModePlayerEnum.ENEMY) return this.enemyRoles;
|
|
|
|
}
|
|
|
|
|
2023-11-21 01:57:40 +08:00
|
|
|
//获取存活的宠物
|
|
|
|
getOnesRoleAlive(type: GPVPModePlayerEnum):GRoleDefault[]{
|
|
|
|
if(type == GPVPModePlayerEnum.PLAYER) return this.playerRoles.filter(role => !!role.get());
|
|
|
|
if(type == GPVPModePlayerEnum.ENEMY) return this.enemyRoles.filter(role => !!role.get());
|
|
|
|
}
|
|
|
|
|
2023-10-24 02:32:06 +08:00
|
|
|
//获取敌人
|
2023-11-01 02:01:35 +08:00
|
|
|
getEnumy(player:GRoleDefault,type:GPVPModePlayerEnum):GRoleDefault{
|
2023-10-24 02:32:06 +08:00
|
|
|
|
|
|
|
let enumyOnes = GPVPModePlayerEnum.ENEMY
|
|
|
|
//如果是ENEMY 则 它的敌人是 PLAYER
|
2023-11-01 02:01:35 +08:00
|
|
|
if(type == GPVPModePlayerEnum.ENEMY) enumyOnes = GPVPModePlayerEnum.PLAYER
|
2023-10-24 02:32:06 +08:00
|
|
|
|
|
|
|
//获取敌人
|
2023-11-21 01:57:40 +08:00
|
|
|
let roles = this.getOnesRoleAlive(enumyOnes);
|
|
|
|
|
|
|
|
//通过距离获取最近的敌人
|
|
|
|
if(roles[0]){
|
|
|
|
let len = Math.abs(Vec2.distance(player.v2World,roles[0].v2World));
|
|
|
|
let enumy = roles[0];
|
|
|
|
for (let index = 0; index < roles.length; index++) {
|
|
|
|
const role = roles[index];
|
|
|
|
let tLen;
|
|
|
|
if(tLen = Math.abs(Vec2.distance(player.v2World,role.v2World)) < len){
|
|
|
|
enumy = role;
|
|
|
|
len = tLen;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return enumy;
|
|
|
|
}else{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//角色死亡回调
|
|
|
|
onRoleKillBack(role:GRoleDefault){
|
|
|
|
|
|
|
|
//死亡销毁
|
|
|
|
JNFrameTime.getInstance().setTimeout(() => {
|
|
|
|
if(role.isValid)
|
|
|
|
role.node.destroy()
|
|
|
|
},3000)
|
|
|
|
|
|
|
|
this.onUpdateEndState();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//刷新结束状态
|
|
|
|
onUpdateEndState(){
|
|
|
|
|
|
|
|
//如果已经结束则返回
|
|
|
|
if(this.isEndGame) return;
|
|
|
|
|
|
|
|
//判断是否有队伍都死亡
|
|
|
|
if(this.getOnesRoleAlive(GPVPModePlayerEnum.PLAYER).length == 0 || this.getOnesRoleAlive(GPVPModePlayerEnum.ENEMY).length == 0){
|
|
|
|
this.isEndGame = true;
|
2023-11-22 17:46:08 +08:00
|
|
|
let winner = this.data.leftPlayerId;
|
|
|
|
if(this.getOnesRoleAlive(GPVPModePlayerEnum.ENEMY).length){
|
|
|
|
winner = this.data.rightPlayerId;
|
|
|
|
}
|
2023-11-21 01:57:40 +08:00
|
|
|
//结束游戏
|
|
|
|
JNFrameTime.getInstance().setTimeout(() => {
|
2023-11-22 03:51:37 +08:00
|
|
|
console.log(this.getOnesRoleAlive(GPVPModePlayerEnum.PLAYER).length,this.getOnesRoleAlive(GPVPModePlayerEnum.ENEMY).length)
|
2023-11-22 17:46:08 +08:00
|
|
|
this.Close(winner);
|
2023-11-21 01:57:40 +08:00
|
|
|
},3000)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//角色受击回调
|
|
|
|
onHitBack(role:GRoleDefault,hit:number){
|
|
|
|
|
|
|
|
if(!role.get()) return;
|
|
|
|
|
|
|
|
//添加受击显示
|
2023-12-23 19:00:53 +08:00
|
|
|
app.event.emit(GModeEvent.HIT,{
|
|
|
|
mode:this,
|
|
|
|
role:role,
|
|
|
|
hit:hit,
|
|
|
|
world:role.v2World,
|
|
|
|
camera:this.camera,
|
|
|
|
});
|
2023-10-24 02:32:06 +08:00
|
|
|
|
2023-10-25 19:19:52 +08:00
|
|
|
}
|
2023-10-23 18:56:01 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|