武士游戏角色控制

Published on
/
/趣玩前端
<!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 {
          /*usando !important para corrigir um bug do javascript, que não
		consegue executar o keyup após um keydown muito rápido*/
          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>