iPhone坂道まる

坂道を丸が転がり続けるiPhoneアプリのサンプルコードを描いてみます。

動かすとこんな感じです

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface SlopeScene : SKScene

@property float currentPosition;

@property int mapCount;

@property (nonatomic, strong) NSDate *lastJump;

@property (nonatomic, weak) SKNode *currentSlope;

@end

@implementation SlopeScene

– (void)didMoveToView:(SKView *)view

{

    [self createSceneContents];

}

– (void)createSceneContents

{

    self.backgroundColor = [SKColor colorWithRed:0.7 green:0.7 blue:1.0 alpha:1.0];

    self.physicsWorld.speed = 0.5;

    [self createSlopeAtPosition:CGPointMake(50, 50)];

    [self createPlayer];

}

– (void)createSlopeAtPosition:(CGPoint)p

{

    // slope

    float w = hypotf(CGRectGetMaxX(self.frame), CGRectGetMaxY(self.frame));

    SKSpriteNode *slope = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(w, 200)];

    slope.name = @”fieldObject”;

    slope.zRotation = –atan2(CGRectGetMaxY(self.frame), CGRectGetMaxX(self.frame));

    

    slope.position = p;

    [self addChild:slope];

    

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

    slope.physicsBody.dynamic = NO;

    

    // obstacle

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

        float hue = (arc4random() % 10) * 0.1;

        float size = arc4random() % 20 + 20;

        SKSpriteNode *obstacle = [SKSpriteNode spriteNodeWithColor:[SKColor colorWithHue:hue saturation:0.8 brightness:0.8 alpha:1.0] size:CGSizeMake(size, size)];

        

        obstacle.name = @”fieldObject”;

        

        float y = arc4random() % 100 + 100;

        obstacle.position = [slope convertPoint:CGPointMake(i * 100, y) toNode:self];

        [self addChild:obstacle];

        

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

        obstacle.physicsBody.dynamic = NO;

    }

    

    self.currentSlope = slope;

}

– (void)createPlayer

{

    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-10, –10, 20, 20)];

    SKShapeNode *player = [SKShapeNode node];

    player.name = @”player”;

    player.path = path.CGPath;

    player.position = CGPointMake(30, 280);

    player.fillColor = [SKColor yellowColor];

    player.strokeColor = [SKColor brownColor];

    [self addChild:player];

    

    player.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];

}

– (void)didSimulatePhysics

{

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

    

    float xMax = 250;

    float yMin = 100;

    

    float x = player.position.x;

    float y = player.position.y;

    float dx = 0;

    float dy = 0;

    

    if (x > xMax) {

        dx = x – xMax;

        x = xMax;

        self.currentPosition += dx;

    }

    if (y < yMin) {

        dy = y – yMin;

        y = yMin;

    }

    

    player.position = CGPointMake(x, y);

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

        if (node.position.x < – 400) {

            [node removeFromParent];

        } else {

            node.position = CGPointMake(node.position.x – dx, node.position.y – dy);

        }

    }];

    

    if (self.currentPosition > 400 * self.mapCount) {

        float sx = self.currentSlope.position.x + self.currentSlope.frame.size.width130;

        float sy = self.currentSlope.position.y330;

        [self createSlopeAtPosition:CGPointMake(sx, sy)];

        self.mapCount++;

    }

}

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

{

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

    

    BOOL ready = self.lastJump ? [self.lastJump timeIntervalSinceNow] < –1.0 : YES;

    if (ready) {

        [player.physicsBody applyImpulse:CGVectorMake(1, 8)];

        self.lastJump = [NSDate new];

    }

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidAppear:(BOOL)animated

{

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

    [self.view addSubview:spriteView];

    

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

    [spriteView presentScene:scene];

}

@end