iOS7 SKScene how to make a sprite bounce off the edge of the screen?

烂漫一生 提交于 2019-12-05 18:01:28

You don't need to write much code to make the ball bounce off the edge of the screen. the physics environment can handle all of the above, you just need to instantiate the sprites in the correct way.

First, you will have to set the physicsBody of the scene as such:

self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];

In your scene's .h file create two bitmask categories:

static const uint8_t ballCategory = 1;
static const uint8_t wallCategory = 2;

And give the scene's physics body a category:

self.physicsBody.categoryBitMask = wallCategory;

Then create your sprite:

SKSpriteNode *spriteNode = [SKSpriteNode spriteNodeWithImageNamed:@"ball.png"]; 

spriteNode.name = @"ball";

spriteNode.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:25];
spriteNode.position = CGPointMake(10.0,10.0); //or anything you want
spriteNode.physicsBody.dynamic = YES;
spriteNode.physicsBody.affectedByGravity = NO;

spriteNode.physicsBody.categoryBitMask = ballCategory;
spriteNode.physicsBody.collisionBitMask = wallCategory;

spriteNode.physicsBody.restitution = 1.0;
spriteNode.physicsBody.friction = 0.0;
spriteNode.physicsBody.linearDamping = 0.0;
spriteNode.physicsBody.angularDamping = 0.0;

[self addChild:spriteNode];

Instead of giving the spriteNode a [SKAction moveTo: duration:], apply an impulse to it's physics body.

CGVector impulse = CGVectorMake(1.0,1.0);
[spriteNode.physicsBody applyImpulse:impulse];

And voila! The ball will be bouncing off the walls with nothing to stop it.

This is what the .h file should look like:

#import <SpriteKit/SpriteKit.h>

static const uint8_t ballCategory = 1;
static const uint8_t wallCategory = 2;

@interface BallBounce : SKScene

@end

And this is how the .m file should look like:

#import "BallBounce.h"

@implementation BallBounce

-(instancetype)initWithSize:(CGSize)size
{
    if (self = [super initWithSize:size])
    {
        self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
        self.physicsBody.categoryBitMask = wallCategory;

        SKSpriteNode *spriteNode = [SKSpriteNode spriteNodeWithColor:[UIColor greenColor] size:CGSizeMake(50, 50)];

        spriteNode.name = @"ball";

        spriteNode.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:25];
        spriteNode.position = CGPointMake(10.0,10.0); //or anything you want
        spriteNode.physicsBody.dynamic = YES;
        spriteNode.physicsBody.affectedByGravity = NO;

        spriteNode.physicsBody.categoryBitMask = ballCategory;
        spriteNode.physicsBody.collisionBitMask = wallCategory;

        spriteNode.physicsBody.restitution = 1.0;
        spriteNode.physicsBody.friction = 0.0;
        spriteNode.physicsBody.linearDamping = 0.0;
        spriteNode.physicsBody.angularDamping = 0.0;

        [self addChild:spriteNode];

        CGVector impulse = CGVectorMake(100.0,100.0);
        [spriteNode.physicsBody applyImpulse:impulse];

    }

    return self;
}

@end

Have you tried setting the physics body of SKScene

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

That should keep your node's inside the frame.

W

This is from the http://www.raywenderlich.com/49721/how-to-create-a-breakout-game-using-spritekit

    SKPhysicsBody* borderBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
    // 2 Set physicsBody of scene to borderBody
    self.physicsBody = borderBody;
    // 3 Set the friction of that physicsBody to 0
    self.physicsBody.friction = 0.0f;

    // 1
    SKSpriteNode* ball = [SKSpriteNode spriteNodeWithImageNamed: @"Sphere.png"];
    ball.name = @"ball";
    ball.position = CGPointMake(self.frame.size.width/3, self.frame.size.height/3);
    [self addChild:ball];

    // 2
    ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.frame.size.width/2];
    // 3
    ball.physicsBody.friction = 0.0f;
    // 4
    ball.physicsBody.restitution = 1.0f;
    // 5
    ball.physicsBody.linearDamping = 0.0f;
    // 6
    ball.physicsBody.allowsRotation = NO;
    ball.physicsBody.affectedByGravity = NO;

    [ball.physicsBody applyImpulse:CGVectorMake(10.0f, 10.0f)];
Rex

This will bring your node in the frame in Swift:

self.physicsBody = SKPhysicsBody (edgeLoopFromRect: self.frame)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!