iPhone 球状ボタン

球状に配置したボタンをポチポチ押すだけのiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNView *sceneView;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

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

    [self setupScene];

    [self createButtons];

}

– (void)setupScene {

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

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

    sv.scene = [SCNScene scene];

    sv.backgroundColor = [self color:4];

    [self.view addSubview:sv];

    self.sceneView = sv;

    

    [self.sceneView.scene.rootNode runAction:[SCNAction rotateByAngle:M_PI aroundAxis:SCNVector3Make(1, 0, 0) duration:30.0]];

}

– (void)createButtons {

    float dangle = M_PI / 5.0;

    

    NSMutableArray *btns = [NSMutableArray array];

    for (int t=0; t<9; t++) {

        for (int p =0; p<9; p++) {

            SCNSphere *btn = [SCNSphere sphereWithRadius:1.2];

            btn.firstMaterial.diffuse.contents = [[self color:0] colorWithAlphaComponent:0.8];

            SCNNode *btnNode = [SCNNode nodeWithGeometry:btn];

            btnNode.position = [self sphericalCoordinateTheata:t * dangle phi:p * dangle r:10];

            btnNode.name = @”btn”;

            

            // check distance

            BOOL skip = NO;

            for (SCNNode *previous in btns) {

                SCNVector3 v0 = previous.position;

                SCNVector3 v1 = btnNode.position;

                SCNVector3 v = SCNVector3Make(v0.x – v1.x, v0.y – v1.y, v0.z – v1.z);

                float d = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);

                if (d < 3.0) {

                    skip = YES;

                }

            }

            

            if (!skip) {

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

                [btns addObject:btnNode];

            }

        }

    }

}

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

{

    CGPoint p = [[touches anyObject] locationInView:self.sceneView];

    NSArray *hits = [self.sceneView hitTest:p options:@{SCNHitTestSortResultsKey : @YES}];

    if (hits.count > 0) {

        SCNNode *hit = [hits.firstObject node];

        if ([hit.name hasPrefix:@”btn”]) {

            

            SCNVector3 p = hit.position;

            [hit runAction:[SCNAction sequence:@[

                [SCNAction moveByX:-p.x * 0.1 y:-p.y * 0.1 z:-p.z * 0.1 duration:0.1],

                [SCNAction moveTo:p duration:0.3]

            ]]];

            hit.geometry.firstMaterial.diffuse.contents = [[self color:2] colorWithAlphaComponent:0.8];

        }

    }

}

– (SCNVector3)sphericalCoordinateTheata:(float)t phi:(float)p r:(float)r {

    float x = r * sin(t) * cos(p);

    float y = r * sin(t) * sin(p);

    float z = r * cos(t);

    return SCNVector3Make(x, y, z);

}

#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(0x5E0042);

        case 1: return ColorHex(0x2C2233);

        case 2: return ColorHex(0x005869);

        case 3: return ColorHex(0x00856A);

        case 4: return ColorHex(0xDFF7B9);

    }

    return nil;

}

@end