iPhoneハンガー

ハンガーをくるくるポンして壁にかけるiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface HangerScene : SKScene

@property (nonatomic, weak) SKPhysicsJoint *joint;

@end

@implementation HangerScene

– (void)didMoveToView:(SKView *)view

{

    self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:CGRectInset(self.frame, –100, –100)];

    [self createPoles];

}

– (void)createPoles

{

    float space = CGRectGetMaxX(self.frame) / 3.0;

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

        float x = space * (i + 0.5);

        float y = 250;

        SKSpriteNode *pole = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(8, 8)];

        pole.position = CGPointMake(x, y);

        pole.zRotation = M_PI/4.0;

        [self addChild:pole];

        pole.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:4];

        pole.physicsBody.dynamic = NO;

    }

}

– (SKNode *)createHanger

{

    SKNode *hanger = [SKNode node];

    hanger.name = @”hanger”;

    [self addChild:hanger];

    

    NSMutableArray *bodies = [NSMutableArray array];

    

    CGPoint pt[] = {CGPointMake(0, 20), CGPointMake(-45, –20), CGPointMake(45, –20)};

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path moveToPoint:pt[0]];

    [path addLineToPoint:pt[1]];

    [path addLineToPoint:pt[2]];

    [path closePath];

    

    SKShapeNode *triangle = [SKShapeNode node];

    triangle.path = path.CGPath;

    triangle.lineWidth = 3;

    triangle.strokeColor = [SKColor blueColor];

    [hanger addChild:triangle];

    [bodies addObject:[SKPhysicsBody bodyWithPolygonFromPath:path.CGPath]];

    

    float dangle = M_PI / 10.0;

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

        float x = 10 * cos(dangle * i);

        float y = 10 * sin(dangle * i) + 40;

        SKSpriteNode *n = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(3, 3)];

        n.position = CGPointMake(x, y);

        [hanger addChild:n];

        [bodies addObject:[SKPhysicsBody bodyWithCircleOfRadius:2 center:n.position]];

    }

    

    UIBezierPath *path2 = [UIBezierPath bezierPath];

    [path2 moveToPoint:CGPointMake(0, 18)];

    [path2 addLineToPoint:CGPointMake(-12, 40)];

    [path2 addLineToPoint:CGPointMake(-10, 40)];

    [path2 addLineToPoint:CGPointMake(0, 20)];

    [path2 closePath];

    SKShapeNode *bar = [SKShapeNode node];

    bar.lineWidth = 1;

    bar.strokeColor = [SKColor blueColor];

    bar.fillColor = [SKColor blueColor];

    bar.path = path2.CGPath;

    [hanger addChild:bar];

    [bodies addObject:[SKPhysicsBody bodyWithPolygonFromPath:path2.CGPath]];

    

    hanger.physicsBody = [SKPhysicsBody bodyWithBodies:bodies];

    return hanger;

}

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

{

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

    SKNode *hanger = [self createHanger];

    hanger.position = p;

    

    [hanger.physicsBody applyImpulse:CGVectorMake(0, –6) atPoint:CGPointMake(300, 0)];

    

    SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:hanger.physicsBody bodyB:self.physicsBody anchor:CGPointMake(hanger.position.x + 30, hanger.position.y)];

    [self.physicsWorld addJoint:pin];

    self.joint = pin;

}

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

{

    if (self.joint) {

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

        [self.physicsWorld removeJoint:self.joint];

        [hanger.physicsBody applyImpulse:CGVectorMake(0, 50)];

        hanger.name = @””;

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            [hanger removeFromParent];

        });

    }

}

@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 = [[HangerScene alloc] initWithSize:spriteView.frame.size];

    [spriteView presentScene:scene];

}

@end