お餅を積み上げて、鏡餅!という感じで、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