JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

Location: <select id='ex-select-location'></select>
Season: <select id='ex-select-season'></select>
Time: <select id='ex-select-time'></select>
<button id='launch-explore-btn'>Explore</button>
<hr>
Map: <select id='battle-select-map'></select>
Pet: <select id='battle-select-pet'></select>
Enemy: <select id='battle-select-enemy'></select>
<button id='launch-battle-btn'>Battle</button>


<div id='container'>

<div id='battle-popup' style='display:none'>
   <div id='battle-container'>
        
        <!-- Top bar. -->
        <div id='battle-top'>
            <div id='battle-forfeit-btn' class='battle-top-btn'>Forfeit</div>
            <div id='battle-top-text'>
                Sparring/Ceremonial/Battle...
            </div>
            <div id='battle-close-btn' class='battle-top-btn'>Close</div>
        </div>
        
        <!-- Pretty background panel. -->
        <div id='battle-background'>
        
            <!-- Two fighter images. -->
            <div id='battle-fighter-images'>
                <div id='battle-enemy-image' class='battle-fighter-image'>ENEMY</div>
                <div id='battle-pet-image' class='battle-fighter-image'>PET</div>
            </div>
            
            <!-- Two panels with name, HP etc -->
            <div id='battle-fighter-panels'>
            
                <div class='battle-fighter-panel'>
                
                    <!-- Name. -->
                    <div id='battle-pet-name' class='battle-fighter-name'>
                        <a href=''>Enemy Name Here</a>
                    </div>
                    
                    <div class='battle-fighter-info'>
                    
                    <!-- HP, MP counts and bars. -->
                    <div class='battle-fighter-bars'>
                    
                        <div class='battle-fighter-bar'>
                            <div class='battle-bar-icon'></div>
                            <div id='battle-enemy-hp'...

CSS

/* Stop padding, borders etc changing sizes. */
div, span, img, button, p, a {
    box-sizing: border-box;
}
#container {
    width: 970px;
    height: 1000px;
}


/* Darken rest of screen while an important popup is active - like explore, battle, inventory item... */
#shade-overlay {
    z-index: 3;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.3);
}

#container {
    width: 970px;
    margin: auto;
}

#battle-popup {
    /* display: none; */
    z-index: 5;
    width: 800px;
    height: 550px;
    background-color: #fff;
    border: 1px solid #000;
    box-shadow: 0 0 40px 5px rgba(0, 0, 0, 0.4);
    /*position: fixed;
    top: calc(50% - 200px);
    left: calc(50% - 300px);*/
}
#battle-container {
    width: 100%;
    height: 100%;
}

/* Close/Forfeit buttons, and intro text. */
#battle-top {
    height: 45px;
    padding: 5px 10px;
    background-color: #fff;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
#battle-top .battle-top-btn {
    padding: 5px 10px;
    background-color: #eee;
    border: 1px solid silver;
}
#battle-top .battle-top-btn:hover {
    cursor: pointer;
    background-color: silver;
    border: 1px solid grey;
}
#battle-top-text {
    text-align: center;
    font-size: 20px;
}

/* Background scenery panel. */
#battle-background {
    height: 300px;
    background-image: url("https://i.pinimg.com/originals/1b/1a/e4/1b1ae4299375e41e3118e31cbb47c06c.jpg");
    background-size: cover;
}

/* Two images of fighters. */
#battle-fighter-images {
    padding-top: 30px;
    display: flex;
    justify-content: space-evenly;
}
.battle-fighter-image {
    width: 220px;
    height: 155px;
    background-color: rgba(255, 255, 255, 0.4);
    border: 1px dashed #000;
}

/* Status boxes for the two fighters. */
#battle-fighter-panels {
    position: relative;
    top: 25px;
    display: flex;
    justify-content: space-evenly;
    background-image:...

JavaScript

// This object acts like a database.
const db = {

    // Paths for loading images
    tilePath: "http://images.neopets.com/nq/tp/",
   
    // Temporary. IDs, names, XY and option text
    // are sent by server, just for rendering.
    enemies: [
        {
            id: 1, name: "Beached Glaucus", 
            option: "Attack", 
            map: 1, x: 9, y: 9
        },{
            id: 2, name: "Rabbit", 
            option: "Pounce", 
            map: 1, x: 11, y: 5
        },{
            id: 3, name: "Guinea Pig", 
            option: "Pounce", 
            map: 2, x: 6, y: 9
        },{
            id: 4, name: "Bird Nest", 
            option: "Search", 
            map: 2, x: 11, y: 11
        },{
            id: 5, name: "Dragon Nest", 
            option: "Search", 
            map: 3, x: 6, y: 9
        },{
            id: 6, name: "Salmon", 
            option: "Catch", 
            map: 3, x: 11, y: 8
        },{
            id: 7, name: "Pile of Sand", 
            option: "Dig", 
            map: 4, x: 6, y: 9
        },{
            id: 8, name: "Fruit Bush", 
            option: "Harvest", 
            map: 4, x: 10, y: 8
        },{
            id: 9, name: "Flower Patch", 
            option: "Harvest", 
            map: 1, x: 3, y: 3
        },{
            id: 10, name: "Koi", 
            option: "Catch", 
            map: 2, x: 2, y: 8
        },
    ],
    
    // Temporary. IDs, names and XY are sent
    // by server, just for rendering.
    npcs: [
          {id: 1, name: "Eleus", map: 1, x: 5, y: 4},
          {id: 2, name: "Choras", map: 2, x: 5, y: 5},
          {id: 3, name: "Mokti", map: 3, x: 6, y: 6},
          {id: 4, name: "Gali", map: 4, x: 5, y: 6},
          {id: 5, name: "Denethrir", map: 5, x: 5, y: 5},
          {id: 6, name: "Guard", map: 6, x: 5, y: 5},
          {id: 7, name: "Faleinn", map: 7, x: 5, y: 5},
          {id: 8, name: "Faleinn", map: 8, x: 5, y: 5}
    ],
    
    /*
    * Fightable creatures.
    * Small...