如何从另一个已经在 SpriteKit 中旋转的纹理创建旋转纹理

How to create a rotated texture from another already rotated in SpriteKit

我正在从 SKTexture 创建精灵,而精灵又是从从图集加载的另一个纹理创建的,如下所示:

SKTexture *textureFromAtlas = [SKTexture textureWithImageNamed:@“MyImage.png”];
CGRect myRect = textureFromAtlas.textureRect;
myRect.size.with *= 0.5;
myRect.size.height *= 0.5;
SKTexture *newTexture = [SKTexture textureWithRect:myRect inTexture:textureFromAtlas];
SKSpriteNode * MySprite = [SKSpriteNode spriteNodeWithTexture:newTexture];

textureFromAtlas 恰好被旋转了,因为在应用程序包中的文件夹 Images.atlasc 中,Images.1.png显示MyImage.png 旋转,Images.plist 有键 textureRotated 为该子图像设置为 YES

如何创建 MySprite 以使其具有正确的旋转?

(A) 是人们所期望的,因为 SpriteKit 会自动旋转; (B) 是实际结果,即从上面的代码得到的结果

编辑:

我不得不添加一些代码来获得 MyImage.png 的大小,但是图集中包含的旋转的, 看是否旋转, 然后计算一个新旋转的 myRect 用于 mySrpite

CGRect textureRect = textureFromAtlas.textureRect;
CGSize atlasSize = [[SKTexture textureWithRect:CGRectMake(0, 0, 1, 1)
                                     inTexture:textureFromAtlas] size];
CGSize sizeInAtlas = CGSizeMake(textureRect.size.width * atlasSize.width,
                                textureRect.size.height * atlasSize.height);
myRect = CGRectMake(myRect.origin.x,
                    myRect.origin.y+myRect.size.height-sizeInAtlas.height/atlasSize.height);
SKTexture *rotatedTexture = [SKTexture textureWithRect:myRect
                                             inTexture:textureFromAtlas];
mySprite = [SKSpriteNode spriteWithTexture: rotatedTexture];
mySprite.zRotation = M_PI_2;

这有效地 "moves" Image.1.png[=55 中旋转图像左上角的矩形=],因此 mySprite 将是 (A) 中的那个,但这仅在 MyImage.png 完全不透明或没有透明边框时有效,因为SpriteKit 对那些具有透明度的图像进行了一些优化,并且 textureRect 小于图集中的实际框架。

不幸的是,使用来自 SKTextureAtlas 的纹理时 textureWithRect:inTexture 似乎存在错误。这是有道理的,因为您要做的是从 sprite 贴图创建 sprite 贴图,我可以看到这会导致一些性能问题。

为了得到你想要的结果,我看到它有两种不同的工作方式。

第一个选项将 MyImage 移出图集文件夹(或使用资产目录)并使用 textureWithRect:inTexture。如果图像已经创建为 sprite sheet 并且您不想将其切碎,则这是理想的选择。这不是一个糟糕的解决方案,但您可能会使用第二个选项获得更好的结果。

SKTexture *textureFromAtlas = [SKTexture textureWithImageNamed:@“MyImage.png”];
CGRect myRect = CGRectMake(0,.5,.5,.5);
SKTexture *newTexture = [SKTexture textureWithRect:myRect inTexture:textureFromAtlas];
SKSpriteNode * MySprite = [SKSpriteNode spriteNodeWithTexture:newTexture];

第二个选项切碎你的图像,然后将这些图像添加到 images.atlas 如果你想获得可能在一个精灵上同时渲染的其他纹理,这是更理想的 sheet (图集)。 SpriteKit 会在 运行 时间将它们组合成一张图片。

Red/Green 将是切碎的图像,然后将其组合在一起,pink/green 只是一张像您以前的图像。

然后您将能够轻松地使用代码,例如...

SKTexture *textureFromAtlas = [SKTexture textureWithImageNamed:@"MyImage1.png"];
SKSpriteNode *mySprite = [SKSpriteNode spriteNodeWithTexture:textureFromAtlas];

这两个选项都不需要担心旋转问题。即使 .atlas 在您取出图像时旋转它,它也不会旋转。