1
votes

Reanimating a bouncing ball in sprite-kit

I have a question about the best way to reanimate a bouncing ball. Using Ray Wenderlich's tutorial on building a break out game as a reference I have a number of circular shape nodes which continually bounce around a gravity-less environment. When the user touches one of them, it centers on the screen, stops moving, and transforms into something else. When the user touches it again, it is supposed to transform back into the circular shape node and then continue bouncing around the screen.

I have it all working as I like except for reanimating the ball. The manner in which I stop the animation is simply to set the physicsBody to nil. Once I want to reanimate, I call the method that sets up the physicsBody for the node and I apply an impulse to it. But frustratingly, the impulse does not have the effect I think it should. Clearly, my expectations are incorrect.

Here is the code in question:

- (void)applyPhysics
{
    // Set physics properties
    self.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:self.frame.size.width/2];
    self.physicsBody.friction = 0.0f;
    self.physicsBody.restitution = 1.0f;
    self.physicsBody.linearDamping = 0.0f;
    self.physicsBody.allowsRotation = NO;
    self.physicsBody.collisionBitMask = wallCategory;
    self.physicsBody.categoryBitMask = bubbleCategory;
}

- (void)morphPicker
{
    BOOL check = NO;
    if (check) NSLog(@"morphPicker called.");

    [self runAction:[SKAction fadeAlphaTo:0.0 duration:.5]];

    if (self.flipped) {

        if (check) NSLog(@"The information side is showing.");
        self.fillColor = bubbleColors[self.index % bubbleColors.count];
        self.alpha = .9;

        // Resume physics:
        [self applyPhysics];
        [self.physicsBody applyImpulse:CGVectorMake(10.0f, -10.0f)];

    } else {

        // stop physics:
        self.physicsBody = nil;

        if (check) NSLog(@"The statistic side is showing.");
        self.fillColor = [SKColor blackColor];
        self.alpha = .9;
        [self transformToPickerNode];
        [self removeAllChildren];

    }

    self.flipped = !self.flipped;

}

So my questions are these:

  1. How should I be reanimating the ball if applying an impulse to it is not the correct method?

  2. Is there a more elegant way to stop the animation after centering the node than setting the physicsBody to nil? Even to my novice instincts it feels like a brutish method.

1
I tried using physicsBody.resting = NO instead of physicsBody = nil, but that did not work. The shape nodes did not come to a stop. Any suggestions would be most welcome.zeeple
Also this: I have discovered that using 'resting' does not affect the movement of the balls at all. However, setting dynamic to no, will cause the movement to stop, but then setting it back to yes, and then reapplying the same impulse does not propel it as I thought it would.zeeple
I have not found a solution for this but I have found a work-around, which is very hacky, and not very elegant and I do not like it. However, it does accomplish the task of causing a node to comtinue moving after it has been at rest. What I am doing is removing all the children and readding them all back. This creates them fresh and the impulse I apply during their creation keeps them moving around the screen.zeeple

1 Answers

0
votes

After all my trials and searching for an answer to this I firmly believe that there is no elegant way to apply a new impulse to a sprite and expect it to move in the physics world. Thus my answer must be "it cannot be done at this point." However, my solution of removing all the the animated sprites from the scene and recreating them turned out to be the best solution for a completely different reason. The nature of my physics world caused my "floating bubbles" to eventually end up in the corners of the scene where they remained unmoving. Occasionally removing and recreating them had the effect of sending them happily bouncing around the scene again :)