iphoneニュートンゆりかご

ニュートンのゆりかごみたいなカチカチ球をぶつけるiPhoneアプリのサンプルを描いてみます。


動作イメージ
XcodeからiOS7 iPhone Simulatorで動かすとこんな感じになります。

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface CradleScene : SKScene

@property BOOL contentCreated;

@end

@implementation CradleScene

– (void)didMoveToView:(SKView *)view

{

    if (!self.contentCreated) {

        [self createSceneContents];

        self.contentCreated = YES;

    }

}

– (void)createSceneContents

{

    SKSpriteNode *bar = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(320, 10)];

    bar.position = CGPointMake(160, 250);

    [self addChild:bar];

    bar.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bar.size];

    bar.physicsBody.dynamic = NO;

    

    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-20, –20, 40, 40)];

    for (int i=0; i<5; i++) {

        SKShapeNode *ball = [SKShapeNode node];

        ball.name = @”ball”;

        ball.path = path.CGPath;

        ball.fillColor = [SKColor whiteColor];

        ball.strokeColor = [SKColor clearColor];

        ball.position = CGPointMake(41 * i + 80, 100);

        [self addChild:ball];

        ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:20];

        ball.physicsBody.restitution = 1.0;

        

        SKSpriteNode *wire = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(1, 130)];

        wire.position = CGPointMake(ball.position.x, 185);

        [self addChild:wire];

        wire.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:wire.size];

        wire.physicsBody.affectedByGravity = NO;

        

        SKPhysicsJointPin *top = [SKPhysicsJointPin jointWithBodyA:bar.physicsBody bodyB:wire.physicsBody anchor:CGPointMake(wire.position.x, 240)];

        [self.physicsWorld addJoint:top];

        

        SKPhysicsJointPin *ballAndWire = [SKPhysicsJointPin jointWithBodyA:wire.physicsBody bodyB:ball.physicsBody anchor:CGPointMake(wire.position.x, 130)];

        ballAndWire.frictionTorque = 1.0;

        [self.physicsWorld addJoint:ballAndWire];

    }

    

    SKLabelNode *stop = [SKLabelNode node];

    stop.text = @”stop”;

    stop.name = @”stop”;

    stop.position = CGPointMake(160, 20);

    [self addChild:stop];

}

– (void)reset

{

    [self enumerateChildNodesWithName:@”ball” usingBlock:^(SKNode *node, BOOL *stop) {

        node.physicsBody.velocity = CGVectorMake(0, 0);

    }];

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    CGPoint p = [[touches anyObject] locationInNode:self];

    [self enumerateChildNodesWithName:@”ball” usingBlock:^(SKNode *node, BOOL *stop) {

        if ([node containsPoint:p]) {

            float dx = 20;

            if (p.x < 160) {

                dx = -dx;

            }

            [node.physicsBody applyImpulse:CGVectorMake(dx, 0)];

        }

    }];

    

    SKNode *stop = [self childNodeWithName:@”stop”];

    if ([stop containsPoint:p]) {

        [self reset];

    }

    

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];

    [self.view addSubview:spriteView];

    

    SKScene *scene = [[CradleScene alloc] initWithSize:spriteView.bounds.size];

    [spriteView presentScene:scene];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end