您的位置:首页 > 其它

控制地图显示范围

2017-04-10 10:40 309 查看
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 }


修正(上面那个瞬间移动的话会出现为未显示区域)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: