iPhone ひこうきゴーランド

飛行機がくるくるまわるメリーゴーランドなiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController () <SCNSceneRendererDelegate>

@property (nonatomic, weak) SCNScene *scene;

@property (nonatomic) NSTimeInterval last;

@property (nonatomic) float phi;

@property (nonatomic, strong) NSMutableArray *planesSlider;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor lightGrayColor];

    [self setupScene];

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

        [self createPlane:[UIColor colorWithHue:0.3 * i saturation:0.5 brightness:1 alpha:1] name:[NSString stringWithFormat:@”plane%d”, i]];

    }

    [self createCamera];

    [self createLight];

    [self createController];

}

– (void)setupScene {

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

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

    sv.backgroundColor = [UIColor colorWithHue:0.45 saturation:0.3 brightness:1 alpha:1];

    sv.scene = [SCNScene scene];

    sv.delegate = self;

    [self.view addSubview:sv];

    

    self.scene = sv.scene;

}

– (void)createPlane:(UIColor*)color name:(NSString*)name{

    SCNNode *plane = [SCNNode node];

    plane.name = name;

    [self.scene.rootNode addChildNode:plane];

    

    [plane runAction:[SCNAction rotateByAngle:-M_PI/2.0 aroundAxis:SCNVector3Make(1, 0, 0) duration:2.0]];

    

    SCNCylinder *body = [SCNCylinder cylinderWithRadius:0.5 height:3];

    body.firstMaterial.diffuse.contents = color;

    SCNNode *bodyNode = [SCNNode nodeWithGeometry:body];

    [plane addChildNode:bodyNode];

    

    SCNBox *wing = [SCNBox boxWithWidth:3 height:1 length:0.3 chamferRadius:1];

    wing.firstMaterial.diffuse.contents = color;

    SCNNode *wingNode = [SCNNode nodeWithGeometry:wing];

    wingNode.position = SCNVector3Make(0, 0.4, 0.2);

    [plane addChildNode:wingNode];

    

    SCNBox *tail = [SCNBox boxWithWidth:0.3 height:1 length:1 chamferRadius:1];

    tail.firstMaterial.diffuse.contents = color;

    SCNNode *tailNode = [SCNNode nodeWithGeometry:tail];

    tailNode.position = SCNVector3Make(0, –1.5, 0.5);

    [plane addChildNode:tailNode];

    

    SCNBox *propeller = [SCNBox boxWithWidth:2 height:0.2 length:0.4 chamferRadius:1];

    propeller.firstMaterial.diffuse.contents = color;

    SCNNode *propellerNode = [SCNNode nodeWithGeometry:propeller];

    propellerNode.position = SCNVector3Make(0, 2, 0);

    [plane addChildNode:propellerNode];

    [propellerNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByAngle:0.2 aroundAxis:SCNVector3Make(0, 1, 0) duration:0.1]]];

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

    camera.position = SCNVector3Make(0, –2, 30);

    [self.scene.rootNode addChildNode:camera];

}

– (void)createLight {

    SCNLight *light = [SCNLight light];

    light.type = SCNLightTypeOmni;

    SCNNode *lightNode = [SCNNode node];

    lightNode.light = light;

    lightNode.position = SCNVector3Make(0, 5, 60);

    [self.scene.rootNode addChildNode:lightNode];

}

– (void)createController {

    

    self.planesSlider = [NSMutableArray array];

    

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

        UISlider *slider = [[UISlider alloc] init];

        slider.minimumValue = 0;

        slider.maximumValue = M_PI/2.0;

        [slider sizeToFit];

        slider.center = CGPointMake((i+1) * CGRectGetMaxX(self.view.bounds) / 5.0, CGRectGetMidY(self.view.bounds) + 100);

        slider.transform = CGAffineTransformMakeRotation(-M_PI/2.0);

        [self.view addSubview:slider];

        

        UIImage *img = [self imageWithColor:[UIColor colorWithHue:i * 0.3 saturation:0.6 brightness:1 alpha:1]];

        [slider setThumbImage:img forState:UIControlStateNormal];

        

        [self.planesSlider addObject:slider];

    }

}

– (UIImage *)imageWithColor:(UIColor *)color

{

    CGRect rect = CGRectMake(0, 0, 40, 40);

    UIGraphicsBeginImageContext(rect.size);

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(ctx, color.CGColor);

    CGContextFillRect(ctx, rect);

    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return img;

}

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

{

    float r = 15;

    float dAnble = M_PI / 10.0;

    self.phi = (time – self.last) * dAnble;

    

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

        float phi = self.phi + i * M_PI/2.0;

        SCNNode *plane = [self.scene.rootNode childNodeWithName:[NSString stringWithFormat:@”plane%d”, i] recursively:NO];

        plane.transform = SCNMatrix4MakeRotation(-M_PI/2.0, 1, 0, 0);

        plane.transform = SCNMatrix4Rotate(plane.transform, M_PI – phi, 0, 1, 0);

        

        

        float theta = M_PI * 0.7 – ((UISlider*)self.planesSlider[i]).value;

        plane.position = [self sphericalCoordinateTheta:theta phi:phi r:r];

    }

}

– (SCNVector3)sphericalCoordinateTheta:(float)theta phi:(float)phi r:(float)r {

    float x = r * sin(theta) * cos(phi);

    float z = r * sin(theta) * sin(phi);

    float y = r * cos(theta);

    return SCNVector3Make(x, y, z);

}

@end