Back to shtanton's homepage
summaryrefslogtreecommitdiff
path: root/src/index.html.in
diff options
context:
space:
mode:
Diffstat (limited to 'src/index.html.in')
-rw-r--r--src/index.html.in234
1 files changed, 204 insertions, 30 deletions
diff --git a/src/index.html.in b/src/index.html.in
index fcfb8ef..5414f09 100644
--- a/src/index.html.in
+++ b/src/index.html.in
@@ -11,9 +11,9 @@ html, body {
overflow: hidden;
text-align: center;
width: 100%;
+ color: white;
}
h1 {
- color: white;
margin: 0;
}
button {
@@ -22,21 +22,123 @@ button {
margin: 0.3em;
width: 25%;
}
+
+canvas {
+ margin: auto;
+}
</style>
-<canvas></canvas>
+<div id="tutorial" style="overflow-y: scroll; height: 90vh">
+ <h1>Depths of the Mind</h1>
+
+ <p>
+ The mind is an intricate thing, with many tiny components working together
+ in perfect harmony... Until something came in and messed everything up!
+ </p>
+
+ <p>
+ If you want to set all the pieces of the mind right, you'll need to know how
+ it works!
+ </p>
+
+ <img src=
+#include "../build/tutorial_black_white.png.b64"
+ >
+
+ <p>
+ The structure of the brain consists of black blocks filling a white void.
+ </p>
+
+ <img src=
+#include "../build/tutorial_red_yellow.png.b64"
+ >
+
+ <p>
+ Black blocks will turn red when clicked (if you have red in your inventory on the left).
+ While the brain is running, black blocks next to red blocks will turn red!
+ Red blocks will eventually tire to yellow, and then back to black. They don't stay red very long!
+ This is what allows the brain to send signals along a series of black blocks.
+ Yellow blocks can be placed with a right click on a black block (if you have one in your inventory)
+ </p>
+
+ <img src=
+#include "../build/tutorial_direction_red.png.b64"
+ >
+
+ <p>
+ Sometimes, only one side of a block turns red.
+ When this happens, it will try to move in that direction (and leave a yellow behind it)
+ but if it cannot it will turn clockwise and try again.
+ </p>
+
+ <span>
+ <img src=
+#include "../build/tutorial_blue_1.png.b64"
+ >
+ <img src=
+#include "../build/tutorial_blue_2.png.b64"
+ >
+
+ <p>
+ Blue blocks need to be moved around to keep things running smoothly!
+ When a blue block is touched by a single red block, it will start rolling
+ away from it.
+ Each level has a goal in faint red which needs at least one blue block to be delivered to it.
+ Some levels will also have faint blue areas that create new blue blocks for you!
+ </p>
+
+ <img src=
+#include "../build/tutorial_blue_clone.png.b64"
+ >
+
+ <p>
+ Finally, if a blue block touches a red block <em>while in motion</em> it will be cloned!
+ One will be left behind and the other will continue.
+ </p>
+
+ <button id="play-button">Play!</button>
+</div>
+
+<canvas style="display: none;"></canvas>
<script>
// Mirror these in src/all.c
const INPUT_NONE = 0;
-const INPUT_UP = 1;
-const INPUT_DOWN = 2;
-const INPUT_LEFT = 3;
-const INPUT_RIGHT = 4;
+const INPUT_CLICK = 1;
+const INPUT_RCLICK = 2;
+const INPUT_PAUSE_PLAY = 3;
+const INPUT_MOVE = 4;
+const INPUT_RESTART = 5;
const WASM =
#include "../build/main.wasm.b64"
+const MUSIC =
+#include "../build/music.mp3.b64"
+
+const IMAGES = [
+#include "../build/continue.png.b64"
+,
+#include "../build/exit.png.b64"
+,
+#include "../build/pause.png.b64"
+,
+#include "../build/play.png.b64"
+,
+#include "../build/restart.png.b64"
+,
+#include "../build/nelson.png.b64"
+,
+#include "../build/nelson_left.png.b64"
+,
+#include "../build/nelson_up.png.b64"
+,
+#include "../build/nelson_right.png.b64"
+,
+#include "../build/nelson_down.png.b64"
+,
+];
+
async function main() {
let bytes = Uint8Array.from(atob(WASM), function(c) {
return c.charCodeAt(0);
@@ -46,54 +148,126 @@ async function main() {
let exports = wasm.exports;
let html = document.querySelector("html");
let canvas = document.querySelector("canvas");
+ const tutorial = document.querySelector("#tutorial");
let ctx = canvas.getContext("2d");
let memory = exports.memory;
+ let mousex = 0;
+ let mousey = 0;
+
+ const audio = new Audio();
+ audio.src = MUSIC;
+ audio.volume = 0.2;
+ audio.loop = true;
+ let musicPlaying = false;
+
+ let images = [null];
+ for (let i = 0; i < IMAGES.length; i++) {
+ const image = new Image();
+ image.src = IMAGES[i];
+ images.push(image);
+ }
+
+ const start = Date.now();
+ function now() {
+ return Date.now() - start;
+ }
+
function min(a, b) {
return b<a ? b : a;
}
- function max_width() {
- return html.clientHeight * 0.7 | 0;
- }
-
function render() {
- let width = canvas.width = min(html.clientWidth, max_width());
- let height = canvas.height = width;
- let ptr = exports.game_render(width, height);
+ if (64 + html.clientHeight * (20 / 16) > html.clientWidth) {
+ canvas.width = html.clientWidth;
+ canvas.height = (html.clientWidth - 64) * (16 / 20);
+ } else {
+ canvas.width = 64 + html.clientHeight * (20 / 16);
+ canvas.height = html.clientHeight;
+ }
+ let width = canvas.width;
+ let height = canvas.height;
+ let ptr = exports.game_render(width, height, mousex, mousey);
let dl = new Int32Array(memory.buffer, ptr);
let len = dl[0];
let ops = dl.subarray(1);
+ ctx.fillStyle = "#000000";
+ ctx.fillRect(0, 0, width, height);
for (let i = 0; i < len; i++) {
- let op = ops.subarray(5*i, 5*i+5);
- const color = new Uint8Array(new Uint32Array(ops.subarray(4, 5)).buffer);
- let style = `#${color[0].toString(16).padStart(2, "0")}${color[1].toString(16).padStart(2, "0")}${color[2].toString(16).padStart(2, "0")}`;
- ctx.fillStyle = style;
+ let op = ops.subarray(7*i, 7*i+7);
+ const color = new Uint8Array(new Uint32Array(op.subarray(4, 6)).buffer);
+ ctx.fillStyle = `#${color[0].toString(16).padStart(2, "0")}${color[1].toString(16).padStart(2, "0")}${color[2].toString(16).padStart(2, "0")}`;
+ ctx.globalAlpha = color[3] / 255;
ctx.fillRect(op[0], op[1], op[2], op[3]);
+ ctx.strokeStyle = `#${color[4].toString(16).padStart(2, "0")}${color[5].toString(16).padStart(2, "0")}${color[6].toString(16).padStart(2, "0")}`;
+ ctx.globalAlpha = color[7] / 255;
+ ctx.strokeRect(op[0], op[1], op[2], op[3]);
+ const image = new Uint8Array(new Uint32Array(op.subarray(6, 7)).buffer);
+ if (image[0] !== 0) {
+ console.log(image);
+ ctx.globalAlpha = image[1] / 255;
+ ctx.drawImage(images[image[0]], op[0], op[1], op[2], op[3]);
+ }
}
}
- function onresize() { html.style.maxWidth = `${max_width()}px`; }
+ function onresize() { /*html.style.maxWidth = `${max_width()}px`; */}
window.addEventListener("resize", onresize);
onresize();
- document.addEventListener("keydown", function(e) {
- if (e.key == "w") {
- exports.game_update(INPUT_UP);
- } else if (e.key == "a") {
- exports.game_update(INPUT_LEFT);
- } else if (e.key == "s") {
- exports.game_update(INPUT_DOWN);
- } else if (e.key == "d") {
- exports.game_update(INPUT_RIGHT);
- }
- })
+ function doUpdate(input) {
+ if (exports.game_update(input, mousex, mousey, now()) !== 0) {
+ canvas.style.display = "none";
+ tutorial.style.display = "block";
+ }
+ }
+
+ canvas.addEventListener("mousemove", function(e) {
+ const rect = e.target.getBoundingClientRect();
+ mousex = e.clientX - rect.left;
+ mousey = e.clientY - rect.top;
+ doUpdate(INPUT_MOVE);
+ });
+
+ canvas.addEventListener("mousedown", function(e) {
+ const rect = e.target.getBoundingClientRect();
+ mousex = e.clientX - rect.left;
+ mousey = e.clientY - rect.top;
+ if (e.button == 0) {
+ doUpdate(INPUT_CLICK);
+ } else if (e.button == 2) {
+ e.preventDefault();
+ doUpdate(INPUT_RCLICK);
+ }
+ });
+
+ document.getElementById("play-button").addEventListener("click", function (e) {
+ if (!musicPlaying) {
+ musicPlaying = true;
+ audio.play();
+ }
+
+ canvas.style.display = "block";
+ tutorial.style.display = "none";
+ });
+
+ canvas.addEventListener("contextmenu", function (e) {
+ e.preventDefault();
+ });
+
+ document.addEventListener("keydown", function (e) {
+ if (e.key === " ") {
+ doUpdate(INPUT_PAUSE_PLAY);
+ } else if (e.key == "r") {
+ doUpdate(INPUT_RESTART);
+ }
+ });
function animate() {
// TODO: stop requesting frames when state is static
requestAnimationFrame(animate);
- exports.game_update(INPUT_NONE);
+ doUpdate(INPUT_NONE);
render();
}
requestAnimationFrame(animate);