
カエルが葉っぱにジャンプするiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@interface ViewController () <SCNSceneRendererDelegate, SCNPhysicsContactDelegate>
@property (nonatomic, weak) SCNView *sceneView;
@property (nonatomic, strong) NSMutableArray *leaves;
@property (nonatomic, weak) SCNNode *flog;
@property (nonatomic, weak) SCNNode *contactLeaf;
@property (nonatomic) NSTimeInterval start;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
[self setupScene];
[self createPool];
[self createLeaf];
[self createFlog];
[self createCamera];
}
– (void)setupScene {
SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];
sv.backgroundColor = [UIColor colorWithHue:0.5 saturation:0.05 brightness:1 alpha:1];
sv.delegate = self;
sv.scene = [SCNScene scene];
sv.scene.physicsWorld.contactDelegate = self;
sv.autoenablesDefaultLighting = YES;
[self.view addSubview:sv];
self.sceneView = sv;
}
– (void)createPool {
SCNBox *pool = [SCNBox boxWithWidth:12 height:1 length:10 chamferRadius:0];
pool.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.5 saturation:0.6 brightness:1 alpha:0.7];
SCNNode *poolNode = [SCNNode nodeWithGeometry:pool];
poolNode.position = SCNVector3Make(0, –0.5, 0);
[self.sceneView.scene.rootNode addChildNode:poolNode];
}
– (void)createLeaf {
self.leaves = [NSMutableArray array];
for (int i=0; i<5; i++) {
SCNCylinder *leaf = [SCNCylinder cylinderWithRadius:1 height:0.1];
leaf.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.3 saturation:0.7 brightness:1 alpha:1];
SCNNode *leafNode = [SCNNode nodeWithGeometry:leaf];
leafNode.position = SCNVector3Make(0, 0, 4 – i * 2);
leafNode.physicsBody = [SCNPhysicsBody staticBody];
[self.sceneView.scene.rootNode addChildNode:leafNode];
[self.leaves addObject:leafNode];
}
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.camera = [SCNCamera camera];
camera.position = SCNVector3Make(0, 10, 20);
camera.rotation = SCNVector4Make(1, 0, 0, –0.5);
[self.sceneView.scene.rootNode addChildNode:camera];
}
– (void)createFlog {
SCNNode *flog = [SCNNode node];
flog.name = @”flog”;
flog.position = SCNVector3Make(0, 1, 5.5);
[self.sceneView.scene.rootNode addChildNode:flog];
SCNBox *body = [SCNBox boxWithWidth:1 height:0.4 length:1.2 chamferRadius:0];
body.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.25 saturation:0.9 brightness:0.8 alpha:1];
SCNNode *bodyNode = [SCNNode nodeWithGeometry:body];
[flog addChildNode:bodyNode];
for (int i=0; i<4; i++) {
SCNBox *f = [SCNBox boxWithWidth:0.2 height:0.4 length:0.2 chamferRadius:0];
f.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.25 saturation:0.9 brightness:0.8 alpha:1];
SCNNode *fNode = [SCNNode nodeWithGeometry:f];
float x = (i % 2) * 1.2 – 0.6;
float z = (i / 2) * 1.0 – 0.5;
fNode.position = SCNVector3Make(x, –0.3, z);
[flog addChildNode:fNode];
}
flog.physicsBody = [SCNPhysicsBody dynamicBody];
flog.physicsBody.allowsResting = NO;
flog.physicsBody.type = SCNPhysicsBodyTypeStatic;
flog.physicsBody.angularVelocityFactor = SCNVector3Make(0, 0, 0);
self.flog = flog;
}
– (void)physicsWorld:(SCNPhysicsWorld *)world didBeginContact:(SCNPhysicsContact *)contact {
if (contact.nodeA == self.flog) {
self.contactLeaf = contact.nodeB;
} else if (contact.nodeB == self.flog) {
self.contactLeaf = contact.nodeA;
}
self.flog.physicsBody.type = SCNPhysicsBodyTypeStatic;
}
– (void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
self.start = time – 0.001;
});
for (int i=0; i<self.leaves.count; i++) {
float dt = time – self.start + 5 * i;
float x = dt – 20 * ((int)dt / 20); // 0 ~ 20
if (x < 10) {
x = x – 5;
} else {
x = 15 – x;
}
SCNNode *n = self.leaves[i];
n.position = SCNVector3Make(x, 0, n.position.z);
self.sceneView.playing = YES;
}
if (self.contactLeaf) {
self.flog.position = SCNVector3Make(self.contactLeaf.position.x, 0.5, self.contactLeaf.position.z);
}
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.contactLeaf.physicsBody = nil;
self.contactLeaf = nil;
self.flog.physicsBody.type = SCNPhysicsBodyTypeDynamic;
[self.flog.physicsBody applyForce:SCNVector3Make(0, 6, –2) impulse:YES];
}
@end