iPhoneボール混ぜ

円筒の中でボールをまぜまぜするiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNScene *scene;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

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

    

    [self createScene];

    [self createCup];

    [self createMuddler];

    [self createCamera];

}

– (void)createScene {

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

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

    sv.backgroundColor = [self color:1];

    sv.scene = [SCNScene scene];

    [self.view addSubview:sv];

    

    self.scene = sv.scene;

}

– (void)createCup {

    SCNTube *tube = [SCNTube tubeWithInnerRadius:10 outerRadius:11 height:20];

    tube.firstMaterial.diffuse.contents = [[self color:2] colorWithAlphaComponent:0.2];

    SCNNode *tubeNode = [SCNNode nodeWithGeometry:tube];

    tubeNode.physicsBody = [SCNPhysicsBody staticBody];

    tubeNode.physicsBody.physicsShape = [SCNPhysicsShape shapeWithGeometry:tube options:@{SCNPhysicsShapeTypeKey: SCNPhysicsShapeTypeConcavePolyhedron}];

    [self.scene.rootNode addChildNode:tubeNode];

    

    SCNCylinder *bottom = [SCNCylinder cylinderWithRadius:10 height:1];

    bottom.firstMaterial.diffuse.contents = [[self color:2] colorWithAlphaComponent:0.2];

    SCNNode *bottomNode = [SCNNode nodeWithGeometry:bottom];

    bottomNode.position = SCNVector3Make(0, –10, 0);

    bottomNode.name = @”bottom”;

    bottomNode.physicsBody = [SCNPhysicsBody staticBody];

    [self.scene.rootNode addChildNode:bottomNode];

}

– (void)createMuddler {

    SCNCylinder *muddler = [SCNCylinder cylinderWithRadius:0.5 height:18];

    muddler.firstMaterial.diffuse.contents = [self color:3];

    SCNNode *muddlerNode = [SCNNode nodeWithGeometry:muddler];

    muddlerNode.rotation = SCNVector4Make(0, 0, 1, M_PI/2.0);

    muddlerNode.position = SCNVector3Make(0, –8, 0);

    [self.scene.rootNode addChildNode:muddlerNode];

    

    muddlerNode.physicsBody = [SCNPhysicsBody staticBody];

    

    [muddlerNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByAngle:M_PI aroundAxis:SCNVector3Make(0, 1, 0) duration:2.0]]];

    

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

    camera.position = SCNVector3Make(0, 20, 50);

    [self.scene.rootNode addChildNode:camera];

    

    camera.constraints = @[[SCNLookAtConstraint lookAtConstraintWithTarget:[self.scene.rootNode childNodeWithName:@”bottom” recursively:NO]]];

}

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

    SCNSphere *ball = [SCNSphere sphereWithRadius:1];

    if (arc4random()%2){

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

    } else {

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

    }

    SCNNode *ballNode = [SCNNode nodeWithGeometry:ball];

    ballNode.position = SCNVector3Make(5, 10, 0);

    [self.scene.rootNode addChildNode:ballNode];

    

    ballNode.physicsBody = [SCNPhysicsBody dynamicBody];

    ballNode.physicsBody.damping = 0.7;

}

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

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

    switch (i) {

        case 0: return ColorHex(0x56626B);

        case 1: return ColorHex(0x6C9380);

        case 2: return ColorHex(0xC0CA55);

        case 3: return ColorHex(0xF07C6C);

        case 4: return ColorHex(0xAD5472);

        default:

            break;

    }

    return nil;

}

@end