iPhoneキリンブロック

ブロックを積んでキリンを作るiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNView *sceneView;

@property (nonatomic, strong) NSArray *blockData;

@property (nonatomic) int count;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createGround];

    [self createBlockData];

}

– (void)setupScene {

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

    sv.scene = [SCNScene scene];

    sv.backgroundColor = [self color:0];

    sv.allowsCameraControl = YES;

    sv.autoenablesDefaultLighting = YES;

    [self.view addSubview:sv];

    

    self.sceneView = sv;

}

– (void)createGround {

    SCNBox *ground = [SCNBox boxWithWidth:40 height:1 length:40 chamferRadius:0];

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

    SCNNode *groundNode = [SCNNode nodeWithGeometry:ground];

    groundNode.physicsBody = [SCNPhysicsBody staticBody];

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

}

– (void)createBlockData {

    // type(rect or circle), color(yellow or brown), x, y, z

    self.blockData = @[

       @{@”type”:@”r”, @”color”:@2, @”x”:@2, @”y”:@0, @”z”:@0, @”w”:@1, @”l”:@1},

       @{@”type”:@”r”, @”color”:@2, @”x”:@5, @”y”:@0, @”z”:@0, @”w”:@1, @”l”:@1},

       @{@”type”:@”r”, @”color”:@2, @”x”:@2, @”y”:@0, @”z”:@3, @”w”:@1, @”l”:@1},

       @{@”type”:@”r”, @”color”:@2, @”x”:@5, @”y”:@0, @”z”:@3, @”w”:@1, @”l”:@1},

       

       @{@”type”:@”r”, @”color”:@3, @”x”:@2.5, @”y”:@1, @”z”:@0, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@3, @”x”:@5.5, @”y”:@1, @”z”:@0, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@3, @”x”:@2.5, @”y”:@1, @”z”:@3, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@3, @”x”:@5.5, @”y”:@1, @”z”:@3, @”w”:@2, @”l”:@1},

       

       @{@”type”:@”r”, @”color”:@3, @”x”:@2.5, @”y”:@2, @”z”:@0, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@3, @”x”:@5.5, @”y”:@2, @”z”:@0, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@3, @”x”:@2.5, @”y”:@2, @”z”:@3, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@3, @”x”:@5.5, @”y”:@2, @”z”:@3, @”w”:@2, @”l”:@1},

       

       @{@”type”:@”r”, @”color”:@2, @”x”:@2.5, @”y”:@3, @”z”:@0, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@2, @”x”:@5.5, @”y”:@3, @”z”:@0, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@2, @”x”:@2.5, @”y”:@3, @”z”:@3, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@2, @”x”:@5.5, @”y”:@3, @”z”:@3, @”w”:@2, @”l”:@1},

       

       @{@”type”:@”r”, @”color”:@3, @”x”:@2.5, @”y”:@4, @”z”:@1.5, @”w”:@2, @”l”:@4},

       @{@”type”:@”r”, @”color”:@3, @”x”:@5.5, @”y”:@4, @”z”:@1.5, @”w”:@2, @”l”:@4},

       

       @{@”type”:@”r”, @”color”:@3, @”x”:@3.5, @”y”:@5, @”z”:@1.5, @”w”:@4, @”l”:@2},

       @{@”type”:@”r”, @”color”:@2, @”x”:@6, @”y”:@5, @”z”:@1.5, @”w”:@1, @”l”:@2},

       

       @{@”type”:@”r”, @”color”:@3, @”x”:@2.5, @”y”:@6, @”z”:@1, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@2, @”x”:@2.5, @”y”:@6, @”z”:@2, @”w”:@2, @”l”:@1},

       

       @{@”type”:@”r”, @”color”:@3, @”x”:@2.5, @”y”:@7, @”z”:@1.5, @”w”:@2, @”l”:@2},

       

       @{@”type”:@”r”, @”color”:@3, @”x”:@2, @”y”:@8, @”z”:@1.5, @”w”:@1, @”l”:@2},

       @{@”type”:@”r”, @”color”:@2, @”x”:@3, @”y”:@8, @”z”:@1.5, @”w”:@1, @”l”:@2},

       

       @{@”type”:@”r”, @”color”:@2, @”x”:@2.5, @”y”:@9, @”z”:@1, @”w”:@2, @”l”:@1},

       @{@”type”:@”r”, @”color”:@3, @”x”:@2.5, @”y”:@9, @”z”:@2, @”w”:@2, @”l”:@1},

       

       @{@”type”:@”r”, @”color”:@2, @”x”:@2, @”y”:@10, @”z”:@1.5, @”w”:@1, @”l”:@2},

       @{@”type”:@”r”, @”color”:@3, @”x”:@3, @”y”:@10, @”z”:@1.5, @”w”:@1, @”l”:@2},

       

       @{@”type”:@”r”, @”color”:@3, @”x”:@2, @”y”:@11, @”z”:@1.5, @”w”:@3, @”l”:@2},

       

       @{@”type”:@”r”, @”color”:@3, @”x”:@1, @”y”:@12, @”z”:@1.5, @”w”:@2, @”l”:@2},

       @{@”type”:@”r”, @”color”:@3, @”x”:@3, @”y”:@12, @”z”:@1.5, @”w”:@1, @”l”:@4},

       

       @{@”type”:@”r”, @”color”:@3, @”x”:@2.5, @”y”:@13, @”z”:@1.5, @”w”:@2, @”l”:@2},

       

       @{@”type”:@”c”, @”color”:@2, @”x”:@3, @”y”:@14, @”z”:@1, @”w”:@1, @”l”:@1},

       @{@”type”:@”c”, @”color”:@2, @”x”:@3, @”y”:@14, @”z”:@2, @”w”:@1, @”l”:@1}];

    

}

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

{

    NSPredicate *pred = [NSPredicate predicateWithFormat:@”y == %d”, self.count];

    [[self.blockData filteredArrayUsingPredicate:pred] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        

        SCNGeometry *g = nil;

        if ([obj[@”type”] isEqual:@”r”]) {

            g = [SCNBox boxWithWidth:[obj[@”w”] floatValue] height:0.6 length:[obj[@”l”] floatValue] chamferRadius:0.1];

        } else {

            g = [SCNCylinder cylinderWithRadius:[obj[@”w”] floatValue] * 0.5 height:0.6];

        }

        g.firstMaterial.diffuse.contents = [self color:[obj[@”color”] intValue]];

        

        SCNNode *bn = [SCNNode nodeWithGeometry:g];

        bn.position = SCNVector3Make([obj[@”x”] floatValue], 30, [obj[@”z”] floatValue]);

        bn.physicsBody = [SCNPhysicsBody dynamicBody];

        bn.physicsBody.velocityFactor = SCNVector3Make(0, 1, 0);

        bn.physicsBody.angularVelocityFactor = SCNVector3Zero;

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

    }];

    

    ++self.count;

}

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

    if (i>3) return nil;

    int colorCode[] = {0xF0F0F0, 0x67CC4F, 0x7F6E00, 0xFFDB00};

    return ColorHex(colorCode[i]);

}

@end