末日类slg-战略地图
一、概述
战略地图是项目中放大级别基于大地图和世界地图(小地图)的第三种地图:
1、大地图划分成战略格子,一个战略格子对应于n*n个大地图格子
2、战略地图内容来自于大地图,有:城池(基地、废墟、村庄等)、野外建筑、部队、标记
二、实现
1、前端使用TiledMap+大地图数据
2、城池、建筑、标记
(1)数据处理
a、因为数据变化不频繁,首次打开战略地图,请求全部数据;数据变化时,后端推送变化的数据(包括新增、更新、删除)
b、计算、记录数据对象归属于哪个战略格子
(2)显示处理
a、刷新当前显示范围格子中的显示对象(数据和显示对象分离,显示对象以标识字符串+id为key)
b、剔除已加载、不在显示范围格子中的显示对象
3、部队
(1)数据处理
a、因为数据变化较为频繁,前端定时请求大地图部队数据
b、计算格子归属
c、设置更新值
(2)显示处理
a、更新显示范围格子中的部队显示对象,插值移动
b、剔除格子归属在显示范围外的对象
c、删除未更新的显示对象
三、总结
1、坐标转换
(1)像素坐标与瓦块坐标转换
a、像素坐标转瓦块坐标:
沿着绿色x轴,瓦块坐标s递增、t递减;沿着绿色y轴,瓦块坐标s递减、t递减。以绿色轴交点看,x不变,y对s的影响为(mapHeight - y / tileHeight) - 0.5*mapHeight;y不变,x对t的影响为- (x / tileWidth - 0.5*mapWidth)。
所以得到s= x/ tileWidth + (mapHeight - y / tileHeight) - 0.5*mapHeight;t = mapHeight - y / tileHeight- (x / tileWidth - 0.5*mapWidth)
b、瓦块坐标转像素坐标:
沿着红色s轴,像素坐标x递增、y递减;沿着红色t轴x递减、y递减;以瓦块坐标系原点看,s不变,t对x的影响为-(t- 1) * (tileWidth/ 2);t不变,s对y的影响为- (s- 1) * (tileHeight / 2)。
所以得到x = (tileWidth * 0.5) * (mapWidth + s- t);y = 0.5*tileHeight * (2*mapHeight + 1 - t - s)
(2)大地图坐标与战略地图坐标转换
大地图与战略地图,从像素和瓦块,都是36:1,所以直接进行像素坐标的转换,然后在各自的坐标系下进行各自的瓦块坐标转换
2、地图拖动限制
从表现上,是窗口范围在地图中的限制。可以具体成,窗口左下角所在瓦块坐标的限制。沿着红色轴,瓦块坐标s被限制在dis_s_1、mapWidth - dis_s_2;沿着绿色轴,瓦块坐标t被限制在dis_t_1、mapHeight - dis_t_2。
因为本来就有像素位置的限制、对于dis_s_1、dis_s_2、dis_t_1、dis_t_2,只需根据期望的边缘范围,给出固定值。这种情况对于地图缩放后,同样适用。
3、TiledMap瓦块地图
(1)数据
TiledMap有两个重要的数据对象:瓦块集(Tileset)和层(Layer)
a、瓦块集(Tileset)
瓦块集可以包含多个瓦块数据,firstgid是这些瓦块的最小id;瓦块集有一张大图纹理,并且定义了每个子瓦块的纹理矩形范围。瓦块还可以定义用户属性,为键值对的形式。
b、层(Layer)
一个地图可以定义多个层,层定义的是格子对应的瓦块id。
(2)渲染
图层的格子是由精灵的渲染命令来渲染的,精灵的纹理由gid对应的瓦块数据中的纹理及纹理范围决定;图层的格子是动态渲染的,每帧只刷新在屏幕范围内的格子。
4、地图格子属性合并
为方便自定义属性的读取,将多个属性合并成一个组合属性;通过格子坐标获取这个组合属性,然后再分解出具体属性。