皇室战争 路线行走 (二)

改进了一下,中间的河流,做成第五区域,桥两端 分上下 两个点。

具体做法如下图

先设置10个空对象,按照固定位置排好,L代表左 R 代表右 M代表中,D下U上,都是英文首字母。 比如桥左上端,就是 LUM 左上中,因为桥是中间 。桥右下 就是 RDM 右下中。

这段代表就是把  10个节点的坐标 都保存起来,用单例,这样以后获取就不要 找来找去。

 GroundVector = new Transform[10];
        GameObject GroundVectors = GameObject.FindGameObjectWithTag("GroundVector");
        List<Vector2> list = new List<Vector2>();
        for (int i = 0; i < 10; i++)
        {
            GroundVector[i] = GroundVectors.transform.GetChild(i);
            list.Add(GroundVector[i].position);
        }
        GModel.getInstance.Cv.OnSetSenceVector(list);
    }

除了 保存 坐标,单例里面还有2个方法

1  获得区域

2 寻路

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CalculationVector
{
    public Vector2 LU;//左上
    public Vector2 RU;//右上
    public Vector2 LD;//左下
    public Vector2 RD;//右下
    public Vector2 LUM;//左上中
    public Vector2 RUM;//右上中
    public Vector2 LDM;//左下中
    public Vector2 RDM;//右下中
    public Vector2 UM;//上中
    public Vector2 DM;//下中
    public float Offset;//偏移量
    public int region;//区域
    //设置场景各个坐标
    public void OnSetSenceVector(List<Vector2> list)
    {
        LU = list[0];
        RU = list[1];
        LD = list[2];
        RD = list[3];
        UM = list[4];
        DM = list[5];
        LUM = list[6];
        RUM = list[7];
        LDM = list[8];
        RDM = list[9];
    }

    //五大 区域
    private int OnSetRegion(Vector2 vec)
    {
        if (LUM.x < vec.x && vec.x < DM.x)// 1,3 5区域
        {
            if (LD.y < vec.y && vec.y < LDM.y)//1 区域
            {
                region = 1;
            }
            else if (LDM.y < vec.y && vec.y < LUM.y)  //5区域
            {
                region = 5;
            }
            else
            {
                region = 3;
            }
        }
        else                    //2,4  5区域
        {
            if (RD.y < vec.y && vec.y < RDM.y)//2 区域
            {
                region = 2;
            }
            else if (RDM.y < vec.y && vec.y < RUM.y)  //5区域
            {
                region = 5;
            }
            else
            {
                region = 4;
            }
        }
        return region;
    }

    // 区域对应 路线
    public List<Vector2> OnRoute(Vector2 v, int oneself)//判断自己还是对方 0,1 (1是自己)
    {
        int region = OnSetRegion(v);
        List<Vector2> list = new List<Vector2>();

        switch (region)
        {
            case 1:
                if (oneself == 1)
                {
                    if (v.y < LD.y)//如果压底部
                    {
                        list.Add(LD);
                        list.Add(LDM);
                        list.Add(LUM);
                        list.Add(LU);
                        list.Add(UM);
                    }
                    else
                    {
                        list.Add(LDM);
                        list.Add(LUM);
                        list.Add(LU);
                        list.Add(UM);
                    }
                }
                else
                {
                    if (v.y < LD.y)//如果压底部
                    {
                        list.Add(DM);
                    }
                    else
                    {
                        list.Add(LD);
                        list.Add(DM);
                    }
                }
                break;
            case 2:
                if (oneself == 1)
                {
                    if (v.y < RD.y)//如果压底部
                    {
                        list.Add(RD);
                        list.Add(RDM);
                        list.Add(RUM);
                        list.Add(RU);
                        list.Add(UM);
                    }
                    else
                    {
                        list.Add(RDM);
                        list.Add(RUM);
                        list.Add(RU);
                        list.Add(UM);
                    }
                }
                else
                {
                    if (v.y < RD.y)//如果压底部
                    {
                        list.Add(DM);
                    }
                    else
                    {
                        list.Add(RD);
                        list.Add(DM);
                    }
                }
                break;
            case 3:
                if (oneself == 1)
                {
                    if (v.y > LU.y)//如果压底部
                    {
                        list.Add(UM);
                    }
                    else
                    {
                        list.Add(LU);
                        list.Add(UM);
                    }
                }
                else
                {
                    if (v.y > LU.y)//如果压底部
                    {
                        list.Add(LU);
                        list.Add(LUM);
                        list.Add(LDM);
                        list.Add(LD);
                        list.Add(DM);
                    }
                    else
                    {
                        list.Add(LUM);
                        list.Add(LDM);
                        list.Add(LD);
                        list.Add(DM);
                    }
                }
                break;
            case 4:
                if (oneself == 1)
                {
                    if (v.y > RU.y)//如果压底部
                    {
                        list.Add(DM);
                    }
                    else
                    {
                        list.Add(RU);
                        list.Add(DM);
                    }
                }
                else
                {
                    if (v.y > RU.y)//如果压底部
                    {
                        list.Add(RU);
                        list.Add(RUM);
                        list.Add(RDM);
                        list.Add(RD);
                        list.Add(DM);
                    }
                    else
                    {
                        list.Add(RUM);
                        list.Add(RDM);
                        list.Add(RD);
                        list.Add(DM);
                    }
                }
                break;
            case 5:
                if (oneself == 1)
                {
                    if (v.x < DM.x)
                    {
                        list.Add(LUM);
                        list.Add(LU);
                        list.Add(UM);
                    }
                    else
                    {
                        list.Add(RUM);
                        list.Add(RU);
                        list.Add(UM);
                    }
                }
                else
                {
                    if (v.x < DM.x)
                    {
                        list.Add(LDM);
                        list.Add(LD);
                        list.Add(UM);
                    }
                    else
                    {
                        list.Add(RDM);
                        list.Add(RD);
                        list.Add(UM);
                    }
                }
                break;
            default: break;
        }
        return list;
    }
}

这样,用户在逻辑帧 就能随时 调用 寻路路径。速度杠杠的。

另外,如果检测 敌人,要跟踪,那么必须要 a*寻路。

为了性能,考虑2个问题。

1.格子 少一点,我觉得11 * 7 就可。1-3毫秒就能寻到,不影响性能。

2. 规定 A*  一帧使用数量,也就是说,如果当前帧有100个要用 A*寻路,那么程序假设规定最大一帧只能20个,寻路的贴上以寻,没寻的,等下一帧寻路。

好处,当然是不会卡,虽然大家会担心另外80个会不会  因为这帧不寻路 迟钝,但 逻辑帧 只要保证1秒 5帧以上,那么 这个迟钝 用户是 看不出来的,毕竟没有可能一次100个都要用a*寻路

更多优化:可以把桥 左右 做成 5,6区域。如果同区域 跟踪,可以走直线,不a*。这也是 一个优化思路。

当然,这个思路仅仅是针对  皇室战争 地图,如果同一个区域  不是 规则形状,需要绕,那么 这个只能走a*

原文地址:https://www.cnblogs.com/big-zhou/p/11505628.html

时间: 2024-10-31 07:49:32

皇室战争 路线行走 (二)的相关文章

Android学习路线(二十)运用Fragment构建动态UI

要在Android系统上创建一个动态或者多面板的用户界面,你需要将UI组件以及activity行为封装成模块,让它能够在你的activity中灵活地切换显示与隐藏.你可以使用Fragment类来创建这些模块,它们能够表现得有些像嵌套的activity,它们定义着自己的布局,管理自己的生命周期. 当一个fragment指定了它自己的布局,它可以在activity中和其他的fragment配置为不同的组合,这样就能够为不同的屏幕尺寸来修改你的布局配置(在小屏幕上一次展现一个fragment,而在大屏

Android学习路线(二十一)运用Fragment构建动态UI——创建一个Fragment

你可以把fragment看成是activity的模块化部分,它拥有自己的生命周期,接受它自己的输入事件,你可以在activity运行时添加或者删除它(有点像是一个"子activity",你可以在不同的activity中重用它).本课将向你展示如何使用Support Libaray继承 Fragment 类来让你的应用能够兼容正在运行Android 1.6的设备. 提示: 如果你决定你的应用需求的最低API级别是11或者更高,那么你不需要使用Support Library,你可以直接使用

Android学习路线(二十四)ActionBar Fragment运用最佳实践

通过前面的几篇博客,大家看到了Google是如何解释action bar和fragment以及推荐的用法.俗话说没有demo的博客不是好博客,下面我会介绍一下action bar和fragment在实战中的应用,以及相关demo源码,希望和大家相互交流. 了解过fragment的同学们应该都知道,fragment是android 3.0版本才出现的的,因此如果要在支持android 3.0一下版本的工程中使用fragment的话是需要添加Support Library的.具体如何添加我就不再赘述

Android学习路线(二十二)运用Fragment构建动态UI——构建一个灵活的UI

先占个位置,下次翻译 :p When designing your application to support a wide range of screen sizes, you can reuse your fragments in different layout configurations to optimize the user experience based on the available screen space. For example, on a handset devi

Android学习路线(二十三)运用Fragment构建动态UI——Fragment间通讯

先占个位置,下次翻译 :p In order to reuse the Fragment UI components, you should build each as a completely self-contained, modular component that defines its own layout and behavior. Once you have defined these reusable Fragments, you can associate them with

安卓模拟器的使用--皇室战争免费快速成长之路

最近皇室战争好火,朋友圈一堆人在玩.我也被拉进去玩了几天.一般打到三阶竞技场就会龟速前进了,基本上就是每天等宝箱时间,偶尔会进入四阶擂台,打两场就被打下来,一直在900-1200之间浮动.今天听说能用虚拟机玩,这样就可以用小号来捐卡给大号了. 首先,要有一台能上网的电脑,废话. 下载安卓虚拟机,我是直接在360下载的 搜一下"安卓模拟器",发现很多,我就选了个最高分的下载吧--天天安卓模拟器.我还是给个百度下载吧.其实我也不知道哪个好用. 下载后安装,记得避开那些广告软件的选项.安装后

Android学习路线(二)创建Android项目

一个Android项目包含了Android app代码在内的所有文件.Android SDK工具提供默认的项目目录和文件让创建一个项目变得很简单. 这篇课程会向大家展示,如何通过Eclipse(包含ADT插件)或者通过在命令行使用SDK工具来创建一个新项目. 提示: 你必须得先安装好Android SDK,如果你使用的是Eclipse,那么你还必须安装了ADT 插件(22.6.2版本或更高).如果你没有这些,可以通过Android SDK安装向导安装好,然后再回到这片课程. 通过Eclipse创

中小企业的大数据技术路线选择(二)-Cassandra+Presto方案

中小企业的大数据技术路线选择(二)-Cassandra+Presto方案 我前面曾经写过:中小企业的大数据技术路线选择 和 低调.奢华.有内涵的敏捷式大数据方案:Flume+Cassandra+Presto+SpagoBI . 最近用了两个月的时间终于把Cassandra+Presto+SpagoBI方案验证通过了.验证了Presto的JDBC Driver .Prestogres网关.SHIB三种方式. 一.Presto JDBC驱动方案 Presto JDBC驱动方案,Java动用客户端,如

《皇室战争》月流水破7亿 CR主播已赚到钱

自 3 月份以来,Supercell 在全球持续获得了非常高的关注,除了旗下游戏累计突破 1 亿 DAU 之外,该公司第四款全球上线的手游<皇室战争>起到了更为关键的作用.苹果的超常规全球推荐.App Store 首页定制化推荐这样的待遇几乎是业内前所未有的.而且,该游戏还进入了中美日韩四个主要地区以及大多数欧美手游市场的收入榜前十名. 今天,业内数据追踪公司 Newzoo 透露,<皇室战争>在 3 月份给 Supercell 带来了 8000 万美元的收入,这个数字不包括苹果和谷