iPhone箱つぶし

上下から棒ではさんで箱をつぶして遊ぶ。といったiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SpriteKit;

@interface CompressScene : SKScene

@property (nonatomic) int8_t press;

@property (nonatomic, weak) NSTimer *timer;

@end

@implementation CompressScene

– (void)didMoveToView:(SKView *)view

{

    [self createPressBar];

    [self createLine];

    [self startBox];

}

– (void)createPressBar

{

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

        SKSpriteNode *bar = [SKSpriteNode spriteNodeWithColor:[SKColor orangeColor] size:CGSizeMake(30, 155)];

        bar.name = [NSString stringWithFormat:@”bar%d”, i];

        float y = (i == 0) ? 270 : 50;

        bar.position = CGPointMake(CGRectGetMidX(self.frame), y);

        [self addChild:bar];

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

        bar.physicsBody.allowsRotation = NO;

        bar.physicsBody.affectedByGravity = NO;

        

        SKSpriteNode *mark = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(8, 8)];

        [bar addChild:mark];

    }

}

– (void)createLine

{

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

        SKSpriteNode *line = [SKSpriteNode spriteNodeWithColor:[[SKColor whiteColor] colorWithAlphaComponent:0.5] size:CGSizeMake(CGRectGetMaxX(self.frame), 2)];

        line.position = CGPointMake(CGRectGetMidX(self.frame), i ? 270 : 240);

        [self addChild:line];

    }

}

– (void)startBox

{

    self.timer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(createBox) userInfo:nil repeats:YES];

}

– (void)createBox

{

    SKShapeNode *box = [SKShapeNode node];

    box.name = @”box”;

    box.fillColor = [SKColor clearColor];

    box.strokeColor = [SKColor brownColor];

    box.lineWidth = 7;

    box.path = [UIBezierPath bezierPathWithRect:CGRectMake(-20, –15, 40, 30)].CGPath;

    box.position = CGPointMake(-20, CGRectGetMidY(self.frame));

    [self addChild:box];

    

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

        SKSpriteNode *content = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(2, 2)];

        content.name = @”content”;

        float x = 20 – (i / 2) * 8;

        float y = 15 – (i % 2) * 30;

        content.position = CGPointMake(x, y);

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

        content.physicsBody.affectedByGravity = NO;

        [box addChild:content];

    }

}

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

{

    self.press = 1;

}

– (void)update:(NSTimeInterval)currentTime

{

    SKNode *barA = [self childNodeWithName:@”bar0″];

    SKNode *barB = [self childNodeWithName:@”bar1″];

    

    CGVector boxV = CGVectorMake(0, 0);

    if (self.press == 1) {

        [self.timer invalidate];

        barA.physicsBody.velocity = CGVectorMake(0, –20);

        barB.physicsBody.velocity = CGVectorMake(0, 20);

        if (barA.position.y < 240) {

            self.press = 2;

        }

        

    } else if (self.press == 2) {

        if (barA.position.y > 270) {

            [self startBox];

            self.press = 0;

            barA.physicsBody.velocity = CGVectorMake(0, 0);

            barB.physicsBody.velocity = CGVectorMake(0, 0);

        } else {

            barA.physicsBody.velocity = CGVectorMake(0, 20);

            barB.physicsBody.velocity = CGVectorMake(0, –20);

        }

    } else {

        boxV = CGVectorMake(30, 0);

    }

    

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

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

            node.physicsBody.velocity = boxV;

        }];

    }];

}

– (void)didSimulatePhysics

{

    // update box shape

    

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

        UIBezierPath *path = [UIBezierPath bezierPath];

        for (int i=0; i<box.children.count; i+=2) {

            SKNode *na = box.children[i];

            SKNode *nb = box.children[i + 1];

            [path moveToPoint:na.position];

            [path addLineToPoint:nb.position];

        }

        ((SKShapeNode *)box).path = path.CGPath;

    }];

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidAppear:(BOOL)animated

{

    [super viewDidAppear:animated];

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

    [self.view addSubview:spriteView];

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

    [spriteView presentScene:scene];

}

@end