iPhoneかがみもち

お餅を積み上げて、鏡餅!という感じで、iPhoneゲームのサンプルコードを描いてみます。


サンプルを動かすとこんな感じです。

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface OmochiScene : SKScene

@property BOOL contentCreated;

@property (strong, nonatomic) NSMutableArray *omochiAll;

@end

@implementation OmochiScene

– (void)didMoveToView:(SKView *)view

{

    if (!self.contentCreated) {

        [self createSceneContents];

        self.contentCreated = YES;

    }

}

– (void)createSceneContents

{

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

    ground.position = CGPointMake(160, 20);

    [self addChild:ground];

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

    ground.physicsBody.dynamic = NO;

    

    [self createOrange];

}

– (void)createOmochi

{

    NSMutableArray *omochiNodes = [[NSMutableArray alloc] init];

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

        CGPoint o = CGPointMake(160, 360);

        if (i == 0) {

            SKSpriteNode *node = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(16, 16)];

            node.position = CGPointMake(o.x, o.y);

            [self addChild:node];

            node.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:9];

            [omochiNodes addObject:node];

        }

        

        float angle = (2.0 * M_PI / 10.0) * i;

        float x = 30 * cos(angle) + o.x;

        float y = 30 * sin(angle) + o.y;

        SKSpriteNode *node = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(16, 16)];

        node.name = @”omochi”;

        node.position = CGPointMake(x, y);

        [self addChild:node];

        node.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];

        node.physicsBody.restitution = 0.3;

        node.physicsBody.friction = 30;

        [omochiNodes addObject:node];

    }

    

    for (int i=1; i<11; i++) {

        SKPhysicsBody *body0 = [omochiNodes[0] physicsBody];

        SKPhysicsBody *bodyi = [omochiNodes[i] physicsBody];

        SKPhysicsJointSpring *sjoint = [SKPhysicsJointSpring jointWithBodyA:body0 bodyB:bodyi anchorA:body0.node.position anchorB:bodyi.node.position];

        sjoint.frequency = 8.0;

        sjoint.damping = 8.0;

        [self.physicsWorld addJoint:sjoint];

    }

    [self updateOmochiShape:omochiNodes];

    

    if (!self.omochiAll) {

        self.omochiAll = [[NSMutableArray alloc] init];

    }

    [self.omochiAll addObject:omochiNodes];

}

– (void)updateOmochiShape:(NSArray *)omochiNodes

{

    UIBezierPath *path = [UIBezierPath bezierPath];

    for (int i=1; i<11; i++) {

        SKNode *node = omochiNodes[i];

        if (i==1) {

            [path moveToPoint:node.position];

        } else if (i < 10) {

            [path addLineToPoint:node.position];

        } else {

            [path addLineToPoint:node.position];

            [path closePath];

        }

    }

    SKShapeNode *omochiShape = [SKShapeNode node];

    omochiShape.name = @”omochiShape”;

    omochiShape.path = path.CGPath;

    omochiShape.fillColor = [SKColor whiteColor];

    omochiShape.lineWidth = 5;

    omochiShape.glowWidth = 5;

    omochiShape.antialiased = YES;

    [self addChild:omochiShape];

}

– (void)createOrange

{

    SKShapeNode *orange = [SKShapeNode node];

    orange.name = @”orange”;

    orange.fillColor = [SKColor orangeColor];

    orange.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-15, –10, 30, 20)].CGPath;

    orange.position = CGPointMake(160, 400);

    [self addChild:orange];

    

    orange.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:orange.frame.size];

    orange.physicsBody.dynamic = NO;

    orange.physicsBody.restitution = 0;

    orange.physicsBody.linearDamping = 1.0;

}

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

{

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

    

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

    if ([orange containsPoint:p]) {

        orange.physicsBody.dynamic = YES;

    } else {

        [self createOmochi];

    }

}

– (void)didSimulatePhysics

{

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

        [node removeFromParent];

    }];

    

    for (NSArray *omochi in self.omochiAll) {

        [self updateOmochiShape:omochi];

    }

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

}

– (void)viewDidAppear:(BOOL)animated

{

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

    [self.view addSubview:spriteView];

    

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

    [spriteView presentScene:scene];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end