iPhoneカード選び

手前に向かってくるカードをどんどん選んでいくiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController () <SCNSceneRendererDelegate>

@property (nonatomic, weak) SCNView *sceneView;

@property (nonatomic) NSTimeInterval t;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createCamera];

    [self createLight];

}

– (void)setupScene {

    SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];

    sv.backgroundColor = [self color:0];

    sv.delegate = self;

    sv.scene = [SCNScene scene];

    sv.scene.physicsWorld.gravity = SCNVector3Zero;

    [self.view addSubview:sv];

    self.sceneView = sv;

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

    camera.camera.zFar = 200;

    camera.position = SCNVector3Make(0, 30, 80);

    camera.rotation = SCNVector4Make(1, 0, 0, –0.2);

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

}

– (void)createLight {

    SCNLight *light = [SCNLight light];

    light.type = SCNLightTypeOmni;

    SCNNode *lightNode = [SCNNode node];

    lightNode.light = light;

    lightNode.position = SCNVector3Make(0, 30, 80);

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

}

– (void)createCard {

    SCNBox *card = [SCNBox boxWithWidth:10 height:16 length:2.0 chamferRadius:1];

    int color = arc4random_uniform(4) + 1;

    card.firstMaterial.diffuse.contents = [self color:color];

    SCNNode *cardNode = [SCNNode nodeWithGeometry:card];

    cardNode.name = @”card”;

    int x = arc4random_uniform(3) * 11.011.0;

    cardNode.position = SCNVector3Make(x, 0, –80);

    cardNode.physicsBody = [SCNPhysicsBody dynamicBody];

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

}

– (void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time

{

    if (time – self.t > 0.8) {

        [self createCard];

        self.t = time;

    }

    

    [self.sceneView.scene.rootNode enumerateChildNodesUsingBlock:^(SCNNode *child, BOOL *stop) {

        if ([child.name isEqual:@”card”]) {

            child.physicsBody.velocity = SCNVector3Make(0, 0, 30);

            if (child.presentationNode.position.z > 90) {

                [child removeFromParentNode];

            }

        }

    }];

}

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

{

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

    SCNNode *hit = [[self.sceneView hitTest:p options:@{SCNHitTestSortResultsKey:@YES}].firstObject node];

    

    if ([hit.name isEqual:@”card”]) {

        // move other

        [self.sceneView.scene.rootNode enumerateChildNodesUsingBlock:^(SCNNode *child, BOOL *stop) {

            if ([child.name isEqual:@”selected card”]) {

                [child runAction:[SCNAction moveTo:SCNVector3Make(child.position.x + 5, child.position.y + 1, child.position.z2) duration:0.2]];

            }

        }];

        

        hit.name = @”selected card”;

        hit.physicsBody = nil;

        [hit runAction:[SCNAction moveTo:SCNVector3Make(-20, 40, –20) duration:0.5]];

    }

}

#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(0xF2DFBB);

        case 1: return ColorHex(0x3D4772);

        case 2: return ColorHex(0x686D8C);

        case 3: return ColorHex(0xA68965);

        case 4: return ColorHex(0x594834);

    }

    return nil;

}

@end