Is it possible to rotate a Node around an arbitrary point in SpriteKit?

后端 未结 4 1345
猫巷女王i
猫巷女王i 2020-12-15 19:51

Is there a way to rotate a Node in SpriteKit around an arbitrary point? I now I can manipulate the anchorPoint of my Node, but that is not suff

相关标签:
4条回答
  • 2020-12-15 20:32

    The code itself didn't go through

    Second point calculation option

    +(NSArray *)calculatePoints:(CGPoint)point withRadius:(CGFloat)radius numberOfPoints:    (int)numberOfPoints{ //or sprite kit equivalent thereof 
    //                [drawNode clear];
    
    
    NSMutableArray *points = [[NSMutableArray alloc]init];
    for (int j = 1; j < 5; j++) {
        float currentDistance;
        float myRadius = radius;
        float xAdd;
        float yAdd;
        int xMultiplier;
        int yMultiplier;
        CCColor *color = [[CCColor alloc]init]; //Will be used later to draw the position of the node, for debugging only 
        for (int i = 0; i < numberOfPoints; i += 1){ 
            //You also have to change the if (indextogoto == <value>) in the moveGumliMethod;
        float opposite = sqrtf( powf(myRadius, 2) - powf(currentDistance, 2) );
        currentDistance = i;
    
        switch (j) {
            case 1:
                xMultiplier = 1;
                yMultiplier = 1;
                xAdd = currentDistance;
                yAdd = opposite;
                color = [CCColor blueColor];
                break;
            case 2:
               xMultiplier = 1;
                yMultiplier = -1;
                xAdd = opposite;
                yAdd = currentDistance;
                color = [CCColor orangeColor];
                break;
            case 3:
                xMultiplier = -1;
                yMultiplier = -1;
                xAdd = currentDistance;
                yAdd = opposite;
                color = [CCColor redColor];
                break;
            case 4:
                xMultiplier = -1;
                yMultiplier = 1;
                xAdd = opposite;
                yAdd = currentDistance;
                color = [CCColor purpleColor];
                break;
            default:
                break;
        }
       int x = (CGFloat)(point.x + xAdd * xMultiplier); //or sprite kit equivalent thereof 
       int y = (CGFloat)(point.y + yAdd * yMultiplier); //or sprite kit equivalent thereof 
       CGPoint newPoint = CGPointMake((CGFloat)x,(CGFloat)y); //or sprite kit equivalent thereof 
    
    
       NSValue *pointWrapper = [NSValue valueWithCGPoint:newPoint]; //or sprite kit equivalent thereof 
       NSLog(@"Point is %@",pointWrapper);
      [points addObject:pointWrapper];
        }
    }
    return points;
    }
    

    Calculating Nearest Point To Object

    -(CGPoint)calculateNearestGumliPoint:(CGPoint)search point { // MY Character is named    Gumli
        float closestDist = 2000;
        CGPoint closestPt = ccp(0,0);
        for (NSValue *point in points) {
            CGPoint cgPoint = [point CGPointValue];
            float dist = sqrt(pow( (cgPoint.x - searchpoint.x), 2) + pow( (cgPoint.y - searchpoint.y), 2));
        if (dist < closestDist) {
            closestDist = dist;
            closestPt = cgPoint;
    
            }
        }
    
        return closestPt;
    }
    
    0 讨论(0)
  • 2020-12-15 20:34

    I was also trying to solve this problem a few weeks back, and did not implement the anchor points solution because I did not want to have to worry about removing the anchor point when lets say the object collides with another node and should leave its orbit and bounce away.

    Instead, I came up with two solutions, both of which work if tweaked. The first took a long time to perfect, and is still not perfect. It involves calculating a certain number of points around a center position offset by a set radius, and then if a certain object comes in a certain distance of the center point, it will continually use physics to send the object on a trajectory path along the "circumference" of the circle, points that it calculated (see above).

    There are two ways of calculating points with a radius

    The first uses the pythagorean theorem, and the second ultimately uses trigonometry proper. In the first, you increment a for loop by a certain amount, while it is less that 361 (degree), and for each iteration of the loop, calculate using sine and cosine a point with that angle at a certain radius from the center point.

    The second uses the pythagorean theorem, and its code is below:

    After you calculate points, you should create a scheduled selector [<object> scheduled selector...]; or a timer in your didMoveToView, or use a fixed update method, in addition to an instance variable called int which will hold the index of the next location to which your object will move. Every time the timer method is called, it will move the object to the next point in your calculate points array using your own or the below code labeled physicsMovement; You can play around with the physics values, and even the frequency of the ttimer for different movement effects. Just make sure that you are getting the index right. Also, for more realism, I used a method which calculates the closest point in the array of calculated point to the object, which is called only once the collision begins. It is also below labeled nearestPointGoTo. If you need any more help, just say so in the comments. Keep Hacking!

    I used the second, and here is the source code for it:

    0 讨论(0)
  • 2020-12-15 20:49

    Since you're asking for the best way, here's one that works well (best is subjective):

    Create an SKNode and set its position to the center of rotation. Add the node that should rotate around that center as child to the center node. Set the child node's position to the desired offset (ie radius, say x + 100). Change the rotation property of the center node to make the child node(s) rotate around the center point. The same works for cocos2d btw.

    0 讨论(0)
  • 2020-12-15 20:50

    I think the best way to make this work is through two SKNode and joint them with SKPhysicsJointPin (Look at the pin example below)

    I tried to hang a door sign (SKSpriteNode) on my door(`SkScene), and would like to rotate around on the hanging spot when someone touch it

    What I did is making a 1x1 SKNode with a HUGH mass and disabled it's gravity effects.

    var doorSignAnchor = SKSpriteNode(color: myUIColor, size: CGSize(width: 1, height: 1))
    doorSignAnchor.physicsBody = SKPhysicsBody(rectangleOf: doorSignAnchor.frame.size)
    doorSignAnchor.physicsBody!.affectedByGravity = false // MAGIC PART
    doorSignAnchor.physicsBody!.mass = 9999999999 // MAGIC PART
    
    var doorSignNode = SKSpriteNode(imageNamed:"doorSign")
    doorSignNode.physicsBody = SKPhysicsBody(rectangleOf: doorSignNode.frame.size)
    

    and created a SKPhysicsJointPin to connect them all

    let joint = SKPhysicsJointPin.joint(
          withBodyA:  doorSignAnchor.physicsBody!,
          bodyB: doorSignNode.physicsBody!,
          anchor: doorSignAnchor.position)
    mySkScene.physicsWorld.add(joint)
    

    So it will move like actual door sign, rotate around an arbitrary point (doorSignAnchor)

    Reference:

    • Official document about Sumulating Physics
    • How to Make Hanging Chains With SpriteKit Physis Joints
    0 讨论(0)
提交回复
热议问题