iPhoneハムスターホイール

ハムスターがくるくる回すホイールのiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNView *sceneView;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createWheel];

    [self createCamera];

    [self createHamster];

}

– (void)setupScene {

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

    sv.scene = [SCNScene scene];

    sv.backgroundColor = [self color:3];

    sv.allowsCameraControl = YES;

    [self.view addSubview:sv];

    

    self.sceneView = sv;

}

– (void)createWheel {

    SCNNode *wheel = [SCNNode node];

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

    

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

        SCNTube *tube = [SCNTube tubeWithInnerRadius:9.75 outerRadius:10.25 height:1];

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

        SCNNode *tubeNode = [SCNNode nodeWithGeometry:tube];

        tubeNode.rotation = SCNVector4Make(1, 0, 0, M_PI/2.0);

        tubeNode.position = SCNVector3Make(0, 0, i == 0 ? –4 : 4);

        [wheel addChildNode:tubeNode];

    }

    

    float dw = M_PI / 10.0;

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

        float x = 10.0 * cos(dw * i);

        float y = 10.0 * sin(dw * i);

        SCNCylinder *cylinder = [SCNCylinder cylinderWithRadius:0.2 height:8];

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

        SCNNode *cylinderNode = [SCNNode nodeWithGeometry:cylinder];

        cylinderNode.rotation = SCNVector4Make(1, 0, 0, M_PI/2.0);

        cylinderNode.position = SCNVector3Make(x, y, 0);

        [wheel addChildNode:cylinderNode];

    }

    

    wheel.physicsBody = [SCNPhysicsBody dynamicBody];

    wheel.physicsBody.angularDamping = 0;

    wheel.physicsBody.physicsShape = [SCNPhysicsShape shapeWithNode:wheel options:@{SCNPhysicsShapeTypeKey : SCNPhysicsShapeTypeConcavePolyhedron}];

    SCNPhysicsHingeJoint *joint = [SCNPhysicsHingeJoint jointWithBody:wheel.physicsBody axis:SCNVector3Make(0, 0, 1) anchor:wheel.position];

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

}

– (void)createHamster {

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

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

    SCNNode *boxNode = [SCNNode nodeWithGeometry:box];

    boxNode.name = @”hamster”;

    boxNode.physicsBody = [SCNPhysicsBody dynamicBody];

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

    

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

        SCNSphere *eye = [SCNSphere sphereWithRadius:0.4];

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

        SCNNode *eyeNode = [SCNNode nodeWithGeometry:eye];

        eyeNode.position = SCNVector3Make(2, 0.7, i==0 ? 1 : –1);

        [boxNode addChildNode:eyeNode];

    }

}

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

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

    [ham.physicsBody applyForce:SCNVector3Make(10, 10, 0) atPosition:SCNVector3Make(-1, 0, 0) impulse:YES];

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

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

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

}

#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[] = {0xF6F792, 0x333745, 0x77C4D3, 0xDAEDE2, 0xEA2E49};

    return ColorHex(colorCode[i]);

}

@end