JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

<canvas id='map-canvas'></canvas>

<p>
    Width: <input type='number' id='select-width' min='10' max='300' value='30'> - 
    Height: <input type='number' id='select-height' min='10' max='200' value='30'> - 
    Tile size: <input type='number' id='select-tileSize' min='1' max='20' value='8'> - 
    <button id='generate-map-btn'>Generate</button>
</p>
<p>
    Resources? <input type='checkbox' id='select-resources'> <button id='scatter-resources-btn'>Scatter</button> - 
    Colour: <select id='select-colour'>
        <option value='0'>None</option>
        <option value='1'>Sunset</option>
        <option value='2'>Night</option>
        <option value='3'>Misty</option>
        <option value='4'>Flames</option>
    </select> Weather: <select id='select-weather'>
        <option value='0'>None</option>
        <option value='1'>Snow</option>
        <option value='2'>Rain</option>
        <option value='3'>Dust</option>
        <option value='4'>Mist</option>
    </select>
</p>

<table>
    <tr>
        <th>Layer</th>
        <th>Chance</th>
        <th>Birth</th>
        <th>Death</th>
        <th>Steps</th>
        <th>Options</th>
        <th>On?</th>
        <th>In?</th>
    </tr>
    <tr>
        <td>Basic</td>
        <td>
            <input type='number' class='layer-settings' id='select-chance-1' value='0.4' min='0.1' max='0.9' step='0.1' data-layer='1'>
        </td>
        <td>
            <input type='number' class='layer-settings' id='select-birth-1' min='1' max='6' value='4' data-layer='1'>
        </td>
        <td>
            <input type='number' class='layer-settings' id='select-death-1' min='1' max='6' value='3' data-layer='1'>
        </td>
        <td>
            <input type='number' class='layer-settings' id='select-steps-1' min='1' max='6' value='4' data-layer='1'>
        </td>
        <td>
            <button class='generate-layer-btn' data-layer='1'>Random</button>
        </td>
        <td>-</td>
        <td>-</td>
    </tr>
    <tr>
   ...

CSS

div, img, canvas, table, tr, td, th, input, select {
    box-sizing: border-box;
}

input {
    width: 50px;
}

table {
    width: 100%;
    max-width: 700px;
    border-collapse: collapse;
    text-align: center;
}
table th {
    padding: 3px 5px;
    border: 1px solid grey;
    background-color: silver;
}
table td {
    padding: 3px 5px;
    border: 1px solid silver;
}


.map_holder {
    font-size: 0px;
}

.map_tile {
    width: 16px;
    height: 16px;
    display: inline-block;
    margin: 0px;
    position: relative;
}

.map_tile img {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 100%;
}

JavaScript

// 0 is dead (walls), 1 is alive (open area).

const db = {

    // Scattered randomly over maps.
    // Specify which terrains they appear on,
    // and in which weathers (if all, omit).
    resources: [
        {id: 1, name: "Deer", hex: ""},
        {id: 2, name: "Rabbit", hex: ""},
        {id: 3, name: "Salmon", hex: ""},
        {id: 4, name: "Beehive", hex: ""},
        {id: 5, name: "Koi", hex: ""},
        {id: 6, name: "Mine", hex: ""},
        {id: 7, name: "Snow Hare", hex: ""},
        {id: 8, name: "Ice Dragon", hex: ""},
        {id: 9, name: "Mist Dragon", hex: ""},
        {id: 10, name: "Pheasant", hex: ""}
    ],
    
    // May only appear once per map.
    npcs: [],
    
    
    // Specify layers of terrain, and 
    // resources that can appear on them.
    // Need 2 default terrain types + tiles too.
    maps: [
        {
            id: 1, area: 1, season: 1, time: 1,
            layers: [
                {
                    name: "Water", hex: "",
                    chance: 0.4, steps: 3,
                    birth: 4, death: 3,
                    display: true, inside: true,
                    passable: 1
                }
            ],
            resources: [
                {
                    id: 1, chance: 0.04,
                    layer: [3,4],
                    weather: [1,2],
                    moves: "away" // toward/random/no
                }
            ]
        }
    ],
    
    
    areas: [
        {id: 1, name: "Flooded Cavern"},
        {id: 2, name: "Tropical Island"},
        {id: 3, name: "Volcanic Cavern"},
        {id: 4, name: "Dusty Canyon"},
        {id: 5, name: "Snow Island"}
    ]
};

class CellMap {

    constructor(){
        this.canvas = document.getElementById("map-canvas");
        this.ctx = this.canvas.getContext("2d");
        
        this.getSettings();
        this.generate();
    }
    
    // Fetch data from inputs on page.
    getSettings(){
        this.settings = {};
        
    ...