運動会の競技、台風の目みたいなiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@interface ViewController () <SCNSceneRendererDelegate>
@property (nonatomic, weak) SCNView *sceneView;
@property (nonatomic) int status;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
[self setupScene];
[self createRunnerBar];
[self createCone];
[self createCamera];
}
– (void)setupScene {
SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];
sv.backgroundColor = [UIColor brownColor];
sv.scene = [SCNScene scene];
sv.autoenablesDefaultLighting = YES;
sv.delegate = self;
[self.view addSubview:sv];
self.sceneView = sv;
}
– (void)createRunnerBar {
SCNNode *runBar = [SCNNode node];
runBar.name = @”run bar”;
SCNCylinder *bar = [SCNCylinder cylinderWithRadius:0.3 height:8];
bar.firstMaterial.diffuse.contents = [UIColor colorWithHue:0 saturation:1 brightness:0.8 alpha:1];
SCNNode *barNode = [SCNNode nodeWithGeometry:bar];
barNode.rotation = SCNVector4Make(1, 0, 0, M_PI * 0.5);
[runBar addChildNode:barNode];
for (int i=0; i<4; i++) {
SCNNode *runner = [SCNNode node];
runner.position = SCNVector3Make(-1.2, –0.3, 2 * i – 3);
[runBar addChildNode:runner];
SCNSphere *head = [SCNSphere sphereWithRadius:0.6];
head.firstMaterial.diffuse.contents = [UIColor darkGrayColor];
SCNNode *headNode = [SCNNode nodeWithGeometry:head];
headNode.position = SCNVector3Make(0, 1, 0);
[runner addChildNode:headNode];
SCNBox *body = [SCNBox boxWithWidth:0.5 height:1 length:0.5 chamferRadius:0.25];
body.firstMaterial.diffuse.contents = [UIColor darkGrayColor];
SCNNode *bodyNode = [SCNNode nodeWithGeometry:body];
[runner addChildNode:bodyNode];
for (int i=0; i<2; i++) {
SCNBox *foot = [SCNBox boxWithWidth:0.4 height:1 length:0.4 chamferRadius:0.2];
foot.firstMaterial.diffuse.contents = [UIColor darkGrayColor];
SCNNode *footNode = [SCNNode nodeWithGeometry:foot];
footNode.pivot = SCNMatrix4MakeTranslation(0, 0.5, 0);
footNode.position = SCNVector3Make(0, –0.4, i==0 ? 0.25 : –0.25);
footNode.rotation = SCNVector4Make(0, 0, 1, i==0 ? 0.3 : –0.3);
[runner addChildNode:footNode];
SCNBox *arm = [SCNBox boxWithWidth:1 height:0.3 length:0.3 chamferRadius:0.1];
arm.firstMaterial.diffuse.contents = [UIColor darkGrayColor];
SCNNode *armNode = [SCNNode nodeWithGeometry:arm];
armNode.position = SCNVector3Make(0.5, 0.3, i==0 ? 0.4 : –0.4);
[runner addChildNode:armNode];
}
}
runBar.physicsBody = [SCNPhysicsBody dynamicBody];
runBar.physicsBody.velocityFactor = SCNVector3Make(1, 0, 1);
runBar.physicsBody.angularDamping = 0.6;
[self.sceneView.scene.rootNode addChildNode:runBar];
}
– (void)createCone {
SCNCone *corn = [SCNCone coneWithTopRadius:0.2 bottomRadius:1 height:2];
corn.firstMaterial.diffuse.contents = [UIColor redColor];
SCNNode *cornNode = [SCNNode nodeWithGeometry:corn];
cornNode.position = SCNVector3Make(10, 0, –4);
[self.sceneView.scene.rootNode addChildNode:cornNode];
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.camera = [SCNCamera camera];
camera.position = SCNVector3Make(10, 10, 20);
camera.rotation = SCNVector4Make(1, 0, 0, –0.4);
[self.sceneView.scene.rootNode addChildNode:camera];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.status == 0) {
self.status = 2;
} else {
self.status = 1;
}
self.sceneView.playing = YES;
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
self.status = 2;
}
– (void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time
{
if (self.status == 0) {
return;
}
SCNNode *runbar = [self.sceneView.scene.rootNode childNodeWithName:@”run bar” recursively:NO];
if (self.status == 1) {
[runbar.physicsBody applyForce:SCNVector3Make(-0.02, 0, 0) atPosition:SCNVector3Make(0, 0, –5) impulse:YES];
} else {
SCNVector3 v = [runbar.presentationNode convertPosition:SCNVector3Make(3, 0, 0) toNode:self.sceneView.scene.rootNode];
runbar.physicsBody.velocity = SCNVector3Sub(v, runbar.presentationNode.position);
}
}
static inline SCNVector3 SCNVector3Sub(SCNVector3 a, SCNVector3 b)
{
return SCNVector3Make(a.x – b.x, a.y – b.y, a.z – b.z);
}
@end