zoukankan      html  css  js  c++  java
  • 控制地图显示范围

     1  private void ControlDisplayArea(Vector3 pos, bool IsInit)
     2     {
     3 
     4         IntVector2 newcoord = GetCoord(pos);//新得到的地图下标
     5         if (IsInit)//如果为初始化显示
     6         {
     7             ControlDisplayAll(false);
     8             int x_min = newcoord.x - area >= 0 ? newcoord.x - area : 0;
     9             int y_min = newcoord.y - area >= 0 ? newcoord.y - area : 0;
    10             int x_max = newcoord.x + area <= size_x - 1 ? newcoord.x + area : size_x - 1;
    11             int y_max = newcoord.y + area <= size_z - 1 ? newcoord.y + area : size_z - 1;
    12             for (int i = y_min; i <= y_max; i++)
    13                 for (int j = x_min; j <= x_max; j++)
    14                 {
    15                     if (GetOrder(j, i) != -1)
    16                         map.GetChild(GetOrder(j, i)).gameObject.SetActive(true);
    17                 }
    18             return;
    19         }
    20         if (newcoord == oldcoord)//如果对象下标未更新
    21             return;
    22         int index;//计算下标的辅助变量
    23         if (newcoord.x - oldcoord.x != 0)//左右方向更新
    24         {
    25             bool IsLeft = newcoord.x - oldcoord.x < 0 ? true : false;
    26 
    27             for (int i = newcoord.y - area; i <= newcoord.y + area; i++)//生成按新坐标边界
    28             {
    29                 index = GetOrder(IsLeft ? newcoord.x - area : newcoord.x + area, i);
    30                 if (index != -1)
    31                     map.GetChild(index).gameObject.SetActive(true);
    32             }
    33             for (int j = oldcoord.y - area; j <= oldcoord.y + area; j++)//消去按旧坐标边界
    34             {
    35                 index = GetOrder(IsLeft ? oldcoord.x + area : oldcoord.x - area, j);
    36                 if (index != -1)
    37                     map.GetChild(index).gameObject.SetActive(false);
    38             }
    39         }
    40 
    41         if (newcoord.y - oldcoord.y != 0)//上下方向更新
    42         {
    43             bool IsUp = newcoord.y - oldcoord.y > 0 ? true : false;
    44 
    45             for (int i = newcoord.x - area; i <= newcoord.x + area; i++)//生成按新坐标边界
    46             {
    47                 index = GetOrder(i, IsUp ? newcoord.y + area : newcoord.y - area);
    48                 if (index != -1)
    49                     map.GetChild(index).gameObject.SetActive(true);
    50             }
    51             for (int j = oldcoord.x - area; j <= oldcoord.x + area; j++)
    52             {
    53                 index = GetOrder(j, IsUp ? oldcoord.y - area : oldcoord.y + area);
    54                 if (index != -1)
    55                     map.GetChild(index).gameObject.SetActive(false);//消去按旧坐标边界
    56             }
    57         }
    58         oldcoord = newcoord;
    59     }

    新的方法的原理。每次对象坐标改变时,先记录下改变前其n圈内的格子坐标,然后算出改变后n圈内的格子坐标,后者全部setActive(true).后者减去前者作为显示对象。前者减去后者作为隐藏对象

      1 using System.Collections;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using UnityEngine;
      5 
      6 public class Control_Area : MonoBehaviour
      7 {
      8     
      9     public Transform mPlayer;//监控对象
     10     public Transform mMap;//地图
     11     public int mMaxRow;//最大行数
     12     public int mMaxCol;//最大列数
     13     public int mSize;//chunk尺寸,用来计算目标所在坐标
     14     public int Area=3;//显示范围
     15     //坐标类
     16 
     17     private Coordinate CurCoord = new Coordinate(-99,-99);
     18     private List<Coordinate> curCbs = null;//用来显示范围内的格子
     19     private List<Coordinate> preCbs = null;//用来消去上次范围内但不在现范围内的格子
     20 
     21 
     22     /// <summary>
     23     /// 用来初始化参数
     24     /// </summary>
     25     /// <param name="max_row"></param>
     26     /// <param name="max_col"></param>
     27     /// <param name="size"></param>
     28     /// <param name="map"></param>
     29     /// <returns></returns>
     30     public void Init(int max_row, int max_col,int size,Transform map)
     31     {
     32         mMaxRow = max_row;
     33         mMaxCol = max_col;
     34         mSize = size;
     35         mMap = map;
     36     }
     37 
     38     public void Start()
     39     { 
     40         //初始化时隐藏所有chunk
     41         for (int i = 0; i < mMap.childCount; i++)
     42         {
     43             Transform tf = mMap.GetChild(i);
     44             tf.gameObject.SetActive(false);
     45         }
     46         InvokeRepeating("ChunkPositionUpdate", 0f, 1f);
     47     }
     48 
     49     /// <summary>
     50     /// 更新位置,允许超出范围
     51     /// </summary>
     52     /// <returns></returns>
     53     public void ChunkPositionUpdate()
     54     {
     55         if (mPlayer == null || mMap == null)
     56         {
     57             return;
     58         }
     59         //将人物的世界坐标变换为地图的局部坐标
     60         Vector3 localHeroPos = mMap.transform.InverseTransformPoint(mPlayer.transform.position);
     61 
     62         int col = (int)(localHeroPos.x / mSize);
     63         int row = (int)(localHeroPos.z / mSize);
     64 
     65        //如果仍然处于旧位置
     66         if (CurCoord.Row == row && CurCoord.Col == col)
     67         {
     68             return;
     69         }
     70         //先把旧的周围所有圈方块记录下来
     71         preCbs = null;
     72         curCbs = null;
     73         preCbs = new List<Coordinate>();
     74         curCbs = new List<Coordinate>();
     75         for (int i = 0; i <Area; ++i)
     76         {
     77             preCbs.AddRange(new List<Coordinate>(GetCoordInR(CurCoord.Row, CurCoord.Col, i)));
     78         }
     79 
     80         CurCoord.Row = row;
     81         CurCoord.Col = col;
     82         ChunkVisibleUpdate();
     83     }
     84 
     85     /// <summary>
     86     /// 获取ChunkID
     87     /// </summary>
     88     /// <param name="row"></param>
     89     /// <param name="col"></param>
     90     /// <returns>int</returns>
     91     public int GetChunkID(int row,int col)
     92     {
     93         return row * mMaxCol + col;
     94     }
     95 
     96     /// <summary>
     97     /// 更新可见度
     98     /// </summary>
     99     /// <returns></returns>
    100     public void ChunkVisibleUpdate()
    101     {
    102         for (int i = 0; i < Area; ++i)
    103         {
    104             Coordinate[] cbs = GetCoordInR(CurCoord.Row, CurCoord.Col, i);
    105             curCbs.AddRange(new List<Coordinate>(cbs)); 
    106         }
    107         List<Coordinate> display = new List<Coordinate>(curCbs.ToArray());//显示的新格子
    108         List<Coordinate> hide = new List<Coordinate>(preCbs.ToArray());//消去的旧格子
    109         for (int i = curCbs.Count-1; i >=0; i--)
    110         {
    111             for (int j = preCbs.Count-1; j>=0;j--)
    112             {
    113                 if (Coordinate.Equal(curCbs[i],preCbs[j]))
    114                 {
    115                     display[i] = null;
    116                     hide[j] = null;
    117                 }
    118             }
    119         }
    120 
    121         display.RemoveAll(item =>{ return item == null; });//消去为null的坐标,这里指新坐标和旧坐标公有的格子
    122         hide.RemoveAll(item => { return item == null; });
    123 
    124         for (int i = 0; i < display.Count; ++i)
    125         {
    126             mMap.GetChild(GetChunkID(display[i].Row, display[i].Col)).gameObject.SetActive(true);
    127         }
    128 
    129         for (int i = 0; i < hide.Count; ++i)
    130         {
    131             mMap.GetChild(GetChunkID(hide[i].Row, hide[i].Col)).gameObject.SetActive(false);
    132         }
    133 
    134     }
    135 
    136 
    137     /// <summary>
    138     /// 返回地图范围内的坐标
    139     /// </summary>
    140     /// <param name="i"></param>
    141     /// <param name="j"></param>
    142     /// <returns>Coordinate</returns>
    143     private Coordinate GetValidCoord(int i, int j)
    144     {
    145         if (i < 0 || i >= mMaxRow || j < 0 || j >= mMaxCol)
    146         {
    147             return null;
    148         }
    149         return new Coordinate(i,j);
    150     }
    151 
    152 
    153 
    154     /// <summary>
    155     /// 返回返回指定第几围的坐标,若是超出范围则被排除在外
    156     /// </summary>
    157     /// <param name="row"></param>
    158     /// <param name="col"></param>
    159     /// <param name="r"></param>
    160     /// <returns>Coordinate[]</returns>
    161     private Coordinate[] GetCoordInR(int row, int col, int r)
    162     {
    163         List<Coordinate> list = new List<Coordinate>();
    164         for (int i = 0; i < 2 * r + 1; ++i)
    165         {
    166             Coordinate cb = GetValidCoord(row - r, col - r + i);
    167             if (cb != null && !list.Contains(cb))
    168             {
    169                 list.Add(cb);
    170             }
    171             cb = GetValidCoord(row - r + i, col - r);
    172             if (cb != null && !list.Contains(cb))
    173             {
    174                 list.Add(cb);
    175             }
    176             cb = GetValidCoord(row + r, col - r + i);
    177             if (cb != null && !list.Contains(cb))
    178             {
    179                 list.Add(cb);
    180             }
    181             cb = GetValidCoord(row - r + i, col + r);
    182             if (cb != null && !list.Contains(cb))
    183             {
    184                 list.Add(cb);
    185             }
    186         }
    187         return list.ToArray();
    188     }
    189 
    190     /// <summary>
    191     /// 坐标类
    192     /// </summary>
    193     class Coordinate
    194     {
    195         public int Row;
    196         public int Col;
    197         public Coordinate(int row, int col)
    198         {
    199             Row = row;
    200             Col = col;
    201         }
    202         public Coordinate(Coordinate m)
    203         {
    204             Row = m.Row;
    205             Col = m.Col;
    206         }
    207         public static bool Equal(Coordinate a, Coordinate b)
    208         {
    209             if (a.Col == b.Col && a.Row == b.Row)
    210                 return true;
    211             else
    212                 return false;
    213         }
    214     }
    215 }
    修正(上面那个瞬间移动的话会出现为未显示区域)
  • 相关阅读:
    多线程之缓存一致性协议
    Redis基础入门-linux安装
    Linux 上传文件rz 命令提示 -bash: rz: command not found 问题解决办法
    面试题之十亿条记录,怎么获取出现最多的前十个
    设计模式之工厂设计模式
    设计模式之单例设计模式
    数据结构之红黑树
    Eclipse使用Maven创建web3.0项目
    Eclipse创建Maven工程报错
    Oracle中的commit详解
  • 原文地址:https://www.cnblogs.com/luxishi/p/6687862.html
Copyright © 2011-2022 走看看