commit 41ec0814f7b976396d9b7a24a464f9006c6ca1ca Author: sfja Date: Wed Aug 20 20:10:44 2025 +0200 init diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..4a61c86 Binary files /dev/null and b/favicon.ico differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..1e2cab8 --- /dev/null +++ b/index.html @@ -0,0 +1,64 @@ + + + + + + + + Document + + + + + + + +
+ + +
+ +
+ +
+ + + + +
+
Karlkode 1.0
+ +
+
+ +
+
+
+lib.clear("green");
+
+lib.drawRect(100, 100, 100, 100, "blue");
+
+lib.println("hello world!");
+
+let playerX = 0;
+
+function loop(deltaT) {
+
+    playerX += 100 * deltaT;
+
+    lib.drawRect(playerX, 200, 50, 50, "red");
+}
+
+lib.startGameLoop(loop);
+
+return 5;
+
+
+ + +
+ + + + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..1716e81 --- /dev/null +++ b/index.js @@ -0,0 +1,91 @@ +"use strict"; + +let _gameLoopTimeout = undefined; + +(function () { + const editor = ace.edit("editor"); + editor.setTheme("ace/theme/gruvbox"); + editor.session.setMode("ace/mode/javascript"); + + if (editor.getValue() === "") { + editor.setValue( + ``, + ); + } + + let running = false; + + const startStopButton = document.querySelector("#start-stop"); + const saveButton = document.querySelector("#save"); + const consoleCode = document.querySelector("#console-code"); + + startStopButton.onclick = (ev) => { + if (running) { + if (_gameLoopTimeout) { + clearTimeout(_gameLoopTimeout); + _gameLoopTimeout = undefined; + } + startStopButton.textContent = "Start"; + running = false; + } else { + const code = editor.getValue(); + runCode(code, consoleCode); + startStopButton.textContent = "Stop"; + running = true; + } + }; +})(); + +const lib = (() => { + const consoleCode = document.querySelector("#console-code"); + + const width = 480; + const height = 360; + + const canvas = document.querySelector("canvas"); + canvas.width = width; + canvas.height = height; + const cx = canvas.getContext("2d"); + cx.imageSmoothingEnabled = false; + + function rgb(red, green, blue) { + return `rgb(${red}, ${green}, ${blue})`; + } + + function clear(color) { + cx.fillStyle = color; + cx.fillRect(0, 0, width, height); + } + + function drawRect(x, y, width, height, color) { + cx.fillStyle = color; + cx.fillRect(x, y, width, height); + } + + function println(msg) { + consoleCode.textContent += `${msg}\n`; + } + + function startGameLoop(loopFunction) { + let before = Date.now(); + _gameLoopTimeout = setInterval(() => { + const now = Date.now(); + const deltaT = (now - before) / 1000; + before = now; + loopFunction(deltaT); + }, 16); + } + + return { width, height, rgb, clear, drawRect, println, startGameLoop }; +})(); + +async function runCode(code, consoleCode) { + lib; + consoleCode.textContent += `\nRunning code....\n`; + try { + const result = await eval(`(async function () {${code}})()`); + consoleCode.textContent += `Code returned ${result}\n`; + } catch (error) { + consoleCode.textContent += `${error}\n`; + } +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..033cdc0 --- /dev/null +++ b/style.css @@ -0,0 +1,81 @@ +* { + box-sizing: border-box; +} + +body { + margin: 0; + height: 100vh; +} + +main { + display: flex; + flex-direction: row; + height: 100vh; +} + +#buttons { + width: 100%; + display: flex; + flex-direction: row; + justify-content: end; + align-items: center; + gap: 10px; +} + +#buttons button { + margin: 5px; + padding: 10px; + min-width: 100px; +} + +#dashboard { + display: flex; + flex-direction: column; + gap: 5px; + width: 40vw; + justify-content: space-evenly; + align-items: center; +} + +canvas { + background-color: black; + width: 100%; +} + +#console { + width: 100%; + padding: 5px; +} + +#console pre { + color: white; + background-color: black; + margin: 0; + width: 100%; + font-size: 1rem; + height: 24rem; +} + +#console input { + width: 100%; + margin: 0; + outline: none; + border: 2px solid white; + padding: none; + color: white; + background-color: black; + font-family: monospace; + font-size: 1rem; +} + +#editor-area { + width: 100%; + height: 100%; +} + +#editor { + margin: 0; + width: 100%; + height: 100%; + font-size: 16px; +}