iPhone らせん階段

らせん階段をくるくると作っていくiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNView *sceneView;

@property (nonatomic) int state;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createPole];

    [self createCamera];

}

– (void)setupScene {

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

    sv.backgroundColor = [self color:0];

    sv.scene = [SCNScene scene];

    sv.autoenablesDefaultLighting = YES;

    [self.view addSubview:sv];

    

    self.sceneView = sv;

}

– (void)createPole {

    SCNCylinder *cylinder = [SCNCylinder cylinderWithRadius:2 height:50];

    cylinder.firstMaterial.diffuse.contents = [self color:4];

    SCNNode *poleNode = [SCNNode nodeWithGeometry:cylinder];

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

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.name = @”camera”;

    camera.camera = [SCNCamera camera];

    camera.camera.zFar = 200;

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

    camera.rotation = SCNVector4Make(1, 0, 0, –M_PI * 0.5);

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

}

– (void)createStaircase {

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

        SCNBox *box = [SCNBox boxWithWidth:20 height:1.2 length:4 chamferRadius:0];

        box.firstMaterial.diffuse.contents = [self color:1];

        SCNNode *boxNode = [SCNNode nodeWithGeometry:box];

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

        boxNode.pivot = SCNMatrix4MakeTranslation(-12, 0, 0);

        boxNode.position = SCNVector3Make(0, –23, 0);

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

    }

}

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

{

    if (self.state == 0) {

        self.state++;

        SCNNode *camera = [self.sceneView.scene.rootNode childNodeWithName:@”camera” recursively:NO];

        [camera runAction:[SCNAction group:@[

                                             [SCNAction rotateToX:0 y:0 z:0 duration:0.5],

                                             [SCNAction moveTo:SCNVector3Make(0, 0, 100) duration:0.5]

                                             ]] completionHandler:^{

            [self createStaircase];

        }];

    } else {

        [self upstairs:0];

    }

}

– (void)upstairs:(int)count {

    

    NSPredicate *pred = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {

        NSString *name = [evaluatedObject name];

        if ([name hasPrefix:@”box”]) {

            int num = [[name substringFromIndex:@”box”.length] intValue];

            if (num >= count) return YES;

        }

        return NO;

    }];

    [[self.sceneView.scene.rootNode.childNodes filteredArrayUsingPredicate:pred] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        [obj runAction:[SCNAction sequence:@[

                                             [SCNAction moveBy:SCNVector3Make(0, 2.2, 0) duration:0.4],

                                             [SCNAction rotateByX:0 y:0.3 z:0 duration:0.4]

                                             ]]];

        

        if (idx == 0) {

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                [self upstairs:count + 1];

            });

        }

    }];

}

#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 {

    if (i > 4) return nil;

    int colorCode[] = {0x7D2A35, 0xCC9258, 0x917A56, 0xB4BA6C, 0xFEFFC2};

    return ColorHex(colorCode[i]);

}

@end