Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用HTML5画布水平翻转精灵?_Javascript_Html_Animation_Canvas - Fatal编程技术网

Javascript 如何使用HTML5画布水平翻转精灵?

Javascript 如何使用HTML5画布水平翻转精灵?,javascript,html,animation,canvas,Javascript,Html,Animation,Canvas,我正在尝试使用纹理图集制作动画: 当角色面朝右时效果很好。我试图水平翻转它,但它的位置错误: 这是我目前的代码: <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

我正在尝试使用纹理图集制作动画:

当角色面朝右时效果很好。我试图水平翻转它,但它的位置错误:

这是我目前的代码:

<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);
})();

变量元数据=[
{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,//位置x
dy=0,//位置y
指数=0//帧索引
(函数图(){
context2D.clearRect(0,0,c.宽度,c.高度);
var cur=元数据[索引];
如果(朝向右侧){
context2D.drawImage(
img,
当前x,当前y,
当前w,当前h,
dx+cur.offsetX,dy+cur.offsetY,
电流w,电流h
);
}否则{
context2D.save();
context2D.translate(cur.w,0);
上下文2D.比例(-1,1);
context2D.drawImage(
img,
当前x,当前y,
当前w,当前h,
dx,dy+cur.offsetY,
电流w,电流h
);
context2D.restore();
}
index=++索引%metaData.length;
设置超时(绘图,100);
})();
我使用
scale(-1,1)
来翻转精灵,但我不知道如何将其保持在相同的位置,比如向右。我应该修正偏移值吗


请,如果您有任何帮助,我们将不胜感激:)

您将节省大量时间使用图像编辑器,并使所有精灵适合整个精灵表中相同大小的区域

无需
元数据
怪异,代码更简单(单个
w
,单个
h
x=w*i
等)

例如,您最大的精灵宽度约为70px,因此您应该将所有其他精灵放入其中一个框中:

现在,看起来你所有的精灵都共享前脚的相同位置。所以你应该用它作为定位点来对齐你所有的精灵

大概是这样的:

请注意,对于所有精灵,前脚相对于其自身的长方体始终处于相同的位置

现在很容易编写此精灵表的动画,甚至可以翻转它:

const ssheet=new Image();
ssheet.src=https://i.stack.imgur.com/kXKIc.png“;//同样没有边界
ssheet.onload=启动sheetanim;
功能启动sheetanim(evt){
const ctx=c.getContext('2d');
常数h=49;
常数w=70;
设i=0;
函数anim(){
setTransform(1,0,0,1,0,0);
ctx.clearRect(0,0,c.宽度,c.高度);
ctx.图纸图像(图纸,
(i*w),1,w,h,
0,0,w,h
);
//缩放(翻转-x)和平移
setTransform(-1,0,0,1,w*2,0);
ctx.图纸图像(图纸,
(i*w),1,w,h,
0,0,w,h
);
i=(i+1)%12
设置超时(动画,100);
}
动漫();
}

@kaido我让它们大小相同,这个纹理图集是由TexturePacker打包的,它生成一个JSON文件,我使用这些信息来制作元数据。我不知道这个TexturePacker,但这些不是纹理,这些是精灵。为了便于使用,你需要将它们对齐,并将它们设置为大小相同的不可见框。目前它们是“根本没有。它们甚至没有y对齐。(字符精灵最好是底部对齐)@kaido我在PhotoShop中对齐它们,并用TexturePacker打包,它在JSON文件中给了我这样的正确位置:{“文件名”:“00.png”,“帧”:{“x”:0,“y”:0,“w”:35,“h”:38},“旋转”:false,“修剪”:true,“spriteSourceSize”:{“x”:3,“y”:9,“w”:35,“h”:38},“sourceSize”:{“w”:65,“h”:49},“pivot”:{“x”:0.5,“y”:1},每帧为65X49,除了翻转外,它可以很好地面对右方运动。谢谢你的详细回答!但我仍然有一个问题,我从一些网站获得精灵,他们总是打包精灵并裁剪透明像素,减少不必要的透明区域以提高性能,我可以直接使用它还是必须重新定位它们?在我看来,重新定位它们更容易是的……我不知道为什么它们一开始就这样打包。如果是为了图像大小,那么它们就做错了:我的sprite表比你问题中的sprite表有更好的压缩,因此更轻。空像素通常不会太重,而且你会避免JSON。这会导致吗GPU上的性能?因为会有很多不必要的透明区域被渲染。不,不是以一种敏感的方式。用更少的cpu,你会有大约相同的GPU影响。真的很感激!我想我可以从你的经验中得到很多:)