diff --git a/src/gamelib.js b/src/gamelib.js
index 3f49570..e8f3e41 100644
--- a/src/gamelib.js
+++ b/src/gamelib.js
@@ -44,11 +44,11 @@ export class Gamelib {
}
}, 16);
- if (this.codeStopper.isStopped()) {
+ if (this.codeStopper?.isStopped()) {
clearInterval(loopInterval);
}
- this.codeStopper.addListener(() => {
+ this.codeStopper?.addListener(() => {
clearInterval(loopInterval);
});
}
diff --git a/src/html_exporter.js b/src/html_exporter.js
new file mode 100644
index 0000000..94f474b
--- /dev/null
+++ b/src/html_exporter.js
@@ -0,0 +1,71 @@
+import { minifyJs } from "./utils.js";
+
+export class HtmlExporter {
+ constructor(spriteProvider) {
+ this.spriteProvider = spriteProvider;
+ }
+
+ async export(projectName, code) {
+ const js = code
+ .split("\n")
+ .map((line) => " ".repeat(12) + line).join("\n");
+
+ let lib = await (await fetch("./src/gamelib.js")).text();
+ lib = minifyJs(lib);
+
+ const sprites = this.spriteProvider.getAll();
+
+ const html = `
+
+
+
+
+
+ ${projectName}
+
+
+
+
+
+
+
+
+`;
+
+ return html;
+ }
+}
diff --git a/src/index.js b/src/index.js
index 6e88ee7..43e23ab 100644
--- a/src/index.js
+++ b/src/index.js
@@ -12,6 +12,8 @@ import { promptUpload } from "./prompt_upload.js";
import { GamelibCompleter } from "./gamelib_completer.js";
import { TextCompleter } from "./text_completer.js";
import { ConsoleInput } from "./console_input.js";
+import { downloadFile } from "./utils.js";
+import { HtmlExporter } from "./html_exporter.js";
const playgroundConsole = new PlaygroundConsole(
document.querySelector("#console-code"),
@@ -26,6 +28,8 @@ const spriteEditor = new SpriteEditor(document.querySelector("#sprite-editor-con
new ConsoleInput(document.querySelector("#console-input"), playgroundConsole, codeRunner);
+const htmlExporter = new HtmlExporter(spriteProvider);
+
const gamelib = new Gamelib(
playgroundConsole,
codeStopper,
@@ -122,32 +126,6 @@ runButton.onclick = () => {
}
};
-function downloadFile(content, extension, mime) {
- const filename = prompt("Filename?");
- if (filename === null) return;
-
- const blob = new Blob([content], { type: mime });
- const url = URL.createObjectURL(blob);
-
- const element = document.createElement("a");
-
- element.href = url;
- element.download = filename.endsWith(extension) ? filename : filename + extension;
- element.style.display = "none";
-
- document.body.appendChild(element);
-
- element.click();
-
- document.body.removeChild(element);
-}
-
-function minifyJs(code) {
- return code
- .replace(/[\s\n]+/g, " ")
- .replace(/;\s+/g, ";");
-}
-
saveButton.onclick = () => {
if (saveButton.classList.contains("active")) {
saveButton.classList.remove("active");
@@ -164,48 +142,9 @@ saveJsButton.onclick = () => {
};
saveHtmlButton.onclick = async () => {
- const js = editor.getValue()
- .split("\n")
- .map((line) => " ".repeat(12) + line).join("\n");
- let lib = await (await fetch("./js/lib.js")).text();
- lib = minifyJs(lib);
+ const html = await htmlExporter.export(projectName.value, editor.getValue());
- const html = `
-
-
-
-
-
- Game
-
-
-
-
-
-
-
-`;
-
- downloadTextFile(html, ".html", "text/html");
+ downloadFile(html, ".html", "text/html");
};
function saveKarlKoder() {
diff --git a/src/sprite_provider.js b/src/sprite_provider.js
index 019acb5..ce996de 100644
--- a/src/sprite_provider.js
+++ b/src/sprite_provider.js
@@ -14,4 +14,14 @@ export class SpriteProvider {
}
return `data:${sprite.mime};base64,${sprite.bytes.toBase64()}`;
}
+
+ getAll() {
+ const result = {};
+
+ for (const sprite of this.sprites) {
+ result[sprite.name] = this.url(sprite.name);
+ }
+
+ return result;
+ }
}
diff --git a/src/utils.js b/src/utils.js
new file mode 100644
index 0000000..1fe23c8
--- /dev/null
+++ b/src/utils.js
@@ -0,0 +1,25 @@
+export function downloadFile(content, extension, mime) {
+ const filename = prompt("Filename?");
+ if (filename === null) return;
+
+ const blob = new Blob([content], { type: mime });
+ const url = URL.createObjectURL(blob);
+
+ const element = document.createElement("a");
+
+ element.href = url;
+ element.download = filename.endsWith(extension) ? filename : filename + extension;
+ element.style.display = "none";
+
+ document.body.appendChild(element);
+
+ element.click();
+
+ document.body.removeChild(element);
+}
+
+export function minifyJs(code) {
+ return code
+ .replace(/[\s\n]+/g, " ")
+ .replace(/;\s+/g, ";");
+}