我正在尝试使用纹理图集制作动画:
当角色朝右时,它很有效。我尝试水平翻转它,但它的位置错误:
这是我目前的代码:
<canvas id="c" width="200" height="100" style="background: #000"></canvas>
var metaData = [
{x:0,y:0,w:35,h:38,offsetX:3,offsetY:9},
{x:37,y:0,w:31,h:37,offsetX:6,offsetY:10},
{x:70,y:0,w:65,h:47,offsetX:0,offsetY:1},
{x:137,y:0,w:65,h:47,offsetX:0,offsetY:1},
{x:204,y:0,w:61,h:46,offsetX:1,offsetY:1},
{x:267,y:0,w:42,h:46,offsetX:1,offsetY:1},
{x:311,y:0,w:43,h:44,offsetX:1,offsetY:3},
{x:356,y:0,w:38,h:37,offsetX:6,offsetY:10},
{x:396,y:0,w:35,h:34,offsetX:6,offsetY:13},
{x:433,y:0,w:33,h:37,offsetX:7,offsetY:10},
{x:468,y:0,w:36,h:40,offsetX:5,offsetY:7},
{x:506,y:0,w:34,h:39,offsetX:6,offsetY:8}
],
dx = 0, //position x
dy = 0, //position y
index = 0; //frame index
(function draw() {
context2D.clearRect(0,0,c.width,c.height);
var cur = metaData[index];
if(facingRight) {
context2D.drawImage(
img,
cur.x, cur.y,
cur.w, cur.h,
dx + cur.offsetX, dy + cur.offsetY,
cur.w, cur.h
);
} else {
context2D.save();
context2D.translate(cur.w,0);
context2D.scale(-1,1);
context2D.drawImage(
img,
cur.x, cur.y,
cur.w, cur.h,
dx, dy + cur.offsetY,
cur.w, cur.h
);
context2D.restore();
}
index = ++index % metaData.length;
setTimeout(draw,100);
})();
我使用scale(-1,1)
来翻转精灵,但我不知道如何将它保持在相同的位置,就像面对正确一样。我应该修复偏移值吗?
请,任何帮助将不胜感激:)
答案 0 :(得分:2)
您可以节省大量时间拍摄图像编辑器,并使所有精灵都适合整个精灵表中相同大小的区域。
不需要metadata
奇怪,代码更简单(一个w
,一个h
,x = w * i
等。
例如,你最大的精灵大约是70px宽,所以你应该把所有其他精灵都装在这样的盒子中:
现在,似乎所有的精灵都拥有相同的前脚位置。因此,您应该将它用作对齐所有精灵的锚点。
这样的事情:
请注意,对于所有精灵,前脚总是在相对于自己的盒子的相同位置。
现在很容易编写这个精灵表的动画,甚至翻转它:
const ssheet = new Image();
ssheet.src = 'https://i.stack.imgur.com/kXKIc.png'; // same without borders
ssheet.onload = startSheetAnim;
function startSheetAnim(evt) {
const ctx = c.getContext('2d');
const h = 49;
const w = 70;
let i = 0;
function anim() {
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, c.width, c.height);
ctx.drawImage(ssheet,
(i * w), 1, w, h,
0, 0, w, h
);
// scale (flip-x) and translate
ctx.setTransform(-1, 0, 0, 1, w * 2, 0);
ctx.drawImage(ssheet,
(i * w), 1, w, h,
0, 0, w, h
);
i = (i + 1) % 12
setTimeout(anim, 100);
}
anim();
}
&#13;
<canvas id="c"></canvas>
&#13;