使用精灵表的问题

问题描述 投票:0回答:1

我正在为学校编写一些代码,该代码应该从在线源获取精灵表并运行它们,使其看起来只是运行精灵动画。我不确定我需要在这里修复什么,因为我几乎只是使用老师给我的纸条来编写所有代码。

let img = new Image();
img.src = 'https://opengameart.org/sites/default/files/Green-Cap-Character-16x18.png';
img.onload = function() {
  init();
};

let canvas = document.getElementById('c');
let ctx = canvas.getContext('2d');

const scale = 2;
const width = 16;
const height = 18;
const scaledWidth = scale * width;
const scaledHeight = scale * height;

function drawFrame(frameX, frameY, canvasX, canvasY) {
  ctx.drawImage(img, frameX * width, frameY * height, width, height, canvasX, canvasY, scaledWidth, scaledHeight);
}

const cycleLoop = [0, 1, 0, 2];
let currentLoopIndex = 0;
let frameCount = 0;

function step() {
  frameCount++;
  if (frameCount < 15) {
    window.requestAnimationFrame(step);
    return;
  }
  frameCount = 0;
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawFrame(cycleLoop[currentLoopIndex], 0, 0, 0);
  currentLoopIndex++;
  if (currentLoopIndex >= cycleLoop.length) {
    currentLoopIndex = 0;
  }
  window.requestAnimationFrame(step);
}

function init() {
  window.requestAnimationFrame(step);
}
canvas {
  border: 1px solid black;
}
<canvas id="c" width="300" height="200"></canvas>

任何帮助将不胜感激

-蒂姆

javascript html sprite-sheet
1个回答
0
投票

您可以通过索引查找帧,然后将该索引转换为行和列索引,只要您知道精灵表中有多少列即可。

在下面的示例中,我通过为每个动画指定索引序列来渲染所有 4 个步行动画。这些索引是 0-11,从上到下、从左到右。

let img = new Image();
img.src = 'https://opengameart.org/sites/default/files/Green-Cap-Character-16x18.png';
img.onload = function() {
  init();
};

let canvas = document.getElementById('c');
let ctx = canvas.getContext('2d');

const scale = 2.0;
const width = 16;
const height = 18;
const scaledWidth = scale * width;
const scaledHeight = scale * height;

function drawFrame(x, y, index, cols, x, y) {
  const row = Math.floor(index / cols);
  const col = index % cols;
  const xOff = col * width;
  const yOff = row * height;

  ctx.drawImage(img,
    xOff, yOff,
    width, height,
    x, y,
    scaledWidth, scaledHeight);
}

const cycleCount = 4;
const walkCycles = {
  down  : [0,  1, 0,  2],
  up    : [3,  4, 3,  5],
  left  : [6,  7, 6,  8],
  right : [9, 10, 9, 11]
};

let currentLoopIndex = 0;
let frameCount = 0;

function step() {
  frameCount++;
  if (frameCount < 15) {
    window.requestAnimationFrame(step);
    return;
  }
  frameCount = 0;
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  Object.entries(walkCycles).forEach(([key, cycle], i) => {
    const x = i * scaledWidth;
    drawFrame(x, 0, cycle[currentLoopIndex], 3, x, 0);
  });
  currentLoopIndex = (currentLoopIndex + 1) % cycleCount;
  window.requestAnimationFrame(step);
}

function init() {
  window.requestAnimationFrame(step);
}

Object.assign(canvas, {
  width: scaledWidth * Object.keys(walkCycles).length,
  height: scaledHeight
})
html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #222;
}

canvas {
  background: #6AF
}
<canvas id="c" width="300" height="200"></canvas>

© www.soinside.com 2019 - 2024. All rights reserved.