iPhone7箱パズル

7つの箱をタップして色をそろえるiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNView *sceneView;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createSevenBox];

    [self createCamera];

}

– (void)setupScene {

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

    sv.backgroundColor = [self color:0];

    sv.scene = [SCNScene scene];

    sv.allowsCameraControl = YES;

    sv.autoenablesDefaultLighting = YES;

    [self.view addSubview:sv];

    

    self.sceneView = sv;

}

– (void)createSevenBox {

    float l = 10;

    SCNVector3 points[] = {

        SCNVector3Make(0, 0, 0),

        SCNVector3Make(l, 0, 0),

        SCNVector3Make(-l, 0, 0),

        SCNVector3Make(0, l, 0),

        SCNVector3Make(0, -l, 0),

        SCNVector3Make(0, 0, l),

        SCNVector3Make(0, 0, -l),

    };

    

    float s = l * 0.6;

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

        SCNBox *box = [SCNBox boxWithWidth:s height:s length:s chamferRadius:0.1];

        box.firstMaterial.diffuse.contents = (i==6) ? [self color:2] : [self color:4];

        box.firstMaterial.specular.contents = [self color:1];

        

        SCNNode *boxNode = [SCNNode nodeWithGeometry:box];

        boxNode.name = (i==6) ? @”on” : @”off”;

        boxNode.position = points[i];

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

    }

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

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

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

}

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

{

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

    

    // x y z +-

    void (^setupNode)(SCNNode *n) = ^(SCNNode *n){

        SCNMaterial *material = [SCNMaterial material];

        material.specular.contents = [self color:1];

        if ([n.name isEqual:@”on”]) {

            n.name = @”off”;

            material.diffuse.contents = [self color:4];

        } else {

            n.name = @”on”;

            material.diffuse.contents = [self color:2];

        }

        n.geometry.firstMaterial = material;

    };

    

    

    SCNNode *hit = [[self.sceneView hitTest:p options:@{SCNHitTestSortResultsKey:@YES}].firstObject node];

    if (!hit) return;

    else setupNode(hit);

    

    

    [self.sceneView.scene.rootNode.childNodes enumerateObjectsUsingBlock:^(SCNNode *n, NSUInteger idx, BOOL *stop) {

        float dx = fabs(n.position.x – hit.position.x);

        float dy = fabs(n.position.y – hit.position.y);

        float dz = fabs(n.position.z – hit.position.z);

        

        if ((dx == 10 && dy == 0 && dz == 0)

            || (dx == 0 && dy == 10 && dz == 0)

            || (dx == 0 && dy == 0 && dz == 10)

            ) {

            setupNode(n);

        }

    }];

}

#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 > 3) return nil;

    int colorCode[] = {0xFFE261, 0xFFFAF4, 0x040014, 0xDEFDFF};

    return ColorHex(colorCode[i]);

}

@end