
チューブの中を落ちていくような感じでiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@interface ViewController () <SCNSceneRendererDelegate>
@property (nonatomic, weak) SCNScene *scene;
@property (nonatomic, weak) SCNView *sceneView;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [self color:2];
[self setupScene];
[self createTube];
[self createCamera];
[self createLight];
[self createBlock];
[self createPlayer];
}
– (void)setupScene {
float w = CGRectGetMaxX(self.view.bounds);
SCNView *sv = [[SCNView alloc] initWithFrame:CGRectMake(0, 0, w, w)];
SCNScene *scene = [SCNScene scene];
sv.backgroundColor = [self color:0];
sv.scene = scene;
sv.delegate = self;
[self.view addSubview:sv];
self.sceneView = sv;
self.scene = sv.scene;
self.scene.physicsWorld.speed = 5.0;
}
– (void)createTube {
SCNTube *tube = [SCNTube tubeWithInnerRadius:39 outerRadius:40 height:600];
tube.firstMaterial.diffuse.contents = [self color:1];
SCNNode *tubeNode = [SCNNode nodeWithGeometry:tube];
[self.scene.rootNode addChildNode:tubeNode];
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.camera = [SCNCamera camera];
camera.camera.zNear = 0;
camera.camera.zFar = 200;
camera.rotation = SCNVector4Make(1, 0, 0, M_PI/2.0);
camera.position = SCNVector3Make(0, –60, 0);
[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, –80, 0);
[self.scene.rootNode addChildNode:lightNode];
}
– (void)createBlock {
SCNBox *box = [SCNBox boxWithWidth:5 height:5 length:5 chamferRadius:0];
box.name = @”box”;
box.firstMaterial.diffuse.contents = [self color:3];
SCNNode *boxNode = [SCNNode nodeWithGeometry:box];
float x = (arc4random_uniform(10) – 5.0) * 4.0;
float z = (arc4random_uniform(10) – 5.0) * 4.0;
float y = 400;
boxNode.position = SCNVector3Make(x, y, z);
[self.scene.rootNode addChildNode:boxNode];
boxNode.physicsBody = [SCNPhysicsBody dynamicBody];
}
– (void)createPlayer {
SCNPyramid *pyramid = [SCNPyramid pyramidWithWidth:2 height:2 length:2];
pyramid.firstMaterial.diffuse.contents = [[self color:4] colorWithAlphaComponent:0.8];
SCNNode *player = [SCNNode nodeWithGeometry:pyramid];
player.name = @”player”;
player.position = SCNVector3Make(0, –40, –3);
[self.scene.rootNode addChildNode:player];
player.physicsBody = [SCNPhysicsBody staticBody];
[player runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:0 z:1 duration:1.0]]];
}
– (void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time
{
if (arc4random() % 30 == 0) {
[self createBlock];
}
[self.scene.rootNode.childNodes enumerateObjectsUsingBlock:^(SCNNode* obj, NSUInteger idx, BOOL *stop) {
if ([obj.name isEqual:@”box”]) {
if (obj.position.z < –80) {
[obj removeFromParentNode];
}
}
}];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
SCNNode *player = [self.scene.rootNode childNodeWithName:@”player” recursively:NO];
CGPoint p = [[touches anyObject] locationInView:self.sceneView];
float xmax = CGRectGetMaxX(self.sceneView.bounds);
float ymax = CGRectGetMaxY(self.sceneView.bounds);
SCNVector3 v = SCNVector3Make(20.0 * p.x/xmax – 10.0, player.position.y, –20.0 * p.y/ymax + 10.0);
[player runAction:[SCNAction moveTo:v duration:0.2]];
}
#define ColorHex(rgb) [UIColor colorWithRed:((rgb & 0xFF0000) >> 16)/255.0 green:((rgb & 0xFF00) >> 8)/255.0 blue:(rgb & 0xFF) / 255.0 alpha:1]
– (UIColor *)color:(int)i {
switch (i) {
case 0:
return ColorHex(0x332532);
case 1:
return ColorHex(0x644D52);
case 2:
return ColorHex(0xF77A52);
case 3:
return ColorHex(0xFF974F);
case 4:
return ColorHex(0xA49A87);
default:
break;
}
return nil;
}
@end