iPhoneコマ

コマを回すiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNView *sceneView;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

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

    

    [self setupScene];

    [self createPlate];

    [self createCamera];

    [self createSpinningTop];

}

– (void)setupScene {

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

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

    sceneView.scene = [SCNScene scene];

    sceneView.backgroundColor = [UIColor colorWithHue:0.5 saturation:0.2 brightness:0.8 alpha:1];

    sceneView.center = CGPointMake(w/2.0, CGRectGetMidY(self.view.bounds));

    [self.view addSubview:sceneView];

    

    self.sceneView = sceneView;

}

– (void)createPlate

{

    SCNBox *box = [SCNBox boxWithWidth:20 height:2 length:20 chamferRadius:5];

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

    SCNNode *desk = [SCNNode nodeWithGeometry:box];

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

    

    desk.physicsBody = [SCNPhysicsBody staticBody];

}

– (void)createCamera

{

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

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

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

}

– (void)createSpinningTop

{

    SCNNode *top = [SCNNode node];

    top.name = @”top”;

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

    

    SCNNode *tmpNode;

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

        float r = i + 0.1;

        SCNCylinder *disk = [SCNCylinder cylinderWithRadius:r height:1];

        disk.firstMaterial.diffuse.contents = i == 4 ? [self createMark] : [UIColor colorWithHue:0.1 + 0.2 * i saturation:0.4 brightness:0.8 alpha:1];

        SCNNode *n = [SCNNode nodeWithGeometry:disk];

        n.position = SCNVector3Make(0, i + 10, 0);

        [top addChildNode:n];

        

        n.physicsBody = [SCNPhysicsBody dynamicBody];

        if (tmpNode) {

            SCNPhysicsSliderJoint *behavior = [SCNPhysicsSliderJoint jointWithBodyA:n.physicsBody axisA:SCNVector3Make(0, 1, 0) anchorA:n.position bodyB:tmpNode.physicsBody axisB:SCNVector3Make(0, 1, 0) anchorB:tmpNode.position];

            

            if (i == 4) {

                behavior.motorTargetAngularVelocity = 80;

            }

            

            behavior.minimumLinearLimit = –2;

            [self.sceneView.scene.physicsWorld addBehavior:behavior];

        }

        tmpNode = n;

    }

}

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

{

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

        if ([child.name isEqual:@”top”] && [child.childNodes[0] presentationNode].position.y < –1) {

            [child removeFromParentNode];

        }

    }];

    

    [self createSpinningTop];

}

– (CALayer *)createMark

{

    CATextLayer *l = [CATextLayer layer];

    l.frame = CGRectMake(0, 0, 40, 50);

    l.backgroundColor = [UIColor colorWithHue:0.8 saturation:0.4 brightness:0.8 alpha:1].CGColor;

    l.string = @”++”;

    l.foregroundColor = [UIColor yellowColor].CGColor;

    return l;

}

– (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

}

@end