iPhoneボール箱

叩くとボールがとびだす箱を表示するiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNScene *scene;

@property (nonatomic, weak) SCNNode *boxfront;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [self color:3];

    

    [self setupScene];

    [self createBallBox];

    [self createCamera];

    [self createLight];

    [self createBall];

}

– (void)setupScene {

    float w = CGRectGetMaxX(self.view.bounds);

    SCNView *sv = [[SCNView alloc] initWithFrame:CGRectMake(0, 0, w, w)];

    sv.backgroundColor = [self color:0];

    sv.scene = [SCNScene scene];

    [self.view addSubview:sv];

    

    self.scene = sv.scene;

}

– (void)createBallBox {

    

    SCNBox *box = [SCNBox boxWithWidth:20 height:0.5 length:20 chamferRadius:0];

    box.firstMaterial.diffuse.contents = [self color:2];

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

        SCNNode *boxNode = [SCNNode nodeWithGeometry:box];

        boxNode.physicsBody = [SCNPhysicsBody staticBody];

        boxNode.transform = SCNMatrix4Translate(boxNode.transform, 0, 10.6, 0);

        if (i < 4) {

            float angle = (M_PI / 2.0) * i;

            boxNode.transform = SCNMatrix4Rotate(boxNode.transform, angle, 0, 0, 1);

        } else {

            float angle = (M_PI) * (i – 4) + M_PI / 2.0;

            boxNode.transform = SCNMatrix4Rotate(boxNode.transform, angle, –1, 0, 0);

        }

        [self.scene.rootNode addChildNode:boxNode];

    }

    

    SCNNode *front = self.scene.rootNode.childNodes.lastObject;

    front.physicsBody = [SCNPhysicsBody dynamicBody];

    front.physicsBody.physicsShape = [SCNPhysicsShape shapeWithGeometry:front.geometry options:nil];

    SCNPhysicsHingeJoint *joint = [SCNPhysicsHingeJoint jointWithBody:front.physicsBody axis:SCNVector3Make(1, 0, 0) anchor:SCNVector3Make(0, 0, 10)];

    [self.scene.physicsWorld addBehavior:joint];

    

    self.boxfront = front;

}

– (void)createBall {

    SCNSphere *ball = [SCNSphere sphereWithRadius:5];

    ball.firstMaterial.diffuse.contents = [self color:4];

    SCNNode *ballNode = [SCNNode nodeWithGeometry:ball];

    ballNode.name = @”ball”;

    ballNode.physicsBody = [SCNPhysicsBody dynamicBody];

    ballNode.physicsBody.physicsShape = [SCNPhysicsShape shapeWithGeometry:ball options:nil];

    [self.scene.rootNode addChildNode:ballNode];

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

    camera.position = SCNVector3Make(0, 15, 60);

    camera.rotation = SCNVector4Make(1, 0, 0, –0.3);

    [self.scene.rootNode addChildNode:camera];

}

– (void)createLight {

    SCNLight *light = [SCNLight light];

    light.type = SCNLightTypeSpot;

    

    SCNNode *lightNode = [SCNNode node];

    lightNode.light= light;

    lightNode.position = SCNVector3Make(0, 0, 80);

    [self.scene.rootNode addChildNode:lightNode];

}

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

{

    [self.boxfront.physicsBody applyForce:SCNVector3Make(0, 0, 5) atPosition:SCNVector3Make(0, 15, 0) impulse:YES];

    

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

    [ball.physicsBody applyForce:SCNVector3Make(0, 0, 30) atPosition:SCNVector3Make(0, 5, 0) impulse:YES];

}

#define ColorHex(rgb) [UIColor colorWithRed:((rgb & 0xFF0000) >> 16)/255.0 green:((rgb & 0xFF00) >> 8)/255.0 blue:(rgb & 0xFF)/255.0 alpha:1.0]

– (UIColor *)color:(int)i {

    switch (i) {

        case 0: return ColorHex(0x703030);

        case 1: return ColorHex(0x2F343B);

        case 2: return ColorHex(0x7E827A);

        case 3: return ColorHex(0xE3CDA4);

        case 4: return ColorHex(0xC77966);

        default:

            break;

    }

    return nil;

}

@end