
「だんでらいおん」たちを、そよ風にのせて飛ばすiPhoneアプリを描いてみます。
— movie —
— sample code —
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
@interface DandelionScene : SKScene
@end
@implementation DandelionScene
– (void)didMoveToView:(SKView *)view
{
self.backgroundColor = [SKColor greenColor];
self.physicsWorld.gravity = CGVectorMake(0, –0.01);
[self createDandelion];
[self createStem];
[self createButton];
}
#define LionCenter CGPointMake(CGRectGetMidX(self.frame)/2.0, CGRectGetMidY(self.frame))
– (void)createDandelion
{
CGPoint o = LionCenter;
float r = 50;
float dAngle = M_PI / 5.0;
for (int i=0; i<10; i++) {
float x = r * cos(i * dAngle) + o.x;
float y = r * sin(i * dAngle) + o.y;
SKNode *lion = [self createLionSeed];
lion.position = CGPointMake(x, y);
[self addChild:lion];
}
dAngle = M_PI / 3.0;
r = 25;
for (int i=0; i<6; i++) {
float x = r * cos(i * dAngle) + o.x;
float y = r * sin(i * dAngle) + o.y;
SKNode *lion = [self createLionSeed];
lion.position = CGPointMake(x, y);
[self addChild:lion];
}
SKNode *lion = [self createLionSeed];
lion.position = o;
[self addChild:lion];
}
– (SKNode *)createLionSeed
{
SKNode *lion = [SKNode node];
lion.name = @”lion”;
float r = 12;
float dAngle = M_PI / 4.0;
float s = 10;
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-s/2.0, -s/2.0, s, s)];
for (int i=0; i<8; i++) {
float x = r * cos(dAngle * i);
float y = r * sin(dAngle * i);
SKShapeNode *bit = [SKShapeNode node];
bit.fillColor = [SKColor yellowColor];
bit.path = path.CGPath;
bit.position = CGPointMake(x, y);
[lion addChild:bit];
}
s = 22;
UIBezierPath *facePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-s/2.0, -s/2.0, s, s)];
SKShapeNode *face = [SKShapeNode node];
face.path = facePath.CGPath;
face.position = CGPointZero;
face.fillColor = [SKColor yellowColor];
face.lineWidth = 0;
[lion addChild:face];
CGPoint p[] = {CGPointMake(-6, 2), CGPointMake(6, 2), CGPointMake(0, –3)};
for (int i=0; i<3; i++) {
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-1.5, –1.5, 3, 3)];
SKShapeNode *dot = [SKShapeNode node];
dot.path = path.CGPath;
dot.fillColor = [SKColor blackColor];
dot.lineWidth = 0;
dot.position = p[i];
[lion addChild:dot];
}
for (int i=0; i<2; i++) {
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-4, –3, 8, 6)];
SKShapeNode *white = [SKShapeNode node];
white.path = path.CGPath;
white.fillColor = [SKColor whiteColor];
white.strokeColor = [SKColor darkGrayColor];
white.lineWidth = 0.5;
white.position = CGPointMake(i * 8 – 4, –5);
[lion addChild:white];
}
return lion;
}
– (void)createStem
{
CGPoint start = LionCenter;
CGPoint end = CGPointMake(LionCenter.x, LionCenter.y – 200);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:start];
[path addCurveToPoint:end controlPoint1:CGPointMake(start.x – 50, start.y) controlPoint2:CGPointMake(end.x – 50, end.y)];
SKShapeNode *stem = [SKShapeNode node];
stem.path = path.CGPath;
stem.lineWidth = 3;
stem.zPosition = –1;
stem.strokeColor = [SKColor darkGrayColor];
[self addChild:stem];
}
– (void)createButton
{
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:120 startAngle:0.1 endAngle:M_PI/2.0 clockwise:NO];
SKShapeNode *button = [SKShapeNode node];
button.name = @”button”;
button.fillColor = [[SKColor yellowColor] colorWithAlphaComponent:0.6];
button.path = path.CGPath;
button.position = CGPointMake(CGRectGetMaxX(self.frame), 0);
[self addChild:button];
SKLabelNode *label = [SKLabelNode node];
label.text = @”breeze”;
label.zRotation = M_PI_4;
label.position = CGPointMake(-40, 40);
[button addChild:label];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
SKNode *button = [self childNodeWithName:@”button”];
if ([button containsPoint:p]) {
SKAction *action = [SKAction sequence:@[[SKAction scaleTo:0.8 duration:0.1], [SKAction scaleTo:1.0 duration:0.2]]];
[button runAction:action];
[self breeze];
}
}
– (void)breeze
{
[self enumerateChildNodesWithName:@”lion” usingBlock:^(SKNode *node, BOOL *stop) {
int duration = arc4random() % 15;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
node.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:20];
node.physicsBody.categoryBitMask = 0x1;
node.physicsBody.collisionBitMask = 0x2;
float x = (arc4random() % 3);
float y = (arc4random() % 3);
float vy = (arc4random() % 10);
[node.physicsBody applyForce:CGVectorMake(15, vy) atPoint:CGPointMake(x, y)];
});
}];
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidAppear:(BOOL)animated
{
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[DandelionScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
@end