UNPKG

ts-raycasting

Version:
108 lines (100 loc) 3.5 kB
/// <reference path="../../dist/interfaces/IRay.d.ts"/> declare const raycast: any; // initialize canvas const ctx = (<HTMLCanvasElement>document.getElementById('canvas')).getContext('2d'); const mctx = (<HTMLCanvasElement>document.getElementById('minimap')).getContext('2d'); ctx.fillStyle = "black"; ctx.fillRect(0, 0, 256, 300); mctx.fillStyle = "black"; mctx.fillRect(0, 0, 130, 130); // initiliaze world and camera const map: number[][] = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1], [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], [1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1], [1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ]; let camX = 3.5; let camY = 3.5; let camRot = (Math.PI / 2); const h = 80; // test every ray's intersection const testIntersection = (row: number, column: number, cell: number): boolean => { if (cell === 1) { return false; } return true; } // calculate new position const forward = (): void => { camX += Math.cos(camRot) * 0.5; camY += Math.sin(camRot) * 0.5; }; document.addEventListener("keyup", (e) => { switch (e.keyCode) { case 38: forward(); break; case 37: camRot -= (Math.PI / 12); break; case 39: camRot += (Math.PI / 12); break; default: { console.log('unexpected key'); } } }); // main setInterval(() => { // 2.5d plot ctx.fillStyle = "black"; ctx.fillRect(0, 0, 256, 300); // clear canvas ctx.fillStyle = "grey"; ctx.fillRect(0, 150, 256, 150); // draw floor // minimap mctx.fillStyle = "black"; mctx.fillRect(0, 0, 130, 130); // clear canvas // render minimap map.forEach((row: number[], r: number) => row.forEach((cell: number, c: number) => { if (cell === 1) { mctx.fillStyle = "white"; } else { mctx.fillStyle = "black"; } mctx.fillRect(c * 10, r * 10, c * 10 + 10, r * 10 + 10); })); // render 2.5d plot mctx.strokeStyle = "green"; const rays: IRay[] = raycast.castRays(map, camX, camY, camRot, testIntersection); rays.forEach((ray: IRay, index: number) => { if (ray.side) { ctx.fillStyle = "yellow"; } else { ctx.fillStyle = "blue"; } ctx.fillRect(index, 150 - (h / ray.dist), 1, 2 * (h / ray.dist)); // draw on miminap mctx.beginPath(); mctx.moveTo(Math.floor(camX * 10), Math.floor(camY * 10)); mctx.lineTo(Math.floor(ray.x * 10), Math.floor(ray.y * 10)); mctx.stroke(); }); const dirRay: IRay = raycast.castRay(map, camX, camY, testIntersection, camRot); mctx.strokeStyle = "red"; mctx.beginPath(); mctx.moveTo(Math.floor(camX * 10), Math.floor(camY * 10)); mctx.lineTo(Math.floor(dirRay.x * 10), Math.floor(dirRay.y * 10)); mctx.stroke(); }, 1000 / 30);