]> git.mdlowis.com Git - proto/jstoys.git/commitdiff
refactored singleton objects for controls and canvas access
authorMichael D. Lowis <mike.lowis@gentex.com>
Wed, 14 Nov 2018 17:45:18 +0000 (12:45 -0500)
committerMichael D. Lowis <mike.lowis@gentex.com>
Wed, 14 Nov 2018 17:45:18 +0000 (12:45 -0500)
raycast.html

index 53dc55e2cbc2dbe0c856f558f1fb83fd12ceacba..5a2484e1be10856225b3f7e310cdc132605778b3 100644 (file)
@@ -5,52 +5,50 @@
     <title>Raycaster</title>
   </head>
   <body style='background: #000; margin: 0; padding: 0; width: 100%; height: 100%;'>
-    <canvas id='display' width='1' height='1' style='width: 100%; height: 100%;' />
+    <canvas id='display' style='width: 100%; height: 100%;' />
     <script>
 "use strict";
 const TAU = Math.PI * 2;
 const WALK_SPEED = 5;
-const TURN_SPEED = Math.PI * 0.5;
+const TURN_SPEED = TAU/4;
 const MAX_VIEW_DIST = 32;
 const LIGHT_RANGE = 20;
 const FOCAL_LENGTH = 0.8;
 const VIEW_SCALER = 1.0;
 const MAP_SIZE = 32;
+const START_POS = { x: 15.3, y: -1.2, direction: Math.PI * 0.3};
+
+const Keys = { left: 37, right: 39, up: 38, down: 40 };
+const Canvas = display.getContext('2d');
 
 const FrameTimer = (()=>{
     let prev = 1, curr = 1;
-    const ctx = display.getContext('2d');
     return {
         update: (now) => (prev = curr, curr = now, (curr - prev) / 1000),
         render: () => {
-            ctx.fillStyle = "Red";
-            ctx.font = "normal 12pt Arial";
-            ctx.fillText(Math.round(1/((curr - prev) / 1000)) + " fps", 10, 26);
+            Canvas.fillStyle = "Red";
+            Canvas.font = "normal 12pt Arial";
+            Canvas.fillText(Math.round(1/((curr - prev) / 1000)) + " fps", 10, 26);
         }
     };
 })();
 
 const Controls = (()=>{
-    const self = { states: { 'left': false, 'right': false, 'forward': false, 'backward': false } };
-    const codes = { 37: 'left', 39: 'right', 38: 'forward', 40: 'backward' };
-    const onKey = (val, e)=>{
-        const state = codes[e.keyCode];
-        if (typeof state === 'undefined') return;
-        self.states[state] = val;
+    const self = {};
+    const onKey = (val) => ((e)=>{
+        self[e.keyCode] = val;
         e.preventDefault && e.preventDefault();
         e.stopPropagation && e.stopPropagation();
-    };
-    document.addEventListener('keydown', onKey.bind(self, true), false);
-    document.addEventListener('keyup', onKey.bind(self, false), false);
+    });
+    document.addEventListener('keydown', onKey(true), false);
+    document.addEventListener('keyup', onKey(false), false);
     return self;
 })();
 
-const Player = ((x, y, direction)=>{
-    const self = {x: x, y: y, direction: direction};
+const Player = (()=>{
+    const self = START_POS;
 
-    const rotate = (angle)=>{
-        self.direction = (self.direction + angle + TAU) % (TAU);
-    };
+    const rotate = (angle)=>(self.direction = (self.direction + angle + TAU) % TAU);
 
     const walk = (distance)=>{
         const dx = Math.cos(self.direction) * distance;
@@ -60,27 +58,26 @@ const Player = ((x, y, direction)=>{
     };
 
     self.update = (seconds)=>{
-        if (Controls.states.left) rotate(-TURN_SPEED * seconds);
-        if (Controls.states.right) rotate(TURN_SPEED * seconds);
-        if (Controls.states.forward) walk(WALK_SPEED * seconds);
-        if (Controls.states.backward) walk(-WALK_SPEED * seconds);
+        if (Controls[Keys.left]) rotate(-TURN_SPEED * seconds);
+        if (Controls[Keys.right]) rotate(TURN_SPEED * seconds);
+        if (Controls[Keys.up]) walk(WALK_SPEED * seconds);
+        if (Controls[Keys.down]) walk(-WALK_SPEED * seconds);
     };
 
     return self;
-})(15.3, -1.2, Math.PI * 0.3);
+})();
 
-const Map = ((size)=>{
-    let grid = new Uint8Array(size*size);
+const Map = (()=>{
+    let grid = new Uint8Array(MAP_SIZE * MAP_SIZE);
     return {
-        get: (x, y)=>(grid[Math.floor(y) * size + Math.floor(x)] || -1),
+        get: (x, y)=>(grid[Math.floor(y) * MAP_SIZE + Math.floor(x)] || -1),
         randomize: ()=>(grid = grid.map((i) => (Math.random() < 0.3 ? 1 : 0))),
     };
-})(MAP_SIZE);
+})();
 
 const Camera = (()=>{
     const self = {};
     let columns = [], ceiling = null, floor = null;
-    const ctx = display.getContext('2d');
 
     const resizeView = ()=>{
         if (self.width != window.innerWidth || self.height != window.innerHeight) {
@@ -97,24 +94,24 @@ const Camera = (()=>{
             });
 
             /* Generate floor and ceiling gradients */
-            ceiling = ctx.createLinearGradient(0, self.height/2, 0, 0);
+            ceiling = Canvas.createLinearGradient(0, self.height/2, 0, 0);
             ceiling.addColorStop(0, '#000011');
             ceiling.addColorStop(1, '#000055');
-            floor = ctx.createLinearGradient(0, self.height/2, 0, self.height);
+            floor = Canvas.createLinearGradient(0, self.height/2, 0, self.height);
             floor.addColorStop(0, '#110000');
             floor.addColorStop(1, '#550000');
         }
     };
 
     self.render = ()=>{
-        ctx.save();
+        Canvas.save();
         const data = {};
         resizeView();
 
-        ctx.fillStyle = ceiling;
-        ctx.fillRect(0, 0, self.width, self.height/2);
-        ctx.fillStyle = floor;
-        ctx.fillRect(0, self.height/2, self.width, self.height);
+        Canvas.fillStyle = ceiling;
+        Canvas.fillRect(0, 0, self.width, self.height/2);
+        Canvas.fillStyle = floor;
+        Canvas.fillRect(0, self.height/2, self.width, self.height);
 
         columns.map((col, i)=>{
             /* pre-calculate trig functions related to the ray to cast */
@@ -128,18 +125,18 @@ const Camera = (()=>{
                 wall.top = (self.height / 2 * (1 + 1 / z)) - wall.height;
 
                 /* draw wall slice */
-                ctx.fillStyle = '#999999';
-                ctx.globalAlpha = 1;
-                ctx.fillRect(i, wall.top, 1, wall.height);
+                Canvas.fillStyle = '#999999';
+                Canvas.globalAlpha = 1;
+                Canvas.fillRect(i, wall.top, 1, wall.height);
 
                 /* draw shadow over wall slice */
-                ctx.fillStyle = '#000000';
-                ctx.globalAlpha = Math.max((obj.distance) / LIGHT_RANGE, 0);
-                ctx.fillRect(i, wall.top, 1, wall.height);
+                Canvas.fillStyle = '#000000';
+                Canvas.globalAlpha = Math.max((obj.distance) / LIGHT_RANGE, 0);
+                Canvas.fillRect(i, wall.top, 1, wall.height);
             }
         });
 
-        ctx.restore();
+        Canvas.restore();
     };
 
     const snapToGrid = (pos, dist) =>