<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>武士游戏角色控制</title>
<style>
@import url("https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap");
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-size: 62.5%;
font-optical-sizing: auto;
font-family: "Press Start 2P", system-ui;
font-weight: 400;
font-style: normal;
}
html,
body {
width: 100vw;
min-height: 100vh;
min-height: 100dvh;
}
body {
position: relative;
margin: 0;
background-color: #7c7c7c;
overflow-x: hidden;
display: grid;
grid-template-rows: repeat(2, auto);
align-items: center;
justify-items: center;
}
h1 {
margin: 0;
padding: 0;
&.logo {
color: #edab50;
font-size: clamp(4rem, 10vw, 8rem);
text-align: center;
text-transform: uppercase;
text-shadow: 0 5px 0 #dc7237, 0 15px 0 #8c241d;
}
}
.subheading {
margin-top: 2rem;
text-align: center;
}
.samurai {
position: absolute;
top: 50%;
left: 45%;
width: 96px;
height: 96px;
background-repeat: no-repeat;
image-rendering: pixelated;
transform: scale(4);
overflow: hidden;
&.idle {
background-image: url("https://fecoder-pic-1302080640.cos.ap-nanjing.myqcloud.com/s__IDLE.webp") !important;
animation: idle 1s steps(10, end) infinite !important;
}
&.run {
background-image: url("https://fecoder-pic-1302080640.cos.ap-nanjing.myqcloud.com/s_RUN.webp");
animation: run 1s steps(16) infinite;
}
&.attack {
background-image: url("https://fecoder-pic-1302080640.cos.ap-nanjing.myqcloud.com/s__ATTACK+1.webp");
animation: attack 0.35s steps(7, end) infinite;
}
}
@keyframes idle {
0% {
background-position-x: 0;
}
100% {
background-position-x: -960px;
}
}
@keyframes run {
0% {
background-position-x: 0;
}
100% {
background-position-x: -1536px;
}
}
@keyframes attack {
0% {
background-position-x: 0;
}
100% {
background-position-x: -672px;
}
}
</style>
</head>
<body>
<main class="main">
<header class="header">
<h1 class="logo">Samurai</h1>
<h2 class="subheading">use the keys A, D and K</h2>
</header>
<div class="samurai idle"></div>
</main>
<script>
window.addEventListener("load", function (ev) {
const samurai = document.querySelector(".samurai");
let classes = null;
let keys = {};
const removeClasses = () => {
classes.forEach((classe) => {
if (classe !== "samurai") {
samurai.classList.remove(classe);
}
});
};
const setIdle = () => {
removeClasses();
samurai.classList.add("idle");
};
window.addEventListener("keydown", function (ev) {
classes = Array.from(samurai.classList);
console.log("keydown");
removeClasses();
keys[ev.key] = true;
switch (ev.key) {
case "d":
samurai.style.transform = "scaleX(4) scaleY(4)";
samurai.classList.add("run");
break;
case "a":
samurai.style.transform = "scaleX(-4) scaleY(4)";
samurai.classList.add("run");
break;
case "k":
samurai.classList.add("attack");
}
});
window.addEventListener("keyup", function (ev) {
keys[ev.key] = false;
setIdle();
});
setInterval(() => {
for (let key in keys) {
if (!keys["a"] && !keys["d"] && !keys["k"]) {
setIdle();
}
}
}, 100);
});
</script>
</body>
</html>