JSFiddle - React, Tailwind, and code Playground

by btipling

HTML

<!DOCTYPE html>
<html>
<head><title>ChamberedTest</title></head>
<script type="text/javascript" src="js/chambered.js"></script>
<style type="text/css">
    canvas, img {
        image-rendering: optimizeSpeed;
        image-rendering: -moz-crisp-edges;
        image-rendering: -webkit-optimize-contrast;
        image-rendering: optimize-contrast;
        -ms-interpolation-mode: nearest-neighbor;
        width:848px;
        height:480px;
    }

</style>

<body>
<div>
  <canvas id="game" width="424" height="240"></canvas>
</div>
<div style="padding:5px;">
<h1 style="font-weight:900">
Controls
</h1>
<div>
  <label>
     rotation 
    <input type="checkbox" id="rotation" checked onChange="updateOptions();"/>
  </label>
</div>
<div>
  <label>
    travel 
    <input type="checkbox" id="travel" checked onChange="updateOptions();">
  </label>
</div>
<div>
  <label>
    rotate screen 
    <input type="checkbox" id="screen_rotation" checked onChange="updateOptions();">
  </label>
</div>
<div>
  <label>
     texture u v coords 
    <input type="checkbox" id="texture_uv_coords" checked onChange="updateOptions();"/>
  </label>
</div>
<div>
  <label>
     depth lighting
    <input type="checkbox" id="depth_lighting" checked onChange="updateOptions();"/>
  </label>
</div>
<div>
Disable rotation to use these:
</div>
<div>
  <label>
    x cos 
    <input type="range" value="50" id="xcos" min="0" max="100" onInput="updateOptions();"/>
  </label>
</div>
<div>
  <label>
    y cos 
    <input type="range" value="100" id="ycos" min="0" max="100" onInput="updateOptions();"/>
  </label>
</div>
<div>
  <label>
    x sine 
    <input type="range" value="100" id="xsine" min="0" max="100" onInput="updateOptions();"/>
  </label>
</div>
<div>
  <label>
    y sine 
    <input type="range" value="50" id="ysine" min="0" max="100" onInput="updateOptions();"/>
  </label>
</div>
</div>
<script type="text/javascript">init();</script>
</body>
</html>

JavaScript

var canvasContext;
var canvasPixels;

var canvasWidth = 212 * 2;
var canvasHeight = 120 * 2;

var worldSize = 64;
var worldMap = new Array(worldSize * worldSize * worldSize);
var blockDimensions = 16;
var numTextures = 16;
var numSurfacesPerTexture = 3;
var textureMap = new Array(blockDimensions * blockDimensions * numSurfacesPerTexture * numTextures);

var transparentBlock = 0;
var grassBlock = 1;
var dirtBlock = 2; // also 3, 6, 10, 11, 12, 13, 14, 15
var stoneBlock = 4;
var brickBlock = 5;
var treeBlock = 7;
var leavesBlock = 8;
var waterBlock = 9;
var invalidBlock = 16;
var numBlocks = 16;

var maxBrightness = 0xff;
var brown = 0x966C4A;
var treeBrown = 0x675231;
var woodBrown = 0xBC9862;
var gray = 0x7F7F7F;
var greenGrass = 0x6AAA40;
var red = 0xB53A15;
var cementGray = 0xBCAFA5;
var blue = 0x4040ff;
var leavesGreen = 0x50D937;
var transparent = 0x000000;

// addPielBrightness is a function that takes a pixel color and a brightness to each channel (R, G, or B) independently
function addPixelBrightness(pixelColor, pixelBrightness) {
    // 0xRRGGBB
    var redPosition = 16;
    var greenPosition = 8;
    var bluePosition = 0;

    var colorChannelPositions = [redPosition, greenPosition, bluePosition];

    var finalColor = 0;
    for (var i = 0; i < colorChannelPositions.length; i++) {
        var currentChannel = colorChannelPositions[i];

        var channelValue = (pixelColor >> currentChannel) & maxBrightness;

        var channelValueWithBrightness = channelValue * pixelBrightness / maxBrightness;

        finalColor = finalColor | (channelValueWithBrightness << currentChannel);
    }
    return finalColor;
}

var grassPatternVariation = 81;

// colorForBlockKind is a function that takes a block kind and a position (x, y) and returns a color for each position in the blocks texture
function colorForBlockKind(blockKind, x, y) {
    switch (blockKind) {
        case stoneBlock:
            return gray;
        case waterBlock:
            return blue;
    ...