JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

<div id='container'>

<p>Little Dragon Game, by Gwyn Milcote. Work in progress.</p>

<div id='ldg-container'>

Biome: <select id='ldg-biome'>
    <option value='1'>Forest</option>
    <option value='2'>Swamp</option>
    <option value='3'>Taiga</option>
</select> 
Colour: <select id='ldg-colour'>
    <option value='1'>Gold</option>
    <option value='2'>Silver</option>
    <option value='3'>Black</option>
    <option value='4'>Purple</option>
    <option value='5'>Green</option>
    <option value='6'>Blue</option>
</select> 
Name: <input type='text' id='ldg-name' value='Little Al' maxlength='10'>
<button id='ldg-restart-btn'>Restart</button>

<div id='ldg-popup-container'>
    <div id='ldg-popup-title'>Oh dear...</div>
    <div id='ldg-popup-inner'>...</div>
    <div id='ldg-popup-close'>Close</div>
</div>

<div id='ldg-top'>
    
    <div id='ldg-right'>
    
        <div id='ldg-compass'>
            <button id='move-n' class='ldg-move-btn' data-dir='n'>North</button>
            <button id='move-s' class='ldg-move-btn' data-dir='s'>South</button>
            <button id='move-e' class='ldg-move-btn' data-dir='e'>East</button>
            <button id='move-w' class='ldg-move-btn' data-dir='w'>West</button>
            <button id='move-x' class='ldg-move-btn' data-dir='x'>Wait</button>
        </div>
        
        <div id='ldg-stats'>
        <div id='ldg-block'></div>
        
            <div class='ldg-stat'>
            Turns: <span id='ldg-turns'></span>
            </div>
            <div class='ldg-stat'>
            Energy: <span id='ldg-energy'></span>
            </div>
            <div class='ldg-stat'>
            HP: <span id='ldg-hp'></span>
            </div>
            <div class='ldg-stat'>
            MP: <span id='ldg-mp'></span>
            </div>
            <div class='ldg-stat'>
            Power: <span id='ldg-power'></span>
            </div>
            <div class='ldg-stat'>
            Speed: <span id='ldg-speed'></span>
           ...

CSS

img, div, button, p, span {
    box-sizing: border-box;
}

#container {
    /*width: 900px;
    margin: 20px auto;*/
}

#ldg-top, 
#ldg-bottom {
    width: 900px;
    margin: 10px auto;
    display: flex;
    flex-flow: row;
    justify-content: space-between;
}


#ldg-right {
    width: 280px;
    position: relative;
}
#ldg-compass,
#ldg-stats,
#ldg-terrain-info {
    position: absolute;
    background-color: #eee;
    border: 1px solid silver;
    padding: 5px;
}

#ldg-compass {
    top: 0;
    left: 0;
    height: 120px;
    width: 120px;
}
#ldg-compass .ldg-move-btn {
    position: absolute;
    width: 40px;
    height: 40px;
    background-color: #fff;
}
#ldg-compass .ldg-move-btn:hover {
    cursor: pointer;
    background-color: silver;
}
#move-n {
    top: 0;
    left: 40px;
}
#move-s {
    top: 80px;
    left: 40px;
}
#move-e {
    left: 80px;
    top: 40px;
}
#move-w {
    left: 0px;
    top: 40px;
}
#move-x {
    left: 40px;
    top: 40px;
}

/**/
#ldg-stats {
    top: 130px;
    left: 0;
    display: flex;
    flex-flow: row wrap;
}
#ldg-stats .ldg-stat {
    width: 50%;
}


/**/
#ldg-terrain-info {
    bottom: 0;
    left: 0;
}



#ldg-map-container {
    width: 610px;
    height: 410px;
    background-color: silver;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
}

/* Game board. Tiles are in here. Size can vary. */
#ldg-map {
    border: 2px solid black;
    line-height: 0px;
    margin: auto;
    position: relative;
}

/* Dark squares of un-visited areas. */
.ldg-tile {
    width: 20px;
    height: 20px;
    /*box-shadow: inset 0 0 1px 1px rgba(0, 0, 0, 0.2);*/
    display: inline-block;
    background-size: cover;
}
.ldg-tile-dark {
    width: 100%;
    height: 100%;
    background-color: #2d2d2d;
}

/* Sprite that moves around. */
#ldg-dragon {
    width: 20px;
    height: 20px;
    position: absolute;
    box-shadow: inset 0 0 2px 2px purple;
}


/**/
#ldg-reports {
    width: 280px;
   ...

JavaScript

/*
* Fixed stuff, for looking up only.
* Current game stats/progress are in LDG class.
*/
const db = {
    // Basic settings.
    path: "http://mythstable.epizy.com/ldg/",
    tileSize: 20,
    mapWidth: 30,
    mapHeight: 20,
    
    // Stats etc to start with, and save.
    // Used for validation too.
    data: [
        {name: "turns", type: "number", min: 0, default: 0},
        {name: "colour", type: "number", min: 1, max: 9, default: 1},
        {name: "maxHp", type: "number", min: 10, max: 1000, default: 10},
        {name: "maxMp", type: "number", min: 5, max: 200, default: 5},
        {name: "hp", type: "number", default: 10},
        {name: "mp", type: "number", default: 5},
        {name: "energy", type: "number", default: 80, min: 0, max: 100},
        {name: "power", type: "number", min: 3, max: 300, default: 3},
        {name: "speed", type: "number", min: 4, max: 300, default: 4},
        {name: "level", type: "number", min: 1, max: 100, default: 1},
        {name: "exp", type: "number", min: 0, default: 0},
        {name: "map", type: "number", min: 1, max: 3, default: 1},
        {name: "x", type: "number", min: 1, default: 1},
        {name: "y", type: "number", min: 1, default: 1},
        {name: "visited", type: "array", default: []},
        //{name: "encs", type: "array", default: []},
        {name: "spells", type: "array", default: [1]}
        // map generation
        //{name: "seed", type: "number", min: "1", max: "65500"},
    ],
    
    /*
    * Castable spells in battle.
    * No elements yet; all enemies affected equally.
    */
    spells: [
        {
            id: 1, name: "Spark", 
            mp: 3, power: 8
        },{
            id: 2, name: "Fire", 
            mp: 8, power: 12
        },{
            id: 3, name: "Spark2", 
            mp: 14, power: 8
        },{
            id: 4, name: "Fire2", 
            mp: 28, power: 12
        }
    ],
    
    /*
    * Interactive things to be encountered.
    */
   ...