iPhone3段タイマー

円盤の3段重ねなタイマーを動かすiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNView *sceneView;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createDisk];

    [self createCamera];

}

– (void)setupScene {

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

    sv.backgroundColor = [self color:0];

    sv.scene = [SCNScene scene];

    sv.autoenablesDefaultLighting = YES;

    sv.allowsCameraControl = YES;

    [self.view addSubview:sv];

    

    self.sceneView = sv;

}

– (void)createDisk {

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

        SCNCylinder *c = [SCNCylinder cylinderWithRadius:10 height:3];

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

        SCNNode *cn = [SCNNode nodeWithGeometry:c];

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

        cn.position = SCNVector3Make(0, 3.1 * i, 0);

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

        

        

        SCNBox *redLine = [SCNBox boxWithWidth:0.2 height:2 length:0.1 chamferRadius:0.4];

        redLine.firstMaterial.diffuse.contents = [self color:2];

        SCNNode *redLineNode = [SCNNode nodeWithGeometry:redLine];

        redLineNode.position = SCNVector3Make(0, –0.6, 10.1);

        [cn addChildNode:redLineNode];

        

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

            float x = 10.05 * cos(i * M_PI / 30.0);

            float z = 10.05 * sin(i * M_PI / 30.0);

            SCNBox *dot = [SCNBox boxWithWidth:0.1 height:0.3 length:0.1 chamferRadius:0];

            dot.firstMaterial.diffuse.contents = [self color:3];

            SCNNode *dotNode = [SCNNode nodeWithGeometry:dot];

            dotNode.position = SCNVector3Make(x, 1.2, z);

            [cn addChildNode:dotNode];

        }

        

        [cn runAction:[SCNAction rotateByAngle:i * M_PI / 5.0 aroundAxis:SCNVector3Make(0, 1, 0) duration:0.4]];

    }

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

    camera.position = SCNVector3Make(0, 15, 60);

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

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

}

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

{

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

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

    

    [top runAction:[SCNAction rotateToX:0 y:0 z:0 duration:60.0 * top.rotation.w / (2.0 * M_PI)] completionHandler:^{

        SCNSphere *s = [SCNSphere sphereWithRadius:5];

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

        SCNNode *sn = [SCNNode nodeWithGeometry:s];

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

        sn.physicsBody = [SCNPhysicsBody dynamicBody];

        [sn.physicsBody applyForce:SCNVector3Make(0, 20, 0) impulse:YES];

    }];

    [mid runAction:[SCNAction rotateToX:0 y:0 z:0 duration:60.0 * mid.rotation.w / (2.0 * M_PI)] completionHandler:^{

        SCNSphere *s = [SCNSphere sphereWithRadius:3];

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

        SCNNode *sn = [SCNNode nodeWithGeometry:s];

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

        sn.physicsBody = [SCNPhysicsBody dynamicBody];

        [sn.physicsBody applyForce:SCNVector3Make(0, 20, 0) impulse:YES];

    }];

}

#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[] = {0x2F343B, 0x7E827A, 0x703030, 0xE3CDA4, 0xC77966};

    return ColorHex(colorCode[i]);

}

@end