iPhone千本引き

お祭りの屋台で千本引き、 といった感じのiPhoneアプリのサンプルコードを描いてみます。

動かすとこんな感じです

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

typedef enum : int8_t {

    ColliderTypePrize = 0x1 << 1,

    ColliderTypeWall = 0x1 << 2,

    ColliderTypeOther = 0x1 << 3,

} ColliderType;

@interface RopeScene : SKScene

@end

@implementation RopeScene

– (void)didMoveToView:(SKView *)view

{

    [self createSceneContents];

}

– (void)createSceneContents

{

    self.backgroundColor = [SKColor lightGrayColor];

    [self createBottom];

    [self createTopPlate];

    [self createFrontRope];

    [self createPrize];

}

– (void)createTopPlate

{

    SKSpriteNode *topPlate = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(320, 50)];

    topPlate.position = CGPointMake(160, CGRectGetMaxY(self.view.bounds) – 100);

    [self addChild:topPlate];

    

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

    topPlate.physicsBody.dynamic = NO;

    topPlate.physicsBody.categoryBitMask = ColliderTypeOther;

    topPlate.physicsBody.collisionBitMask = 0x0;

    

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

        float x = i * 60135;

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

        hole.position = CGPointMake(x, 0);

        [topPlate addChild:hole];

    }

}

– (void)createFrontRope

{

    NSArray *marks = @[@”A”, @”B”, @”C”, @”D”, @”E”];

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

        float x = i * 60 + 25;

        SKSpriteNode *rope = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(8, 50)];

        rope.name = [NSString stringWithFormat:@”rope %d”, i];

        rope.position = CGPointMake(x, CGRectGetMaxY(self.view.bounds) – 125);

        [self addChild:rope];

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

        rope.physicsBody.dynamic = NO;

        rope.physicsBody.categoryBitMask = ColliderTypeOther;

        rope.physicsBody.collisionBitMask = ColliderTypeOther;

        

        SKLabelNode *ropeLabel = [SKLabelNode node];

        ropeLabel.name = [NSString stringWithFormat:@”label %d”,i];

        ropeLabel.text = marks[i];

        ropeLabel.position = CGPointMake(x, CGRectGetMaxY(self.view.bounds) – 180);

        [self addChild:ropeLabel];

        ropeLabel.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(10, 10)];

        ropeLabel.physicsBody.dynamic = NO;

        ropeLabel.physicsBody.categoryBitMask = ColliderTypeOther;

        ropeLabel.physicsBody.collisionBitMask = ColliderTypeOther;

        

        SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:rope.physicsBody bodyB:ropeLabel.physicsBody anchor:ropeLabel.position];

        [self.physicsWorld addJoint:pin];

    }

}

– (void)createPrize

{

    NSMutableArray *numbers = [@[@(0), @(1), @(2), @(3), @(4)] mutableCopy];

    

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

        int rand = arc4random() % (numbers.count);

        int no = [[numbers objectAtIndex:rand] intValue];

        [numbers removeObjectAtIndex:rand];

        

        SKSpriteNode *prizeRope = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(1, 200)];

        prizeRope.name = [NSString stringWithFormat:@”prizeRope %d”, no];

        prizeRope.position = CGPointMake(i * 60 + 50, 300);

        prizeRope.zPosition = –1;

        [self addChild:prizeRope];

        

        

        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-20, –20, 40, 40)];

        SKShapeNode *prize = [SKShapeNode node];

        prize.name = [NSString stringWithFormat:@”prize %d”, no];

        prize.position = CGPointMake(i * 60 + 50, 200);

        prize.path = path.CGPath;

        prize.fillColor = [SKColor colorWithHue:i*0.2 saturation:0.8 brightness:0.9 alpha:1.0];

        [self addChild:prize];

        

        prize.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:20];

        prize.physicsBody.dynamic = NO;

        

        if (i==2) {

            SKLabelNode *lucky = [SKLabelNode node];

            lucky.text = @”★”;

            lucky.fontColor = [SKColor whiteColor];

            lucky.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;

            [prize addChild:lucky];

        }

    }

}

– (void)createBottom

{

    SKSpriteNode *right = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(160, 20)];

    right.position = CGPointMake(80, 50);

    right.zRotation = –M_PI * 0.1;

    [self addChild:right];

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

    right.physicsBody.dynamic = NO;

    right.physicsBody.categoryBitMask = ColliderTypeWall;

    

    SKSpriteNode *left = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(160, 20)];

    left.position = CGPointMake(240, 50);

    left.zRotation = M_PI * 0.1;

    [self addChild:left];

    left.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:right.size];

    left.physicsBody.dynamic = NO;

    left.physicsBody.categoryBitMask = ColliderTypeWall;

}

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

{

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

    

    NSPredicate *whereMark = [NSPredicate predicateWithFormat:@”name contains %@”, @”label”];

    [[self.children filteredArrayUsingPredicate:whereMark] enumerateObjectsUsingBlock:^(SKNode *obj, NSUInteger idx, BOOL *stop) {

        if ([obj containsPoint:p]) {

            obj.physicsBody.dynamic = YES;

            

            int no = [[obj.name substringFromIndex:obj.name.length1] intValue];

            SKNode *rope = [self childNodeWithName:[NSString stringWithFormat:@”rope %d”, no]];

            rope.physicsBody.dynamic = YES;

            

            SKNode *prizeRope = [self childNodeWithName:[NSString stringWithFormat:@”prizeRope %d”, no]];

            [prizeRope removeFromParent];

            

            SKNode *prize = [self childNodeWithName:[NSString stringWithFormat:@”prize %d”, no]];

            prize.physicsBody.dynamic = YES;

            [prize.physicsBody applyImpulse:CGVectorMake(0, 20)];

        }

    }];

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

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

    [self.view addSubview:spriteView];

    

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

    [spriteView presentScene:scene];

}

@end