From d848ad511ebefa09d7fa9827e50f469458e5965c Mon Sep 17 00:00:00 2001 From: Renan LE CARO Date: Thu, 13 Mar 2025 10:02:49 +0100 Subject: [PATCH] wip --- dist/editor-fe.b49a32c1.js | 602 +++ dist/editor-fe.b49a32c1.js.map | 1 + dist/index.248e51be.css | 52 + dist/index.248e51be.css.map | 1 + dist/index.497c99a1.js | 639 +++ dist/index.497c99a1.js.map | 1 + dist/index.a9335429.js | 218 + dist/index.a9335429.js.map | 1 + dist/index.html | 3852 ++++++++++++++++- dist/levels_editor.227fd609.js | 927 ++++ dist/levels_editor.227fd609.js.map | 1 + dist/levels_editor.2b1191d6.js | 602 +++ dist/levels_editor.2b1191d6.js.map | 1 + dist/levels_editor.de5e7f9b.css | 52 + dist/levels_editor.de5e7f9b.css.map | 1 + dist/levels_editor.html | 18 + editor/patterns.html | 163 - editserver.js | 5 +- package.json | 6 +- patterns.html | 163 + editor/index.html => src/levels_editor.html | 4 +- .../editclient.less => src/levels_editor.less | 0 editor/editclient.js => src/levels_editor.ts | 134 +- tsconfig.json | 2 +- 24 files changed, 7195 insertions(+), 251 deletions(-) create mode 100644 dist/editor-fe.b49a32c1.js create mode 100644 dist/editor-fe.b49a32c1.js.map create mode 100644 dist/index.248e51be.css create mode 100644 dist/index.248e51be.css.map create mode 100644 dist/index.497c99a1.js create mode 100644 dist/index.497c99a1.js.map create mode 100644 dist/index.a9335429.js create mode 100644 dist/index.a9335429.js.map create mode 100644 dist/levels_editor.227fd609.js create mode 100644 dist/levels_editor.227fd609.js.map create mode 100644 dist/levels_editor.2b1191d6.js create mode 100644 dist/levels_editor.2b1191d6.js.map create mode 100644 dist/levels_editor.de5e7f9b.css create mode 100644 dist/levels_editor.de5e7f9b.css.map create mode 100644 dist/levels_editor.html delete mode 100644 editor/patterns.html create mode 100644 patterns.html rename editor/index.html => src/levels_editor.html (77%) rename editor/editclient.less => src/levels_editor.less (100%) rename editor/editclient.js => src/levels_editor.ts (69%) diff --git a/dist/editor-fe.b49a32c1.js b/dist/editor-fe.b49a32c1.js new file mode 100644 index 0000000..603e2fe --- /dev/null +++ b/dist/editor-fe.b49a32c1.js @@ -0,0 +1,602 @@ +// modules are defined as an array +// [ module function, map of requires ] +// +// map of requires is short require name -> numeric require +// +// anything defined in a previous bundle is accessed via the +// orig method which is the require for previous bundles + +(function (modules, entry, mainEntry, parcelRequireName, globalName) { + /* eslint-disable no-undef */ + var globalObject = + typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {}; + /* eslint-enable no-undef */ + + // Save the require from previous bundle to this closure if any + var previousRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + + var cache = previousRequire.cache || {}; + // Do not use `require` to prevent Webpack from trying to bundle this call + var nodeRequire = + typeof module !== 'undefined' && + typeof module.require === 'function' && + module.require.bind(module); + + function newRequire(name, jumped) { + if (!cache[name]) { + if (!modules[name]) { + // if we cannot find the module within our internal map or + // cache jump to the current global require ie. the last bundle + // that was added to the page. + var currentRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + if (!jumped && currentRequire) { + return currentRequire(name, true); + } + + // If there are other bundles on this page the require from the + // previous one is saved to 'previousRequire'. Repeat this as + // many times as there are bundles until the module is found or + // we exhaust the require chain. + if (previousRequire) { + return previousRequire(name, true); + } + + // Try the node require function if it exists. + if (nodeRequire && typeof name === 'string') { + return nodeRequire(name); + } + + var err = new Error("Cannot find module '" + name + "'"); + err.code = 'MODULE_NOT_FOUND'; + throw err; + } + + localRequire.resolve = resolve; + localRequire.cache = {}; + + var module = (cache[name] = new newRequire.Module(name)); + + modules[name][0].call( + module.exports, + localRequire, + module, + module.exports, + globalObject + ); + } + + return cache[name].exports; + + function localRequire(x) { + var res = localRequire.resolve(x); + return res === false ? {} : newRequire(res); + } + + function resolve(x) { + var id = modules[name][1][x]; + return id != null ? id : x; + } + } + + function Module(moduleName) { + this.id = moduleName; + this.bundle = newRequire; + this.exports = {}; + } + + newRequire.isParcelRequire = true; + newRequire.Module = Module; + newRequire.modules = modules; + newRequire.cache = cache; + newRequire.parent = previousRequire; + newRequire.register = function (id, exports) { + modules[id] = [ + function (require, module) { + module.exports = exports; + }, + {}, + ]; + }; + + Object.defineProperty(newRequire, 'root', { + get: function () { + return globalObject[parcelRequireName]; + }, + }); + + globalObject[parcelRequireName] = newRequire; + + for (var i = 0; i < entry.length; i++) { + newRequire(entry[i]); + } + + if (mainEntry) { + // Expose entry point to Node, AMD or browser globals + // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js + var mainExports = newRequire(mainEntry); + + // CommonJS + if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = mainExports; + + // RequireJS + } else if (typeof define === 'function' && define.amd) { + define(function () { + return mainExports; + }); + + // - Level editor - - + + + Breakout 71 + + + + + + + + + + + diff --git a/dist/levels_editor.227fd609.js b/dist/levels_editor.227fd609.js new file mode 100644 index 0000000..b588db1 --- /dev/null +++ b/dist/levels_editor.227fd609.js @@ -0,0 +1,927 @@ +// modules are defined as an array +// [ module function, map of requires ] +// +// map of requires is short require name -> numeric require +// +// anything defined in a previous bundle is accessed via the +// orig method which is the require for previous bundles + +(function (modules, entry, mainEntry, parcelRequireName, globalName) { + /* eslint-disable no-undef */ + var globalObject = + typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {}; + /* eslint-enable no-undef */ + + // Save the require from previous bundle to this closure if any + var previousRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + + var cache = previousRequire.cache || {}; + // Do not use `require` to prevent Webpack from trying to bundle this call + var nodeRequire = + typeof module !== 'undefined' && + typeof module.require === 'function' && + module.require.bind(module); + + function newRequire(name, jumped) { + if (!cache[name]) { + if (!modules[name]) { + // if we cannot find the module within our internal map or + // cache jump to the current global require ie. the last bundle + // that was added to the page. + var currentRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + if (!jumped && currentRequire) { + return currentRequire(name, true); + } + + // If there are other bundles on this page the require from the + // previous one is saved to 'previousRequire'. Repeat this as + // many times as there are bundles until the module is found or + // we exhaust the require chain. + if (previousRequire) { + return previousRequire(name, true); + } + + // Try the node require function if it exists. + if (nodeRequire && typeof name === 'string') { + return nodeRequire(name); + } + + var err = new Error("Cannot find module '" + name + "'"); + err.code = 'MODULE_NOT_FOUND'; + throw err; + } + + localRequire.resolve = resolve; + localRequire.cache = {}; + + var module = (cache[name] = new newRequire.Module(name)); + + modules[name][0].call( + module.exports, + localRequire, + module, + module.exports, + globalObject + ); + } + + return cache[name].exports; + + function localRequire(x) { + var res = localRequire.resolve(x); + return res === false ? {} : newRequire(res); + } + + function resolve(x) { + var id = modules[name][1][x]; + return id != null ? id : x; + } + } + + function Module(moduleName) { + this.id = moduleName; + this.bundle = newRequire; + this.exports = {}; + } + + newRequire.isParcelRequire = true; + newRequire.Module = Module; + newRequire.modules = modules; + newRequire.cache = cache; + newRequire.parent = previousRequire; + newRequire.register = function (id, exports) { + modules[id] = [ + function (require, module) { + module.exports = exports; + }, + {}, + ]; + }; + + Object.defineProperty(newRequire, 'root', { + get: function () { + return globalObject[parcelRequireName]; + }, + }); + + globalObject[parcelRequireName] = newRequire; + + for (var i = 0; i < entry.length; i++) { + newRequire(entry[i]); + } + + if (mainEntry) { + // Expose entry point to Node, AMD or browser globals + // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js + var mainExports = newRequire(mainEntry); + + // CommonJS + if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = mainExports; + + // RequireJS + } else if (typeof define === 'function' && define.amd) { + define(function () { + return mainExports; + }); + + // + + Level editor + + + + + + +
+
+ +
+ + + \ No newline at end of file diff --git a/editor/patterns.html b/editor/patterns.html deleted file mode 100644 index 7f7dfb3..0000000 --- a/editor/patterns.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - - Patterns preview - - - - - - - \ No newline at end of file diff --git a/editserver.js b/editserver.js index 49d9cec..29957f9 100644 --- a/editserver.js +++ b/editserver.js @@ -4,15 +4,14 @@ const fs = require('fs') const app = express() const port = 4400 -const srcPath = 'src/levels.json' app.use(bodyParser.text({ type: 'text/plain', limit:'1MB' })); -app.post('/', (req, res) => { +app.post('/src/levels.json', (req, res) => { if(req.body?.trim()) { - fs.writeFileSync(srcPath, req.body) + fs.writeFileSync('src/levels.json', req.body) } res.end('OK') }) diff --git a/package.json b/package.json index 1c94d7c..dd37bbe 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,12 @@ "version": "1.0.0", "description": "A roguelite take on the breakout genre, optimised for short runs and replayability.", "scripts": { - "start": "run-p dev:*", - "dev:game-fe": "parcel --port 1234 --open src/index.html", - "dev:editor-fe": "parcel --port 4401 --open editor/index.html", + "start": "rm -rf .parcel-cache && run-p dev:*", + "dev:game-fe": "parcel src/*.html --lazy", "dev:editor-be": "nodemon editserver.js --watch editserver.js", "build": "rm -f dist/* && parcel build src/index.html" }, + "browserslist": "since 2009", "author": "Renan LE CARO", "license": "GNU AGPLv3", "devDependencies": { diff --git a/patterns.html b/patterns.html new file mode 100644 index 0000000..c38dc45 --- /dev/null +++ b/patterns.html @@ -0,0 +1,163 @@ + + + + + Patterns preview + + + + + + + \ No newline at end of file diff --git a/editor/index.html b/src/levels_editor.html similarity index 77% rename from editor/index.html rename to src/levels_editor.html index 4bafb22..e2068a1 100644 --- a/editor/index.html +++ b/src/levels_editor.html @@ -6,7 +6,7 @@ - + @@ -16,5 +16,5 @@ - + \ No newline at end of file diff --git a/editor/editclient.less b/src/levels_editor.less similarity index 100% rename from editor/editclient.less rename to src/levels_editor.less diff --git a/editor/editclient.js b/src/levels_editor.ts similarity index 69% rename from editor/editclient.js rename to src/levels_editor.ts index 07f54a4..b3cb93c 100644 --- a/editor/editclient.js +++ b/src/levels_editor.ts @@ -1,8 +1,16 @@ -console.log('WTF') +import {Palette, RawLevel} from "./types"; +import _backgrounds from './backgrounds.json' +const backgrounds=_backgrounds as string[]; +import _palette from './palette.json' +const palette=_palette as Palette; +import _allLevels from './levels.json' +let allLevels = _allLevels as RawLevel[]; + + let currentCode = '_' -const paletteEl = document.getElementById('palette'); +const paletteEl = document.getElementById('palette') as HTMLDivElement; Object.entries(palette).forEach(([code, color]) => { const btn = document.createElement('button') @@ -30,8 +38,8 @@ function renderAllLevels() { addLevelEditorToList(level, levelIndex) }) } - -function addLevelEditorToList(level, levelIndex) { +const levelsListEl = document?.getElementById('levels') as HTMLDivElement +function addLevelEditorToList(level:RawLevel, levelIndex:number) { const {name, bricks, size, svg, color} = level let div = document.createElement('div') @@ -59,15 +67,15 @@ function addLevelEditorToList(level, levelIndex) { `; - document.getElementById('levels').appendChild(div) + levelsListEl.appendChild(div) renderLevelBricks(levelIndex) updateLevelBackground(levelIndex) } -function updateLevelBackground(levelIndex) { - const div = document.getElementById("bricks-of-" + levelIndex) +function updateLevelBackground(levelIndex:number) { + const div = document.getElementById("bricks-of-" + levelIndex) as HTMLDivElement const level = allLevels[levelIndex] const {svg, color} = level if (color) { @@ -85,7 +93,7 @@ function updateLevelBackground(levelIndex) { } -function renderLevelBricks(levelIndex) { +function renderLevelBricks(levelIndex:number) { const {size, bricks} = allLevels[levelIndex] const buttons = [] @@ -96,7 +104,7 @@ function renderLevelBricks(levelIndex) { }px;width:40px;height: 40px; position: absolute" data-set-color-of="${index}" data-level="${levelIndex}">`) } } - const div = document.getElementById("bricks-of-" + levelIndex) + const div = document.getElementById("bricks-of-" + levelIndex) as HTMLDivElement div.innerHTML = buttons.join('') Object.assign(div.style, { width: size * 40 + 'px', @@ -105,36 +113,30 @@ function renderLevelBricks(levelIndex) { } -document.getElementById('levels').addEventListener('change', e => { - const levelIndexStr = e.target.getAttribute('data-level') +levelsListEl.addEventListener('change', e => { + const target= e.target as HTMLInputElement + const levelIndexStr = target.getAttribute('data-level') if (levelIndexStr) { const levelIndex = parseInt(levelIndexStr) const level = allLevels[levelIndex] - if (e.target.getAttribute('type') === 'color') { - - level.color = e.target.value - level.svg = '' + if (target.getAttribute('type') === 'color') { + level.color = target.value + level.svg = null updateLevelBackground(levelIndex) - } else if (e.target.getAttribute('type') === 'checkbox' && e.target.hasAttribute('data-field')) { - const field = e.target.getAttribute('data-field') - if (field === 'focus') { - allLevels.forEach(l => l.focus = false) - } - level[field] = !!e.target.checked - } - save() } }) -document.getElementById('levels').addEventListener('click', e => { - const resize = e.target.getAttribute('data-offset-level-size') - const moveX = e.target.getAttribute('data-offset-x') - const moveY = e.target.getAttribute('data-offset-y') - const levelIndexStr = e.target.getAttribute('data-level') +levelsListEl.addEventListener('click', e => { + const target= e.target as HTMLButtonElement + if (target.tagName !== 'BUTTON') return + + const resize = target.getAttribute('data-offset-level-size') + const moveX = target.getAttribute('data-offset-x') + const moveY = target.getAttribute('data-offset-y') + const levelIndexStr = target.getAttribute('data-level') if (!levelIndexStr) return - if (e.target.tagName !== 'BUTTON') return const levelIndex = parseInt(levelIndexStr) const level = allLevels[levelIndex] @@ -159,26 +161,17 @@ document.getElementById('levels').addEventListener('click', e => { } } level.bricks = newBricks.map(b => b || '_').join(''); - } else if (e.target.getAttribute('data-rename')) { + } else if (target.getAttribute('data-rename')) { const newName = prompt('Name ? ', level.name) if (newName) { level.name = newName - e.target.textContent = newName + target.textContent = newName } - } else if (e.target.getAttribute('data-delete')) { - + } else if (target.getAttribute('data-delete')) { if (confirm('Delete level')) { allLevels = allLevels.filter((l, i) => i !== levelIndex) save().then(() => window.location.reload()) } - } else if (e.target.getAttribute('data-set-bg-svg')) { - const newBg = prompt('New svg code', level.svg || '') - if (newBg) { - level.svg = newBg - level.color = '' - } - - updateLevelBackground(levelIndex) } renderLevelBricks(levelIndex) save() @@ -188,47 +181,54 @@ document.getElementById('levels').addEventListener('click', e => { let applying = '' -function colorPixel(e) { +function colorPixel(e:Event) { + const target= e.target as HTMLButtonElement if (applying === '') return console.log('colorPixel', applying) - const index = e.target.getAttribute('data-set-color-of') - const level = e.target.getAttribute('data-level') + const index = target.getAttribute('data-set-color-of') + const level = target.getAttribute('data-level') if (index && level) { const levelIndex = parseInt(level) - e.target.style.background = palette[applying] || 'transparent' + target.style.background = palette[applying] || 'transparent' setBrick(levelIndex, parseInt(index), applying) } } -function setBrick(levelIndex, index, chr) { +function setBrick(levelIndex:number, index:number, chr:string) { const bricks = allLevels[levelIndex].bricks allLevels[levelIndex].bricks = bricks.substring(0, index) + chr + bricks.substring(index + 1); } -document.getElementById('levels').addEventListener('mousedown', e => { - const index = parseInt(e.target.getAttribute('data-set-color-of')) - const level = e.target.getAttribute('data-level') - if (typeof index !== "undefined" && level) { - const before = allLevels[parseInt(level)].bricks[index] || '' +let changed=0 +levelsListEl.addEventListener('mousedown', e => { + const target= e.target as HTMLButtonElement + const index = target.getAttribute('data-set-color-of') + const level = target.getAttribute('data-level') + if ( index && level) { + changed=0 + const before = allLevels[parseInt(level)].bricks[parseInt(index)] || '' applying = before === currentCode ? '_' : currentCode console.log({before, applying, currentCode}) colorPixel(e) } }) -document.getElementById('levels').addEventListener('mouseenter', e => { +levelsListEl.addEventListener('mouseenter', e => { if (applying !== '') { colorPixel(e) + changed++ } -}, true) +}, true); -document.addEventListener('mouseup', e => { - applying = '' - save() -}) +document.addEventListener('mouseup', (e:Event) => { + applying = ''; + if(changed) { + save() + }; +}); -document.getElementById('new-level').addEventListener('click', e => { +(document.getElementById('new-level') as HTMLButtonElement).addEventListener('click', (e:Event) => { const name = prompt("Name ? ") if (!name) return; @@ -236,8 +236,9 @@ document.getElementById('new-level').addEventListener('click', e => { allLevels.push({ name, size: 8, - bricks: '', - svg: '', + bricks: '________________________________________________________________', + svg: null, + color:'' }) const levelIndex = allLevels.length - 1 addLevelEditorToList(allLevels[levelIndex], levelIndex) @@ -247,18 +248,19 @@ document.getElementById('new-level').addEventListener('click', e => { renderAllLevels() function save() { - return fetch('/', { - method: 'POST', headers: { + return fetch('http://localhost:4400/src/levels.json', { + method: 'POST', + headers: { 'Content-Type': 'text/plain' }, body: JSON.stringify(allLevels, null, 2) }) } -function hashCode(string) { - var hash = 0; - for (var i = 0; i < string.length; i++) { - var code = string.charCodeAt(i); +function hashCode(string:string) { + let hash = 0; + for (let i = 0; i < string.length; i++) { + let code = string.charCodeAt(i); hash = ((hash << 5) - hash) + code; hash = hash & hash; // Convert to 32bit integer } diff --git a/tsconfig.json b/tsconfig.json index 44114a9..d36d130 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es2015", + "target": "es2017", "rootDir": "src", "strict": true, "skipLibCheck": true,