如何从另一个已经在 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 在您取出图像时旋转它,它也不会旋转。
我正在从 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 在您取出图像时旋转它,它也不会旋转。