iPhoneブランコ

今日のiPhoneアプリのサンプルコードは空中ブランコをする四角形。

動かすとこんな感じです

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface TrapezeScene : SKScene <SKPhysicsContactDelegate>

@property BOOL contentCreated;

@property (nonatomic, weak) SKShapeNode *ropeLayer;

@property (nonatomic, weak) SKNode *currentNode;

@end

@implementation TrapezeScene

– (void)didMoveToView:(SKView *)view

{

    if (!self.contentCreated) {

        [self createSceneContents];

        self.contentCreated = YES;

    }

}

– (void)createSceneContents

{

    self.physicsWorld.contactDelegate = self;

    [self createPin];

    [self createJumper];

    [self createButtons];

}

– (void)createPin

{

    UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-5, –5, 10, 10)];

    

    float p[] = {80, 160, 250, 300, 80, 450};

    for (int i=0; i<sizeof(p)/(2*sizeof(float)); i++) {

        float x = p[2*i];

        float y = p[2*i+1];

        SKShapeNode *pin = [SKShapeNode node];

        pin.name = @”pin”;

        pin.path = circle.CGPath;

        pin.position = CGPointMake(x, y);

        [self addChild:pin];

        

        pin.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:5];

        pin.physicsBody.dynamic = NO;

        

        SKSpriteNode *node = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(5, 5)];

        node.name = [NSString stringWithFormat:@”node%d”, i];

        node.position = CGPointMake(x, y – 80);

        node.zPosition = 2;

        [self addChild:node];

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

        node.physicsBody.categoryBitMask = 0x1 << 2;

        node.physicsBody.contactTestBitMask = 0x1 << 1;

        

        SKPhysicsJointLimit *rope = [SKPhysicsJointLimit jointWithBodyA:pin.physicsBody bodyB:node.physicsBody anchorA:pin.position anchorB:node.position];

        [self.physicsWorld addJoint:rope];

    }

}

– (void)createJumper

{

    SKNode *startNode = [self childNodeWithName:@”node0″];

    self.currentNode = startNode;

    

    SKSpriteNode *jumper = [SKSpriteNode spriteNodeWithColor:[SKColor orangeColor] size:CGSizeMake(30, 30)];

    jumper.name = @”jumper”;

    jumper.position = CGPointMake(startNode.position.x, startNode.position.y);

    jumper.zPosition = 1;

    [self addChild:jumper];

    

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

    jumper.physicsBody.linearDamping = 1.0;

    jumper.physicsBody.angularDamping = 1.0;

    jumper.physicsBody.categoryBitMask = 0x1 << 1;

    

    SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:jumper.physicsBody bodyB:startNode.physicsBody anchor:startNode.position];

    [self.physicsWorld addJoint:pin];

}

– (void)createButtons

{

    SKSpriteNode *btn1 = [SKSpriteNode spriteNodeWithColor:[SKColor lightGrayColor] size:CGSizeMake(40, 40)];

    btn1.name = @”btn1″;

    btn1.position = CGPointMake(240, 20);

    [self addChild:btn1];

    

    SKSpriteNode *btn2 = [SKSpriteNode spriteNodeWithColor:[SKColor lightGrayColor] size:CGSizeMake(40, 40)];

    btn2.name = @”btn2″;

    btn2.position = CGPointMake(290, 20);

    [self addChild:btn2];

}

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

{

    SKNode *btn1 = [self childNodeWithName:@”btn1″];

    SKNode *btn2 = [self childNodeWithName:@”btn2″];

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

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

    

    if ([btn1 containsPoint:p]) {

        // move

        [jumper.physicsBody applyImpulse:CGVectorMake(30, 0)];

    } else if ([btn2 containsPoint:p]) {

        // detach

        [jumper.physicsBody.joints enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

            [self.physicsWorld removeJoint:obj];

        }];

        

        [jumper.physicsBody applyImpulse:CGVectorMake(0, 20)];

    }

}

– (void)didSimulatePhysics

{

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

    if (jumper.position.y < –20) {

        [jumper removeFromParent];

        [self createJumper];

    }

    

    if (!self.ropeLayer) {

        self.ropeLayer = [SKShapeNode node];

        [self addChild:self.ropeLayer];

    }

    

    UIBezierPath *path = [UIBezierPath bezierPath];

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

        [path moveToPoint:pin.position];

        SKPhysicsJoint *joint = pin.physicsBody.joints[0];

        [path addLineToPoint:joint.bodyB.node.position];

    }];

    

    self.ropeLayer.path = path.CGPath;

}

– (void)didBeginContact:(SKPhysicsContact *)contact

{

    SKNode *jumper, *node;

    if (contact.bodyA.categoryBitMask == 0x1<<1) {

        jumper = contact.bodyA.node;

        node = contact.bodyB.node;

    } else if (contact.bodyA.categoryBitMask == 0x1<<2) {

        jumper = contact.bodyB.node;

        node = contact.bodyA.node;

    }

    

    if (node != self.currentNode) {

        self.currentNode = node;

        SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:jumper.physicsBody bodyB:node.physicsBody anchor:contact.contactPoint];

        [self.physicsWorld addJoint:pin];

    }

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidAppear:(BOOL)animated

{

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

    [self.view addSubview:spriteView];

    

    SKScene *scene = [[TrapezeScene alloc] initWithSize:spriteView.frame.size];

    [spriteView presentScene:scene];

}

@end