JSFiddle - React, Tailwind, and code Playground
by Gwyn Milcote
HTML
Crappy map test. Use arrow keys or click-and-hold compass buttons to move.
<p>
Map: <select id='ex-settings-level'>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='3'>Three</option>
</select>
<button id='ex-load-level'>Load</button>
Move speed:
<select id='ex-settings-speed'>
<option value='100'>Snail</option>
<option value='150'>Slow</option>
<option value='200' selected>Normal</option>
<option value='250'>Fast</option>
<option value='300'>Cheetah</option>
</select>
<br>
Display closest tile?
<select class='ex-settings-select' data-type='closestTile'>
<option value='0'>No</option>
<option value='1' selected>Yes</option>
</select>
Display animated tiles?
<select class='ex-settings-select' data-type='animatedTile'>
<option value='0'>No</option>
<option value='1' selected>Yes</option>
</select>
Display tile grid?
<select class='ex-settings-select' data-type='gridTile'>
<option value='0' selected>No</option>
<option value='1'>Yes</option>
</select>
</p>
<p><button id='pause-btn'>Pause</button> - Image loading progress: <span id='loader-progress'></span> - Keys down: <span id='status-keys'></span>
<br>Direction moving: <span id='current-dir'>?</span></p>
<div id='ex-container'>
<div id='canvas-border'>
<div id='canvas-container'>
<canvas id='game-canvas' height='360' width='480'></canvas>
<div id='pause-overlay' style='display: none;'>
<h1>Paused</h1>
</div>
</div>
</div>
<div id='ex-compass'>
<div class='ex-arrow ex-n' data-key='W'>N</div>
<div class='ex-arrow ex-s' data-key='S'>S</div>
<div class='ex-arrow ex-e' data-key='D'>E</div>
<div class='ex-arrow ex-w'...
CSS
div, img, button, p, select, input {
box-sizing: border-box;
}
body {
background-color: #ddd;
}
#canvas-border {
border: 1px solid black;
background-color: silver;
padding: 10px;
}
#canvas-container {
position: relative;
width: 480px;
height: 360px;
}
#canvas-container #game-canvas {
position: absolute;
top: 0;
left: 0;
}
#canvas-container #pause-overlay {
position: absolute;
top: 0;
left: 0;
z-index: 2;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.5);
box-shadow: inset 0 0 50px 0px #fff;
text-align: center;
font-size: 40px;
padding-top: 80px;
}
#ex-container {
position: relative;
width: 800px;
height: 384px;
margin: 20px auto;
background-color: #fff;
border: 1px solid silver;
}
#ex-compass {
position: absolute;
top: 10px;
left: 520px;
width: 170px;
height: 170px;
/*border: 1px solid grey;*/
}
#ex-compass .ex-arrow {
width: 50px;
height: 50px;
position: absolute;
border: 1px solid brown;
background-color: gold;
transition: 0.3s;
}
#ex-compass .ex-arrow:hover {
cursor: pointer;
background-color: ivory;
transition: 0.3s;
}
.ex-n { top: 0; left: 60px; }
.ex-s { top: 120px; left: 60px; }
.ex-e { top: 60px; left: 120px; }
.ex-w { top: 60px; left: 0; }
.ex-ne { top: 0; left: 120px; }
.ex-nw { top: 0; left: 0; }
.ex-se { top: 120px; left: 120px; }
.ex-sw { top: 120px; left: 0; }
/*.ex-x { top: 40px; left: 40px; }*/
#ex-info-section {
position: absolute;
top: 190px;
left: 520px;
width: 260px;
max-height: 100px;
overflow: auto;
border: 1px solid silver;
padding: 5px;
}
JavaScript
/*
* Large pre-drawn images like trees. On top layer.
* Fixed at certain tile co-ords. Can reuse/repeat.
* Can be better than using lots of tiles!
* Need tiles for 'base'/low parts like trunks though,
* so those can appear behind the sprite.
*
* Need a standard size. And tiles are the top-left corners!
*/
const objects = [
{id: 1, name: "Tree 1", url: "https://tse4.mm.bing.net/th?id=OIP.S1ADFIED7QQrOx8ug3LsewAAAA&pid=Api"},
{id: 2, name: "Tree 2", url: "https://tse3.mm.bing.net/th?id=OIP.0xoU0azFfS2kphc4lZgUQgAAAA&pid=Api"},
{id: 3, name: "Tree 3", url: "https://tse1.mm.bing.net/th?id=OIP.HI3bfmyChdtjauA7J-d1pwAAAA&pid=Api"},
{id: 3, name: "Tree 4", url: "https://tse2.mm.bing.net/th?id=OIP.k9TIxKzt2vkidozGwyQg6QAAAA&pid=Api"},
{id: 3, name: "Tree 5", url: "https://tse2.mm.bing.net/th?id=OIP._EmTWBR32M21ag6-z0JtdAAAAA&pid=Api"}
];
const db = {
// Terrain layers, start coords...
maps: [
{
id: 1, name: "Forest",
startX: 5,
startY: 7,
cols: 16, rows: 16,
// Fixed images
objects: [
//{x: 8, y: 6, image: "tree2"},
//{x: 4, y: 10, image: "tree5"}
],
// 2 layers of visual tiles to render.
// Both below sprite. Graphical only.
layers: [
[
[25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25],
[25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25],
[25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25],
[25,25,25,25,25,25,25,25,25,25,25,12,25,25,25,25],
[25,25,25,25,25, 3, 3, 3,25,25,25,12,12,25,25,25],
[25,25,25,25,25, 3,25, 3,25,25,25,25,12,12,25,25],
[25,25,25,25,25, 3, 3, 3,25,25,25,25,12,25,25,25],
[25,25,25,25,25,25,25,25,25,25,25,12,12,25,25,25],
[26,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25],
[25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25],
...