JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

Explore test.

<hr>
<!-- Testing only! -->
<div id='rex-testing'>
    <!--<button id='rex-test-heal'>Heal</button>--> 
    <select id='rex-test-locations'></select>
    <button id='rex-test-teleport'>Teleport there!</button> --- 
    <select id='rex-test-dialogues'></select>
    <button id='rex-test-dialogue'>Start dialogue!</button>
</div>

<div id='rex-container'>

    <!-- Scene -->
    <div id='rex-scene'>
    
        <!-- Background/view of the area -->
        <div id='rex-bg'></div>
        
        <!-- Up to 4 encounters may appear in here. -->
        <div id='rex-encs'></div>
        
        <!-- After doing sth, show result here? -->
        <div id='rex-result'>...</div>

        <!-- If nothing appears, describe the empty scene. -->
        <div id='rex-empty'>...</div>
        
    </div>
    
    <!-- Controls and status -->
    <div id='rex-controls'>

        <!-- Minimap -->
        <div id='rex-map-container'>[tiles here]</div>
    
        <!-- Info about tile you're currently on -->
        <div id='rex-region-name'>[region name]</div>
        <div id='rex-region-desc'>[region desc]</div>
    
        <!-- Choose direction to move in -->
        <div id='rex-compass'>
            <div class='rex-arrow rex-n' data-dir='n'>N</div>
            <div class='rex-arrow rex-s' data-dir='s'>S</div>
            <div class='rex-arrow rex-e' data-dir='e'>E</div>
            <div class='rex-arrow rex-w' data-dir='w'>W</div>
            <div class='rex-arrow rex-ne' data-dir='ne'>NE</div>
            <div class='rex-arrow rex-nw' data-dir='nw'>NW</div>
            <div class='rex-arrow rex-se' data-dir='se'>SE</div>
            <div class='rex-arrow rex-sw' data-dir='sw'>SW</div>
            <div class='rex-arrow rex-x' data-dir='x'>Stay</div>
        </div>
    
        <!-- Choose travel mode -->
        <div id='rex-travel-container'>
            <div><b>Travel mode:</b></div>
            <div class='travel-option' id='mode-1'...

CSS

/* Stop padding, borders etc changing sizes. */
div, span, img, button, p, a {
    box-sizing: border-box;
}

body {
    background-image: url("https://cmkt-image-prd.freetls.fastly.net/0.1.0/ps/6822548/600/400/m2/fpnw/wm1/hl4nswi37es20ha9edxwgr75t4paw77olrgrdokhzkt3glthhpt4asdkekl3qbpn-.jpg?1565862124&s=c83b2af95cc7a12a6d82ac4bbbee4f6b");
    background-size: 100% 120%; /* cover */
    background-position: center;
    background-attachment: fixed;
}

#rex-container {
    width: 800px;
    margin: 20px auto;
}


/* HP and EXP, both yours and enemy's. */
.bar-outer {
    display: inline-block;
    width: 120px;
    height: 20px;
    position: relative;
    border-radius: 3px;
}
.bar-inner {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
}

/* Containers. */
.hp-outer {
    border: 1px solid darkgreen;
}
.exp-outer {
    border: 1px solid brown;
}
/* Inner sections. Width will vary. */
.hp-inner {
    background-color: green;
}
.exp-inner {
    background-color: gold;
}


/* SCENE */

/* BG image fills whole section. */
#rex-scene {
    border: 1px solid black;
    position: relative;
    width: 800px;
    height: 300px;
}
#rex-bg {
    z-index: -2;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
#rex-bg img {
    width: 100%;
    height: 100%;
}

/* Encounters */
#rex-encs {
    border: 1px dotted red;
    display: flex;
    flex-flow: row;
    padding-top: 30px;
    justify-content: space-evenly;
    align-items: center;
}
#rex-encs .rex-enc {
    width: 180px;
    border: 1px solid black;
    padding: 130px 5px 20px 5px;
    background-color: #fff;
    background-size: cover;
    text-align: center;
}
#rex-encs .rex-enc .enc-dark {
    background-color: rgba(0, 0, 0, 0.8);
    color: #fff;
    padding: 5px;
}

#rex-encs .rex-enc .enc-name {
    font-style: bold;
    margin-bottom: 5px;
    border-bottom: 1px solid grey;
    padding-bottom: 5px;
}
#rex-encs .rex-enc .enc-info {
    border: 1px solid...

JavaScript

const db = {

    griffins: [],

    // Paths for loading images
    tilePath: "http://images.neopets.com/nq/tp/",
    enemyPath: "http://images.neopets.com/nq/m/",
    
    // Map landmarks. Can teleport between them, for testing.
    cities: [
        {id: 1, name: "Capital City", map: 1, x: 7, y: 0},
        //{id: 2, name: "Jungle Ruins", map: 1, x: 8, y: 8},
        //{id: 3, name: "Swamp Edge City", map: 1, x: 12, y: 4},
        //{id: 4, name: "Temple of Ice", map: 1, x: 15, y: 11},
        //{id: 5, name: "Mountain Fortress", map: 1, x: 16, y: 13},
        {id: 6, name: "Magic Statue", map: 2, x: 6, y: 6},
        {id: 7, name: "Circle Palace", map: 3, x: 6, y: 6}
    ],
    
    rex_map_features: [],
    
    
    // Player inventory is stored elsewhere
    items: [
        {id: 1, name: "Healing Potion"},
        {id: 2, name: "Crystal Ball"},
        {id: 3, name: "Quartz"},
        {id: 4, name: "Diamond"},
        {id: 5, name: "Tropical Fruits"},
        {id: 6, name: "Gold Nugger"},
        {id: 7, name: "Rusty Medallion"},
        {id: 8, name: "Fancy Hat"}
    ],
   
    // What image URL to use for each tile number.
    terrainTiles: [
        "water", // handled differently
        "grassland",
        "desert",
        "castle",
        "ruins",
        "hills",
        "dirt",
        "forest",
        "mountain",
        "city",
        "jungle",
        "cave",
        "stone",
        "swamp",
        "dungeon",
        "dungeon_barrel",
        "dungeon_chair",
        "dungeon_table",
        "dungeon_pillar",
        "dungeon_crate"
      ],
    // These appear on top of any terrain. Separate IDs
    spriteTiles: [
          "dungeon_up",
          "dungeon_down",
          "cave_ent",
          "cave_exit",
          "dungeon_portal",
          "dungeon_door",
          "dungeon_door",
          "dungeon_door",
          "dungeon_door"
      ],
      
      
    // 'tiles' = which terrain images to display.
    // 'regions' = which...