Question

I'm trying to write a basic game using Apple's Sprite Kit framework. So far, I have a ship flying around the screen, using SKPhysicsBody. I want to keep the ship from flying off the screen, so I edited my update method to make the ship's velocity zero. This works most of the time, but every now and then, the ship will fly off the screen.

Here's my update method.

// const int X_MIN = 60;
// const int X_MAX = 853;
// const int Y_MAX = 660;
// const int Y_MIN = 60;
// const float SHIP_SPEED = 50.0;

- (void)update:(CFTimeInterval)currentTime {
    if (self.keysPressed & DOWN_ARROW_PRESSED) {
        if (self.ship.position.y > Y_MIN) {
            [self.ship.physicsBody applyForce:CGVectorMake(0, -SHIP_SPEED)];
        } else {
            self.ship.physicsBody.velocity = CGVectorMake(self.ship.physicsBody.velocity.dx, 0);
        }
    }

    if (self.keysPressed & UP_ARROW_PRESSED) {
        if (self.ship.position.y < Y_MAX) {
            [self.ship.physicsBody applyForce:CGVectorMake(0, SHIP_SPEED)];
        } else {
            self.ship.physicsBody.velocity = CGVectorMake(self.ship.physicsBody.velocity.dx, 0);
        }
    }

    if (self.keysPressed & RIGHT_ARROW_PRESSED) {
        if (self.ship.position.x < X_MAX) {
            [self.ship.physicsBody applyForce:CGVectorMake(SHIP_SPEED, 0)];
        } else {
            self.ship.physicsBody.velocity = CGVectorMake(0, self.ship.physicsBody.velocity.dy);
        }
    }

    if (self.keysPressed & LEFT_ARROW_PRESSED) {
        if (self.ship.position.x > X_MIN) {
            [self.ship.physicsBody applyForce:CGVectorMake(-SHIP_SPEED, 0)];
        } else {
            self.ship.physicsBody.velocity = CGVectorMake(0, self.ship.physicsBody.velocity.dy);
        }
    }
}

At first, I used applyImpulse in didBeginContact to push the ship back. This made the ship bounce, but I don't want the ship to bounce. I just want it to stop at the edge.

What is the right way to make the ship stop once it reaches the edge? The code above works most of the time, but every now and then the ship shoots off screen. This is for OS X—not iOS—in case that matters.

Was it helpful?

Solution

Check out this link... iOS7 SKScene how to make a sprite bounce off the edge of the screen?

[self setPhysicsBody:[SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame]];  //Physics body of Scene

This should set up a barrier around the edge of your scene.

EDIT: This example project from Apple might also be useful https://developer.apple.com/library/mac/samplecode/SpriteKit_Physics_Collisions/Introduction/Intro.html

OTHER TIPS

Your code is not clear in what the velocity variables represent. Keep in mind that if the velocity is too high your ship will have travelled multiple points between updates. For example, your ship's X/Y is at (500,500) at the current update. Given a high enough velocity, your ship could be at (500,700) at the very next update. If you had your boundary set at (500,650) your ship would already be past it.

I suggest you do a max check on velocity BEFORE applying it to your ship. This should avoid the problem I outlined above.

As for bouncy, bouncy... did you try setting your ship's self.physicsBody.restitution = 0; ? The restitution is the bounciness of the physics body. If you use your own screen boundaries, then I would recommend setting those to restitution = 0 as well.

Your best bet would be to add a rectangle physics body around the screen (boundary). Set the collision and contact categories of the boundary and player to interact with each other. In the didBeginContact method you can check if the bodies have touched and, if they have, you can call a method to redirect the ship.

Your problem is that your update method may not be checking the location frequently enough before the ship gets off screen.

This will help you to define you screen edges in Swift.

self.physicsBody = SKPhysicsBody ( edgeLoopFromRect: self.frame )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top