iPhoneワープ

A, Bのところにくると、四角の位置が瞬間移動。というiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface HoleScene : SKScene

@end

@implementation HoleScene

– (void)didMoveToView:(SKView *)view

{

    self.physicsWorld.speed = 0.3;

    [self createLines];

    [self createBall];

}

– (void)createLines

{

    SKNode *barOne = [self createBar];

    barOne.position = CGPointMake(160, 200);

    barOne.zRotation = M_PI * 0.2;

    

    SKNode *barTwo = [self createBar];

    barTwo.position = CGPointMake(160, 350);

    barTwo.zRotation = –M_PI * 0.2;

}

– (SKNode *)createBar

{

    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(-100, –20, 200, 40) cornerRadius:20];

    SKShapeNode *bar = [SKShapeNode node];

    bar.name = @”bar”;

    bar.path = path.CGPath;

    [self addChild:bar];

    

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

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

        SKShapeNode *hole = [SKShapeNode node];

        hole.position = CGPointMake(-80 + 160 * i, 0);

        hole.path = holePath.CGPath;

        hole.lineWidth = 0;

        hole.fillColor = [SKColor whiteColor];

        [bar addChild:hole];

        

        SKLabelNode *a = [SKLabelNode node];

        a.name = @”hole”;

        a.text = i == 0 ? @”A” : @”B”;

        a.fontColor = [SKColor blackColor];

        a.position = CGPointMake(-80 + 160 * i, 0);

        a.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;

        [bar addChild:a];

    }

    

    bar.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromPath:path.CGPath];

    

    return bar;

}

– (void)createBall

{

    SKColor *color = [[SKColor greenColor] colorWithAlphaComponent:0.8];

    SKSpriteNode *ball = [SKSpriteNode spriteNodeWithColor:color size:CGSizeMake(20, 20)];

    ball.name = @”ball”;

    ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:12];

    ball.position = CGPointMake(160, 200);

    [self addChild:ball];

}

– (void)didSimulatePhysics

{

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

    

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

        [bar enumerateChildNodesWithName:@”hole” usingBlock:^(SKNode *node, BOOL *stop) {

            CGPoint holeCenter = [node.parent convertPoint:node.position toNode:self];

            if ([ball containsPoint:holeCenter]) {

                [self holeIn:(SKLabelNode *)node];

            }

        }];

    }];

}

– (void)holeIn:(SKLabelNode *)hole

{

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

    

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

        if (hole.parent != node) {

            

            SKLabelNode *next = nil;

            for (SKLabelNode *l in node.children) {

                if ([l isKindOfClass:[SKLabelNode class]] && [l.text isEqual:hole.text]) {

                    next = l;

                }

            }

            

            ball.physicsBody = nil;

            ball.name = @”ball animation”;

            CGPoint nextPoint = [next.parent convertPoint:next.position toNode:self];

            SKAction *action1 = [SKAction fadeAlphaTo:0.1 duration:0.5];

            SKAction *action2 = [SKAction moveTo:nextPoint duration:0.2];

            SKAction *action3 = [SKAction fadeInWithDuration:0.5];

            SKAction *action4 = [SKAction customActionWithDuration:0.1 actionBlock:^(SKNode *node, CGFloat elapsedTime) {

                ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:12];

            }];

            SKAction *action5 = [SKAction customActionWithDuration:0 actionBlock:^(SKNode *node, CGFloat elapsedTime) {

                ball.name = @”ball”;

            }];

            [ball runAction:[SKAction sequence:@[action1, action2, action3, action4, [SKAction waitForDuration:1.5], action5]]];

        }

    }];

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

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

    [self.view addSubview:spriteView];

    

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

    [spriteView presentScene:scene];

}

@end