iPhoneワイヤージャンプ

ワイヤーを使ってジャンプするような感じでiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController () <SCNSceneRendererDelegate>

@property (nonatomic, weak) SCNView *sceneView;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createStrap];

    [self createBase];

    [self createHook];

    [self createCamera];

}

– (void)setupScene {

    SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];

    sv.backgroundColor = [UIColor blackColor];

    sv.scene = [SCNScene scene];

    sv.autoenablesDefaultLighting = YES;

    sv.delegate = self;

    [self.view addSubview:sv];

    

    self.sceneView = sv;

}

– (void)createStrap {

    SCNNode *strap = [SCNNode node];

    [self.sceneView.scene.rootNode addChildNode:strap];

    

    SCNBox *bar = [SCNBox boxWithWidth:0.1 height:1 length:0.1 chamferRadius:0];

    bar.firstMaterial.diffuse.contents = [UIColor brownColor];

    SCNNode *barNode = [SCNNode nodeWithGeometry:bar];

    [strap addChildNode:barNode];

    

    for (int i=0; i<4; i++) {

        SCNBox *b = [SCNBox boxWithWidth:0.5 height:0.1 length:0.1 chamferRadius:0];

        b.firstMaterial.diffuse.contents = [UIColor whiteColor];

        SCNNode *bNode = [SCNNode nodeWithGeometry:b];

        if (i < 2) {

            bNode.position = SCNVector3Make(0, (i%2)==0 ? –0.55 : –1, 0);

        } else {

            bNode.position = SCNVector3Make((i%2)==0 ? –0.25 : 0.25, –0.75, 0);

            bNode.rotation = SCNVector4Make(0, 0, 1, M_PI * 0.5);

        }

        [strap addChildNode:bNode];

    }

    strap.rotation = SCNVector4Make(0, 1, 0, M_PI * 0.5);

    strap.physicsBody = [SCNPhysicsBody staticBody];

}

– (void)createBase {

    for (int i=0; i<2; i++) {

        SCNBox *base = [SCNBox boxWithWidth:4 height:1 length:1 chamferRadius:0];

        base.firstMaterial.diffuse.contents = [UIColor grayColor];

        SCNNode *baseNode = [SCNNode nodeWithGeometry:base];

        if (i==1) {

            baseNode.name = @”base”;

        }

        baseNode.position = SCNVector3Make(i==0 ? –5 : 5, –4, 0);

        [self.sceneView.scene.rootNode addChildNode:baseNode];

    }

}

– (void)createHook {

    SCNBox *player = [SCNBox boxWithWidth:0.5 height:0.5 length:0.5 chamferRadius:0.1];

    player.firstMaterial.diffuse.contents = [UIColor yellowColor];

    SCNNode *playerNode = [SCNNode nodeWithGeometry:player];

    playerNode.name = @”player”;

    playerNode.position = SCNVector3Make(-3.5, –3.3, –0.3);

    [self.sceneView.scene.rootNode addChildNode:playerNode];

    

    SCNNode *hook = [SCNNode node];

    hook.name = @”hook”;

    NSArray *b = @[[SCNBox boxWithWidth:0.1 height:0.2 length:0.1 chamferRadius:0],[SCNBox boxWithWidth:0.3 height:0.1 length:0.1 chamferRadius:0],[SCNBox boxWithWidth:0.1 height:0.4 length:0.1 chamferRadius:0]];

    SCNVector3 p[] = {SCNVector3Make(0.15, 0.1, 0), SCNVector3Make(0, 0.2, 0), SCNVector3Make(-0.15, 0, 0)};

    for (int i=0; i<3; i++) {

        ((SCNBox *)b[i]).firstMaterial.diffuse.contents = [UIColor whiteColor];

        SCNNode *bNode = [SCNNode nodeWithGeometry:b[i]];

        bNode.position = p[i];

        [hook addChildNode:bNode];

    }

    hook.position = SCNVector3Make(-3.5, –3, 0);

    [self.sceneView.scene.rootNode addChildNode:hook];

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

    camera.position = SCNVector3Make(0, 0, 8);

    [self.sceneView.scene.rootNode addChildNode:camera];

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    SCNNode *hook = [self.sceneView.scene.rootNode childNodeWithName:@”hook” recursively:NO];

    [hook removeAllActions];

    hook.physicsBody = [SCNPhysicsBody dynamicBody];

    [hook.physicsBody applyForce:SCNVector3Make(6, 6.6, 0) impulse:YES];

    

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        SCNNode *player = [self.sceneView.scene.rootNode childNodeWithName:@”player” recursively:NO];

        player.physicsBody = [SCNPhysicsBody dynamicBody];

        player.physicsBody.mass = 0.1;

        

        SCNPhysicsHingeJoint *j = [SCNPhysicsHingeJoint jointWithBody:player.physicsBody axis:SCNVector3Make(0, 0, 1) anchor:SCNVector3Make(-player.position.x, -player.position.y, 0)];

        [self.sceneView.scene.physicsWorld addBehavior:j];

        

        

        [player.physicsBody applyForce:SCNVector3Make(2, 0.7, 0) impulse:YES];

        

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            SCNNode *base = [self.sceneView.scene.rootNode childNodeWithName:@”base” recursively:NO];

            base.physicsBody = [SCNPhysicsBody staticBody];

        });

    });

}

– (void)renderer:(id<SCNSceneRenderer>)aRenderer didApplyAnimationsAtTime:(NSTimeInterval)time {

    SCNNode *hook = [self.sceneView.scene.rootNode childNodeWithName:@”hook” recursively:NO];

    SCNNode *player = [self.sceneView.scene.rootNode childNodeWithName:@”player” recursively:NO];

    

    SCNNode *ropeOld = [self.sceneView.scene.rootNode childNodeWithName:@”rope” recursively:NO];

    [ropeOld removeFromParentNode];

    

    UIBezierPath *p = [UIBezierPath bezierPath];

    [p moveToPoint:CGPointMake(hook.presentationNode.position.x, hook.presentationNode.position.y)];

    [p addLineToPoint:CGPointMake(hook.presentationNode.position.x+0.1, hook.presentationNode.position.y)];

    [p addLineToPoint:CGPointMake(player.presentationNode.position.x+0.1, player.presentationNode.position.y)];

    [p addLineToPoint:CGPointMake(player.presentationNode.position.x, player.presentationNode.position.y)];

    [p closePath];

    SCNShape *rope = [SCNShape shapeWithPath:p extrusionDepth:0.2];

    rope.firstMaterial.diffuse.contents = [UIColor brownColor];

    SCNNode *ropeN = [SCNNode nodeWithGeometry:rope];

    ropeN.name = @”rope”;

    [self.sceneView.scene.rootNode addChildNode:ropeN];

}

@end