123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 |
- <!DOCTYPE html>
- <html>
- <head>
- <title>Your Electron App</title>
- <style>
- #nav {
- /* 导航栏样式 */
- }
- #content {
- /* 内容区样式 */
- }
- #level-list {
- width: 200px;
- float: left;
- }
- #level-details {
- margin-left: 210px;
- }
- </style>
- </head>
- <body>
- <div id="hdr" style="background-color: antiquewhite; margin-bottom: 20px;">
- <input type="text" id="group-suffix" placeholder="分组文件的后缀">
- <button id="load_grp">加载分组信息</button>
- </div>
- <div id="panels-area" style="display: flex; height: 95vh;">
- <div id="nav" style="overflow-y: scroll; height: 90%; width: 5%; background-color: coral;">
- <ul>
- <li>
- <button id="levels" style="margin-top: 10px;">关卡</button>
- </li>
- <li>
- <button id="examples" style="margin-top: 10px;">实例</button>
- </li>
- <li>
- <button id="templates"style="margin-top: 10px;">模板</button>
- </li>
- </ul>
- </div>
- <div id="content" style="overflow-y: scroll; height: 90%; width: 85%; background-color: beige;">
- <!-- 动态内容 -->
- </div>
- </div>
- <script>
- var levels = null;
- var instances = null;
- var templateFNs = null;
- var templateFNsByDir = null;
- function getInstanceByName(name) {
- for (let i = 0; i < instances.length; i++) {
- if (instances[i].lvinst == name) {
- return instances[i];
- }
- }
- return null;
- }
- function getTemplateByName(name) {
- for (let i = 0; i < templateFNs.length; i++) {
- if (templateFNs[i] == name) {
- return templateFNs[i];
- }
- }
- return null;
- }
- function getAllLvIdsByInstName(name) {
- // 返回所有用到了该实例的关卡的id
- const ids = [];
- for (let i = 0; i < levels.length; i++) {
- if (levels[i].lvinst == name) {
- ids.push(levels[i].lvid);
- }
- }
- return ids;
- }
- function saveInst(div, inst) {
- // 从 div中获取实例信息
- const instName = div.querySelector('#instid-in-inst-detail').textContent.split(':')[1].trim();
- var inst = null;
- for (let i = 0; i < instances.length; i++) {
- if (instances[i].lvinst == instName) {
- inst = instances[i];
- break;
- }
- }
- if (inst == null) {
- alert('实例不存在');
- return;
- }
- inst['template'] = div.querySelector('#template-select').value;
- for (let i = 1; i <= 10; i++) {
- const tileCnt = div.querySelector('#try' + i + '_tileCnt').value;
- const seed = div.querySelector('#try' + i + '_seed').value;
- const param_template = div.querySelector('#try' + i + '_param_template').value;
- const trynParams = tileCnt + '|' + seed + '|' + param_template;
- inst['try' + i + '(tileCnt|seed|param_template)'] = trynParams;
- }
- window.electron.send('save2csv', '../../conf/levelInstInfo.csv', instances);
- }
- function showInstanceInfoAt(div, inst) {
- // 将其显示在页面上,其中template应该是一个下拉框
- // try1-10应该是一个表格, 表格的头部应该是:尝试次数,瓦片数,种子,参数模板,表格里面的每个值是可以编辑的
- div.innerHTML = `
- <h2 id='instid-in-inst-detail'>实例名: ${inst.lvinst}</h2>
- `;
- // 显示所有用到了该实例的关卡
- const lvIds = getAllLvIdsByInstName(inst.lvinst);
- div.innerHTML += `
- <p style="display: inline;">用到了该实例的关卡: ${lvIds}</p>
- `;
- // 加入 template 下拉框
- {
- var div1 = document.createElement('div');
- const p = document.createElement('p');
- p.style.display = 'inline';
- p.appendChild(document.createTextNode('模板名称: '));
- div1.appendChild(p);
- const templateSelect = document.createElement('select');
- templateSelect.id = 'template-select';
- templateFNs.forEach(fn => {
- const option = document.createElement('option');
- option.value = fn;
- option.textContent = fn;
- if (fn == inst.template) {
- option.selected = true;
- }
- templateSelect.appendChild(option);
- });
- div1.appendChild(templateSelect);
- // 增加一个编辑模板的按钮
- const editTemplateButton = document.createElement('button');
- editTemplateButton.id = 'edit-template-button';
- editTemplateButton.textContent = '编辑模板';
- editTemplateButton.style.marginLeft = '10px';
- editTemplateButton.addEventListener('click', () => {
- // 获取当前的模板名称
- const templateName = document.getElementById('template-select').value;
- // 判断模板是在哪个目录下
- for (let dir in templateFNsByDir) {
- if (templateFNsByDir[dir].has(templateName)) {
- window.electron.send('open-app', dir, '/Applications/Tiled.app/Contents/MacOS/Tiled ' + dir + '/' + inst.template + '.json');
- return;
- }
- }
- });
- div1.appendChild(editTemplateButton);
- // 增加一个复制模板的按钮
- const copyTemplateButton = document.createElement('button');
- copyTemplateButton.id = 'copy-template-button';
- copyTemplateButton.textContent = '复制模板';
- copyTemplateButton.style.marginLeft = '10px';
- copyTemplateButton.addEventListener('click', () => {
- // 获取当前的实例
- const inst = getInstanceByName(document.getElementById('instid-in-inst-detail').textContent.split(':')[1].trim());
- if (inst.template == "") {
- // 取options里面当前显示的值
- inst.template = document.getElementById('template-select').value;
- }
- var path = "";
- for (let dir in templateFNsByDir) {
- if (templateFNsByDir[dir].has(inst.template)) {
- path = dir + '/' + inst.template + '.json';
- break;
- }
- }
- window.electron.send('copy-template', path);
- });
- div1.appendChild(copyTemplateButton);
- div.appendChild(div1);
- }
- // 加入表格
- const table = document.createElement('table');
- const thead = document.createElement('thead');
- const tbody = document.createElement('tbody');
- const tr = document.createElement('tr');
- const th1 = document.createElement('th');
- const th2 = document.createElement('th');
- const th3 = document.createElement('th');
- const th4 = document.createElement('th');
- th1.textContent = '尝试次数';
- th2.textContent = '瓦片数';
- th3.textContent = '种子';
- th4.textContent = '参数模板';
- tr.appendChild(th1);
- tr.appendChild(th2);
- tr.appendChild(th3);
- tr.appendChild(th4);
- thead.appendChild(tr);
- table.appendChild(thead);
- table.appendChild(tbody);
- div.appendChild(table);
- // 加入表格内容
- for (let i = 1; i <= 10; i++) {
- var trynParams = inst['try' + i + '(tileCnt|seed|param_template)'].split('|');
- const tr = document.createElement('tr');
- const td1 = document.createElement('td');
- const td2 = document.createElement('td');
- const td3 = document.createElement('td');
- const td4 = document.createElement('td');
- const input1 = document.createElement('input');
- const input2 = document.createElement('input');
- const input3 = document.createElement('input');
- const input4 = document.createElement('input');
- input1.type = 'text';
- input1.value = trynParams[0];
- input1.id = 'try' + i + '_tileCnt';
- input2.type = 'text';
- input2.value = trynParams[1];
- input2.id = 'try' + i + '_seed';
- input3.type = 'text';
- input3.value = trynParams[2];
- input3.id = 'try' + i + '_param_template';
- td1.textContent = i;
- td2.appendChild(input1);
- td3.appendChild(input2);
- td4.appendChild(input3);
- tr.appendChild(td1);
- tr.appendChild(td2);
- tr.appendChild(td3);
- tr.appendChild(td4);
- tbody.appendChild(tr);
- }
- // 增加一个按钮,点击后可以保存
- const saveButton = document.createElement('button');
- saveButton.id = 'save-instance-button';
- saveButton.textContent = '保存';
- div.appendChild(saveButton);
- saveButton.addEventListener('click', () => {
- // 保存实例信息
- saveInst(div, inst);
- });
- }
- function showTemplateInfoAt(div, templateInfo) {
-
- }
- // 过滤实例列表
- function filterInstance() {
- // 获取输入框的值
- var filter = document.getElementById('instance-filter').value;
- // 获取实例列表
- var list = document.getElementById('instance-list').getElementsByTagName('li');
- // 遍历实例列表
- for (var i = 0; i < list.length; i++) {
- // 获取实例的名字
- var name = list[i].innerHTML;
- // 如果实例的名字包含输入框的值,显示实例
- if (name.indexOf(filter) > -1) {
- list[i].style.display = '';
- } else {
- // 否则隐藏实例
- list[i].style.display = 'none';
- }
- }
- }
- function initData(suffix) {
- // 读取关卡信息并填充到页面
- if (levels == null) {
- window.electron.send('parse-csv', '../../conf/levelInfo'+suffix+'.csv')
- window.electron.receive('csv-data', (data) => {
- if (levels == null) {
- levels = data;
- window.electron.send('parse-csv', '../../conf/levelInstInfo'+suffix+'.csv')
- } else {
- if (instances == null) {
- instances = data
- }
- }
- });
- }
- if (templateFNs == null) {
- templateFNs = [];
- templateFNsByDir = {};
- window.electron.send('get-file-list', '../../tf_templates;../../miniGame')
- window.electron.receive('file-list-error', (data) => {
- console.error('Error reading directory: ', err);
- });
- window.electron.receive('file-list-data', (data, path) => {
- templateFNsByDir[path] = new Set();
- // 过滤掉非 .json 后缀的文件
- for (let i = 0; i < data.length; i++) {
- if (data[i].endsWith('.json')) {
- // 去掉后缀
- const name = data[i].substring(0, data[i].length - 5);
- templateFNs.push(name);
- templateFNsByDir[path].add(name);
- }
- }
- });
- }
- //
- }
- // 创建一个新实例,并将其关联到指定的关卡中
- function addNewInst(level) {
- const instDetails = document.getElementById('instance-details');
- // 获取实例名称
- window.electron.send('open-newinst-prompt', 'some data');
- }
- function saveLvInfo() {
- const lvDetails = document.getElementById('level-details');
- // 保存关卡的详细信息
- const lvid = lvDetails.querySelector('#lvid-in-lvdetails').textContent.split(':')[1].trim();
- const instid = lvDetails.querySelector('#inst-select').value;
- const type = lvDetails.querySelector('#type-select-in-lvdetails').value;
- const ddaType = lvDetails.querySelector('#ddatype-in-lvdetails').textContent.split(':')[1].trim();
- const ddaPara = lvDetails.querySelector('#ddapara-in-lvdetails').textContent.split(':')[1].trim();
- var lv = null;
- for (let i = 0; i < levels.length; i++) {
- if (levels[i].lvid == lvid) {
- lv = levels[i];
- break;
- }
- }
- lv['lvinst'] = instid;
- lv['type(normal=0,hard=1,superHard=2)'] = type;
- lv['dda_type'] = ddaType;
- lv['dda_para'] = ddaPara;
- // 保存到文件
- window.electron.send('save2csv', '../../conf/levelInfo.csv', levels);
- }
- function fillLvInfo() {
- // 读取关卡信息并填充到页面
- if (levels != null) {
- const levelList = document.getElementById('level-list');
- const levelDetails = document.getElementById('level-details');
- const instDetails = document.getElementById('instance-details');
- const templateDetails = document.getElementById('tempalte-details');
-
- // 先清空
- levelList.innerHTML = '';
- // 将levels里面的信息填充到页面
- levels.forEach(level => {
- const listItem = document.createElement('li');
- listItem.textContent = level.lvid;
- listItem.addEventListener('click', () => {
- // 将选中的关卡id条目的背景颜色设置为蓝色
- Array.from(levelList.children).forEach(node => {
- if (node.textContent == level.lvid) {
- node.style.backgroundColor = 'lightblue';
- } else {
- node.style.backgroundColor = 'white';
- }
- });
- levelDetails.innerHTML = `
- <h2 id='lvid-in-lvdetails'>关卡ID: ${level.lvid}</h2>`
- // 关卡实例名称
- {
- const div = document.createElement('div');
- const p = document.createElement('p');
- p.style.display = 'inline';
- p.appendChild(document.createTextNode('关卡实例名称: '));
- div.appendChild(p);
-
- // 显示一个下来列表,选择实例
- const instSelect = document.createElement('select');
- instSelect.id = 'inst-select';
- instances.forEach(inst => {
- const option = document.createElement('option');
- option.value = inst.lvinst;
- option.textContent = inst.lvinst;
- if (inst.lvinst == level.lvinst) {
- option.selected = true;
- }
- instSelect.appendChild(option);
- });
- div.appendChild(instSelect);
- levelDetails.appendChild(div);
- }
- // 加入一个按钮,点击后可以创建实例
- {
- const div = document.createElement('div');
- const createInstButton = document.createElement('button');
- createInstButton.id = 'create-instance-button';
- createInstButton.textContent = '创建新的实例';
- createInstButton.style.marginBottom = '15px';
- div.appendChild(createInstButton);
- levelDetails.appendChild(div);
- // createInstButton.addEventListener('click', () => {
- // addNewInst(level);
- // });
- }
- {
- const div = document.createElement('div');
- // 增加一个下拉框,选择类型:normal,hard,super-hard
- const type = level['type(normal=0,hard=1,superHard=2)'];
- const typeSelect = document.createElement('select');
- typeSelect.id = 'type-select-in-lvdetails';
- const normalOption = document.createElement('option');
- normalOption.value = '0';
- normalOption.textContent = 'normal';
- normalOption.selected = type == '0';
- const hardOption = document.createElement('option');
- hardOption.value = '1';
- hardOption.textContent = 'hard';
- hardOption.selected = type == '1';
- const superHardOption = document.createElement('option');
- superHardOption.value = '2';
- superHardOption.textContent = 'super-hard';
- superHardOption.selected = type == '2';
- typeSelect.appendChild(normalOption);
- typeSelect.appendChild(hardOption);
- typeSelect.appendChild(superHardOption);
- const p = document.createElement('p');
- p.style.display = 'inline';
- p.appendChild(document.createTextNode('关卡难度级别:'));
- div.appendChild(p);
- div.appendChild(typeSelect);
- levelDetails.appendChild(div);
- }
-
- // 显示dda类型和参数
- const ddatype = document.createElement('p');
- ddatype.id = 'ddatype-in-lvdetails';
- ddatype.textContent = 'DDA类型: ' + level.dda_type;
- levelDetails.appendChild(ddatype);
- const ddapara = document.createElement('p');
- ddapara.id = 'ddapara-in-lvdetails';
- ddapara.textContent = 'DDA参数: ' + level.dda_para;
- levelDetails.appendChild(ddapara);
- // 增加一个按钮,点击后可以保存
- const saveButton = document.createElement('button');
- saveButton.id = 'save-lv-button';
- saveButton.textContent = '保存';
- levelDetails.appendChild(saveButton);
- levelDetails.addEventListener('click', (event) => {
- if (event.target.id === 'create-instance-button') {
- addNewInst(level);
- } else if (event.target.id === 'save-lv-button') {
- saveLvInfo();
- }
- });
- // 显示实例信息
- const inst = getInstanceByName(level.lvinst);
- if (inst != null) {
- showInstanceInfoAt(instDetails, inst);
- // 显示模板信息
- const template = getTemplateByName(inst.template);
- if (template != null) {
- showTemplateInfoAt(templateDetails, getTemplateByName(inst.template));
- }
- } else {
- instDetails.innerHTML = `
- <h2>实例名: Error:未定义</h2>
- `
- }
- });
- levelList.appendChild(listItem);
- });
- }
- }
- function fillInstanceInfo() {
- // 读取关卡信息并填充到页面
- if (instances != null) {
- const lst = document.getElementById('instance-list');
- const details = document.getElementById('instance-details');
- // 将levels里面的信息填充到页面
- instances.forEach(inst => {
- const listItem = document.createElement('li');
- listItem.textContent = inst.lvinst;
- listItem.addEventListener('click', () => {
- showInstanceInfoAt(details, inst)
- });
- lst.appendChild(listItem);
- });
- }
- }
- function fillTemplateInfo() {
- if (templateFNs != null) {
- const lst = document.getElementById('template-list');
- const details = document.getElementById('template-details');
- // 将levels里面的信息填充到页面
- templateFNs.forEach(fn => {
- const listItem = document.createElement('li');
- listItem.textContent = fn;
- listItem.addEventListener('click', () => {
- // 放入截图
- });
- lst.appendChild(listItem);
- });
- }
- }
- // 处理新增关卡的回复
- window.electron.receive('prompt-newlv-reply', (event, arg) => {
- const lvid = event;
- // 检查是否已经存在
- for (let i = 0; i < levels.length; i++) {
- if (levels[i].lvid == lvid) {
- alert('关卡id已经存在');
- return;
- }
- }
- // 不存在则加入
- const level = {
- lvid: lvid,
- lvinst: '',
- type: 0,
- dda_type: '0',
- dda_para: '0|10000'
- };
- levels.push(level);
- // 刷新页面
- fillLvInfo();
- // 选中该关卡
- const levelList = document.getElementById('level-list');
- levelList.childNodes.forEach(node => {
- if (node.textContent == lvid) {
- node.click();
- }
- });
- })
- // 处理新增实例的回复
- window.electron.receive('prompt-newinst-reply', (event, arg) => {
- const instName = event;
- // 检查是否已经存在
- for (let i = 0; i < instances.length; i++) {
- if (instances[i].lvinst == instName) {
- alert('实例已经存在');
- return;
- }
- }
- // 不存在则加入
- const inst = {
- lvinst: instName,
- template: '',
- 'try1(tileCnt|seed|param_template)': '0|100|normal',
- 'try2(tileCnt|seed|param_template)': '0|200|normal',
- 'try3(tileCnt|seed|param_template)': '0|300|normal',
- 'try4(tileCnt|seed|param_template)': '0|400|normal',
- 'try5(tileCnt|seed|param_template)': '0|500|normal',
- 'try6(tileCnt|seed|param_template)': '0|600|normal',
- 'try7(tileCnt|seed|param_template)': '0|700|normal',
- 'try8(tileCnt|seed|param_template)': '0|800|normal',
- 'try9(tileCnt|seed|param_template)': '0|900|normal',
- 'try10(tileCnt|seed|param_template)': '0|1000|normal'
- };
- instances.push(inst);
- const instDetails = document.getElementById('instance-details');
- showInstanceInfoAt(instDetails, inst);
- // 将当前关卡关联到该实例
- const lvid = document.getElementById('lvid-in-lvdetails').textContent.split(':')[1].trim();
- for (let i = 0; i < levels.length; i++) {
- if (levels[i].lvid == lvid) {
- levels[i].lvinst = instName;
- break;
- }
- }
- // 刷新页面, 增加一个option,并置为选中
- const instId = document.getElementById('inst-select');
- const option = document.createElement('option');
- option.value = instName;
- option.textContent = instName;
- option.selected = true;
- instId.appendChild(option);
- });
- // 处理复制模板的回复
- window.electron.receive('copy-template-replay', (data) => {
- if (data.length == "0") {
- // 失败了
- } else {
- const inst = getInstanceByName(document.getElementById('instid-in-inst-detail').textContent.split(':')[1].trim());
- // 得到文件名和路径前缀
- const arr = data.split('/');
- const filename = arr[arr.length - 1];
- const prefix = arr.slice(0, arr.length - 1).join('/');
- // 放入到templateFNsByDir中
- const templateName = filename.split(".")[0];
- if (templateFNsByDir[prefix] == null) {
- templateFNsByDir[prefix] = new Set();
- }
- templateFNsByDir[prefix].add(templateName);
- // 放入到templateFNs中
- templateFNs.push(templateName);
- // 设置为新的模板
- inst.template = templateName;
- // 刷新页面,增加templateSelect的选项,并选中新的,同时取消旧的选中状态
- const option = document.createElement('option');
- option.value = templateName;
- option.textContent = templateName;
- option.selected = true;
- const templateSelect = document.getElementById('template-select');
- templateSelect.appendChild(option);
- }
- });
- document.getElementById('load_grp').addEventListener('click', function() {
- const suffix = document.getElementById('group-suffix').value;
- // 初始化数据
- if (suffix == '') {
- initData("");
- } else {
- initData("-"+suffix);
- }
- });
- document.getElementById('levels').addEventListener('click', function() {
- fetch('level.html')
- .then(response => response.text())
- .then(data => {
- document.getElementById('content').innerHTML = data;
- fillLvInfo();
- // 绑定新增关卡按钮
- document.getElementById('add-level-button').addEventListener('click', function() {
- window.electron.send('open-newlv-prompt', 'some data')
- });
- })
- .catch(error => {
- console.error('Error loading the levels content:', error);
- });
- });
- document.getElementById('examples').addEventListener('click', function() {
- fetch('instance.html')
- .then(response => response.text())
- .then(data => {
- document.getElementById('content').innerHTML = data;
- fillInstanceInfo();
- // 给过滤按钮添加事件,点击时调用filterInstance函数
- document.getElementById('intance-btn-filter').addEventListener('click', filterInstance);
- })
- .catch(error => {
- console.error('Error loading the intance content:', error);
- });
- });
- document.getElementById('templates').addEventListener('click', function() {
- fetch('template.html')
- .then(response => response.text())
- .then(data => {
- document.getElementById('content').innerHTML = data;
- fillTemplateInfo();
- })
- .catch(error => {
- console.error('Error loading the intance content:', error);
- });
- });
- </script>
- </body>
- </html>
|