I'm developing an iOS7 game with the new API called Sprite Kit. I'd like to horizontally rotated a SKSpriteNode image/texture. I've tried it by first mirroring the image, then creating a SKTexture and finally applying it to the SKSpriteNode but it doesn't work. Is there some way to do this? Or I should have to different images?
Asked
Active
Viewed 1.4k times
4 Answers
38
If you're just trying to flip the sprite along an axis, you can do something like this:
sprite.xScale = -1.0;

Greg
- 33,450
- 15
- 93
- 100
-
1This does not work if you have children added to the node - they get mirrored as well. So if you have stuff like text or hit points labels, they get reflected as well. – Alex Stone Jan 17 '14 at 18:21
-
2Also does not seem to work if you change the anchor point. Any way to do both? – Kudit Jan 25 '14 at 22:51
-
2@Greg doing this xScale = -1.0 makes my SKSpriteNode fall through the ground (before scaling it normally stood on the ground). any ideas why? (7.1) – Zephyer Mar 11 '14 at 07:15
-
1This broke physics collision detection in iOS 7.1. Very surprising that it would just break. – Genki Mar 11 '14 at 17:19
-
1If this is not working, just create a flipped image, you can even do this in code. If you set the texture property, just first create a flipped image then set the texture image with the flipped one. Then you'll probably want a subclass of SKSpriteNode with a property indicating the direction it is facing. This can be done with an enum. – uchuugaka Jul 07 '14 at 03:52
-
Works 100% to me. Thanks! I needed this for my game. – Hedylove Oct 10 '15 at 01:56
26
You can use this code to flip among x-axis:
spriteNode.xScale = spriteNode.xScale * -1;
but be careful you can lose some of physicsbody's property, I highly suggest u to use xScale in this way:
spriteNodeBody = [SKNode node];
spriteNodeBody.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:spriteNode.size];
spriteNodeBody.physicsBody.categoryBitMask = CNPhysicsCategoryPlayer;
spriteNodeBody.physicsBody.collisionBitMask = CNPhysicsCategoryBall;
[spriteNodeBody addChild:spriteNode];
[self addChild:spriteNodeBody];
And now you can safely use:
spriteNode.xScale = spriteNode.xScale * -1;

Ahmet Hayrullahoglu
- 940
- 11
- 15
0
I use this for my rightHanded or leftHanded sprites:
with some help from here Horizontal Flip of a frame in Objective-C
BOOL leftHanded = YES;
SKSpriteNode *sprite;
if (leftHanded) { //my textures point east, so I flip vertically
SKTexture *texture = [SKTexture textureWithImageNamed:@"figure-step0"];
CIFilter *filter = [CIFilter filterWithName:@"CIAffineTransform"];
[filter setValue:[CIImage imageWithCGImage:[texture CGImage]] forKey:kCIInputImageKey];
#ifdef IOS_BLOCK //set these up with defines
CGAffineTransform flipTransform = CGAffineTransformMakeScale(1.0f, -1.0f); // vert
[filter setValue:[NSValue valueWithBytes:&flipTransform
objCType:@encode(CGAffineTransform)]
forKey:@"inputTransform"];
#else //OSX_BLOCK
NSAffineTransform* flipTransform = [NSAffineTransform transform];
[flipTransform scaleXBy:1.0f yBy: -1.0f]; // vert
[filter setValue:flipTransform forKey:@"inputTransform"];
#endif
sprite = [SKSpriteNode spriteNodeWithTexture:
[texture textureByApplyingCIFilter:filter]];
} else {
sprite = [SKSpriteNode spriteNodeWithImageNamed:@"figure-step0"];
}
You can do the same for animation frames likewise. Works for iOS or OS X.
0
This is my solution written in Swift 2.x, usually I prefeer to use landscape
mode for my games, so I write this extension:
extension SKTexture {
class func flipImage(name:String,flipHoriz:Bool,flipVert:Bool)->SKTexture {
if !flipHoriz && !flipVert {
return SKTexture.init(imageNamed: name)
}
let image = UIImage(named:name)
UIGraphicsBeginImageContext(image!.size)
let context = UIGraphicsGetCurrentContext()
if !flipHoriz && flipVert {
// Do nothing, X is flipped normally in a Core Graphics Context
// but in landscape is inverted so this is Y
} else
if flipHoriz && !flipVert{
// fix X axis but is inverted so fix Y axis
CGContextTranslateCTM(context, 0, image!.size.height)
CGContextScaleCTM(context, 1.0, -1.0)
// flip Y but is inverted so flip X here
CGContextTranslateCTM(context, image!.size.width, 0)
CGContextScaleCTM(context, -1.0, 1.0)
} else
if flipHoriz && flipVert {
// flip Y but is inverted so flip X here
CGContextTranslateCTM(context, image!.size.width, 0)
CGContextScaleCTM(context, -1.0, 1.0)
}
CGContextDrawImage(context, CGRectMake(0.0, 0.0, image!.size.width, image!.size.height), image!.CGImage)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return SKTexture(image: newImage)
}
}
Usage:
let spriteTxt = SKTexture.flipImage(imageName, flipHoriz: true, flipVert: false)
P.S.: If you want the same function but to portrait
mode please refeer to this answer

Community
- 1
- 1

Alessandro Ornano
- 34,887
- 11
- 106
- 133