How to rotate an SKSpriteNode around the node'

2020-02-23 00:12发布

问题:

I'm trying to rotate an SKSpriteNode node around it's Y-axis. I know there's the zRotation property and that will rotate the node clockwise or counter-clockwise; however, I'd like to rotate the node around it's own Y axis (like a dancing ballerina for instance), and I can't seem to find any functionality to do so. What is the best recommended way of doing this?

回答1:

Typically if I am wanting to rotate something like you seem to be describing, and want it to look good, I will do it via sprite frames depicting different degrees of rotation.

You can indeed fake it a little by tweening your xScale property from 1 to -1 , and visa versa.

The xScale trick is feasible for cards maybe (or paper mario), but for a ballerina, not so much. You are looking for 3D rotation of a 2D object, and that's not going to happen via that method.

So if the xScale trick is not feasible for your needs, you'll need to handle it via sprite frames.

Here's an example of a 3d SpriteSheet that would allow you to achieve the rotation you desire :

This animated gif is an example of sprite frames to get that y rotation :



回答2:

    SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
    sprite.position = location;
    SKAction* action0 = [SKAction scaleXTo:1.0 duration:0.5];
    SKAction* action1 = [SKAction scaleXTo:0.1 duration:0.5];
    SKAction* action2 = [SKAction scaleXTo:-0.1 duration:0.5];
    SKAction* action3 = [SKAction scaleXTo:-1.0 duration:0.5];

    SKAction* action = [SKAction sequence:@[action0, action1, action2, action3]];
    [sprite runAction:[SKAction repeatActionForever:action]];

    [self addChild:sprite];

This will get you what looks like a 3D card flip, but obviously if you're expecting an object to have depth you wont get that programatically with scaling.

Or well less animations (As LearnCocos2D suggested):

    SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
    sprite.position = location;
    SKAction* action0 = [SKAction scaleXTo:1.0 duration:0.5];
    SKAction* action1 = [SKAction scaleXTo:-1.0 duration:0.5];

    SKAction* action = [SKAction sequence:@[action0, action1]];
    [sprite runAction:[SKAction repeatActionForever:action]];

    [self addChild:sprite];


回答3:

SpriteNode *spriteNode = [SKSpriteNode spriteNodeWithImageNamed@"Sprite"];
spriteNode.position = position;

SKAction *action = [SKAction repeatActionForever:[SKAction customActionWithDuration:duration actionBlock:^(SKNode *node, CGFloat elapsedTime) {
    node.xScale = sin(2 * M_PI * elapsedTime / duration);
}]];

[self addChild:spriteNode];

However, the sprite looks like having no thickness.



回答4:

Although SpriteKit doesn't have full 2.5D capabilities (rotating and transforming along X, Y and Z axes), I've developed a work around for rotating SKSpriteNodes around either the X or Y axes. Because SKView is a subclass of UIView, we can rotate it in 3D space the same way we rotate a UIView, using CATransform3D.

The main point is that the sprite that needs to be rotated on the Y axis lives in its own scene, which is presented in its own SKView.

Triggering the following code on in a loop will animate your SKView (containing the SKScene and the SKSpriteNode) on the y axis. You can still have your main scene running at the same time in the background and swap in the sprites that need to be animated on the y axis and then swap them out when animation complete, and remove Y rotation scene. It's not a pretty solution, but it's all there is until Apple adds better 2.5D capabilities.

I've written a tutorial on SpriteKit and 2.5D with sample code if you need more info. http://www.sdkboy.com/?p=283

self.rotAngle -= 10;

float angle = (M_PI / 180.0f) * self.rotAngle/10;

CATransform3D transform3DRotation = CATransform3DMakeRotation(1.0, angle, 0.0, 0.0);

self.mySKView.layer.transform = transform3DRotation;