iPhoneドアとスイッチ

画面真ん中らへんにあるスイッチにボールをぶつけてドアを開けるといった、iPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SpriteKit;

@interface DoorScene : SKScene <SKPhysicsContactDelegate>

@property (nonatomic) BOOL start;

@end

@implementation DoorScene

– (void)didMoveToView:(SKView *)view

{

    self.backgroundColor = [UIColor lightGrayColor];

    self.physicsWorld.contactDelegate = self;

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

    self.physicsBody.restitution = 1.0;

    [self createSwitch];

    [self createJumper];

    [self createDoor];

}

– (void)createSwitch

{

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

    shelf.position = CGPointMake(160, CGRectGetMaxY(self.frame) – 150);

    shelf.zPosition = 1;

    [self addChild:shelf];

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

    shelf.physicsBody.dynamic = NO;

    

    SKSpriteNode *btn = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(40, 30)];

    btn.name = @”btn”;

    btn.position = CGPointMake(shelf.position.x, shelf.position.y + 15);

    btn.zPosition = 0;

    [self addChild:btn];

    

    SKAction *flash = [SKAction repeatActionForever:[SKAction sequence:@[[SKAction fadeAlphaTo:0.7 duration:0.5], [SKAction fadeAlphaTo:1.0 duration:0.5]]]];

    [btn runAction:flash];

}

– (void)createJumper

{

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

    SKShapeNode *jumper = [SKShapeNode node];

    jumper.name = @”jumper”;

    jumper.path= path.CGPath;

    jumper.position = CGPointMake(160, 200);

    jumper.fillColor = [SKColor blackColor];

    jumper.zPosition = 4;

    [self addChild:jumper];

    

    jumper.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:15];

    jumper.physicsBody.linearDamping = 0;

    jumper.physicsBody.angularDamping = 0;

    jumper.physicsBody.friction = 0;

    jumper.physicsBody.restitution = 1.0;

    jumper.physicsBody.categoryBitMask = 0x1;

    jumper.physicsBody.contactTestBitMask = 0x2;

}

– (void)createDoor

{

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

        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:20 startAngle:M_PI * 0.3 endAngle:M_PI * 1.3 clockwise:i];

        SKShapeNode *medal = [SKShapeNode node];

        medal.path = path.CGPath;

        medal.fillColor = i ? [SKColor colorWithRed:0.95 green:0.95 blue:0 alpha:1] : [SKColor colorWithRed:0.9 green:0.9 blue:0 alpha:1];

        medal.strokeColor = [SKColor yellowColor];

        medal.position = CGPointMake(280, 30);

        medal.zPosition = 1;

        [self addChild:medal];

        

        SKSpriteNode *ribbon = [SKSpriteNode spriteNodeWithColor:i ? [SKColor colorWithRed:0 green:0.9 blue:0 alpha:1] : [SKColor colorWithRed:0 green:0.8 blue:0 alpha:1] size:CGSizeMake(20, 40)];

        ribbon.position = CGPointMake(i ? 270 : 290 , 60);

        ribbon.zRotation = i ? M_PI * 0.1 : – M_PI * 0.1;

        ribbon.zPosition = 0;

        [self addChild:ribbon];

    }

    

    SKNode *door = [SKNode node];

    door.name = @”door”;

    door.position = CGPointMake(280, 40);

    door.zPosition = 3;

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

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

        n.position = CGPointMake(i * 1326, 0);

        [door addChild:n];

    }

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

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

        n.position = CGPointMake(0, i ? –40 : 40);

        [door addChild:n];

    }

    [self addChild:door];

}

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

{

    if (!self.start) {

        self.start = YES;

        

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

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

        return;

    }

    

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

    SKSpriteNode *block = [SKSpriteNode spriteNodeWithColor:[SKColor brownColor] size:CGSizeMake(60, 5)];

    block.name = @”block”;

    block.position = p;

    [self addChild:block];

    

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

    block.physicsBody.dynamic = NO;

    block.physicsBody.friction = 0;

    block.physicsBody.categoryBitMask = 0x2;

}

– (void)update:(NSTimeInterval)currentTime

{

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

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

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

    float ux = fabs(jumper.physicsBody.velocity.dx);

    float uy = fabs(jumper.physicsBody.velocity.dx);

    if (ux > 80) {

        jumper.physicsBody.velocity = CGVectorMake(80 * jumper.physicsBody.velocity.dx/ux, jumper.physicsBody.velocity.dy);

    } else if (uy > 80) {

        

        jumper.physicsBody.velocity = CGVectorMake(jumper.physicsBody.velocity.dx, 80 * jumper.physicsBody.velocity.dy/uy);

    }

    

    if ([btn intersectsNode:jumper]) {

        // clear!!

        if (jumper.physicsBody) {

            [btn runAction:[SKAction moveByX:0 y:-20 duration:0.5]];

            [door runAction:[SKAction moveByX:0 y:80 duration:1.5]];

        }

        jumper.physicsBody = nil;

    }

}

– (void)didBeginContact:(SKPhysicsContact *)contact

{

    if([contact.bodyA.node.name isEqual:@”block”]) {

        [contact.bodyB applyImpulse:CGVectorMake(0, 2.0)];

    }

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

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

    [self.view addSubview:spriteView];

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

    [spriteView presentScene:scene];

}

@end