diff options
Diffstat (limited to 'src/index.html.in')
-rw-r--r-- | src/index.html.in | 234 |
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); |