Skip to content
Permalink
main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="./liblilray.js"></script>
<style>
.keys > div {
border: 1px solid #cccccc;
width: 4em;
text-align: center;
user-select: none;
}
a {
color: coral;
}
a :visited {
color: coral;
}
</style>
</head>
<body style="background: black; color: #cccccc; font-family: monospace">
<div style="width: 640px; margin: auto;">
<canvas id="canvas" width="640" heigh="480" tabindex="-1" style="width: 640px; height: 480px; user-select: none; border: none; outline-style: none;"></canvas>
<div class="keys" style="display: flex; justify-content: center; width: 100%; font-size: 4em;">
<div id="up"></div>
<div id="down"></div>
<div id="left"></div>
<div id="right"></div>
</div>
<p>'lilray' is small recreational project to learn about raycasting, sub pixel precision rendering, fixed point math, and other 80ies and 90ies style game technologies, transplanted into the year 2022.</p>
<p>It's implemented as a simple (shoddy) C++ library with a C wrapper so it can be exposed to other platforms, like this very JavaScript/WASM demo.</p>
<h3><a href="https://github.com/badlogic/lilray">GitHub</a></h3>
</div>
</body>
<script>
let lib;
let canvas = document.getElementById("canvas");
canvas.focus();
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
let keyW = false, keyS = false, keyA = false, keyD = false;
canvas.addEventListener("keydown", (event) => {
if (event.key === "w") keyW = true;
if (event.key === "s") keyS = true;
if (event.key === "a") keyA = true;
if (event.key === "d") keyD = true;
}, false);
canvas.addEventListener("keyup", (event) => {
if (event.key === "w") keyW = false;
if (event.key === "s") keyS = false;
if (event.key === "a") keyA = false;
if (event.key === "d") keyD = false;
}, false);
canvas.focus();
document.getElementById("left").addEventListener("mousedown", () => keyA = true);
document.getElementById("left").addEventListener("mouseup", () => keyA = false);
document.getElementById("left").addEventListener("touchstart", () => keyA = true);
document.getElementById("left").addEventListener("touchend", () => keyA = false);
document.getElementById("right").addEventListener("mousedown", () => keyD = true);
document.getElementById("right").addEventListener("mouseup", () => keyD = false);
document.getElementById("right").addEventListener("touchstart", () => keyD = true);
document.getElementById("right").addEventListener("touchend", () => keyD = false);
document.getElementById("up").addEventListener("mousedown", () => keyW = true);
document.getElementById("up").addEventListener("mouseup", () => keyW = false);
document.getElementById("up").addEventListener("touchstart", () => keyW = true);
document.getElementById("up").addEventListener("touchend", () => keyW = false);
document.getElementById("down").addEventListener("mousedown", () => keyS = true);
document.getElementById("down").addEventListener("mouseup", () => keyS = false);
document.getElementById("down").addEventListener("touchstart", () => keyS = true);
document.getElementById("down").addEventListener("touchend", () => keyS = false);
let loadImage = async (url) => {
let response = await fetch(url)
if (!response.ok) throw new Error("Couldn't load image: " + url);
let data = new Uint8Array(await response.arrayBuffer());
let ptr = lib._malloc(data.byteLength);
lib.HEAPU8.set(data, ptr);
let image = lib._lilray_image_create_from_memory(ptr, data.byteLength);
lib._free(ptr);
return image;
}
let initialize = async function () {
lib = await liblilray();
const resX = 640, resY = 480;
const rotationSpeed = 70;
const movementSpeed = 2.5;
let textures = await Promise.all([
loadImage("assets/STARG2.png"),
loadImage("assets/STARG3.png"),
loadImage("assets/STARGR2.png"),
loadImage("assets/TEKWALL1.png"),
loadImage("assets/TEKWALL2.png"),
loadImage("assets/TEKWALL3.png"),
loadImage("assets/TEKWALL4.png"),
]);
let texturesPtr = lib._malloc(textures.length * 4);
lib.HEAPU32.set(textures, texturesPtr / 4);
let cells = [
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 2, 2, 2, 0, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
];
let cellsPtr = lib._malloc(cells.length * 4);
lib.HEAPU32.set(cells, cellsPtr / 4);
let grunt = await loadImage("assets/grunt.png");
let sprites = [
lib._lilray_sprite_create(4.5, 2.5, 0.7, grunt),
lib._lilray_sprite_create(4.5, 1.5, 0.7, grunt),
lib._lilray_sprite_create(5.5, 2.0, 0.7, grunt)
];
let spritesPtr = lib._malloc(sprites.length * 4);
lib.HEAPU32.set(sprites, spritesPtr / 4);
let map = lib._lilray_map_create(21, 21, cellsPtr);
let camera = lib._lilray_camera_create(2.5, 2.5, 0, 66);
let renderer = lib._lilray_renderer_create(resX, resY, texturesPtr, textures.length, textures[1], textures[1]);
let lastFrameTime = Date.now();
function render() {
let time = Date.now();
let delta = (time - lastFrameTime) / 1000;
lastFrameTime = time;
if (keyW) lib._lilray_camera_move(camera, map, movementSpeed * delta);
if (keyS) lib._lilray_camera_move(camera, map, -movementSpeed * delta);
if (keyA) lib._lilray_camera_rotate(camera, -rotationSpeed * delta);
if (keyD) lib._lilray_camera_rotate(camera, rotationSpeed * delta);
lib._lilray_renderer_render(renderer, camera, map, spritesPtr, sprites.length, 6);
let frame = lib._lilray_renderer_get_frame(renderer);
lib._lilray_image_to_rgba(frame);
let framePixels = new Uint8ClampedArray(lib.HEAPU8.buffer, lib._lilray_image_get_pixels(frame), resX * resY * 4);
let imageData = new ImageData(framePixels, resX, resY);
this.canvas.getContext("2d").putImageData(imageData, 0, 0);
requestAnimationFrame(render);
}
render();
}
initialize();
</script>
</html>