iPhone坂ループ

ボールを坂に転がして一回転させるiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNView *sceneView;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createSlider];

}

– (void)setupScene {

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

    sv.backgroundColor = [self color:3];

    sv.scene = [SCNScene scene];

    sv.allowsCameraControl = YES;

    [self.view addSubview:sv];

    self.sceneView = sv;

}

– (void)createSlider {

    

    float d = 0.1;

    float l = d / sqrt(2.0);

    SCNBox *s = [SCNBox boxWithWidth:d height:d length:d chamferRadius:0];

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

    

    // straight

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

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

            SCNNode *node = [SCNNode nodeWithGeometry:s];

            node.rotation = SCNVector4Make(1, 0, 0, – M_PI * 0.25);

            node.position = SCNVector3Make(j==0 ? –5 : –4, – i * l, i * l);

            node.physicsBody = [SCNPhysicsBody staticBody];

            node.physicsBody.restitution = 0;

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

        }

    }

    

    // loop 1/2

    float dw = M_PI/75.0;

    float r = 25.0 * l;

    

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

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

            float z = r * cos(dw * i – M_PI * 0.75) + 100.0 * l + r / sqrt(2.0);

            float y = r * sin(dw * i – M_PI * 0.75) – 100.0 * l + r / sqrt(2.0);

            SCNNode *node = [SCNNode nodeWithGeometry:s];

            node.position = SCNVector3Make((j==0 ? –5 : –4) + 0.0001 * pow(i, 2), y, z);

            node.rotation = SCNVector4Make(1, 0, 0, -dw * i + 0.25 * M_PI);

            node.physicsBody = [SCNPhysicsBody staticBody];

            node.physicsBody.restitution = 0;

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

        }

    }

}

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

{

    SCNSphere *ball = [SCNSphere sphereWithRadius:0.51];

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

    SCNNode *ballNode = [SCNNode nodeWithGeometry:ball];

    ballNode.position = SCNVector3Make(-4.5, 0.48, 0);

    ballNode.physicsBody = [SCNPhysicsBody dynamicBody];

    ballNode.physicsBody.restitution = 0;

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

    

    [ballNode.physicsBody applyTorque:SCNVector4Make(1, 0, 0, 20) impulse:YES];

    [ballNode.physicsBody applyForce:SCNVector3Make(0, –5, 5) impulse:YES];

    

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

        [ballNode removeFromParentNode];

    });

}

#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 {

    if (i > 4) return nil;

    int colorCode[] = {0xC194A7, 0xFF92B9, 0xFFC6EB, 0xE9FFFF, 0xCAEE9F};

    return ColorHex(colorCode[i]);

}

@end