MyWFX.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. #if UNITY_EDITOR
  6. using UnityEditor;
  7. #endif
  8. using UnityEngine;
  9. using Utility;
  10. public class WFXMapInfo
  11. {
  12. public int x;
  13. public int y;
  14. public int px;
  15. public int py;
  16. public List<string> excludeName = new List<string>();
  17. public List<string> showName = new List<string>();
  18. public string currShowName;
  19. public List<string> huiTuiName = new List<string>();
  20. public GameObject g;
  21. }
  22. public class MyWFX : MonoBehaviour
  23. {
  24. public MapConfig MapConfig;
  25. public int w;
  26. public int h;
  27. private int[,] _indexCount;
  28. public WFXMapInfo[,] WfxMapInfos;
  29. public float xJg;
  30. public float yJg;
  31. public int startX;
  32. public int startY;
  33. public int suijiShu;
  34. // public int lasetStartX;
  35. // public int lasetStartY;
  36. // public int lasetWidth;
  37. // public int lasetHeight;
  38. public List<TileMapInfo> allMapInfo = new List<TileMapInfo>();
  39. private System.Random _random;
  40. private List<WFXMapInfo> currFindMap = new List<WFXMapInfo>();
  41. public bool isRun;
  42. private bool isHuiTui;
  43. private List<WFXMapInfo> _huiTuiMap = new List<WFXMapInfo>();
  44. public Map<int, WFXMapInfo> currAllMapName = new Map<int, WFXMapInfo>();
  45. private void Start()
  46. {
  47. StartMap();
  48. }
  49. [ContextMenu("测试生成.")]
  50. public void StartMap()
  51. {
  52. _random = new System.Random(suijiShu);
  53. WfxMapInfos = new WFXMapInfo[w, h];
  54. for (int i = 0; i < w; i++)
  55. {
  56. for (int j = 0; j < h; j++)
  57. {
  58. WfxMapInfos[i, j] = new WFXMapInfo();
  59. WfxMapInfos[i, j].x = i;
  60. WfxMapInfos[i, j].y = j;
  61. WfxMapInfos[i, j].px = i;
  62. WfxMapInfos[i, j].py = j;
  63. }
  64. }
  65. allMapInfo = MapConfig.allMapInfo;
  66. RandMap(startX, startY, "zhixian");
  67. for (int k = 0; k < allMapInfo.Count; k++)
  68. {
  69. if (allMapInfo[k].root.name.Equals("zhixian"))
  70. {
  71. WfxMapInfos[startX, startY].g = GameObject.Instantiate(allMapInfo[k].root);
  72. WfxMapInfos[startX, startY].g.transform.position = new Vector3(startX * xJg, 0, startY * yJg);
  73. break;
  74. }
  75. }
  76. _huiTuiMap.Add(WfxMapInfos[startX, startY]);
  77. StartCoroutine(ShengChengMap());
  78. }
  79. public void NewShengCheng(WFXMapInfo[,] WfxMapInfos, List<WFXMapInfo> huiTuiMap, int w, int h)
  80. {
  81. this.w = w;
  82. this.h = h;
  83. _huiTuiMap = huiTuiMap;
  84. this.WfxMapInfos = WfxMapInfos;
  85. StartCoroutine(ShengChengMap());
  86. }
  87. #if UNITY_EDITOR
  88. private void OnDrawGizmos()
  89. {
  90. if (WfxMapInfos == null)
  91. {
  92. return;
  93. }
  94. for (int i = 0; i < w; i++)
  95. {
  96. for (int j = 0; j < h; j++)
  97. {
  98. WFXMapInfo wfxMapInfo = WfxMapInfos[i, j];
  99. if (wfxMapInfo.currShowName != null)
  100. {
  101. Color color = Handles.color;
  102. Handles.color = Color.red;
  103. Handles.Label(new Vector3(wfxMapInfo.px * xJg, 0, wfxMapInfo.py * yJg),
  104. "!!" + wfxMapInfo.currShowName);
  105. Handles.color = color;
  106. }
  107. else
  108. {
  109. string data = "";
  110. for (int k = 0; k < wfxMapInfo.showName.Count; k++)
  111. {
  112. data += wfxMapInfo.showName[k] + "_";
  113. }
  114. if (string.IsNullOrEmpty(data))
  115. {
  116. data = "无";
  117. }
  118. Handles.Label(new Vector3(wfxMapInfo.px * xJg, 0, wfxMapInfo.py * yJg), data);
  119. }
  120. }
  121. }
  122. }
  123. #endif
  124. private void Update()
  125. {
  126. if (isRun)
  127. {
  128. return;
  129. }
  130. if (Input.GetMouseButtonDown(0))
  131. {
  132. StartCoroutine(ShengChengMap());
  133. }
  134. }
  135. private IEnumerator ShengChengMap()
  136. {
  137. bool isFinish = false;
  138. while (true)
  139. {
  140. isHuiTui = false;
  141. currFindMap.Clear();
  142. for (int i = 0; i < w; i++)
  143. {
  144. for (int j = 0; j < h; j++)
  145. {
  146. WFXMapInfo wfxMapInfo = WfxMapInfos[i, j];
  147. wfxMapInfo.excludeName.Clear();
  148. wfxMapInfo.showName.Clear();
  149. }
  150. }
  151. Run(0, 0);
  152. if (isHuiTui)
  153. {
  154. WFXMapInfo wfxMapInfo = _huiTuiMap[_huiTuiMap.Count - 1];
  155. Debug.Log("回退" + wfxMapInfo.x + "__" + wfxMapInfo.y);
  156. wfxMapInfo.huiTuiName.Add(wfxMapInfo.currShowName);
  157. wfxMapInfo.currShowName = null;
  158. _huiTuiMap.Remove(wfxMapInfo);
  159. continue;
  160. }
  161. bool isJx = false;
  162. WFXMapInfo minMap = null;
  163. int minCount = int.MaxValue;
  164. int lingju = int.MaxValue;
  165. for (int i = 0; i < w; i++)
  166. {
  167. for (int j = 0; j < h; j++)
  168. {
  169. WFXMapInfo wfxMapInfo = WfxMapInfos[i, j];
  170. if (string.IsNullOrEmpty(wfxMapInfo.currShowName))
  171. {
  172. isJx = true;
  173. }
  174. else
  175. {
  176. continue;
  177. }
  178. if (wfxMapInfo.showName.Count < minCount)
  179. {
  180. minMap = wfxMapInfo;
  181. minCount = wfxMapInfo.showName.Count;
  182. }
  183. }
  184. }
  185. if (!isJx)
  186. {
  187. isFinish = true;
  188. break;
  189. }
  190. if (minMap != null)
  191. {
  192. bool isOk = RandMap(minMap.x, minMap.y);
  193. if (!isOk)
  194. {
  195. if (_huiTuiMap.Count <= 0)
  196. {
  197. Debug.Log("没有有效数据生成地图");
  198. yield break;
  199. }
  200. WFXMapInfo wfxMapInfo = _huiTuiMap[_huiTuiMap.Count - 1];
  201. wfxMapInfo.huiTuiName.Add(wfxMapInfo.currShowName);
  202. wfxMapInfo.currShowName = null;
  203. continue;
  204. }
  205. else
  206. {
  207. GameObject sprite = null;
  208. for (int k = 0; k < allMapInfo.Count; k++)
  209. {
  210. if (allMapInfo[k].root.name.Equals(minMap.currShowName))
  211. {
  212. sprite = allMapInfo[k].root;
  213. break;
  214. }
  215. }
  216. // if (minMap.g == null)
  217. // {
  218. // minMap.g = new GameObject(minMap.x + "__" + minMap.y);
  219. // minMap.g.AddComponent<SpriteRenderer>();
  220. // }
  221. if (minMap.g != null)
  222. {
  223. GameObject.Destroy(minMap.g);
  224. }
  225. // SpriteRenderer spriteRenderer = minMap.g.GetComponent<SpriteRenderer>();
  226. minMap.g = GameObject.Instantiate(sprite);
  227. minMap.g.transform.position = new Vector3(minMap.px * xJg, 0, minMap.py * yJg);
  228. yield return new WaitForSeconds(0.0f);
  229. }
  230. if (!_huiTuiMap.Contains(minMap))
  231. {
  232. _huiTuiMap.Add(minMap);
  233. }
  234. else
  235. {
  236. Debug.Log("重复数据");
  237. yield break;
  238. }
  239. }
  240. if (!isRun)
  241. {
  242. break;
  243. }
  244. }
  245. if (!isFinish)
  246. {
  247. yield break;
  248. }
  249. Debug.Log("循环完成");
  250. for (int i = 0; i < w; i++)
  251. {
  252. for (int j = 0; j < h; j++)
  253. {
  254. WFXMapInfo wfxMapInfo = WfxMapInfos[i, j];
  255. int n = wfxMapInfo.px * 10000 + wfxMapInfo.py;
  256. // if (currAllMapName.TryGetValue(n,out WFXMapInfo data))
  257. // {
  258. // if (!wfxMapInfo.currShowName.Equals(data))
  259. // {
  260. // Debug.LogError("重复的地块纯在不通的名字");
  261. // }
  262. // }
  263. currAllMapName[n] = wfxMapInfo;
  264. // Sprite sprite = null;
  265. // for (int k = 0; k < allMapInfo.Count; k++)
  266. // {
  267. // if (allMapInfo[k].root.name.Equals(wfxMapInfo.currShowName))
  268. // {
  269. // sprite = allMapInfo[k].root;
  270. // break;
  271. // }
  272. // }
  273. //
  274. // GameObject g = new GameObject(i + "__" + j);
  275. // SpriteRenderer spriteRenderer = g.AddComponent<SpriteRenderer>();
  276. // spriteRenderer.sprite = sprite;
  277. // g.transform.position = new Vector3(i * xJg, j * yJg);
  278. }
  279. }
  280. }
  281. private bool RandMap(int x, int y, string defName = null)
  282. {
  283. WFXMapInfo wfxMapInfo = WfxMapInfos[x, y];
  284. List<TileMapInfo> currUseMap = new List<TileMapInfo>();
  285. int allOdd = 0;
  286. for (int i = 0; i < allMapInfo.Count; i++)
  287. {
  288. TileMapInfo tileMapInfo = allMapInfo[i];
  289. if (wfxMapInfo.excludeName.Contains(tileMapInfo.root.name))
  290. {
  291. continue;
  292. }
  293. if (wfxMapInfo.huiTuiName.Contains(tileMapInfo.root.name))
  294. {
  295. continue;
  296. }
  297. allOdd += tileMapInfo.gailu;
  298. currUseMap.Add(tileMapInfo);
  299. }
  300. if (currUseMap.Count <= 0)
  301. {
  302. return false;
  303. }
  304. if (string.IsNullOrEmpty(defName))
  305. {
  306. int odds = _random.Next(0, allOdd);
  307. int currOdds = 0;
  308. for (int i = 0; i < currUseMap.Count; i++)
  309. {
  310. currOdds += currUseMap[i].gailu;
  311. if (odds <= currOdds)
  312. {
  313. wfxMapInfo.currShowName = currUseMap[i].root.name;
  314. return true;
  315. }
  316. // else if(i!=0)
  317. // {
  318. //
  319. // }
  320. }
  321. // int index = _random.Next(0, currUseMap.Count);
  322. }
  323. else
  324. {
  325. wfxMapInfo.currShowName = defName;
  326. }
  327. return true;
  328. }
  329. private void Run(int x, int y)
  330. {
  331. if (isHuiTui)
  332. {
  333. return;
  334. }
  335. WFXMapInfo wfxMapInfo = WfxMapInfos[x, y];
  336. if (currFindMap.Contains(wfxMapInfo))
  337. {
  338. return;
  339. }
  340. currFindMap.Add(wfxMapInfo);
  341. string xianZhiName = wfxMapInfo.currShowName;
  342. List<TileMapInfo> allName = new List<TileMapInfo>();
  343. if (!string.IsNullOrEmpty(xianZhiName))
  344. {
  345. for (int i = 0; i < allMapInfo.Count; i++)
  346. {
  347. TileMapInfo tileMapInfo = allMapInfo[i];
  348. if (xianZhiName.Equals(tileMapInfo.root.name))
  349. {
  350. allName.Add(tileMapInfo);
  351. }
  352. }
  353. }
  354. else
  355. {
  356. if (wfxMapInfo.excludeName.Count > 0)
  357. {
  358. for (int i = 0; i < allMapInfo.Count; i++)
  359. {
  360. TileMapInfo tileMapInfo = allMapInfo[i];
  361. if (wfxMapInfo.excludeName.Contains(tileMapInfo.root.name))
  362. {
  363. continue;
  364. }
  365. allName.Add(tileMapInfo);
  366. }
  367. }
  368. else
  369. {
  370. allName.AddRange(allMapInfo);
  371. }
  372. }
  373. bool isOk1 = SetHind(x - 1, y, allName, 0);
  374. bool isOk2 = SetHind(x + 1, y, allName, 1);
  375. bool isOk3 = SetHind(x, y + 1, allName, 2);
  376. bool isOk4 = SetHind(x, y - 1, allName, 3);
  377. if (!isOk1 || !isOk2 || !isOk3 || !isOk4)
  378. {
  379. isHuiTui = true;
  380. }
  381. }
  382. private bool SetHind(int x, int y, List<TileMapInfo> allName, int type)
  383. {
  384. if (x < 0 || x >= w || y < 0 || y >= h)
  385. {
  386. return true;
  387. }
  388. WFXMapInfo wfxMapInfo = WfxMapInfos[x, y];
  389. if (string.IsNullOrEmpty(wfxMapInfo.currShowName))
  390. {
  391. {
  392. List<string> showName = new List<string>();
  393. // for (int i = 0; i < allName.Count; i++)
  394. {
  395. for (int j = 0; j < allName.Count; j++)
  396. {
  397. List<GameObject> showSprite = null;
  398. switch (type)
  399. {
  400. case 0: //左
  401. showSprite = allName[j].zuo;
  402. break;
  403. case 1: //右
  404. showSprite = allName[j].you;
  405. break;
  406. case 2: //上
  407. showSprite = allName[j].shang;
  408. break;
  409. case 3: //下
  410. showSprite = allName[j].xia;
  411. break;
  412. }
  413. for (int k = 0; k < showSprite.Count; k++)
  414. {
  415. if (wfxMapInfo.excludeName.Contains(showSprite[k].name))
  416. {
  417. continue;
  418. }
  419. if (wfxMapInfo.huiTuiName.Contains(showSprite[k].name))
  420. {
  421. continue;
  422. }
  423. if (showName.Contains(showSprite[k].name))
  424. {
  425. continue;
  426. }
  427. showName.Add(showSprite[k].name);
  428. }
  429. }
  430. }
  431. for (int i = 0; i < allMapInfo.Count; i++)
  432. {
  433. TileMapInfo tileMapInfo = allMapInfo[i];
  434. if (wfxMapInfo.excludeName.Contains(tileMapInfo.root.name))
  435. {
  436. continue;
  437. }
  438. if (showName.Contains(tileMapInfo.root.name))
  439. {
  440. continue;
  441. }
  442. wfxMapInfo.excludeName.Add(tileMapInfo.root.name);
  443. if (wfxMapInfo.showName.Contains(tileMapInfo.root.name))
  444. {
  445. wfxMapInfo.showName.Remove(tileMapInfo.root.name);
  446. }
  447. }
  448. if (showName.Count <= 0 && string.IsNullOrEmpty(wfxMapInfo.currShowName))
  449. {
  450. Debug.Log("没有可选的图" + x + "___" + y + "___" + type);
  451. return false;
  452. }
  453. for (int i = 0; i < showName.Count; i++)
  454. {
  455. if (!wfxMapInfo.showName.Contains(showName[i]))
  456. {
  457. wfxMapInfo.showName.Remove(showName[i]);
  458. }
  459. }
  460. wfxMapInfo.showName = showName;
  461. }
  462. }
  463. Run(x, y);
  464. return true;
  465. }
  466. }