iPhoneボールキャッチ

飛んでくるボールをキャッチするiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface CatchScene : SKScene

@property (nonatomic) BOOL start;

@end

@implementation CatchScene

– (void)didMoveToView:(SKView *)view

{

    self.backgroundColor = [SKColor colorWithRed:0.9 green:0.9 blue:0.8 alpha:1];

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

    [self createCatcher];

}

– (void)createCatcher

{

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

    SKShapeNode *head = [SKShapeNode node];

    head.path = path.CGPath;

    head.fillColor = [SKColor colorWithWhite:0.1 alpha:1];

    head.position = CGPointMake(CGRectGetMaxX(self.frame) * 0.7, 120);

    [self addChild:head];

    head.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:30];

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

    head.physicsBody.collisionBitMask = 0x1 << 1;

    

    SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(10, 80)];

    body.position = CGPointMake(head.position.x, 40);

    [self addChild:body];

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

    

    SKSpriteNode *hand = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(15, 50)];

    hand.name = @”hand”;

    hand.position = CGPointMake(head.position.x, 60);

    [self addChild:hand];

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

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

    hand.physicsBody.collisionBitMask = 0x1 << 2;

    

    SKPhysicsJointFixed *f = [SKPhysicsJointFixed jointWithBodyA:head.physicsBody bodyB:body.physicsBody anchor:head.position];

    [self.physicsWorld addJoint:f];

    

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

    pin.shouldEnableLimits = YES;

    pin.upperAngleLimit = 0;

    pin.lowerAngleLimit = –M_PI * 0.7;

    [self.physicsWorld addJoint:pin];

    

    SKPhysicsJointPin *floor = [SKPhysicsJointPin jointWithBodyA:body.physicsBody bodyB:self.physicsBody anchor:CGPointMake(body.position.x, 5)];

    floor.shouldEnableLimits = YES;

    floor.upperAngleLimit = 0.1;

    floor.lowerAngleLimit = –0.1;

    [self.physicsWorld addJoint:floor];

}

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

{

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

    [hand.physicsBody applyTorque:-1];

    

    if (!self.start) {

        self.start = YES;

        [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(ball) userInfo:nil repeats:YES];

    }

}

– (void)ball

{

    SKNode *old = [self childNodeWithName:@”ball”];

    if (old)

        [old removeFromParent];

    

    

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

    SKShapeNode *ball = [SKShapeNode node];

    ball.name = @”ball”;

    ball.path = path.CGPath;

    ball.fillColor = [SKColor colorWithWhite:0.95 alpha:1];

    ball.position = CGPointMake(25, 50);

    [self addChild:ball];

    ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:20];

    [ball.physicsBody applyImpulse:CGVectorMake(25, 30)];

    ball.physicsBody.categoryBitMask = 0x1 << 4;

    ball.physicsBody.collisionBitMask = 0x1 << 4 | 0x1 << 1;

}

– (void)didSimulatePhysics

{

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

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

    if ([hand containsPoint:ball.position]) {

        SKPhysicsJointFixed *f = [SKPhysicsJointFixed jointWithBodyA:hand.physicsBody bodyB:ball.physicsBody anchor:ball.position];

        [self.physicsWorld addJoint:f];

    }

}

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

    [spriteView presentScene:scene];

}

@end