iPhone十角タイマー

十角に数字をふってくるくるまわすタイマーのiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController () <SCNSceneRendererDelegate>

@property (nonatomic, weak) SCNView *sceneView;

@property (nonatomic) BOOL stop;

@property (nonatomic) NSTimeInterval interval;

@property (nonatomic, strong) NSMutableArray *decagons;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor colorWithHue:0.1 saturation:0.4 brightness:0.4 alpha:1];

    self.stop = YES;

    [self setupScene];

    [self createCamera];

    [self createTimer];

    [self createLight];

    [self createButton];

}

– (void)setupScene {

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

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

    sceneView.backgroundColor = [UIColor colorWithHue:0.1 saturation:0.3 brightness:1 alpha:1];

    sceneView.scene = [SCNScene scene];

    [self.view addSubview:sceneView];

    

    self.sceneView = sceneView;

    self.sceneView.delegate = self;

}

– (void)createTimer {

    self.decagons = [NSMutableArray array];

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

        float r = 30;

        float l = r * (cos(2.0 * M_PI/5.0) – cos(3.0 * M_PI/5.0));

        SCNNode *decagon = [self createDecagonAtPoint:SCNVector3Make((i-1) * l, 0, 0)];

        [self.decagons addObject:decagon];

    }

}

– (SCNNode *)createDecagonAtPoint:(SCNVector3)p {

    float r = 30;

    float l = r * (cos(2.0 * M_PI/5.0) – cos(3.0 * M_PI/5.0));

    float l2 = 2.0 * r * cos(M_PI/10.0);

    

    SCNNode *decagon = [SCNNode node];

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

        SCNBox *box = [SCNBox boxWithWidth:l height:l length:l2 chamferRadius:0];

        box.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.9 saturation:0.2 brightness:0.6 alpha:1];

        SCNNode *boxNode = [SCNNode nodeWithGeometry:box];

        

        SCNText *front = [SCNText textWithString:[NSString stringWithFormat:@”%d”, i] extrusionDepth:0.5];

        SCNNode *frontNode = [SCNNode nodeWithGeometry:front];

        frontNode.position = SCNVector3Make(-l/6.0, -l/3.0, l2/2.0);

        [boxNode addChildNode:frontNode];

        

        

        SCNText *back = [SCNText textWithString:[NSString stringWithFormat:@”%d”, i+5] extrusionDepth:0.5];

        SCNNode *backNode = [SCNNode nodeWithGeometry:back];

        backNode.transform = SCNMatrix4Rotate(backNode.transform, M_PI, 0, 1, 0);

        backNode.transform = SCNMatrix4Rotate(backNode.transform, M_PI, 0, 0, 1);

        backNode.position = SCNVector3Make(-l/6.0, l/3.0, -l2/2.0);

        [boxNode addChildNode:backNode];

        

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

            boxNode.transform = SCNMatrix4Rotate(boxNode.transform, M_PI/5.0, 1, 0, 0);

        }

        decagon.position = p;

        [decagon addChildNode:boxNode];

    }

    

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

    

    return decagon;

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

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

    [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, 10, 150);

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

}

– (void)createButton {

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];

    btn.titleLabel.font = [UIFont boldSystemFontOfSize:40];

    [btn setTitle:@”Run” forState:UIControlStateNormal];

    [btn sizeToFit];

    btn.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds)+ 180);

    [self.view addSubview:btn];

    

    [btn addTarget:self action:@selector(tapButton:) forControlEvents:UIControlEventTouchUpInside];

}

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

    if (self.stop)

        return;

    

    if (self.interval == 0) {

        self.interval = time;

        return;

    }

    

    float t = time – self.interval;

    float ten = floor(t / 10.0);

    float one = floor(t – ten * 10.0);

    float first = t – ten * 10.0 – one;

    SCNNode *decagon = self.decagons[2];

    SCNVector3 p = decagon.position;

    decagon.transform = SCNMatrix4MakeRotation(-first*2.0*M_PI, 1, 0, 0);

    decagon.position = p;

    

    if (first >= 0.9) {

        SCNNode *decagon = self.decagons[1];

        SCNVector3 p = decagon.position;

        decagon.transform = SCNMatrix4MakeRotation(-(one*0.1 + (first – 0.9)) * 2.0*M_PI, 1, 0, 0);

        decagon.position = p;

    } else if (first < 0.1) {

        SCNNode *decagon = self.decagons[1];

        SCNVector3 p = decagon.position;

        decagon.transform = SCNMatrix4MakeRotation(-one * 2.0*M_PI/10.0, 1, 0, 0);

        decagon.position = p;

    }

    

    if (one >= 9 && first >= 0.9) {

        SCNNode *decagon = self.decagons[0];

        SCNVector3 p = decagon.position;

        decagon.transform = SCNMatrix4MakeRotation(-(ten*0.1 + (first – 0.9)) * 2.0*M_PI, 1, 0, 0);

        decagon.position = p;

    } else if (one == 0 && first < 0.1) {

        SCNNode *decagon = self.decagons[0];

        SCNVector3 p = decagon.position;

        decagon.transform = SCNMatrix4MakeRotation(-ten*2.0*M_PI/10.0, 1, 0, 0);

        decagon.position = p;

    }

}

– (void)tapButton:(UIButton *)sender {

    self.stop = NO;

    

    [self.sceneView setPlaying:YES];

}

@end