index.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Your Electron App</title>
  5. <style>
  6. #nav {
  7. /* 导航栏样式 */
  8. }
  9. #content {
  10. /* 内容区样式 */
  11. }
  12. #level-list {
  13. width: 200px;
  14. float: left;
  15. }
  16. #level-details {
  17. margin-left: 210px;
  18. }
  19. </style>
  20. </head>
  21. <body>
  22. <div id="nav">
  23. <button id="levels">关卡</button>
  24. <button id="examples">实例</button>
  25. <button id="templates">模板</button>
  26. </div>
  27. <div id="content">
  28. <!-- 动态内容 -->
  29. </div>
  30. <script>
  31. var levels = null;
  32. var instances = null;
  33. var templateFNs = null;
  34. function getInstanceByName(name) {
  35. for (let i = 0; i < instances.length; i++) {
  36. if (instances[i].lvinst == name) {
  37. return instances[i];
  38. }
  39. }
  40. return null;
  41. }
  42. function getTemplateByName(name) {
  43. for (let i = 0; i < templateFNs.length; i++) {
  44. if (templateFNs[i] == name) {
  45. return templateFNs[i];
  46. }
  47. }
  48. return null;
  49. }
  50. function getAllLvIdsByInstName(name) {
  51. // 返回所有用到了该实例的关卡的id
  52. const ids = [];
  53. for (let i = 0; i < levels.length; i++) {
  54. if (levels[i].lvinst == name) {
  55. ids.push(levels[i].lvid);
  56. }
  57. }
  58. return ids;
  59. }
  60. function showInstanceInfoAt(div, inst) {
  61. // 将其显示在页面上,其中template应该是一个下拉框
  62. // try1-10应该是一个表格, 表格的头部应该是:尝试次数,瓦片数,种子,参数模板,表格里面的每个值是可以编辑的
  63. div.innerHTML = `
  64. <h2>实例名: ${inst.lvinst}</h2>
  65. `;
  66. // 显示所有用到了该实例的关卡
  67. const lvIds = getAllLvIdsByInstName(inst.lvinst);
  68. div.innerHTML += `
  69. <p>用到了该实例的关卡: ${lvIds}</p>
  70. `;
  71. // 加入 template 下拉框
  72. div.innerHTML += `
  73. <p>模板名称: </p>
  74. `;
  75. const templateSelect = document.createElement('select');
  76. templateSelect.id = 'template-select';
  77. templateFNs.forEach(fn => {
  78. const option = document.createElement('option');
  79. option.value = fn;
  80. option.textContent = fn;
  81. if (fn == inst.template) {
  82. option.selected = true;
  83. }
  84. templateSelect.appendChild(option);
  85. });
  86. div.appendChild(templateSelect);
  87. // 加入表格
  88. const table = document.createElement('table');
  89. const thead = document.createElement('thead');
  90. const tbody = document.createElement('tbody');
  91. const tr = document.createElement('tr');
  92. const th1 = document.createElement('th');
  93. const th2 = document.createElement('th');
  94. const th3 = document.createElement('th');
  95. const th4 = document.createElement('th');
  96. th1.textContent = '尝试次数';
  97. th2.textContent = '瓦片数';
  98. th3.textContent = '种子';
  99. th4.textContent = '参数模板';
  100. tr.appendChild(th1);
  101. tr.appendChild(th2);
  102. tr.appendChild(th3);
  103. tr.appendChild(th4);
  104. thead.appendChild(tr);
  105. table.appendChild(thead);
  106. table.appendChild(tbody);
  107. div.appendChild(table);
  108. // 加入表格内容
  109. for (let i = 1; i <= 10; i++) {
  110. var trynParams = inst['try' + i + '(tileCnt|seed|param_template)'].split('|');
  111. const tr = document.createElement('tr');
  112. const td1 = document.createElement('td');
  113. const td2 = document.createElement('td');
  114. const td3 = document.createElement('td');
  115. const td4 = document.createElement('td');
  116. const input1 = document.createElement('input');
  117. const input2 = document.createElement('input');
  118. const input3 = document.createElement('input');
  119. const input4 = document.createElement('input');
  120. input1.type = 'text';
  121. input1.value = trynParams[0];
  122. input2.type = 'text';
  123. input2.value = trynParams[1];
  124. input3.type = 'text';
  125. input3.value = trynParams[2];
  126. td1.textContent = i;
  127. td2.appendChild(input1);
  128. td3.appendChild(input2);
  129. td4.appendChild(input3);
  130. tr.appendChild(td1);
  131. tr.appendChild(td2);
  132. tr.appendChild(td3);
  133. tr.appendChild(td4);
  134. tbody.appendChild(tr);
  135. }
  136. // 增加一个按钮,点击后可以保存
  137. const saveButton = document.createElement('button');
  138. saveButton.id = 'save-instance-button';
  139. saveButton.textContent = '保存';
  140. div.appendChild(saveButton);
  141. saveButton.addEventListener('click', () => {
  142. // 保存实例信息
  143. });
  144. }
  145. function showTemplateInfoAt(div, templateInfo) {
  146. }
  147. function initData() {
  148. // 读取关卡信息并填充到页面
  149. if (levels == null) {
  150. window.electron.send('parse-csv', '../../conf/levelInfo.csv')
  151. window.electron.receive('csv-data', (data) => {
  152. if (levels == null) {
  153. levels = data;
  154. window.electron.send('parse-csv', '../../conf/levelInstInfo.csv')
  155. } else {
  156. if (instances == null) {
  157. instances = data
  158. }
  159. }
  160. });
  161. }
  162. if (templateFNs == null) {
  163. window.electron.send('get-file-list', '../../tf_templates')
  164. window.electron.receive('file-list-error', (data) => {
  165. console.error('Error reading directory: ', err);
  166. });
  167. window.electron.receive('file-list-data', (data) => {
  168. // 过滤掉非 .json 后缀的文件
  169. templateFNs = [];
  170. for (let i = 0; i < data.length; i++) {
  171. if (data[i].endsWith('.json')) {
  172. templateFNs.push(data[i]);
  173. }
  174. }
  175. });
  176. }
  177. //
  178. }
  179. // 创建一个新实例,并将其关联到指定的关卡中
  180. function addNewInst(level, instDetails) {
  181. // 获取实例名称
  182. window.electron.send('open-newinst-prompt', 'some data');
  183. window.electron.receive('prompt-newinst-reply', (event, arg) => {
  184. const instName = arg;
  185. // 检查是否已经存在
  186. for (let i = 0; i < instances.length; i++) {
  187. if (instances[i].lvinst == instName) {
  188. alert('实例已经存在');
  189. return;
  190. }
  191. }
  192. // 不存在则加入
  193. const inst = {
  194. lvinst: instName,
  195. template: '',
  196. 'try1(tileCnt|seed|param_template)': '0|0|0',
  197. 'try2(tileCnt|seed|param_template)': '0|0|0',
  198. 'try3(tileCnt|seed|param_template)': '0|0|0',
  199. 'try4(tileCnt|seed|param_template)': '0|0|0',
  200. 'try5(tileCnt|seed|param_template)': '0|0|0',
  201. 'try6(tileCnt|seed|param_template)': '0|0|0',
  202. 'try7(tileCnt|seed|param_template)': '0|0|0',
  203. 'try8(tileCnt|seed|param_template)': '0|0|0',
  204. 'try9(tileCnt|seed|param_template)': '0|0|0',
  205. 'try10(tileCnt|seed|param_template)': '0|0|0'
  206. };
  207. instances.push(inst);
  208. showInstanceInfoAt(instDetails, inst);
  209. });
  210. }
  211. function saveLvInfo(lvDetails) {
  212. // 保存关卡的详细信息
  213. }
  214. function fillLvInfo() {
  215. // 读取关卡信息并填充到页面
  216. if (levels != null) {
  217. const levelList = document.getElementById('level-list');
  218. const levelDetails = document.getElementById('level-details');
  219. const instDetails = document.getElementById('instance-details');
  220. const templateDetails = document.getElementById('tempalte-details');
  221. // 将levels里面的信息填充到页面
  222. levels.forEach(level => {
  223. const listItem = document.createElement('li');
  224. listItem.textContent = level.lvid;
  225. listItem.addEventListener('click', () => {
  226. // 将选中的关卡id条目的背景颜色设置为蓝色
  227. Array.from(levelList.children).forEach(node => {
  228. if (node.textContent == level.lvid) {
  229. node.style.backgroundColor = 'lightblue';
  230. } else {
  231. node.style.backgroundColor = 'white';
  232. }
  233. });
  234. levelDetails.innerHTML = `
  235. <h2>关卡ID: ${level.lvid}</h2>
  236. <p>关卡实例名称: ${level.lvinst}</p>`
  237. //
  238. if (level.lvinst == '') {
  239. // 实例不存在,
  240. // 显示一个下来列表,选择实例
  241. const instSelect = document.createElement('select');
  242. instSelect.id = 'inst-select';
  243. instances.forEach(inst => {
  244. const option = document.createElement('option');
  245. option.value = inst.lvinst;
  246. option.textContent = inst.lvinst;
  247. instSelect.appendChild(option);
  248. });
  249. levelDetails.appendChild(instSelect);
  250. }
  251. // 加入一个按钮,点击后可以创建实例
  252. const createInstButton = document.createElement('button');
  253. createInstButton.id = 'create-instance-button';
  254. createInstButton.textContent = '创建新的实例';
  255. levelDetails.appendChild(createInstButton);
  256. // createInstButton.addEventListener('click', () => {
  257. // addNewInst(level);
  258. // });
  259. console.log(createInstButton.onclick);
  260. // 增加一个下拉框,选择类型:normal,hard,super-hard
  261. const typeSelect = document.createElement('select');
  262. typeSelect.id = 'type-select';
  263. const normalOption = document.createElement('option');
  264. normalOption.value = 'normal';
  265. normalOption.textContent = 'normal';
  266. const hardOption = document.createElement('option');
  267. hardOption.value = 'hard';
  268. hardOption.textContent = 'hard';
  269. const superHardOption = document.createElement('option');
  270. superHardOption.value = 'super-hard';
  271. superHardOption.textContent = 'super-hard';
  272. typeSelect.appendChild(normalOption);
  273. typeSelect.appendChild(hardOption);
  274. typeSelect.appendChild(superHardOption);
  275. levelDetails.innerHTML += `
  276. <p>关卡难度级别:</p>`
  277. levelDetails.appendChild(typeSelect);
  278. // 如果 type(normal=0,hard=1,superHard=2)
  279. type = level[2];
  280. if (type == 0) {
  281. normalOption.selected = true;
  282. } else if (type == 1) {
  283. hardOption.selected = true;
  284. } else if (type == 2) {
  285. superHardOption.selected = true;
  286. }
  287. // 显示dda类型和参数
  288. levelDetails.innerHTML +=
  289. `
  290. <p>DDA类型: ${level.dda_type}</p>
  291. <p>DDA参数: ${level.dda_para}</p>
  292. `;
  293. // 增加一个按钮,点击后可以保存
  294. const saveButton = document.createElement('button');
  295. saveButton.id = 'save-lv-button';
  296. saveButton.textContent = '保存';
  297. levelDetails.appendChild(saveButton);
  298. levelDetails.addEventListener('click', (event) => {
  299. if (event.target.id === 'create-instance-button') {
  300. addNewInst(level, instDetails);
  301. } else if (event.target.id === 'save-lv-button') {
  302. saveLvInfo(levelDetails);
  303. }
  304. });
  305. // 显示实例信息
  306. const inst = getInstanceByName(level.lvinst);
  307. if (inst != null) {
  308. showInstanceInfoAt(instDetails, inst);
  309. // 显示模板信息
  310. const template = getTemplateByName(inst.template);
  311. if (template != null) {
  312. showTemplateInfoAt(templateDetails, getTemplateByName(inst.template));
  313. }
  314. } else {
  315. instDetails.innerHTML = `
  316. <h2>实例名: Error:未定义</h2>
  317. `
  318. }
  319. });
  320. levelList.appendChild(listItem);
  321. });
  322. }
  323. }
  324. function fillInstanceInfo() {
  325. // 读取关卡信息并填充到页面
  326. if (instances != null) {
  327. const lst = document.getElementById('instance-list');
  328. const details = document.getElementById('instance-details');
  329. // 将levels里面的信息填充到页面
  330. instances.forEach(inst => {
  331. const listItem = document.createElement('li');
  332. listItem.textContent = inst.lvinst;
  333. listItem.addEventListener('click', () => {
  334. showInstanceInfoAt(details, inst)
  335. });
  336. lst.appendChild(listItem);
  337. });
  338. }
  339. }
  340. function fillTemplateInfo() {
  341. if (templateFNs != null) {
  342. const lst = document.getElementById('template-list');
  343. const details = document.getElementById('template-details');
  344. // 将levels里面的信息填充到页面
  345. templateFNs.forEach(fn => {
  346. const listItem = document.createElement('li');
  347. listItem.textContent = fn;
  348. listItem.addEventListener('click', () => {
  349. // 放入截图
  350. });
  351. lst.appendChild(listItem);
  352. });
  353. }
  354. }
  355. document.getElementById('levels').addEventListener('click', function() {
  356. fetch('level.html')
  357. .then(response => response.text())
  358. .then(data => {
  359. document.getElementById('content').innerHTML = data;
  360. fillLvInfo();
  361. // 绑定新增关卡按钮
  362. document.getElementById('add-level-button').addEventListener('click', function() {
  363. window.electron.send('open-newlv-prompt', 'some data')
  364. window.electron.receive('prompt-newlv-reply', (event, arg) => {
  365. const lvid = arg;
  366. // 检查是否已经存在
  367. for (let i = 0; i < levels.length; i++) {
  368. if (levels[i].lvid == lvid) {
  369. alert('关卡id已经存在');
  370. return;
  371. }
  372. }
  373. // 不存在则加入
  374. const level = {
  375. lvid: lvid,
  376. lvinst: '',
  377. type: 0,
  378. dda_type: '0',
  379. dda_para: '0|10000'
  380. };
  381. levels.push(level);
  382. // 刷新页面
  383. fillLvInfo();
  384. // 选中该关卡
  385. const levelList = document.getElementById('level-list');
  386. levelList.childNodes.forEach(node => {
  387. if (node.textContent == lvid) {
  388. node.click();
  389. }
  390. });
  391. })
  392. });
  393. })
  394. .catch(error => {
  395. console.error('Error loading the levels content:', error);
  396. });
  397. });
  398. document.getElementById('examples').addEventListener('click', function() {
  399. fetch('instance.html')
  400. .then(response => response.text())
  401. .then(data => {
  402. document.getElementById('content').innerHTML = data;
  403. fillInstanceInfo();
  404. })
  405. .catch(error => {
  406. console.error('Error loading the intance content:', error);
  407. });
  408. });
  409. document.getElementById('templates').addEventListener('click', function() {
  410. fetch('template.html')
  411. .then(response => response.text())
  412. .then(data => {
  413. document.getElementById('content').innerHTML = data;
  414. fillTemplateInfo();
  415. })
  416. .catch(error => {
  417. console.error('Error loading the intance content:', error);
  418. });
  419. });
  420. // 初始化数据
  421. initData();
  422. </script>
  423. </body>
  424. </html>