123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- import { _decorator, MeshRenderer, Node, SkeletalAnimation, UITransform, Vec3 } from 'cc';
- import { BaseExp } from '../core/base/BaseExp';
- import { autoBind } from '../extend/AutoBind';
- import { Utils } from '../utils/Utils';
- import { ResUtil } from '../utils/ResUtil';
- import { EAnimType } from './Enemy';
- const { ccclass, property } = _decorator;
- //埋伏点接口类
- export class AmbushPoint {
- //埋伏点位置节点数组
- public standPosArr: Vec3[] = [];
- //中间路径节点
- public roadPosArr: Vec3[] = [];
- //掩体点位置节点
- public ambushPosArr: Vec3[] = [];
- //逃跑点位置节点
- public escapePosArr: Vec3[] = [];
- //是否已经有人在此站位了
- public isVacancy: boolean = false;
- }
- @ccclass('GMap')
- export class GMap extends BaseExp {
- @autoBind({ type: Node, tooltip: "埋伏点配置节点" })
- public ambush_points: Node = null;
- @autoBind({type:Node,tooltip:"敌人出生区域"})
- public enemy_born_area: Node = null;
- @autoBind({type:Node,tooltip:"进门内线,用于敌人是否在门内"})
- public miidle_inline: Node = null;
- @autoBind({type:Node,tooltip:"进门外线,用于敌人是否在门外"})
- public miidle_outline: Node = null;
- @autoBind({type:Node,tooltip:"进去的大门"})
- public doors: Node = null;
-
- //埋伏点配置数组
- public ambushPoints: AmbushPoint[] = [];
- //游戏速度
- public game_speed: number = 1;
- start() {
- /*测试时使用 玩家坐标转换
- let n: Node = this.node.getChildByName('player_points');
- let pwww:Vec3 = Utils.convertPosition(this.node.getChildByName("player"),n);
- console.log("GGGGGGG = " + pwww);*/
- //区域隐藏
- const nodes:Node[] = this.ambush_points.children.flatMap(child => child.children);
- [this.enemy_born_area]
- .concat(nodes).forEach(e => {
- let m: MeshRenderer = e.getComponent(MeshRenderer);
- if(m){m.enabled = false}
- });
- }
- /**
- * 游戏速度
- */
- public multiplySpeed(): number{
- return this.game_speed;
- }
- /**
- * 解析埋伏点
- */
- private parseAmbushPoints() {
- this.ambushPoints = this.ambush_points.children
- .filter(e=>e.active)
- .map(ambushNode => {
- const point = new AmbushPoint();
- point.isVacancy = false;
- //从节点结构获取坐标配置
- point.standPosArr = ambushNode.children
- .filter(e => e.name.startsWith('stand_'))
- .map(node => node.worldPosition.clone());
- point.roadPosArr = ambushNode.children
- .filter(e => e.name.startsWith('road_'))
- .sort((a, b) => {
- //提取数字部分(兼容 road_1 / road_01 / road_001 等所有情况)
- const getNumber = (name: string) => {
- const numPart = name.split('_').pop(); // 取最后一段
- return parseInt(numPart || '0', 10); // 自动忽略前导零
- };
- return getNumber(a.name) - getNumber(b.name); // 按数值升序
- })
- .map(node => node.worldPosition.clone());
- point.ambushPosArr = ambushNode.children
- .filter(e => e.name.startsWith('bunker_'))
- .map(node => node.worldPosition.clone());
- point.escapePosArr = ambushNode.children
- .filter(e => e.name.startsWith('escape_'))
- .map(node => node.worldPosition.clone());
- return point;
- });
- }
- /**
- * 根据敌人信息得到敌人行走路径
- * @param eData 敌人数据
- * @param size 预制体大小
- * @returns
- */
- public getPaths(eData: any){
- let bornPos: Vec3 = this.getRandomBornPosition();
- //进入外门时的坐标
- const outerPos: Vec3 = this.getRandomPos(eData,this.miidle_outline);
- //进入内门时的坐标
- const innerPos: Vec3 = this.getRandomPos(eData,this.miidle_inline);
- //行走路径
- let paths: Array<Vec3> = [bornPos,outerPos,innerPos];
- //最后一个点特殊处理 包含(站位点、埋伏点、逃跑点) 随机一个埋伏点
- const ambush: AmbushPoint = this.getAmbushClas();
- ambush.isVacancy = true;
- eData.ambush = ambush;
- //查找中间路径点
- paths = paths.concat(ambush.roadPosArr);
- //随机一个站立点到最后坐标
- const endPos:Vec3 = Utils.randomArray(ambush.standPosArr)[0];
- endPos.x += Utils.getRandomFloat(1,0.2);
- paths.push(endPos);
- //测试时使用
- /*paths.forEach(e => {
- console.log("FFFFFF = " + this.node.getComponent(UITransform).convertToNodeSpaceAR(e));
- });*/
- return paths;
- }
- /**
- * 得到一个站位点
- */
- private getAmbushClas(){
- if(!this.ambushPoints
- || this.ambushPoints.length <= 0){
- //埋伏点类解析
- this.parseAmbushPoints();
- }
- //获取所有可用的埋伏点(未被占用的)
- const availablePoints = this.ambushPoints.filter(p => !p.isVacancy);
- if (availablePoints.length > 0) {
- //随机返回一个可用埋伏点
- return Utils.randomArray(availablePoints)[0];
- }
- //当所有点位都被占用时,随机返回任意一个
- if(this.ambushPoints.length > 0) {
- return Utils.randomArray(this.ambushPoints)[0];
- }
- return null;
- }
- /**
- * 根据两个坐标点产生一个两个坐标点之前的随机点
- */
- public getRandomPos(eData:any,target: Node): Vec3 {
- //只有坦克走中间
- const isTan: boolean = eData.id == 20003;
- if(isTan){
- return target.worldPosition.clone();
- }
- let basePos: Vec3 = target.children[0].worldPosition.clone();
- if(target.children.length >= 2){
- let pos1: Vec3 = target.children[0].worldPosition.clone();
- let pos2: Vec3 = target.children[1].worldPosition.clone();
- //生成0-1的随机比例因子
- const ratio = Utils.getRandomFloat(0, 1);
- //分别在x和z轴进行线性插值 这儿为了看起来暂时保留x轴上的距离随机
- basePos.x = pos1.x + (pos2.x - pos1.x) * ratio;
- //y轴就是左边的间隔的距离
- basePos.z = pos1.z + (pos2.z - pos1.z) * ratio;
- }
- return basePos;
- }
- /**
- * 获取随机出生点位置
- */
- public getRandomBornPosition(): Vec3 {
- if (!this.enemy_born_area) return Vec3.ZERO;
- //获取3D节点的世界缩放
- const worldScale = this.enemy_born_area.getWorldScale();
- //使用X和Z轴缩放作为区域尺寸
- const areaWidth = worldScale.x;
- const areaDepth = worldScale.z;
- //在XZ平面生成随机坐标(Y轴保持地面高度)
- const randomX = (Math.random() - 0.5) * areaWidth;
- const randomZ = (Math.random() - 0.5) * areaDepth;
- //基于节点原点位置生成世界坐标 保持与出生区域相同高度
- const basePos = this.enemy_born_area.worldPosition;
- return new Vec3(
- basePos.x + randomX,
- basePos.y,
- basePos.z + randomZ
- );
- }
- /**
- * 还原数据
- */
- public resetData(){
- this.ambushPoints.forEach(e => {
- e.isVacancy = false;
- });
- }
- }
|