사용자:Cheongseong9473/HappyFPS/PluginX

리버티게임, 모두가 만들어가는 자유로운 게임
< 사용자:Cheongseong9473
imported>Cheongseong9473님의 2020년 4월 13일 (월) 16:35 판

참고: 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 새로 고쳐야 합니다.

  • 파이어폭스 / 사파리: Shift 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5 또는 Ctrl-R을 입력 (Mac에서는 ⌘-R)
  • 구글 크롬: Ctrl-Shift-R키를 입력 (Mac에서는 ⌘-Shift-R)
  • 인터넷 익스플로러 / 엣지: Ctrl 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5를 입력.
  • 오페라: Ctrl-F5를 입력.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>fortress</title>
    <style>
      body {
        margin: 0;
        height: 100vh;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      #fortress {
        border: 1px solid black;
      }
    </style>
  </head>
  <body>
    <canvas id="fortress" width="1000px" height="700px"></canvas>
    <script>
      const canvas = document.getElementById("fortress");
      const ctx = canvas.getContext("2d");
      const width = canvas.width;
      const height = canvas.height;
      const tankWidth = 50;
      const tankHeight = 50;
      let tankX = 0;
      const tankDx = 3;
      let tankLeftPressed = false;
      let tankRightPressed = false;
      let tankCenterX;
      let tankCenterY;
      let cannonAngle = Math.PI / 4;
      const cannonAngleDIF = Math.PI / 60;
      const cannonLength = tankWidth * Math.sqrt(2);
      const targetWidth = Math.floor(Math.random() * 150 + 30);
      const targetHeight = Math.floor(Math.random() * 100 + 10);
      const targetX = Math.floor(Math.random() * (500 - targetWidth) + 500);
      const targetY = height - targetHeight;
      let missileRadius = 5;
      let missileX;
      let missileY;
      let isCharging = false;
      let isFired = false;
      let isHitted = false;
      let gauge = Math.PI;
      const gaugeDIF = Math.PI / 60;
      const gaugeBarRadius = 30;
      let missilePower;
      let missileDx;
      let missileDy;
      const GRAVITY_ACCELERATION = 0.098;
      const draw = () => {
        ctx.clearRect(0, 0, width, height);
        tankCenterX = tankX + 0.5 * tankWidth;
        tankCenterY = height - 0.5 * tankHeight;
        if (tankLeftPressed && tankX > 0) {
          tankX -= tankDx;
        }
        if (tankRightPressed && tankX + tankWidth < width) {
          tankX += tankDx;
        }
        if (isCharging && !isFired) {
          if (gauge < Math.PI * 2) {
            gauge += gaugeDIF;
          }
          drawGausing();
        }
        if (!isFired) {
          missileX = tankCenterX + cannonLength * Math.cos(cannonAngle);
          missileY = tankCenterY - cannonLength * Math.sin(cannonAngle);
        } else {
          missileDy -= GRAVITY_ACCELERATION;
          missileX = missileX + missileDx;
          missileY = missileY - missileDy;
        }
        checkMissile();
        drawTank();
        if (!isHitted) {
          drawTarget();
          drawMissile();
        }
      };
      const checkMissile = () => {
        // canvas 왼쪽, 오른쪽, 아래 벽에 닿으면
        if (missileX <= 0 || missileX >= width || missileY >= height) {
          isFired = false;
        }
        // target 명중
        if (
          missileX >= targetX &&
          missileX <= targetX + targetWidth &&
          missileY >= targetY
        ) {
          isHitted = true;
          clearInterval(start);
          if (confirm("명중입니다. 다시 하시겠습니까?")) {
            location.reload();
          }
        }
      };
      const drawMissile = () => {
        ctx.beginPath();
        ctx.arc(missileX, missileY, missileRadius, 0, Math.PI * 2);
        ctx.fillStyle = "blue";
        ctx.fill();
        ctx.closePath();
      };
      const drawGausing = () => {
        ctx.beginPath();
        ctx.arc(
          tankCenterX,
          tankCenterY - cannonLength,
          gaugeBarRadius,
          Math.PI,
          gauge,
          false
        );
        ctx.stroke();
      };
      const drawTank = () => {
        ctx.lineWidth = 5;
        ctx.lineCap = "round";
        ctx.beginPath();
        ctx.moveTo(tankX, height - tankHeight);
        ctx.lineTo(tankX + tankWidth, height - tankHeight);
        ctx.lineTo(tankX + tankWidth, height);
        ctx.lineTo(tankX, height);
        ctx.lineTo(tankX, height - tankHeight);
        ctx.moveTo(tankCenterX, tankCenterY);
        ctx.lineTo(
          tankCenterX + cannonLength * Math.cos(cannonAngle),
          tankCenterY - cannonLength * Math.sin(cannonAngle)
        );
        ctx.stroke();
        ctx.closePath();
      };
      const drawTarget = () => {
        ctx.fillRect(targetX, targetY, targetWidth, targetHeight);
        ctx.fillStyle = "red";
      };
      draw();
      const keydownHandler = event => {
        if (event.keyCode === 37) {
          tankLeftPressed = true;
        } else if (event.keyCode === 39) {
          tankRightPressed = true;
        } else if (event.keyCode === 38 && cannonAngle <= Math.PI / 2) {
          cannonAngle += cannonAngleDIF;
        } else if (event.keyCode === 40 && cannonAngle >= 0) {
          cannonAngle -= cannonAngleDIF;
        } else if (event.keyCode === 32 && !isFired) {
          isCharging = true;
        }
      };
      const keyupHandler = event => {
        if (event.keyCode === 37) {
          tankLeftPressed = false;
        } else if (event.keyCode === 39) {
          tankRightPressed = false;
        } else if (event.keyCode === 32 && !isFired) {
          isCharging = false;
          isFired = true;
          missilePower = gauge * 1.6;
          missileDx = missilePower * Math.cos(cannonAngle);
          missileDy = missilePower * Math.sin(cannonAngle);
          gauge = Math.PI;
        }
      };
      const start = setInterval(draw, 10);
      document.addEventListener("keydown", keydownHandler, false);
      document.addEventListener("keyup", keyupHandler, false);
    </script>
  </body>
</html>