JSFiddle - React, Tailwind, and code Playground
by Kofod
HTML
<div id="coasterGame">
<canvas id="coasterCanvas" width="960" height="650"></canvas>
<div id="coasterHud">
<span>🎟 Tickets: <b id="ticketScore">0</b></span>
<span>❤️ Lives: <b id="lifeScore" >3</b></span>
</div>
<div id="coasterOverlay">
<div class="coasterCard">
<h1>🎢 Carnival Coaster</h1>
<p>
Don't hit the clowns.<br>
Collect tickets, but do not fall through the gaps!
</p>
<button id="coasterStart">Start ride</button>
</div>
</div>
</div>
CSS
body {
margin: 0;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #f5edf3;
font-family: Arial, Geneva, sans-serif;
}
#coasterGame {
width: 960px;
height: 650px;
position: relative;
overflow: hidden;
margin: 0 auto;
background: #ffe2ec;
font-family: Arial, Geneva, sans-serif;
box-shadow: 0 8px 20px rgba(90, 45, 70, 0.25);
}
#coasterCanvas {
width: 960px;
height: 650px;
display: block;
}
#coasterHud {
position: absolute;
top: 12px;
left: 12px;
right: 12px;
z-index: 5;
display: flex;
justify-content: space-between;
pointer-events: none;
}
#coasterHud span {
background: rgba(255, 255, 255, 0.82);
border: 2px solid #ff9abb;
color: #6b2844;
padding: 7px 12px;
border-radius: 999px;
font-weight: bold;
font-size: 14px;
}
#coasterHud span:last-child {
transform: translateX(-25px);
}
#coasterOverlay {
position: absolute;
inset: 0;
z-index: 10;
background: rgba(80, 34, 63, 0.45);
display: flex;
align-items: center;
justify-content: center;
text-align: center;
color: #5c2340;
}
#coasterOverlay.hidden {
display: none;
}
.coasterCard {
width: 500px;
padding: 28px;
border-radius: 18px;
background: #fff7bd;
border: 4px solid #ff9abb;
box-shadow: 0 8px 0 #d86f96;
}
.coasterCard h1 {
margin: 0 0 10px;
color: #d84d7c;
font-size: 38px;
}
.coasterCard p {
font-size: 16px;
line-height: 1.5;
}
.coasterCard button {
border: 0;
background: #ff6f9f;
color: white;
padding: 11px 24px;
border-radius: 999px;
font-weight: bold;
cursor: pointer;
font-size: 15px;
box-shadow: 0 5px 0 #bd3e6c;
}
.coasterCard button:hover {
transform: translateY(2px);
box-shadow: 0 3px 0 #bd3e6c;
}
JavaScript
(function () {
var canvas = document.getElementById("coasterCanvas");
var ctx = canvas.getContext("2d");
var overlay = document.getElementById("coasterOverlay");
var startBtn = document.getElementById("coasterStart");
var ticketText = document.getElementById("ticketScore");
var lifeText = document.getElementById("lifeScore");
var root = document.getElementById("coasterGame");
var W = canvas.width;
var H = canvas.height;
/*
INSERT YOUR OWN IMAGE URLS HERE.
Cart = is the
Ferris wheel = Background decoration
Tent = Background decoration
Barrel = Obstacle on the tracks, used to be barrels but switched with clowns to fit theme
Ticket = VP themed? Also collectables*/
var IMAGE_URLS = {
cart: "https://i.postimg.cc/0QwN2H8c/Circus-(1).png",
ferrisWheel: "https://i.postimg.cc/1XnLwLgq/Circus.gif",
tent: "https://i.postimg.cc/DyzWk699/Circus.png",
barrel: "https://i.postimg.cc/s2bxpRx9/httpsi-postimg-cc-Ssz-X5x-Hyimage-png.png",
ticket: "https://i.postimg.cc/4y7mcS4P/Design-uden-navn-(49).png"
};
/*
IMAGE SIZE SETTINGS
You can adjust these depending on how you want your game to look. */
var IMAGE_SETTINGS = {
cart: {
width: 105,
height: 80,
offsetX: -52,
offsetY: -42
},
ferrisWheel: {
width: 230,
height: 230,
offsetX: -115,
offsetY: -115
},
tent: {
width: 175,
height: 145,
offsetY: -145
},
barrel: {
width: 84,
height: 84,
offsetX: -25,
offsetY: -84
},
ticket: {
width: 42,
height: 30,
offsetX: -21,
offsetY: -15
}
};
var images = {};
function makeImage(name, url) {
images[name] = {
img: new Image(),
loaded: false,
failed: false
};
if (!url) {
images[name].failed = true;
return;
}
...