iPhoneクラゲ足し算

クラゲチャートで足し算するiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SpriteKit;

@interface ViewController () <SKPhysicsContactDelegate>

@property (nonatomic, weak) SKScene *scene;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createJellyfish];

    

    [self createTargetNumber];

    [self createNumberBall];

}

– (void)setupScene {

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

    SKScene *s = [SKScene sceneWithSize:sv.frame.size];

    s.physicsWorld.contactDelegate = self;

    s.backgroundColor = [self color:1];

    [sv presentScene:s];

    [self.view addSubview:sv];

    

    self.scene = s;

}

– (void)createJellyfish {

    SKNode *jellyfish = [SKNode node];

    jellyfish.name = @”jellyfish”;

    jellyfish.position = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds) + 100);

    [self.scene addChild:jellyfish];

    

    SKShapeNode *head = [SKShapeNode shapeNodeWithEllipseOfSize:CGSizeMake(160, 120)];

    head.fillColor = [self color:0];

    head.strokeColor = [self color:2];

    [jellyfish addChild:head];

    

    head.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(160, 120)];

    head.physicsBody.dynamic = false;

    

    float dx = CGRectGetMaxX(self.view.bounds) / 8.0;

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

        SKShapeNode *leg = [SKShapeNode shapeNodeWithCircleOfRadius:30];

        leg.position = CGPointMake(dx * (i – 1.5), –100);

        leg.fillColor = head.fillColor;

        leg.strokeColor = head.strokeColor;

        [jellyfish addChild:leg];

        

        SKLabelNode *l = [SKLabelNode labelNodeWithText: (i%2) ? @”+” : @”-“];

        l.fontName = @”MarkerFelt-Wide”;

        l.fontSize = 50;

        l.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;

        l.fontColor = [self color:4];

        [leg addChild:l];

        

        leg.name = [@”leg “ stringByAppendingString:l.text];

        leg.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:30];

        leg.physicsBody.contactTestBitMask = 0x1;

        leg.physicsBody.dynamic = false;

    }

}

– (void)createTargetNumber {

    SKNode *jellyfish = [self.scene childNodeWithName:@”jellyfish”];

    SKLabelNode *targetNumber = [SKLabelNode labelNodeWithText:@”0/10″];

    targetNumber.name = @”target number”;

    targetNumber.position = jellyfish.position;

    targetNumber.fontName = @”MarkerFelt-Wide”;

    targetNumber.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;

    targetNumber.fontSize = 60;

    targetNumber.fontColor = [self color:4];

    

    [self.scene addChild:targetNumber];

}

– (void)createNumberBall {

    NSMutableArray *numbers = [[@”1 2 3 4 5 6 7 8 9″ componentsSeparatedByString:@” “] mutableCopy];

    

    BOOL check = false;

    while (!check) {

        [self shuffle:numbers];

        check = [self checkNumbers:numbers];

    }

    

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

        SKShapeNode *ball = [SKShapeNode shapeNodeWithCircleOfRadius:20];

        ball.userInteractionEnabled = YES;

        ball.fillColor = [self color:2];

        ball.lineWidth = 0;

        ball.position = CGPointMake((i – 0.5) * 80 + CGRectGetMidX(self.view.bounds), 30);

        [self.scene addChild:ball];

        SKLabelNode *l = [SKLabelNode labelNodeWithText:numbers[i]];

        l.fontName = @”MarkerFelt-Wide”;

        l.fontSize = 30;

        l.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;

        l.fontColor = [self color:4];

        [ball addChild:l];

        

        [ball runAction:[SKAction repeatActionForever:

             [SKAction sequence:@[

                  [SKAction moveByX:-160 y:0 duration:2.0],

                  [SKAction moveByX:160 y:0 duration:2.0]]]]];

        

        

        ball.name = [NSString stringWithFormat:@”ball %@”, l.text];

    }

}

– (BOOL)checkNumbers:(NSArray *)arr {

    // +a or -a, +b or -b, +c or -c, +d or -d

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

        int total = 0;

        for (int j=0; j<4; j++) {

            total += (i >> j) & 0x1 ? [arr[j] intValue] : -[arr[j] intValue];

        }

        if (total == 10) return true;

    }

    return false;

}

– (void)shuffle:(NSMutableArray *)arr

{

    NSUInteger count = [arr count];

    for (NSUInteger i = 0; i < count; ++i) {

        NSInteger remainingCount = count – i;

        NSInteger exchangeIndex = i + arc4random_uniform((u_int32_t )remainingCount);

        [arr exchangeObjectAtIndex:i withObjectAtIndex:exchangeIndex];

    }

}

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

{

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

    NSArray *hits = [self.scene nodesAtPoint:p];

    for (SKNode *hit in hits) {

        if ([hit.name hasPrefix:@”ball”]) {

            [hit removeAllActions];

            hit.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:30];

            hit.physicsBody.categoryBitMask = 0x1;

            [hit.physicsBody applyImpulse:CGVectorMake(0, 100)];

        }

    }

}

– (void)didBeginContact:(SKPhysicsContact *)contact

{

    if([contact.bodyA.node.name hasPrefix:@”leg”]

       && [contact.bodyB.node.name hasPrefix:@”ball”]) {

        int op = [[contact.bodyA.node.name componentsSeparatedByString:@” “][1] isEqual:@”+”] ? 1 : –1;

        int number = [[contact.bodyB.node.name componentsSeparatedByString:@” “][1] intValue];

        contact.bodyB.node.name = @”used”;

        

        SKLabelNode *targetNumber = (SKLabelNode *)[self.scene childNodeWithName:@”target number”];

        targetNumber.text = [NSString stringWithFormat:@”%d/10″, [[targetNumber.text componentsSeparatedByString:@”/”][0] intValue] + (op * number)];

    }

}

#define ColorHex(rgb) [UIColor colorWithRed:((rgb & 0xFF0000)>>16)/255.0 green:((rgb & 0xFF00)>>8)/255.0 blue:(rgb & 0xFF)/255.0 alpha:1.0];

– (UIColor *)color:(int)i {

    if (i > 4) return nil;

    int colorCode[] = {0x665EB0, 0x638AA8, 0xBDC5C7, 0x4F7174, 0x339D89};

    return ColorHex(colorCode[i]);

}

@end