手からミサイルをバスバス打ちまくるiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@interface ViewController ()
@property (nonatomic, weak) SCNView *sceneView;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
[self setupScene];
[self createSuit];
[self createTarget];
[self createCamera];
}
– (void)setupScene {
SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];
sv.backgroundColor = [UIColor colorWithHue:0.05 saturation:0.1 brightness:1 alpha:1];
sv.scene = [SCNScene scene];
sv.autoenablesDefaultLighting = YES;
sv.allowsCameraControl = YES;
[self.view addSubview:sv];
self.sceneView = sv;
}
– (void)createSuit {
SCNNode *suit = [SCNNode node];
[self.sceneView.scene.rootNode addChildNode:suit];
UIColor *color = [UIColor brownColor];
SCNBox *head = [SCNBox boxWithWidth:2 height:2 length:2 chamferRadius:0];
head.firstMaterial.diffuse.contents = color;
SCNNode *headNode = [SCNNode nodeWithGeometry:head];
headNode.position = SCNVector3Make(0, 2, 0);
[suit addChildNode:headNode];
SCNBox *body = [SCNBox boxWithWidth:1.5 height:2 length:1.5 chamferRadius:0];
body.firstMaterial.diffuse.contents = color;
SCNNode *bodyNode = [SCNNode nodeWithGeometry:body];
[suit addChildNode:bodyNode];
for (int i=0; i<2; i++) {
SCNBox *arm = [SCNBox boxWithWidth:2 height:1 length:1 chamferRadius:0.48];
arm.firstMaterial.diffuse.contents = color;
SCNNode *armNode = [SCNNode nodeWithGeometry:arm];
armNode.name = @”arm”;
armNode.pivot = SCNMatrix4MakeTranslation(-0.8, 0, 0);
armNode.position = SCNVector3Make(0, 0.8, i==0 ? 1 : –1);
[suit addChildNode:armNode];
[armNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByAngle:M_PI aroundAxis:SCNVector3Make(1, 0, 0) duration:1.0]]];
}
[self createMissile];
}
– (void)createTarget {
SCNBox *target = [SCNBox boxWithWidth:0.5 height:3 length:3 chamferRadius:0.25];
target.firstMaterial.diffuse.contents = [UIColor blackColor];
SCNNode *targetNode = [SCNNode nodeWithGeometry:target];
targetNode.position = SCNVector3Make(10, 0, 0);
[self.sceneView.scene.rootNode addChildNode:targetNode];
targetNode.physicsBody = [SCNPhysicsBody staticBody];
}
– (void)createMissile {
[self.sceneView.scene.rootNode enumerateChildNodesUsingBlock:^(SCNNode *child, BOOL *stop) {
if ([child.name isEqual:@”arm”]) {
for (int j=0; j<4; j++) {
float r = 0.3;
float dw = M_PI / 2.0;
float y = r * cos(dw * j);
float z = r * sin(dw * j);
SCNBox *missile = [SCNBox boxWithWidth:0.5 height:0.2 length:0.2 chamferRadius:0.1];
missile.firstMaterial.diffuse.contents = [UIColor lightGrayColor];
SCNNode *missileNode = [SCNNode nodeWithGeometry:missile];
missileNode.position = SCNVector3Make(0.8, y, z);
missileNode.name = @”missile”;
[child addChildNode:missileNode];
}
}}];
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.camera = [SCNCamera camera];
camera.position = SCNVector3Make(5, 0, 10);
[self.sceneView.scene.rootNode addChildNode:camera];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.sceneView.scene.rootNode enumerateChildNodesUsingBlock:^(SCNNode *child, BOOL *stop) {
if ([child.name isEqual:@”arm”]) {
NSInteger cnt = child.childNodes.count;
for (NSInteger i=cnt-1; i > –1; i–) {
SCNNode *m = child.childNodes[i];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * i * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.sceneView.scene.rootNode addChildNode:m];
m.position = [child convertPosition:m.position toNode:self.sceneView.scene.rootNode];
m.physicsBody = [SCNPhysicsBody dynamicBody];
[m.physicsBody applyForce:SCNVector3Make(20, 0, 0) impulse:YES];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[m removeFromParentNode];
});
});
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self createMissile];
});
}
}];
}
@end