クラゲチャートで足し算する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