「トータス」というおもちゃを買ってみた。まだ足し算はできないので、子供用に出た数をスタンプしていくようなiPhoneアプリのサンプルを描いてみる。

#import “ViewController.h”

@import SpriteKit;

@interface StampScene : SKScene

@property (nonatomic) int stampType;

@end

@implementation StampScene

– (void)didMoveToView:(SKView *)view

{

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

    self.physicsBody.categoryBitMask = 0x1;

    self.physicsBody.dynamic = NO;

    [self createStamps];

    [self createSheet];

    [self createClearButton];

}

#define StampCenter CGPointMake(CGRectGetMidX(self.view.bounds), 0)

#define StampBoardSize CGRectGetMaxX(self.view.bounds) / 5

#define StampSize CGRectGetMaxX(self.view.bounds) / 18.0

– (void)createStamps

{

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

    SKShapeNode *turnBoard = [SKShapeNode node];

    turnBoard.name = @”turnBoard”;

    turnBoard.path = path.CGPath;

    turnBoard.fillColor = [SKColor whiteColor];

    turnBoard.position = StampCenter;

    [self addChild:turnBoard];

    

    turnBoard.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:StampBoardSize];

    SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:turnBoard.physicsBody bodyB:self.physicsBody anchor:turnBoard.position];

    [self.physicsWorld addJoint:pin];

    

    float r = StampBoardSize * 0.6;

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

        float x = r * cos(2.0 * M_PI / 5.0 * i);

        float y = r * sin(2.0 * M_PI / 5.0 * i);

        SKNode *stamp = [self createFigure:i + 2]; // 2: circle, 3: triangle, 4:rectangle

        stamp.position = CGPointMake(x, y);

        [turnBoard addChild:stamp];

        

        stamp.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:StampSize];

        stamp.physicsBody.collisionBitMask = 0x2;

        SKPhysicsJointPin *p = [SKPhysicsJointPin jointWithBodyA:stamp.physicsBody bodyB:turnBoard.physicsBody anchor:[turnBoard convertPoint:stamp.position toNode:self]];

        [self.physicsWorld addJoint:p];

    }

}

– (SKNode *)createFigure:(int)type

{

    UIBezierPath *path;

    SKShapeNode *fig = [SKShapeNode node];

    fig.name = [NSString stringWithFormat:@”%@ %d”, @”stamp”, type];

    fig.fillColor = [SKColor colorWithHue:0.15 * type saturation:0.8 brightness:0.9 alpha:1];

    

    if (type < 3) {

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

        fig.path = path.CGPath;

    } else {

        path = [UIBezierPath bezierPath];

        float dAngle = 2.0 * M_PI / (float)type;

        float r = StampSize;

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

            float x = r * cos(dAngle * i);

            float y = r * sin(dAngle * i);

            if (i == 0) [path moveToPoint:CGPointMake(x, y)];

            else [path addLineToPoint:CGPointMake(x, y)];

        }

        [path closePath];

        fig.path = path.CGPath;

    }

    

    return fig;

}

– (void)createSheet

{

    float l = CGRectGetMaxX(self.view.bounds) / 10.0;

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

        SKSpriteNode *box = [SKSpriteNode spriteNodeWithColor:[SKColor lightGrayColor] size:CGSizeMake(l*0.9, l*0.9)];

        box.position = CGPointMake(l * i + l/2.0, CGRectGetMidY(self.view.bounds));

        [self addChild:box];

    }

}

– (void)createClearButton

{

    SKSpriteNode *clearBtn = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(StampSize * 3.0, StampSize* 1.5)];

    clearBtn.name = @”btn”;

    clearBtn.position = CGPointMake(CGRectGetMaxX(self.frame) * 0.9, CGRectGetMaxY(self.frame) * 0.2);

    [self addChild:clearBtn];

    

    SKLabelNode *l = [SKLabelNode node];

    l.text = @”delete”;

    l.fontSize = StampSize;

    l.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;

    [clearBtn addChild:l];

}

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

{

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

    SKNode *n = [self nodeAtPoint:p];

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

    

    if ([n.name hasPrefix:@”stamp”]) {

        self.stampType = [[n.name componentsSeparatedByString:@” “][1] intValue];

        [[self childNodeWithName:@”advice”] removeFromParent];

        

        SKNode *advice = [self createFigure:self.stampType];

        advice.name = @”advice”;

        advice.xScale = 2.0;

        advice.yScale = 2.0;

        advice.position = CGPointMake(-CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame) * 0.8);

        [self addChild:advice];

        [advice runAction:[SKAction moveToX:CGRectGetMidX(self.frame) duration:0.5]];

        

    } else if ([n.name isEqual:@”stp”]) {

        [n removeFromParent];

        

    } else if ([btn containsPoint:p]) {

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

            [node removeFromParent];

        }];

        

    } else if (self.stampType > 1){

        SKNode *stamp = [self createFigure:self.stampType];

        stamp.name = @”stp”;

        stamp.xScale = 0.7;

        stamp.yScale = 0.7;

        stamp.position = p;

        [self addChild:stamp];

    }

}

– (void)update:(NSTimeInterval)currentTime

{

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

    turnBoard.physicsBody.angularVelocity = 1.0;

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidAppear:(BOOL)animated

{

    [super viewDidAppear:animated];

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

    [self.view addSubview:spriteView];

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

    [spriteView presentScene:scene];

}

@end