JSFiddle - React, Tailwind, and code Playground
by Gwyn Milcote
HTML
choose portal: <select id='select-portal'></select>
<div id='mex-container'>
<div id='mex-map'></div>
<div id='mex-pets'></div>
<div id='mex-controls'></div>
<div id='mex-interact'></div>
</div>
<hr>
map editor, 4 image layers + interactive things in database.
<div id='editor-container'>
<!-- Settings, new/load map, etc. -->
<div id='editor-settings'>
<span>
<button id='create-map-btn'>New blank map</button>
</span>
<span>
<select id='select-map'>[js populate]</select>
<button id='load-map-btn'>Load map</button>
</span>
<span>
Show grid? <input type='checkbox' id='toggle-grid' checked>
</span>
<span>
Show all layers? <input type='checkbox' id='toggle-layers' checked>
</span>
</div>
<!-- Switch between layers/tabs. -->
<div id='layer-btns'>
<div class='layer-btn' data-layer='1'>Terrain</div>
<div class='layer-btn' data-layer='2'>Scenery</div>
<div class='layer-btn' data-layer='3'>Scenery 2/Zones</div>
<div class='layer-btn' data-layer='4'>Passability</div>
</div>
<!-- Spritesheet to click on, select. -->
<div id='tileset-container'></div>
<!-- Zoomed-in section of map. Tile canvas. -->
<div id='tiles-container'></div>
<!-- Pixel image, 600 x 300. -->
<div id='map-container'></div>
</div>
CSS
div, img, canvas, button, input {
box-sizing: border-box;
}
#mex-container {
}
#editor-container {
width: 970px;
}
#editor-container canvas {
cursor: pointer;
margin: auto;
}
/*
* Grid of tiles being edited. Small chunk of map.
* Click a tile on canvas to paint it.
*/
#tiles-container {
min-height: 200px;
background-color: silver;
margin: 20px 0;
}
#tiles-container canvas {
box-shadow: 0 0 0 1px blue;
}
/*
* Contains one tileset canvas.
* The image just switches between tilesets.
*/
#tileset-container {
height: 250px;
overflow: auto;
padding: 10px;
background-color: silver;
}
#tileset-container canvas {
margin: auto;
box-shadow: 0 0 0 1px blue;
}
/*
* Contains 2 canvases. On bottom, the actual
* pixel map. On top, transparent except for
* red square that indicates chunk being edited.
*/
#map-container {
height: 320px;
padding: 10px;
text-align: center;
background-color: silver;
position: relative;
}
#map-container canvas {
position: absolute;
top: 10px;
left: 180px;
box-shadow: 0 0 0 1px blue;
}
JavaScript
const db = {
/*
* Actual tile data (terrain, passable, zone)
* is stored in images. URL is "map{id}.png".
* Later add restrictions: month, time, special event...
*/
maps: [
{
id: 1, name: "Grass Continent",
type: "world", surround: 7
},{
id: 2, name: "Icy Continent",
type: "world", surround: 7
},{
id: 3, name: "Arid Continent",
type: "world", surround: 7
},{
id: 4, name: "Ocean Continent",
type: "world", surround: 7
},{
id: 5, name: "Forest Village",
type: "town", surround: 7
},{
id: 6, name: "Griffin City",
type: "town", surround: 7
},{
id: 7, name: "Fortress Ruins",
type: "town", surround: 7
},{
id: 8, name: "Dragon Shrine",
type: "town", surround: 7
},
],
/*
* Special tiles placed on maps.
* Pointing to somewhere else.
* Can be one-way, or in matching pairs.
*/
portals: [
{
id: 1, mapId: 1, mapX: 5, mapY: 5,
toMap: 2, toX: 8, toY: 8
},{
id: 2, mapId: 2, mapX: 8, mapY: 8,
toMap: 1, toX: 5, toY: 5
},{
id: 3, mapId: 1, mapX: 10, mapY: 10,
toMap: 3, toX: 8, toY: 8
},{
id: 4, mapId: 3, mapX: 8, mapY: 8,
toMap: 1, toX: 10, toY: 10
}
],
/*
* Wildlife and other interactive things
* that pop up while player moves around.
*/
world_resources: [
{
id: 1, name: "", sprite: "",
map: 1, zones: []
}
],
/*
* Similar to above, but visible on map
* and fixed (scattered when map's entered).
* Extra data for positioning, passability.
*/
town_resources: [
{
id: 1, name: "Farmer NPC", sprite: 6,
...