Let’s create the Spiky Dasher Game using HTML, CSS, and JavaScript. This fast-paced mini game challenges players to dash forward, avoid deadly spikes, and survive as long as possible with quick reflexes and perfect timing.
We’ll use:
- HTML to structure the game area, player, and spikes.
- CSS to style the game with smooth animations and a clean arcade look.
- JavaScript to control movement, jumping, collision detection, and scoring.
This project is perfect for learning game logic, animations, and user interaction in the browser. Whether you’re a beginner or an experienced developer, the Spiky Dasher Game is a fun way to sharpen your JavaScript skills and build an addictive mini game. Let’s dash into the code and dodge those spikes! ⚡🕹️
HTML :
This HTML sets up the basic structure of the Spiky Dasher game. It defines the page title and links the external CSS for styling and JavaScript for game logic. Inside the body, a main game container holds the player, alert messages, death counter, and time counter. The comments indicate gameplay controls like arrow keys and double jump, while all actual game behavior and animations are handled by the linked script.js.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Spiky Dasher Game | @coding.stella</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- arrow keys to move and jump -->
<!-- also a double jump -->
<div id='game_console'>
<div id='player2'></div>
<div id='game_alert'></div>
<div id='deaths_counter'></div>
<div id='time_counter'></div>
</div>
<script src="./script.js"></script>
</body>
</html>
CSS :
This CSS file sets up fonts, icons, resets, and core styling for the animated gaming website. It loads custom fonts and an icon font, then applies a global reset to remove default margins and ensure consistent box sizing. Base styles define typography, colors, layout structure, and responsive containers.
It styles reusable components like buttons with smooth hover text animations, a full-screen preloader with a progress bar, and utility classes like visually-hidden for accessibility. The menu styles handle layout, alignment, and animated underline effects on hover. Overall, this CSS creates a clean foundation, smooth animations, and a modern UI look for the site.
:root {
--root-clr: dimgray;
--tile-line-height: 30px;
--tile-size: 10px;
--clr: gray;
--pl-clr:
radial-gradient(circle at 75% 50%, white 1px, transparent 2px),
radial-gradient(circle at 25% 50%, white 1px, transparent 2px),
radial-gradient(circle at 75% 40%, black 3px, transparent 4px),
radial-gradient(circle at 25% 40%, black 3px, transparent 4px),
white;
}
html,
body {
min-width: 100vw;
min-height: 100vh;
overflow: hidden;
margin: 0;
display: grid;
place-items: center;
background: #111;
}
#game_console {
width: 100%;
max-width: 1000px;
aspect-ratio: 16 / 9;
position: relative;
background:
linear-gradient(to bottom, rgba(0, 0, 0, .65), rgba(0, 0, 0, 1)),
var(--root-clr);
text-align: center;
line-height: var(--tile-line-height);
font-size: 0;
color: transparent;
user-select: none;
box-shadow:
0 20px 20px black;
/* overflow: hidden; */
}
#deaths_counter,
#time_counter {
padding: 0rem 1rem;
font-size: 16px;
font-family: system-ui, serif;
line-height: 100%;
color: white;
/* background: rgba(0,0,0,.75); */
position: absolute;
}
#deaths_counter {
top: 0;
left: 0;
transform: translate(0%, -125%);
/* text-align: left; */
}
#time_counter {
top: 0;
right: 0;
transform: translate(0%, -125%);
/* text-align: right; */
}
#game_alert {
padding: 1rem 2rem;
font-size: 16px;
font-family: system-ui, serif;
line-height: 100%;
color: white;
background: rgba(0, 0, 0, .75);
border: 1px dashed white;
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, 125%);
z-index: 99999;
border-radius: 50px;
transition: .5s;
opacity: 0;
pointer-events: none;
user-select: none;
}
h2 {
margin: 0;
margin-bottom: 10px;
}
.tile {
/* outline: 1px dashed rgba(0,0,0,.5); */
}
.ground {
background: var(--root-clr);
box-sizing: border-box;
border-top: 5px solid rgba(0, 0, 0, .25);
border-right: 5px solid rgba(0, 0, 0, .65);
border-bottom: 5px solid rgba(0, 0, 0, .65);
border-left: 5px solid rgba(0, 0, 0, .25);
outline: 0;
z-index: 2;
/* filter: brightness(.75); */
}
.innerwall {
background: var(--root-clr);
outline: 0;
}
/* lava spikes */
.lava {
background:
conic-gradient(at 50% 0%, transparent 0deg 153deg, rgba(0, 0, 0, .5) 155deg 190deg, rgba(255, 255, 255, .5) 192deg 205deg, transparent 207deg 360deg),
conic-gradient(at 50% 0%, transparent 0deg 153deg, var(--root-clr) 155deg 195deg, var(--root-clr) 197deg 205deg, transparent 207deg 360deg);
}
.spleft {
transform: rotate(-90deg);
}
.sptop {
transform: rotate(180deg);
}
.spright {
transform: rotate(90deg);
}
.portal1:after,
.portal2:after {
content: '';
width: 150%;
height: 150%;
position: absolute;
top: -25%;
left: 0;
background:
radial-gradient(circle at 50% 50%,
rgba(0, 0, 0, 1) 3px,
rgba(0, 0, 0, .75) 6px,
rgba(0, 0, 0, .75) 10px,
rgba(0, 0, 0, .5) 11px,
rgba(0, 0, 0, .5) 15px,
rgba(0, 0, 0, .25) 16px,
rgba(0, 0, 0, .25) 20px),
var(--root-clr);
animation: portal 2s linear infinite;
/* box-shadow:
inset 3px 0 0 3px rgb(0 0 0 / 25%),
3px 0px 0 2px rgb(255 255 255 / 50%); */
pointer-events: none;
border-radius: 50%;
}
@keyframes portal {
50% {
transform: scale(1.1);
}
}
.nextlevel {
/* background:
linear-gradient(to bottom right, transparent 10%, var(--root-clr) 10% 30%, transparent 30% 60%, var(--root-clr) 60% 80%, transparent 80%);
background-size: 25px 25px; */
}
#player,
#player:after {
content: '';
width: 25px;
height: 25px;
background: transparent;
position: absolute;
z-index: 10000;
pointer-events: none;
}
#player:before {
content: '';
width: 25px;
height: 25px;
position: absolute;
left: 0;
top: 0;
background:
radial-gradient(circle at 85% 15%, LightSeaGreen 3px, transparent 4px),
radial-gradient(circle at 15% 15%, LightSeaGreen 3px, transparent 4px),
radial-gradient(circle at 65% 90%, LightSeaGreen 2px, transparent 3px),
radial-gradient(circle at 35% 90%, LightSeaGreen 2px, transparent 3px);
}
#player:after {
width: 20px;
height: 25px;
background:
linear-gradient(to top, LightSeaGreen 0%, transparent 0%),
radial-gradient(circle at 60% 40%, PaleTurquoise 2px, transparent 3px),
radial-gradient(circle at 50% 50%, black 5px, transparent 6px),
DarkTurquoise;
position: absolute;
top: -2.5px;
left: 2.5px;
z-index: 10000;
border-radius: 50% 60% 50% 50% / 70% 70% 40% 40%;
pointer-events: none;
box-shadow:
inset 2px 2px 3px 3px rgba(255, 255, 255, .5),
inset -2px -2px 3px 3px rgba(0, 0, 0, .33);
animation: blink 4s linear infinite;
}
@keyframes blink {
5% {
background:
linear-gradient(to bottom, LightSeaGreen 35%, transparent 35%),
radial-gradient(circle at 60% 40%, PaleTurquoise 2px, transparent 3px),
radial-gradient(circle at 50% 50%, black 5px, transparent 6px),
DarkTurquoise;
}
10% {
background:
linear-gradient(to bottom, LightSeaGreen 60%, transparent 60%),
radial-gradient(circle at 60% 40%, PaleTurquoise 2px, transparent 3px),
radial-gradient(circle at 50% 50%, black 5px, transparent 6px),
DarkTurquoise;
}
15% {
background:
linear-gradient(to bottom, LightSeaGreen 0%, transparent 0%),
radial-gradient(circle at 60% 40%, PaleTurquoise 2px, transparent 3px),
radial-gradient(circle at 50% 50%, black 5px, transparent 6px),
DarkTurquoise;
}
}
/* player 2 player 2 player 2 */
#player2,
#player2:after {
content: '';
width: 25px;
height: 25px;
background: transparent;
position: relative;
z-index: 10000;
pointer-events: none;
}
#player2:before {
content: '';
width: 25px;
height: 25px;
position: absolute;
left: 0;
top: 0;
background:
radial-gradient(circle at 65% 90%, white 2px, transparent 3px),
radial-gradient(circle at 35% 90%, white 2px, transparent 3px);
z-index: 10001;
}
#player2:after {
width: 20px;
height: 25px;
background:
radial-gradient(circle at 60% 30%, white 2px, transparent 3px),
radial-gradient(circle at 50% 40%, black 5px, transparent 6px),
linear-gradient(to top, white, gold, orangered 50%),
orangered;
position: absolute;
top: -4px;
left: 2.5px;
z-index: 10000;
border-radius: 15px 15px 4px 4px;
pointer-events: none;
animation: blink2 4s linear infinite;
}
@keyframes blink2 {
5% {
background:
linear-gradient(to top, transparent 75%, orangered 75%),
radial-gradient(circle at 60% 30%, white 2px, transparent 3px),
radial-gradient(circle at 50% 40%, black 5px, transparent 6px),
linear-gradient(to top, white, gold, orangered 50%),
orangered;
}
10% {
background:
linear-gradient(to top, transparent 50%, orangered 50%),
radial-gradient(circle at 60% 30%, white 2px, transparent 3px),
radial-gradient(circle at 50% 40%, black 5px, transparent 6px),
linear-gradient(to top, white, gold, orangered 50%),
orangered;
}
15% {
background:
linear-gradient(to top, transparent 100%, orangered 100%),
radial-gradient(circle at 60% 30%, white 2px, transparent 3px),
radial-gradient(circle at 50% 40%, black 5px, transparent 6px),
linear-gradient(to top, white, gold, orangered 50%),
orangered;
}
}
.goleft:after {
transform: skewX(10deg);
}
.goright:after {
transform: skewX(-10deg);
}
.goleft:before,
.goright:before {}
.trailBall {
position: absolute;
width: 3px;
height: 3px;
background: darkorange;
border-radius: 50%;
opacity: .75;
pointer-events: none;
opacity: 1;
animation: trail .75s linear forwards;
}
@keyframes trail {
100% {
transform: translateY(-25px);
opacity: 0;
}
}
JavaScript:
This JavaScript builds and runs the entire game logic. It creates levels from grid maps, places tiles and the player, applies gravity, jumping, double jump, wall sliding, and left/right movement using keyboard or gamepad input. The game loop constantly checks collisions with ground, lava, portals, and level exits, updates player position, tracks time and deaths, and reloads levels when needed, while also adding small visual effects like trails for smooth gameplay.
const gc = document.querySelector('#game_console')
const gc_loc = gc.getBoundingClientRect()
const player = 'player2'
var pl;
var cols = 40 // multiple of 16
var rows = 22 // multiple of 9
const tile_size = gc_loc.width * (100 / cols / 100)
const pl_size = tile_size * 2
document.body.style.setProperty('--tile-line-height', pl_size + 'px')
gc.style.width = '1000px'
gc.style.height = tile_size * rows + 'px'
var gravity = 8,
kd,
x_speed = 5,
pb_y = 0,
score = 0,
rot = 0,
data_p = 0,
bonus = 1,
dead = false,
kd_list = [],
d = {},
gp,
gpa,
dbljump = false,
dash = false,
timer = 0,
level_num = -1;
const levels = [
{
start: '19.5,0',
map: [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 9, 9, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]
},
{
start: '19.5,0',
map: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 8, 8, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8, 8, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
8, 8, 8, 8, 0, 1, 1, 1, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 1, 1, 1, 1, 0, 8, 8, 8, 8,
8, 8, 8, 8, 0, 2, 2, 2, 2, 2, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 2, 2, 2, 2, 2, 0, 8, 8, 8, 8,
8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8]
},
{
start: '2,13',
map: [8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8, 0, 0, 0, 0, 8, 8, 8, 0, 1, 1, 1, 1, 0, 8, 8, 8, 0, 0, 0, 0, 0, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 0, 8, 8, 8, 0, 1, 1, 1, 1, 0, 8, 0, 0, 0, 1, 1, 1, 0, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 0, 8, 8, 8, 0, 1, 1, 1, 1, 0, 8, 0, 1, 1, 1, 1, 1, 0, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 0, 8, 8, 8, 0, 1, 1, 1, 1, 0, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 0, 8, 8, 8, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 8, 8, 8, 8, 8,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 8, 8, 8, 8, 8,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 8, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 0, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 8, 8, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 0, 1, 1, 1, 1, 1, 0, 8, 8, 8, 8, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 8,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 8, 0, 2, 2, 2, 2, 2, 0, 8, 8, 8, 8, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
8, 8, 8, 8, 0, 1, 1, 1, 1, 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 0, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
8, 8, 8, 8, 0, 2, 2, 2, 2, 2, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
},
{
start: '1,2',
map: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 6, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 0, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 0, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 9,
0, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 9,
0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
8, 8, 8, 8, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 8, 8, 8, 8,
8, 8, 8, 8, 0, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 0, 8, 8, 8, 8,
8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8]
},
{
start: '1,2',
map: [0, 0, 0, 0, 0, 8, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 8, 8, 8, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0,
0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0,
0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 9,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 9,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 9,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 9,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 9,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 9,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
8, 8, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 0, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8, 8,
8, 8, 8, 8, 0, 2, 2, 2, 2, 2, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8, 8,
8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8]
},
{
start: '2,13',
map: [8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8, 0, 0, 0, 0, 8, 8, 8, 0, 1, 1, 1, 1, 0, 8, 8, 8, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 0, 8, 8, 8, 0, 1, 1, 1, 1, 0, 8, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 0, 8, 8, 8, 0, 1, 1, 1, 1, 0, 8, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 0, 8, 8, 8, 0, 1, 1, 1, 1, 0, 8, 0, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 0, 8, 8, 8, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,
8, 0, 1, 1, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8, 8, 8, 8, 8, 8,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 8, 8, 8, 8, 8,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 8, 8, 8, 8, 8,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 8, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8,
1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 8, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 8, 8,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 8,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
8, 8, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
8, 8, 8, 8, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
}
]
function buildGame() {
// clear tiles and update level number
gc.innerHTML = "<div id='" + player + "'></div><div id='game_alert'></div><div id='deaths_counter'></div><div id='time_counter'></div>"
if (level_num < levels.length - 1) {
level_num++
} else {
level_num = 0
}
let time = 0
let deaths = 0
let tc = document.querySelector('#time_counter')
let dc = document.querySelector('#deaths_counter')
tc.innerHTML = 'TIME<br>' + time
dc.innerHTML = 'DEATHS<br>' + deaths
// set random level color
document.body.style.setProperty('--root-clr', 'hsl(' + Math.random() * 360 + 'deg,75%,50%)')
// add tiles for new level
for (var i = 0; i < cols * rows; i++) {
var d = document.createElement('div')
d.className = 'tile'
if (levels[level_num].map[i] == 0) {
d.className = 'tile ground'
// d.style.background = 'dimgray'
}
if (levels[level_num].map[i] == 2) {
d.className = 'tile lava'
}
if (levels[level_num].map[i] == 3) {
d.className = 'tile lava spleft'
}
if (levels[level_num].map[i] == 4) {
d.className = 'tile lava sptop'
}
if (levels[level_num].map[i] == 5) {
d.className = 'tile lava spright'
}
if (levels[level_num].map[i] == 6) {
d.className = 'tile portal1'
}
if (levels[level_num].map[i] == 7) {
d.className = 'tile portal2'
}
if (levels[level_num].map[i] == 8) {
d.className = 'tile innerwall'
}
if (levels[level_num].map[i] == 9) {
d.className = 'tile nextlevel'
}
d.setAttribute('grid_loc', [i % cols, Math.floor(i / cols)])
d.style.width = tile_size + 'px'
d.style.height = tile_size + 'px'
d.style.position = 'absolute'
// d.innerHTML = i
// d.style.outline = '1px dotted gray'
d.style.left = (i % cols) * tile_size + 'px'
d.style.top = Math.floor(i / cols) * tile_size + 'px'
gc.appendChild(d)
}
// add player stuff
const ga = document.querySelector('#game_alert')
var pl = document.querySelector('#' + player)
pl.style.width = tile_size + 'px'
pl.style.height = tile_size + 'px'
pl.style.top = (tile_size * levels[level_num].start.split(',')[1]) + 'px'
pl.style.left = (tile_size * levels[level_num].start.split(',')[0]) + 'px'
// add info box
ga.innerHTML = 'Arrow keys to move and jump<br>double jump / wall sliding'
ga.style.opacity = '1'
var pl_loc = pl.getBoundingClientRect()
var x = pl_loc.left
function updatePlayer() {
// get points based on player location
var pl_loc = pl.getBoundingClientRect()
var pl_center = document.elementFromPoint(pl_loc.x + (tile_size * .5), pl_loc.y + (tile_size * .75))
var pl_xy1 = document.elementFromPoint(pl_loc.x + (pl_loc.width * .25), pl_loc.y + pl_loc.height + gravity)
var pl_xy2 = document.elementFromPoint(pl_loc.x + (pl_loc.width * .75), pl_loc.y + pl_loc.height + gravity)
var pl_xy3 = document.elementFromPoint(pl_loc.x - (x_speed * .5), pl_loc.y + (pl_loc.height * .5))
var pl_xy4 = document.elementFromPoint(pl_loc.x + pl_loc.width + (x_speed * .5), pl_loc.y + (pl_loc.height * .5))
var pl_xy5 = document.elementFromPoint(pl_loc.x + (pl_loc.width * .5), pl_loc.y - (gravity * .5))
var pl_xy6 = document.elementFromPoint(pl_loc.x + (pl_size * .5), pl_loc.y + pl_size)
// console.log(pl_center)
function endGame() {
alert('you died')
}
//if dead stop, else update player and everything else
if (!pl_xy1 || !pl_xy2 || dead) {
// endGame()
} else {
// set player top
// if player on ground set new top
if (pl_xy1.classList.contains('ground') ||
pl_xy2.classList.contains('ground')) {
gravity = 0
} else {
if (gravity < 8) {
gravity += .51
} else {
gravity = 8
}
}
pl.style.top = pl_loc.top - 6.25 - gc_loc.top + gravity + 'px'
// console.log(gravity)
var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads : []);
if (!gamepads) {
return;
}
var gp = gamepads[0];
// add jump-force (change the gravity)
if ((d[38]
|| (gp && (gp.buttons[0].pressed
|| gp.buttons[1].pressed
|| gp.buttons[2].pressed
|| gp.buttons[3].pressed)))
&& gravity == 0) {
dbljump = false
gravity = -9
}
if ((d[38]
|| (gp && (gp.buttons[0].pressed
|| gp.buttons[1].pressed
|| gp.buttons[2].pressed
|| gp.buttons[3].pressed)))
&& gravity > 0) {
if (!dbljump) {
gravity = -9
}
dbljump = true
}
if (gp) {
var gpa = Math.round(gp.axes[0])
if (gpa == 0 || gravity == 0) {
pl.className = ''
pl.style.transform = 'rotate(0deg)'
}
}
// track left/right movement
if ((d[37] || (gp && gpa == -1)) && x > gc_loc.x) {
if (!pl_xy3.classList.contains('ground')) {
x -= x_speed
pl.className = ''
pl.classList.add('goleft')
} else {
if (gravity > 0) {
dbljump = false
gravity = 1
pl.style.transform = 'rotate(90deg)'
}
pl.className = ''
}
}
// console.log(x_speed)
if ((d[39] || (gp && gpa == 1)) && x + pl_loc.width < gc_loc.x + gc_loc.width) {
if (!pl_xy4.classList.contains('ground')) {
x += x_speed
pl.className = ''
pl.classList.add('goright')
} else {
if (gravity > 0) {
dbljump = false
gravity = 1
pl.style.transform = 'rotate(-90deg)'
}
pl.className = ''
}
}
pl.style.left = x - gc_loc.left + 'px'
// pl.style.left = x + x_speed - gc_loc.left + 'px'
// set different interactions based on tile type
if (pl_xy5.classList.contains('ground')) {
gravity = 8
}
if (pl_center.classList.contains('lava')) {
// console.log('lava')
pl.style.top = (tile_size * levels[level_num].start.split(',')[1]) + 'px'
pl.style.left = (tile_size * levels[level_num].start.split(',')[0]) + 'px'
pl_loc = pl.getBoundingClientRect()
x = pl_loc.left
deaths++
dc.innerHTML = 'DEATHS<br>' + deaths
}
if (pl_center.classList.contains('portal1')) {
let p2 = document.querySelector('.portal2')
let p2_loc = p2.getBoundingClientRect()
pl.style.top = p2_loc.top - gc_loc.top + 'px'
pl.style.left = p2_loc.left - gc_loc.left + 'px'
pl_loc = pl.getBoundingClientRect()
x = pl_loc.left
}
if (pl_center.classList.contains('nextlevel')) {
buildGame()
}
timer++
function secondsToTime(e) {
var h = Math.floor(e / 3600).toString().padStart(2, '0'),
m = Math.floor(e % 3600 / 60).toString().padStart(2, '0'),
s = Math.floor(e % 60).toString().padStart(2, '0');
return h + ':' + m + ':' + s;
//return `${h}:${m}:${s}`;
}
tc.innerHTML = 'TIME<br>' + secondsToTime(timer)
playerTrail()
setTimeout(updatePlayer, 1000 / 45) // update player 30-60 times a second
}
}
updatePlayer()
// add trail behind player b/c it's fun
function playerTrail() {
if (player == 'player') {
let x = pl.getBoundingClientRect().x
let y = pl.getBoundingClientRect().y
let b = document.createElement('div')
b.className = 'trailBall'
b.style.left = x + 11 - gc_loc.left + 'px'
b.style.top = y + 5 - gc_loc.top + 'px'
b.onanimationend = function () {
b.remove()
}
gc.appendChild(b)
}
if (player == 'player2') {
let x = pl.getBoundingClientRect().x
let y = pl.getBoundingClientRect().y
let b = document.createElement('div')
b.className = 'trailBall'
let xx = Math.floor(Math.random() * 15) + 5
b.style.left = x + xx - gc_loc.left + 'px'
b.style.top = y - 3 - gc_loc.top + 'px'
b.onanimationend = function () {
b.remove()
}
gc.appendChild(b)
}
}
// key tracking
if (level_num > 0) {
window.addEventListener('keydown', function (e) {
d[e.which] = true;
})
window.addEventListener('keyup', function (e) {
d[e.which] = false;
pl.className = ''
pl.style.transform = 'rotate(0deg)'
})
window.addEventListener("gamepadconnected", function (e) {
var gp = navigator.getGamepads()[e.gamepad.index];
// console.log("A " + gp.id + " was successfully detected! There are a total of " + gp.buttons.length + " buttons.")
});
} else {
timer = 0
deaths = 0
}
}
window.addEventListener('load', buildGame)
window.focus()
In conclusion, building the Spiky Dasher Game using HTML, CSS, and JavaScript is a great way to explore browser-based game development. By combining simple visuals with responsive controls and collision logic, you can create an exciting and challenging game experience 🎮🔥
If you run into any problems with your project, worry not. The remedy is just a click away – Download the source code and confront your coding challenges with enthusiasm. Enjoy your coding adventure!
