Animation SKSpriteNode动画,其中动画中的每个帧未居中

Animation SKSpriteNode动画,其中动画中的每个帧未居中,animation,sprite-kit,ios10,skspritenode,sprite-sheet,Animation,Sprite Kit,Ios10,Skspritenode,Sprite Sheet,我有一个SKSpriteNode,它是120px 120px。 精灵的默认纹理只是一个半径为60px的圆。 我想用以下内容设置精灵的动画: SKAction.animate(with:timePerFrame:resize:restore:) 问题是作为动画一部分的每个纹理的大小都小于120px 120px,因此如果我这样做并将精灵锚定点设置为 CGPoint(x: 0.5, y: 0.5) 动画帧将居中于精灵的中间,这不是我想要的正确动画。我希望动画如下所示: 这意味着我必须在spri

我有一个
SKSpriteNode
,它是120px 120px。 精灵的默认纹理只是一个半径为60px的圆。 我想用以下内容设置精灵的动画:

SKAction.animate(with:timePerFrame:resize:restore:)
问题是作为动画一部分的每个纹理的大小都小于120px 120px,因此如果我这样做并将精灵锚定点设置为

CGPoint(x: 0.5, y: 0.5) 
动画帧将居中于精灵的中间,这不是我想要的正确动画。我希望动画如下所示:

这意味着我必须在sprite atlas中添加所有动画纹理,使其为120px 120px,对吗?如果是这样,这将导致使用空像素浪费atlas空间。有没有更好的方法来实现这一点?i、 e.指定动画中每个纹理帧的中心点


提前感谢。

您还可以尝试:

将注意力集中到
resize=true
如果true,则将调整精灵的大小以匹配每个新纹理。如果为false,则精灵的大小保持不变

如果您需要更多的官方细节,请查看


关于您对下面评论的请求,您可以重新创建
SKAction.animate
例如,制作如下扩展:

extension SKAction
{
    static func animate(withMyTextures textures:[texture:SKTexture], timePerFrame:TimeInterval ,resize:Bool, restore:Bool) ->SKAction {

        var originalTexture : SKTexture!
        let duration = timePerFrame * Double(textures.count)

        return SKAction.customAction(withDuration: duration)
        {
            node,elapsedTime in
            guard let spriteNode = node as? SKSpriteNode
            else
            {
                    assert(false,"animateWithMyTextures only works on members of SKSpriteNode")
                    return
            }
            let index = Int((elapsedTime / CGFloat(duration)) * CGFloat(textures.count))
            //If we havent assigned this yet, lets assign it now
            if originalTexture == nil
            {
                originalTexture = spriteNode.texture
            }
            if(index < textures.count)
            {
                spriteNode.texture = textures[index].texture
            }
            else if(restore)
            {
                spriteNode.texture = originalTexture
            }
            if(resize)
            {
                spriteNode.size = spriteNode.texture!.size()
            }
        }
    }
}
扩展操作
{
静态func动画(使用MyTextures纹理:[纹理:SKTexture],时间性能帧:时间间隔,大小:Bool,还原:Bool)->SKAction{
var originalTexture:SKTexture!
let duration=timePerFrame*Double(textures.count)
返回SKAction.customAction(withDuration:duration)
{
节点,中的elapsedTime
guard let spriteNode=节点as?SKSpriteNode
其他的
{
断言(false,“AnimateWithythTextures仅适用于SKSpriteNode的成员”)
返回
}
让index=Int((elapsedTime/CGFloat(duration))*CGFloat(textures.count))
//如果我们还没有分配,现在就分配吧
如果原始纹理==nil
{
原始纹理=spriteNode.texture
}
如果(索引<纹理数)
{
spriteNode.texture=纹理[索引].纹理
}
否则如果(恢复)
{
spriteNode.texture=原始纹理
}
如果(调整大小)
{
spriteNode.size=spriteNode.texture!.size()
}
}
}
}

这不是调整大小的问题。这是将动画的每个帧定位在正确位置的问题。如果我设置resize=true,则精灵将仅随动画的每一帧调整大小。请看上图中的第二行。这就是动画中每个帧的定位方式。如果这不是调整大小的问题,则制作动画是错误的。在插入透明环境后,如何根据您的喜好将简单图像放置在右侧或左侧?这里有两个问题:一个是精灵顶部/底部的透明区域造成的大小不同(通过resize=true解决),另一个是,你应该在你想要的一边移动你的作品,否则你应该把一个简单的参考像素的transp重新制作动画。保持真实宽度尺寸(或更改背景色)的区域未调整问题的大小。问题是,有没有办法单独定位动画的每个纹理帧,或者为每个动画纹理帧设置不同的定位点?e、 g.框架01锚定点(0.0,0.5)、第二个框架锚定点(0.25,0.5)、第三个框架锚定点(0.5,0.5)等。因为如果图集中的每个纹理都有空像素,那么保存空像素就浪费了内存。这是一个合理的问题。关于它,如果你使用
SKAction.animate
你就做不到。但是,您总是通过代码重新创建“动画”动作,以在自定义动画期间拦截每个具有纹理的精灵,并确定每个精灵的大小:看起来有点不舒服,但这是通过代码进行的唯一方法。另一种方法,正如我所说的,是重新制作动画。另外,我已经更新了我的答案,以帮助您定制
SKAction.animate
,祝您的项目好运。是的,这很有帮助。谢谢