<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Frogger</title>
<style>
body {
background-color: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.points {
font-family: monospace;
color: white;
position: absolute;
margin-top: -390px;
}
.game-board {
font-family: monospace;
line-height: 1.2;
text-align: center;
overflow: hidden;
width: 280px;
height: 360px;
border: 2px solid #444;
position: relative;
}
.car {
position: absolute;
font-size: 36px;
}
.bike {
position: absolute;
font-size: 36px;
}
.aqua {
position: absolute;
font-size: 36px;
}
.sqm {
width: 40px;
height: 40px;
position: relative;
float: left;
}
.water {
background-color: blue;
}
.sidewalk {
background-color: brown;
}
.street {
background-color: gray;
}
.frog {
position: absolute;
font-size: 30px;
color: #fff;
width: 40px;
height: 40px;
}
.invert {
transform: rotateY(180deg)
}
</style>
</head>
<body>
<h1 class="points">0</h1>
<div class="game-board">
<div class="sqm sidewalk end"></div>
<div class="sqm sidewalk end"></div>
<div class="sqm sidewalk end"></div>
<div class="sqm sidewalk end"></div>
<div class="sqm sidewalk end"></div>
<div class="sqm sidewalk end"></div>
<div class="sqm sidewalk end"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm water"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm street"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="sqm sidewalk"></div>
<div class="aqua">🚁</div>
<div class="aqua">🚣</div>
<div class="aqua invert">🚣</div>
<div class="bike">🚴</div>
<div class="car">🚗</div>
<div class="car invert">🚓</div>
<div class="car invert">🚑</div>
<div class="car">🚗</div>
<div class="frog">🐸</div>
</div>
<script>
let state;
const positions = {};
// 🚁🚑🚣🚴🚓🚛🚎
const frogEl = document.querySelector('.frog');
const sqmSize = 40;
for (let x=0;x<9;x++) {
for (let y=0;y<8;y++) {
positions[''+y+x] = {x: sqmSize*y, y: sqmSize*x}
}
}
const initialState = {
points: 0,
side: 0,
sqm: '38',
objects: [{
sqm: '65',
direction: 'L',
moveFactor: 14,
timeCounter: 0,
el: document.querySelectorAll('.car')[0]
}, {
sqm: '26',
direction: 'R',
moveFactor: 10,
timeCounter: 0,
el: document.querySelectorAll('.car')[1]
}, {
sqm: '06',
direction: 'R',
moveFactor: 10,
timeCounter: 0,
el: document.querySelectorAll('.car')[2]
}, {
sqm: '67',
direction: 'L',
moveFactor: 20,
timeCounter: 0,
el: document.querySelectorAll('.car')[3]
}, {
sqm: '64',
direction: 'L',
moveFactor: 20,
timeCounter: 0,
el: document.querySelectorAll('.bike')[0]
}, {
sqm: '61',
direction: 'L',
moveFactor: 10,
timeCounter: 0,
el: document.querySelectorAll('.aqua')[0]
}, {
sqm: '02',
direction: 'R',
moveFactor: 10,
timeCounter: 0,
el: document.querySelectorAll('.aqua')[1]
}, {
sqm: '63',
direction: 'L',
moveFactor: 20,
timeCounter: 0,
el: document.querySelectorAll('.aqua')[2]
}]
};
window.addEventListener("keydown", ({key}) => {
const {sqm} = state;
const [x,y] = sqm.split('');
switch (key) {
case 'w':
if (y == 0) return;
state.sqm = String(x)+(y-1);
break;
case 'a':
if (x == 0) return;
state.sqm = String(x-1)+y;
break;
case 'd':
if (x == 6) return;
state.sqm = String(parseInt(x)+1)+y;
break;
case 's':
if (y == 8) return;
state.sqm = String(x)+(parseInt(y)+1);
break;
}
});
function eventLoop() {
frogEl.style.top = positions[state.sqm].y + 'px';
frogEl.style.left = positions[state.sqm].x + 'px';
for (let o of state.objects) {
o.el.style.top = positions[o.sqm].y + 'px';
o.el.style.left = positions[o.sqm].x + 'px';
let [x,y] = o.sqm.split('');
if (o.timeCounter === o.moveFactor && o.direction == 'L') {
o.sqm = String(x-1>-1 ? x-1 : 7)+y;
o.timeCounter = 0;
} else if (o.timeCounter === o.moveFactor && o.direction == 'R') {
x = parseInt(x);
o.sqm = String(x+1<7 ? x+1 : 0)+y;
o.timeCounter = 0;
}
o.timeCounter++;
}
colisionCheck();
pointCheck();
document.querySelector('.points').innerText = state.points;
}
function start() {
state = {initialState};
}
function pointCheck() {
const [x,y] = state.sqm.split('');
if (state.side && y == 8) {
state.points++;
state.side = 0;
} else if (state.side == 0 && y == 0) {
state.points++;
state.side = 1;
}
}
function colisionCheck() {
const {sqm, objects} = state;
for (let o of objects) {
if (o.sqm === sqm) {
start();
}
}
}
start();
window.setInterval(eventLoop, 20);
</script>
</body>
</html>
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.