iPhoneリング引っ張る

リングを引っ張って、黄色い四角をGetするiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SpriteKit;

@interface PullScene: SKScene

@property (nonatomic, weak) SKNode *selected;

@end

@implementation PullScene

– (void)didMoveToView:(SKView *)view

{

    self.backgroundColor = [SKColor lightGrayColor];

    self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.frame.size];

    self.physicsBody.dynamic = NO;

    self.physicsBody.collisionBitMask = 0x0;

    [self createBase];

    [self createRing];

    [self createApple];

}

– (void)createBase

{

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:40 startAngle:0 endAngle:2.0*M_PI clockwise:NO];

    

    SKShapeNode *base = [SKShapeNode node];

    base.path = path.CGPath;

    base.name = @”base”;

    base.position = CGPointMake(80, CGRectGetMaxY(self.frame) – 80);

    base.strokeColor = [SKColor darkGrayColor];

    base.fillColor = [SKColor whiteColor];

    base.lineWidth = 20;

    [self addChild:base];

    float angle = M_PI / 5.0;

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

        float x = 40 * cos(angle * i);

        float y = 40 * sin(angle * i);

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

        n.zRotation = angle * i + M_PI/4.0;

        n.position = CGPointMake(x, y);

        [base addChild:n];

    }

    

    base.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:40];

    base.physicsBody.angularDamping = 1.0;

    base.physicsBody.collisionBitMask = 0x0;

    

    SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:self.physicsBody bodyB:base.physicsBody anchor:base.position];

    [self.physicsWorld addJoint:pin];

}

– (void)createRing

{

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:25 startAngle:0 endAngle:2.0*M_PI clockwise:NO];

    SKShapeNode *ring = [SKShapeNode node];

    ring.name = @”ring”;

    ring.path = path.CGPath;

    ring.fillColor = [SKColor clearColor];

    ring.strokeColor = [SKColor redColor];

    ring.lineWidth = 15;

    ring.position = CGPointMake(80, CGRectGetMaxY(self.frame) – 80);

    ring.zPosition = 2;

    [self addChild:ring];

    

    SKShapeNode *wire = [SKShapeNode node];

    wire.name = @”wire”;

    wire.strokeColor = [SKColor redColor];

    wire.lineWidth = 5;

    [ring addChild:wire];

}

– (void)update:(NSTimeInterval)currentTime

{

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

    base.physicsBody.angularVelocity = 0.5;

    

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

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

    

    if ([apple containsPoint:ring.position]) {

        apple.zPosition = 3;

        [apple runAction:[SKAction sequence:@[[SKAction scaleTo:3.0 duration:0.5],[SKAction fadeOutWithDuration:0.5]]] completion:^{

            [apple removeFromParent];

        }];

    }

    

    if (ring.position.y > CGRectGetMaxY(self.frame) – 50) {

        [ring removeFromParent];

        [self createRing];

    }

}

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

{

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

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

    if ([ring containsPoint:p]) {

        self.selected = ring;

    }

}

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

{

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

    if (self.selected) {

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

        self.selected.position = CGPointMake(self.selected.position.x, p.y);

        

        UIBezierPath *path = [UIBezierPath bezierPath];

        [path moveToPoint:CGPointMake(0, 30)];

        [path addLineToPoint:CGPointMake(0, base.position.yself.selected.position.y)];

        SKShapeNode *wire = (SKShapeNode *)[self.selected childNodeWithName:@”wire”];

        wire.path = path.CGPath;

    }

}

– (void)createApple

{

    SKSpriteNode *apple = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(20, 20)];

    apple.name = @”apple”;

    apple.position = CGPointMake(300, 200);

    apple.zPosition = 1;

    [self addChild:apple];

    

    SKAction *turn = [SKAction repeatActionForever:[SKAction rotateByAngle:M_PI duration:2.0]];

    [apple runAction:turn];

}

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

{

    if (self.selected) {

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

        self.selected.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:20];

        self.selected.physicsBody.collisionBitMask = 0x0;

        self.selected.physicsBody.density = 0.01;

        

        SKPhysicsJointFixed *joint = [SKPhysicsJointFixed jointWithBodyA:self.selected.physicsBody bodyB:base.physicsBody anchor:base.position];

        [self.physicsWorld addJoint:joint];

        

        self.selected = nil;

    }

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidAppear:(BOOL)animated

{

    [super viewDidAppear:animated];

    

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

    [self.view addSubview:spriteView];

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

    [spriteView presentScene:scene];

}

@end