iPhone吊り橋

今日のサンプルは、吊り橋をつっついて、ボールを飛ばすシンプルなiPhoneゲームにしてみます。


動かすとこんな感じです

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

typedef enum : int8_t

{

    ColliderTypeOther = 0x1 << 1,

    ColliderTypeLog = 0x1 << 2,

    ColliderTypeBall = 0x1 << 3,

} ColliderType;

@interface BridgeScene : SKScene

@property BOOL contentCreated;

@end

@implementation BridgeScene

– (void)didMoveToView:(SKView *)view

{

    if (!self.contentCreated) {

        [self createSceneContents];

        self.contentCreated = YES;

    }

}

– (void)createSceneContents

{

    self.physicsWorld.gravity = CGVectorMake(0, –5);

    self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(1, 1)];

    self.physicsBody.dynamic = NO;

    self.physicsBody.categoryBitMask = ColliderTypeOther;

    self.physicsBody.collisionBitMask = ColliderTypeOther;

    

    [self createSuspensionBridge];

    

    [self createBall];

}

– (void)createSuspensionBridge

{

    int number = 15;

    float size = CGRectGetMaxX(self.frame) / number;

    

    SKNode *previousNode;

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

        SKShapeNode *log = [SKShapeNode node];

        log.name = @”log”;

        log.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-size/2.0, -size/2.0, size, size)].CGPath;

        log.position = CGPointMake(i * size, 200);

        log.lineWidth = 0;

        log.fillColor = [SKColor brownColor];

        [self addChild:log];

        

        log.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:size/2.0];

        log.physicsBody.categoryBitMask = ColliderTypeLog;

        log.physicsBody.collisionBitMask = ColliderTypeBall;

        if (i==0 || i == number – 1) {

            SKPhysicsJointFixed *joint = [SKPhysicsJointFixed jointWithBodyA:self.physicsBody bodyB:log.physicsBody anchor:log.position];

            [self.physicsWorld addJoint:joint];

        }

        

        if (previousNode && i < number) {

            SKPhysicsJointLimit *joint = [SKPhysicsJointLimit jointWithBodyA:previousNode.physicsBody bodyB:log.physicsBody anchorA:previousNode.position anchorB:log.position];

            joint.maxLength = size * 1.05;

            [self.physicsWorld addJoint:joint];

        }

        previousNode = log;

    }

}

– (void)createBall

{

    SKShapeNode *ball = [SKShapeNode node];

    ball.name = @”ball”;

    ball.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-50, –50, 100, 100)].CGPath;

    ball.fillColor = [UIColor yellowColor];

    ball.lineWidth = 10;

    int x = (arc4random() % 200) + 60;

    ball.position = CGPointMake(x , CGRectGetMaxY(self.frame));

    [self addChild:ball];

    ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:50];

    ball.physicsBody.categoryBitMask = ColliderTypeLog;

}

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

{

    CGPoint p = [[touches anyObject] locationInNode:self];

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

        if ([node containsPoint:p]) {

            [node.physicsBody applyImpulse:CGVectorMake(0, 20)];

            SKAction *fade = [SKAction fadeAlphaTo:0.5 duration:0.1];

            SKAction *original = [SKAction fadeAlphaTo:1.0 duration:0.5];

            [node runAction:[SKAction sequence:@[fade, original]]];

            

            *stop = YES;

        }

    }];

}

– (void)didSimulatePhysics

{

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

    if (ball.position.x < –50 || ball.position.x > CGRectGetMaxX(self.frame) + 50) {

        [ball removeFromParent];

        [self createBall];

    }

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

}

– (void)viewDidAppear:(BOOL)animated

{

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

    [self.view addSubview:spriteView];

    

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

    [spriteView presentScene:scene];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end