まゆの形をした玉を坂の上からコロッコロころがしてあそぶiPhoneアプリを描いてみます。
動作イメージ
XcodeからiOS7 iPhone Simulatorで動かすとこんな感じになります。
サンプルコード
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
#define ColorHex(rgbValue) [SKColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
@interface CocoonScene : SKScene
@property BOOL contentCreated;
@end
@implementation CocoonScene
– (void)didMoveToView:(SKView *)view
{
if (!self.contentCreated) {
[self createSceneContents];
self.contentCreated = YES;
}
}
– (void)createSceneContents
{
self.backgroundColor = ColorHex(0x4B5918);
[self createSlopes];
[self createCocoonBall:ColorHex(0xF2F2F2)];
}
– (void)createSlopes
{
SKSpriteNode *slopeA = [SKSpriteNode spriteNodeWithColor:ColorHex(0x262018) size:CGSizeMake(320, 10)];
slopeA.position = CGPointMake(200, 400);
[self addChild:slopeA];
slopeA.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:slopeA.size];
slopeA.physicsBody.dynamic = NO;
slopeA.physicsBody.friction = 5.0;
SKAction *downA = [SKAction rotateByAngle:M_PI/15.0 duration:0];
[slopeA runAction:downA];
SKSpriteNode *slopeB = [SKSpriteNode spriteNodeWithColor:ColorHex(0x262018) size:CGSizeMake(320, 10)];
slopeB.position = CGPointMake(120, 250);
[self addChild:slopeB];
slopeB.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:slopeB.size];
slopeB.physicsBody.dynamic = NO;
slopeB.physicsBody.friction = 5.0;
SKAction *downB = [SKAction rotateByAngle:-M_PI/15.0 duration:0];
[slopeB runAction:downB];
SKSpriteNode *slopeC = [SKSpriteNode spriteNodeWithColor:ColorHex(0x262018) size:CGSizeMake(320, 10)];
slopeC.position = CGPointMake(200, 100);
[self addChild:slopeC];
slopeC.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:slopeC.size];
slopeC.physicsBody.dynamic = NO;
slopeC.physicsBody.friction = 5.0;
SKAction *downC = [SKAction rotateByAngle:M_PI/15.0 duration:0];
[slopeC runAction:downC];
}
– (void)createCocoonBall:(SKColor*)color
{
float r = 20;
UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-r/2.0, -r/2.0, r, r)];
SKShapeNode *circleA = [SKShapeNode node];
circleA.path = circlePath.CGPath;
circleA.position = CGPointMake(250, 470);
circleA.strokeColor = color;
circleA.fillColor = color;
[self addChild:circleA];
circleA.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:r/2.0];
circleA.physicsBody.density = 0.1;
circleA.name = @”cocoonPart”;
SKShapeNode *circleB = [SKShapeNode node];
circleB.path = circlePath.CGPath;
circleB.position = CGPointMake(250, 470 – r);
circleB.strokeColor = color;
circleB.fillColor = color;
[self addChild:circleB];
circleB.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:r/2.0];
circleB.physicsBody.density = 0.1;
circleB.name = @”cocoonPart”;
SKSpriteNode *centerBar = [SKSpriteNode spriteNodeWithColor:color size:CGSizeMake(20, 1.5*r)];
centerBar.position = CGPointMake(250, 470 – r/2.0);
centerBar.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:centerBar.size];
[self addChild:centerBar];
centerBar.name = @”cocoonPart”;
SKPhysicsJointFixed *fixedA = [SKPhysicsJointFixed jointWithBodyA:circleA.physicsBody bodyB:centerBar.physicsBody anchor:circleA.position];
[self.physicsWorld addJoint:fixedA];
SKPhysicsJointFixed *fixedB = [SKPhysicsJointFixed jointWithBodyA:circleB.physicsBody bodyB:centerBar.physicsBody anchor:circleB.position];
[self.physicsWorld addJoint:fixedB];
SKShapeNode *weight = [SKShapeNode node];
weight.name = @”cocoonPart”;
weight.path = circlePath.CGPath;
weight.fillColor = [SKColor clearColor];
weight.strokeColor = [SKColor clearColor];
weight.position = centerBar.position;
[self addChild:weight];
weight.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:r/2.0];
weight.physicsBody.categoryBitMask = 0x00000000;
weight.physicsBody.collisionBitMask = 0x00000000;
weight.physicsBody.contactTestBitMask = 0xFFFFFFFF;
weight.physicsBody.linearDamping = 0;
weight.physicsBody.density = 50.0;
SKPhysicsJointSliding *sl = [SKPhysicsJointSliding jointWithBodyA:centerBar.physicsBody bodyB:weight.physicsBody anchor:weight.position axis:CGVectorMake(0, 1)];
sl.shouldEnableLimits = YES;
sl.lowerDistanceLimit = -r/2.0;
sl.upperDistanceLimit = r/2.0;
[self.physicsWorld addJoint:sl];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
int rand = arc4random() % 3;
switch (rand) {
case 0:
[self createCocoonBall:ColorHex(0xF2F2F2)];
break;
case 1:
[self createCocoonBall:ColorHex(0xBFAC88)];
break;
case 2:
[self createCocoonBall:ColorHex(0x732D14)];
break;
}
}
– (void)didSimulatePhysics
{
[self enumerateChildNodesWithName:@”cocoonPart” usingBlock:^(SKNode *node, BOOL *stop) {
if (node.position.y < 0) {
[node removeFromParent];
}
}];
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[CocoonScene alloc] initWithSize:spriteView.bounds.size];
[spriteView presentScene:scene];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end