iPhone コインまわる

まわっているコインをタッチして集めるiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@import SpriteKit;

@interface ViewController ()

@property (nonatomic, weak) SCNView *sceneView;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor grayColor];

    

    [self setupScene];

    [self createGround];

    [self createCamera];

    [self createCounter];

    [self startTimer];

}

– (void)setupScene {

    float w = CGRectGetMaxX(self.view.bounds);

    SCNView *sv = [[SCNView alloc] initWithFrame:CGRectMake(0, 0, w, w)];

    sv.backgroundColor = [self color:4];

    sv.scene = [SCNScene scene];

    sv.overlaySKScene = [SKScene sceneWithSize:sv.frame.size];

    [self.view addSubview:sv];

    

    self.sceneView = sv;

}

– (void)createGround {

    SCNBox *ground = [SCNBox boxWithWidth:40 height:1 length:40 chamferRadius:0];

    ground.firstMaterial.diffuse.contents = [UIColor lightGrayColor];

    SCNNode *groundNode = [SCNNode nodeWithGeometry:ground];

    groundNode.name = @”ground”;

    [self.sceneView.scene.rootNode addChildNode:groundNode];

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

    camera.position = SCNVector3Make(0, 20, 50);

    camera.constraints = @[[SCNLookAtConstraint lookAtConstraintWithTarget:[self.sceneView.scene.rootNode childNodeWithName:@”ground” recursively:NO]]];

    [self.sceneView.scene.rootNode addChildNode:camera];

}

– (void)createCounter {

    float w = CGRectGetMaxX(self.view.bounds) / 4.0;

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

        SKSpriteNode *box = [SKSpriteNode spriteNodeWithColor:[self color:i] size:CGSizeMake(w, w)];

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

        box.position = CGPointMake(i * w + w/2.0, w/2.0);

        [self.sceneView.overlaySKScene addChild:box];

        

        SKLabelNode *l = [SKLabelNode labelNodeWithText:[NSString stringWithFormat:@”%d”, 0]];

        l.name = @”numberLabel”;

        l.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;

        l.fontSize = 50;

        [box addChild:l];

    }

}

– (void)startTimer {

    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(tick) userInfo:nil repeats:YES];

}

– (void)tick {

    float x = arc4random() % 4020.0;

    float z = arc4random() % 4020.0;

    

    SCNCylinder *coin = [SCNCylinder cylinderWithRadius:2 height:0.5];

    

    int colorIdx = arc4random() % 4;

    coin.firstMaterial.diffuse.contents = [self color:colorIdx];

    SCNNode *coinNode = [SCNNode nodeWithGeometry:coin];

    coinNode.name = [NSString stringWithFormat:@”coin%d”, colorIdx];

    coinNode.position = SCNVector3Make(x, 5, z);

    coinNode.rotation = SCNVector4Make(1, 0, 0, M_PI/2.0);

    coinNode.transform = SCNMatrix4Scale(coinNode.transform, 1, 1, 1.4);

    [self.sceneView.scene.rootNode addChildNode:coinNode];

    

    [coinNode runAction:[SCNAction rotateByAngle:M_PI aroundAxis:SCNVector3Make(0, 1, 0) duration:1.0]];

}

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

{

    CGPoint p = [[touches anyObject] locationInView:self.sceneView];

    NSArray *hits = [self.sceneView hitTest:p options:@{SCNHitTestSortResultsKey : @YES}];

    if (hits.count > 0) {

        SCNNode *hit = [hits.firstObject node];

        if ([hit.name hasPrefix:@”coin”]) {

            SKNode *counterBox = [self.sceneView.overlaySKScene childNodeWithName:[NSString stringWithFormat:@”box%@”, [hit.name substringFromIndex:4]]];

            SKLabelNode *l = (SKLabelNode *)[counterBox childNodeWithName:@”numberLabel”];

            l.text = [NSString stringWithFormat:@”%d”, [l.text intValue] + 1];

            

            [hit removeAllActions];

            [hit runAction:[SCNAction moveByX:0 y:5 z:0 duration:0.2] completionHandler:^{

                [hit removeFromParentNode];

            }];

        }

    }

}

#define ColorHex(rgb) [UIColor colorWithRed:((rgb & 0xFF0000) >> 16) / 255.0 green:((rgb & 0xFF00) >> 8) / 255.0 blue:(rgb & 0xFF) / 255.0 alpha:1.0]

– (UIColor *)color:(int)i {

    switch (i) {

        case 0 : return ColorHex(0xC8385A);

        case 1 : return ColorHex(0xFFCF48);

        case 2 : return ColorHex(0x1FCECB);

        case 3 : return ColorHex(0x1CA9C9);

        case 4 : return ColorHex(0xECEABE);

        default:

            break;

    }

    return nil;

}

@end