在画布中同时渲染精灵表中的多个部分?

Posted

技术标签:

【中文标题】在画布中同时渲染精灵表中的多个部分?【英文标题】:Render Multiple Sections from Sprite Sheet Simultaneously in Canvas? 【发布时间】:2014-06-13 11:05:31 【问题描述】:

已编辑:以下渲染精灵表图像;现在我需要为每个实体赋予不同的行为:男孩的关键动作,猫头鹰的随机动画。我可以用孤立的图像来做到这一点,但是在哪里/如何包含每个 drawImage 实例的行为?谢谢。

<script>
var width = 50,
        height = 50,
        frames = 3,

        currentFrame = 0,

        canvas = document.getElementById("myCanvas");
        ctx = canvas.getContext("2d");
        image = new Image();
        image.src = "sprites.png"

        var draw = function()
                ctx.clearRect(200, 400, width, height); //boy
                ctx.clearRect(150, 300, width, height); //owl
                ctx.clearRect(50, 400, width, height); //goat

                ctx.drawImage(image, 0, height * currentFrame, width, height, 200,400, width, height); //boy

                ctx.drawImage(image, 50, 50 * 2, width, height, 150, 300, width, height); //owl

                ctx.drawImage(image, 150, 50 * currentFrame, width, height, 50, 400, width, height); //goat

                ctx.drawImage(image, 100, 50 * 3, width, height, 150, 400, width, height); //bush


                if (currentFrame == frames) 
                  currentFrame = 0;
                 else 
                  currentFrame++;
                
        

        setInterval(draw, 550);

【问题讨论】:

Rtfm. developer.mozilla.org/fr/docs/Web/API/… 谢谢——tfm 很有帮助。 【参考方案1】:

您可以创建一个函数来根据 spritesheet 布局获取图块位置和大小。这使得这类事情更容易处理。提供索引 [0, 15] ,您将返回一个具有图块位置的对象:

function getTile(index) 

    var row = (index / 4)|0,   // line
        col = index % 4,       // column
        w = 50,                // tile width and height
        h = 50;

    return 
        x: col * w,
        y: row * h,
        w: w,
        h: h
    

drawImage() 方法以这种方式工作(对于这个重载):

drawImage(image, sx, sy, sw, sh,  dx, dy, dw, dh);

其中 s* 是您的 spritesheet 中的 坐标,d* 是您从 s* 坐标获得的剪切区域的目标位置和大小。

所以你可以在这里做:

var width = 50,
    height = 50,
    frames = 16,
    currentFrame = 0,
    canvas = document.getElementById("myCanvas"),
    ctx = canvas.getContext("2d"),
    image = new Image();

image.onload = function() 
    setInterval(draw, 400);  // start when image has finished loading

image.src = "sprites.png"

function draw()

    ctx.clearRect(0, 0, width, height);

    var tile = getTile(currentFrame);        
    ctx.drawImage(image, tile.x, tile.y, tile.w, tile.h, 0, 0, width, height); 

    currentFrame++;

    if (currentFrame === frames) 
      currentFrame = 0;
    

【讨论】:

感谢 Epistemex,修改了上面的代码——现在可以渲染图像了。根据您的回复,我猜我应该为每个实体(男孩、猫头鹰等)创建平铺变量,以便为精灵提供行为?谢谢。 @p1nesap 你可以这样做,你可以扩展 getTile 函数以支持 spritesheet 的特定指标(即平铺宽度和高度、列数等)。希望这会有所帮助! 行为是指将箭头键移动分配给“男孩”等。我在哪里/如何开始执行此操作,以及如何根据电子表格创建索引数组,如果这是我需要做的?谢谢。 @p1nesap 这有点超出了这个问题的范围。您可以针对这些特定事物提出新问题。如果答案解决了本题的问题,请考虑采纳答案。 好的,会的。再次感谢。

以上是关于在画布中同时渲染精灵表中的多个部分?的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D:画布上的 Sprite 渲染器与图像渲染器问题

reactjs重新渲染时画布闪烁

多个精灵表中的 Unity 9-slice

是否可以同时在 FabricJS 画布上独立拖放多个对象?

html5画布精灵表随机行/列

根据 ajax 请求渲染多个刀片视图部分