jquery 如何在画布内调整精灵工作表框架大小?

ahy6op9u  于 2023-06-22  发布在  jQuery
关注(0)|答案(1)|浏览(136)

我有一个画布元素,我在这个小鸭子精灵表上画,从屏幕的右边飞到左边。我现在的代码实现了这一点。但我不能为我的生活弄清楚如何使框架中的鸭子,更大,而不与动画的混乱。
现在看来,鸭子被限制在一个像这样的小盒子里||所以你只能看到动画的点点滴滴,远远不足以看到它始终如一地飞过屏幕。每次我试着调整宽度或框架,它只是使鸭子大得多。
我知道这个片段不起作用,因为它不会加载到资产中,但是你可以看到它的JS部分,希望这能有所帮助!
谢谢你们
ducksprite工作表:

$(document).ready(function () {
  // Variables for IDs - getContext to draw and clear canvas
  const canvas = $("#game-canvas")[0];
  const context = canvas.getContext("2d");
  const startButton = $("#start-button");

  const backgroundImage = new Image();
  backgroundImage.src = "https://opengameart.org/sites/default/files/duck_spritesheet.png";

  // Onload function to pull the background image of the game
  $(backgroundImage).on("load", function () {
    context.drawImage(backgroundImage, 0, 0);
  });

  // On click function to change the crosshair and pull in the duck image
  startButton.on("click", function () {
    const spriteSheet = new Image();
    spriteSheet.src = "https://opengameart.org/sites/default/files/duck_spritesheet.png";

    $("#game-canvas").on("mouseenter", function () {
      $(this).addClass("canvas-cursor");
    });

    $("#game-canvas").on("mouseleave", function () {
      $(this).removeClass("canvas-cursor");
    });

    $(spriteSheet).on("load", function () {
      const totalFrames = 4; // Total number of frames in the sprite sheet
      const scale = 3; // Scale to TRY and scale it, didn't work...
      const duckSpeed = 10; // ducks movement speed across the canvas

      //multiplying any of these didn't work for me
      const duckWidth = spriteSheet.width / totalFrames;
      const duckHeight = spriteSheet.height / totalFrames;
      const frameWidth = duckWidth;
      const frameHeight = duckHeight; 

      const animationSpeed = 200; // Milliseconds per frame

      let currentFrame = 0; // Current frame of the animation
      let duckX = canvas.width; // Starting position of the duck on the right side of the canvas
      let duckY = canvas.height / 2 - (frameHeight * scale) / 2; // Center the duck vertically

      function animateDuck() {
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.drawImage(backgroundImage, 0, 0);

        const frameX = (currentFrame % totalFrames) * frameWidth;
        const frameY = Math.floor(currentFrame / totalFrames) * frameHeight;

        // Draw the current frame of the duck image 
        context.drawImage(
          spriteSheet,
          frameX,
          frameY,
          frameWidth,
          frameHeight,
          duckX,
          duckY,
          frameWidth * scale,
          frameHeight * scale
        );

        // current frame
        currentFrame = (currentFrame + 1) % (totalFrames * totalFrames);

        // duck's position
        duckX -= duckSpeed;

        // if the duck has reached the left side of the canvas
        if (duckX + frameWidth * scale * 2 < 0) {
          duckX = canvas.width;
        }

        setTimeout(animateDuck, animationSpeed);
      }

      animateDuck();
    });
  });
});
body {
  background-color: #eee;
  text-align: center;
  font-family: Verdana, Geneva, Tahoma, sans-serif;
}

h1 {
  color: #333;
}

#game-container {
  position: relative;
}

#game-canvas {
  display: block;
  margin: 0 auto;
  border: 1px solid black;
  background-color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<body>
    <div id="game-container">
        <canvas id="game-canvas" width="400" height="100"></canvas>
    </div>
    <button id="start-button">Start Game</button>
</body>
lc8prwob

lc8prwob1#

再看看你的精灵:

然后是你的代码:

const duckWidth = spriteSheet.width / totalFrames;
      const duckHeight = spriteSheet.height / totalFrames;
      const frameWidth = duckWidth;
      const frameHeight = duckHeight; 
    ...
    const frameX = (currentFrame % totalFrames) * frameWidth;

这应该是足够的线索让你动起来。。
手工计算,这很有帮助,你得到了帧的期望值吗?
下面是我对你的代码的修正,挑战一下你自己,试着在不看我的代码片段的情况下修正你的代码

const canvas = $("#game-canvas")[0];
  const context = canvas.getContext("2d");

  const spriteSheet = new Image();
  spriteSheet.src = "https://opengameart.org/sites/default/files/duck_spritesheet.png";
  $(spriteSheet).on("load", function() {
    const totalFrames = 4; // Total number of frames in the sprite sheet
    const scale = 3; // Scale to TRY and scale it, didn't work...
    const duckSpeed = 2; // ducks movement speed across the canvas

    const duckWidth = spriteSheet.width;
    const duckHeight = spriteSheet.height / totalFrames;
    const frameWidth = duckWidth;
    const frameHeight = duckHeight;

    let currentFrame = 0; // Current frame of the animation
    let duckX = canvas.width;
    let duckY = canvas.height / 2 - (frameHeight * scale) / 2;

    function animateDuck() {
      context.clearRect(0, 0, canvas.width, canvas.height);

      const frameX = 0
      const frameY = Math.floor(currentFrame / totalFrames) * frameHeight;

      context.drawImage(spriteSheet, frameX, frameY, frameWidth, frameHeight, duckX, duckY, frameWidth * scale, frameHeight * scale );
      currentFrame = (currentFrame + 1) % (totalFrames * totalFrames);
      duckX -= duckSpeed;
      if (duckX + frameWidth * scale * 2 < 0) {
        duckX = canvas.width;
      }

      setTimeout(animateDuck, 40);
    }
    animateDuck();
  });
body {
  background-color: #eee;
  text-align: center;
  font-family: Verdana, Geneva, Tahoma, sans-serif;
}

h1 {
  color: #333;
}

#game-container {
  position: relative;
}

#game-canvas {
  display: block;
  margin: 0 auto;
  border: 1px solid black;
  background-color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<body>
  <div id="game-container">
    <canvas id="game-canvas" width="400" height="100"></canvas>
  </div>
</body>

简而言之,你的精灵图像不是正方形而是矩形,鸭子宽度不需要除以总帧数,framex也不是一个会为你的精灵而改变的值,它总是0。
如果你想挑战自己,试试其他的精灵,比如这个:
https://opengameart.org/content/explosion-sheet

相关问题