You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

299 lines
8.1 KiB

  1. local Map = class("Map");
  2. require("luaScript.Map.MapDrawer")(Map);
  3. Map.ObstacleType =
  4. {
  5. -- 不是障碍块
  6. ObstacleNone = 1,
  7. -- 是障碍块
  8. ObstacleNormal = 0,
  9. }
  10. -- TileWidth
  11. Map.TileWidth = 60
  12. -- tileHeight
  13. Map.TileHeight = 30
  14. -- 构造函数
  15. function Map:ctor()
  16. -- 默认构造一个1136 X 640的地图
  17. -- self:initWidthAndHeight(1136, 640, 60, 30);
  18. -- 障碍信息
  19. self.obstacles = cc.CAStar:new();
  20. -- 当障碍块改变时回调
  21. self.ObstacleChanged = nil;
  22. end
  23. -- 重新计算地图
  24. function Map:recalculate()
  25. self.TileHalfWidth = self.TileWidth / 2;
  26. self.TileHalfHeight = self.TileHeight / 2;
  27. -- 根据地图大小和tile的大小,计算tile的个数以及tile的偏移
  28. local widthLen = math.ceil(self.MapWidth / self.TileWidth);
  29. local heightLen = math.ceil(self.MapHeight / self.TileHeight);
  30. self.TileCountX = widthLen + heightLen;
  31. self.TileCountY = widthLen + heightLen;
  32. -- X轴不需要偏移,只偏移Y轴
  33. self.OffsetX = 0;
  34. self.OffsetY = heightLen;
  35. end
  36. -- 初始化地图的宽度和高度
  37. function Map:initWidthAndHeight(width, height, tileWidth, tileHeight)
  38. self.MapWidth = width;
  39. self.MapHeight = height;
  40. self.TileWidth = tileWidth;
  41. self.TileHeight = tileHeight;
  42. -- 重新计算地图
  43. self:recalculate();
  44. end
  45. -- 初始化障碍块
  46. function Map:initObstacles()
  47. self.obstacles:resize(self.TileCountX , self.TileCountY);
  48. end
  49. -- 增加一个障碍块
  50. -- x y 为逻辑坐标
  51. function Map:addObstacle(x, y)
  52. -- 如果不在地图内则添加不成功
  53. if self:isInMap(x, y) == false or self:isObstacle(x, y) then
  54. return
  55. end
  56. self.obstacles:setBlock(x , y , Map.ObstacleType.ObstacleNormal);
  57. if self.ObstacleChanged then
  58. self.ObstacleChanged(x , y , Map.ObstacleType.ObstacleNormal);
  59. end
  60. end
  61. -- 删除一个障碍块
  62. -- x y 为逻辑坐标
  63. function Map:removeObstacle(x, y)
  64. if self:isInMap(x, y) then
  65. self.obstacles:setBlock(x , y , Map.ObstacleType.ObstacleNone);
  66. if self.ObstacleChanged then
  67. self.ObstacleChanged(x , y , Map.ObstacleType.ObstacleNone);
  68. end
  69. end
  70. end
  71. -- 判断一个点是否是障碍点
  72. -- x y 为逻辑坐标
  73. function Map:isObstacle(x, y)
  74. if self:isInMap(x, y) then
  75. return self.obstacles:isBlock(x,y);
  76. end
  77. return false;
  78. end
  79. -- 根据点的坐标或者障碍数据
  80. function Map:getObstacle(x, y)
  81. if self:isInMap(x, y) == false then
  82. return 0;
  83. end
  84. return self.obstacles:getBlock(x,y);
  85. end
  86. -- 判断一个坐标点是否在地图内
  87. function Map:isInMap(x, y)
  88. if x < 0 or y < 0 then
  89. print("x or y is less 0", "current x is", x, "current y is", y);
  90. return false;
  91. end
  92. if x >= self.TileCountX or y >= self.TileCountY then
  93. print("Map:TileCountX is", self.TileCountX, " current x is", x);
  94. print("Map:TileCountY is", self.TileCountY, " current y is", y);
  95. return false;
  96. end
  97. return true;
  98. end
  99. function Map:loadFromLuaNode(luaNode)
  100. -- 初始化地图数据
  101. self:initWidthAndHeight(tonumber(luaNode.width), tonumber(luaNode.height), tonumber(luaNode.tileWidth), tonumber(luaNode.tileHeight));
  102. if luaNode.mapdata then
  103. -- 兼容老格式
  104. self.obstacles:resize(self.TileCountX , self.TileCountY);
  105. for i , v in pairs(luaNode.mapdata) do
  106. local x = math.floor((i - 1) / self.TileCountY);
  107. local y = (i - 1) % self.TileCountY;
  108. if v == 0 then
  109. self.obstacles:setBlock(x , y , 1);
  110. else
  111. self.obstacles:setBlock(x , y , 0);
  112. end
  113. end
  114. end
  115. end
  116. function Map:saveToXmlNode(xmlNode)
  117. -- 保存tile的偏移
  118. xmlNode.offsetX = self.OffsetX;
  119. xmlNode.offsetY = self.OffsetY;
  120. xmlNode.col = self.TileCountX;
  121. xmlNode.row = self.TileCountY;
  122. -- 保存地图宽高和Tile宽高
  123. xmlNode.width = self.MapWidth;
  124. xmlNode.height = self.MapHeight;
  125. xmlNode.tileWidth = self.TileWidth;
  126. xmlNode.tileHeight = self.TileHeight;
  127. -- 保存障碍块
  128. local obstaclesStr;
  129. local singleObstacleStr;
  130. -- 将障碍信息压成一个字符串
  131. for x = 0, self.TileCountX - 1 do
  132. for y = 0, self.TileCountY - 1 do
  133. local obstacle = self:getObstacle(x, y);
  134. -- 障碍信息
  135. if obstacle == 0 then
  136. singleObstacleStr = "1";
  137. else
  138. singleObstacleStr = "0";
  139. end
  140. -- 开始直接赋值,否则叠加
  141. if obstaclesStr == nil then
  142. obstaclesStr = {singleObstacleStr};
  143. else
  144. table.insert(obstaclesStr , "," .. singleObstacleStr);
  145. end
  146. end
  147. end
  148. xmlNode.mapdata = table.concat(obstaclesStr);
  149. end
  150. function Map:createXmlNode()
  151. local xmlNode = xml.new("map");
  152. self:saveToXmlNode(xmlNode);
  153. return xmlNode;
  154. end
  155. -- 保存一个地图到XML文件
  156. function Map:saveXml(fullFilePath)
  157. local xmlNode = self:createXmlNode();
  158. xmlNode:save(fullFilePath);
  159. end
  160. -- 保存一个地图到lua文件
  161. function Map:saveLua(fullFilePath)
  162. local luaNode = {}
  163. -- 保存tile的偏移
  164. luaNode.offsetX = self.OffsetX;
  165. luaNode.offsetY = self.OffsetY;
  166. luaNode.col = self.TileCountX;
  167. luaNode.row = self.TileCountY;
  168. -- 保存地图宽高和Tile宽高
  169. luaNode.width = self.MapWidth;
  170. luaNode.height = self.MapHeight;
  171. luaNode.tileWidth = self.TileWidth;
  172. luaNode.tileHeight = self.TileHeight;
  173. self.obstacles:saveToFile(fullFilePath .. ".blocks");
  174. table.saveFile(luaNode , fullFilePath);
  175. end
  176. -- 载入一个地图文件
  177. function Map:loadLua(luaFile)
  178. print("加载map:" , luaFile);
  179. local xmlFile = table.loadFile(luaFile);
  180. if xmlFile then
  181. self:loadFromLuaNode(xmlFile);
  182. if not xmlFile.mapdata then
  183. self.obstacles:loadFromFile(luaFile .. ".blocks");
  184. end
  185. end
  186. print("map 加载完成");
  187. end
  188. -- 载入一个地图文件
  189. function Map:loadXml(nodeFile)
  190. local xmlFile = loadXmlFileWithCache(nodeFile);
  191. if xmlFile then
  192. self:loadFromXmlNode(xmlFile:find("map"));
  193. end
  194. end
  195. --
  196. -- 获取45度A*单元格矩阵坐标
  197. -- @param px 目标点X坐标
  198. -- @param py 目标点Y坐标
  199. -- @return {@link Position} 矩阵点坐标
  200. function Map:getTilePosition(px, py)
  201. -- 界面坐标 计算以屏幕左上为原点的世界坐标
  202. local logicalx = px / (2 * self.TileHalfWidth) + (-py) / (2 * self.TileHalfHeight) + self.OffsetX;
  203. local logicaly = px / (2 * self.TileHalfWidth) - (-py) / (2 * self.TileHalfHeight) + self.OffsetY;
  204. return cc.p(math.floor(logicalx), math.floor(logicaly));
  205. end
  206. --
  207. -- 获取45度A*单元格矩阵坐标(不对齐到网格)
  208. -- @param px 目标点X坐标
  209. -- @param py 目标点Y坐标
  210. -- @return {@link Position} 矩阵点坐标
  211. function Map:_getTilePosition(px, py)
  212. -- 界面坐标 计算以屏幕左上为原点的世界坐标
  213. local logicalx = px / (2 * self.TileHalfWidth) + (-py) / (2 * self.TileHalfHeight) + self.OffsetX;
  214. local logicaly = px / (2 * self.TileHalfWidth) - (-py) / (2 * self.TileHalfHeight) + self.OffsetY;
  215. return cc.p(logicalx, logicaly);
  216. end
  217. --
  218. -- 获取45度A*单元格矩阵坐标转舞台从标(获得的是格子的中心点坐标)
  219. -- @param px 舞台X坐标
  220. -- @param py 舞台Y坐标
  221. -- @return {@link Position} 矩阵点坐标
  222. function Map:getPixelPosition(tileX, tileY)
  223. local nOffX = tileX - self.OffsetX;
  224. local nOffY = tileY - self.OffsetY;
  225. local positionX = nOffX * self.TileHalfWidth + nOffY * self.TileHalfWidth; -- 斜坐标 x每加1 竖坐标x+1/2 y+1/2
  226. local positionY = nOffX * self.TileHalfHeight - nOffY * self.TileHalfHeight; -- 斜坐标 y每加1 竖坐标x+1/2 y-1/2
  227. return cc.p(positionX, -positionY);
  228. end
  229. -- 载入场景文件
  230. function loadScene(nodeFile)
  231. print("加载场景" , nodeFile);
  232. TimeSpan:enterSpan("loadScene" .. nodeFile);
  233. TimeSpan:enterSpan("createNodeFromFile");
  234. print("加载模型");
  235. LoadingScene = true;
  236. local node = cc.StreamObject:loadFromFile(nodeFile);
  237. LoadingScene = false;
  238. node:setCollectAnimationClip(false);
  239. TimeSpan:leaveSpan();
  240. if not EditorMode then
  241. -- 普通模式,屏蔽掉HD内容
  242. local hd = node:findNode("HD");
  243. if hd then
  244. local function onQualityChanged(key , value)
  245. -- 高质量
  246. hd:setVisible(value == 1);
  247. end
  248. hd:bind(app.systemSetting.info , "graphicQuality" , onQualityChanged);
  249. end
  250. end
  251. -- 创建一个题图载入资源
  252. TimeSpan:enterSpan("requireMap");
  253. print("加载障碍块");
  254. local map = require("luaScript.Map.Map"):new();
  255. local arr = string.split(nodeFile, ".");
  256. map:loadLua(arr[1] .. ".lmap");
  257. TimeSpan:leaveSpan();
  258. TimeSpan:leaveSpan();
  259. return node , map;
  260. end
  261. return Map;