iPhone4連ランチャー

手からミサイルをバスバス打ちまくる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