
10までの足し算を3つずつの塊を意識しながら答えていくiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@interface ViewController ()
@property (nonatomic, weak) SCNView *sceneView;
@property (nonatomic, strong) NSMutableArray *questions;
@property (nonatomic, strong) NSArray *currentAB;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
[self setupScene];
[self createCover];
[self createNumber];
[self createThreeEachButton];
[self setupQuestion];
[self nextQuestion];
}
– (void)setupScene {
SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];
sv.backgroundColor = [UIColor colorWithHue:0.6 saturation:0.5 brightness:0.7 alpha:1];
sv.scene = [SCNScene scene];
sv.autoenablesDefaultLighting = YES;
sv.allowsCameraControl = YES;
[self.view addSubview:sv];
self.sceneView = sv;
}
– (void)setupQuestion {
self.questions = [NSMutableArray array];
for (int i=0; i<=10; i++) {
for (int j=1; i + j <= 10; j++) {
[self.questions addObject:@[@(i), @(j)]];
}
}
[self.questions sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return (arc4random() % 2) == 0;
}];
}
– (void)createCover {
SCNBox *top = [SCNBox boxWithWidth:10 height:2 length:0.1 chamferRadius:0];
top.firstMaterial.diffuse.contents = [UIColor lightGrayColor];
SCNNode *topNode = [SCNNode nodeWithGeometry:top];
topNode.position = SCNVector3Make(0, 3.45, 0);
[self.sceneView.scene.rootNode addChildNode:topNode];
SCNBox *bottom = [SCNBox boxWithWidth:10 height:5 length:0.1 chamferRadius:0];
bottom.firstMaterial.diffuse.contents = [UIColor lightGrayColor];
SCNNode *bottomNode = [SCNNode nodeWithGeometry:bottom];
bottomNode.position = SCNVector3Make(0, –0.95, 0);
[self.sceneView.scene.rootNode addChildNode:bottomNode];
}
– (void)createNumber {
for (int i=0; i<2; i++) {
SCNNode *dial = [self createNumberDial];
dial.position = SCNVector3Make(i==0 ? 1.5 : –1.5, 2, –1.2);
dial.name = [NSString stringWithFormat:@”dial%d”, i];
}
for (int i=0; i<2; i++) {
SCNBox *bar = [SCNBox boxWithWidth:0.2 height:0.8 length:0.2 chamferRadius:0];
bar.firstMaterial.diffuse.contents = [UIColor purpleColor];
SCNNode *barNode = [SCNNode nodeWithGeometry:bar];
barNode.position = SCNVector3Make(0, 2, 0);
if (i==0) barNode.rotation = SCNVector4Make(0, 0, 1, M_PI * 0.5);
[self.sceneView.scene.rootNode addChildNode:barNode];
}
}
– (SCNNode *)createNumberDial {
float r = 1.2;
SCNNode *dial = [SCNNode node];
[self.sceneView.scene.rootNode addChildNode:dial];
float dw = M_PI / 5.5;
for (int i=0; i<=10; i++) {
SCNBox *plate = [SCNBox boxWithWidth:1.2 height:0.8 length:0.1 chamferRadius:0];
plate.firstMaterial.diffuse.contents = [UIColor purpleColor];
SCNNode *plateNode = [SCNNode nodeWithGeometry:plate];
plateNode.pivot = SCNMatrix4MakeTranslation(0, 0, -r);
plateNode.rotation = SCNVector4Make(1, 0, 0, dw * i);
SCNText *n = [SCNText textWithString:[NSString stringWithFormat:@”%d”, i] extrusionDepth:0.12];
n.font = [UIFont systemFontOfSize:0.7];
n.alignmentMode = kCAAlignmentRight;
n.firstMaterial.diffuse.contents = [UIColor whiteColor];
SCNNode *nNode = [SCNNode nodeWithGeometry:n];
SCNVector3 p = SCNVector3Zero;
CGFloat r = 0;
[nNode getBoundingSphereCenter:&p radius:&r];
nNode.pivot = SCNMatrix4MakeTranslation(p.x, p.y, 0);
[plateNode addChildNode:nNode];
[dial addChildNode:plateNode];
}
return dial;
}
– (void)createThreeEachButton {
for (int i=0; i<10; i++) {
float x = (i % 3) * 1 – 1;
float y = 0.5 – (i / 3) * 1 ;
SCNSphere *btn = [SCNSphere sphereWithRadius:0.4];
btn.firstMaterial.diffuse.contents = [UIColor lightGrayColor];
SCNNode *btnNode = [SCNNode nodeWithGeometry:btn];
btnNode.name = [NSString stringWithFormat:@”btn %d”, i + 1];
btnNode.position = SCNVector3Make(x, y, 0);
[self.sceneView.scene.rootNode addChildNode:btnNode];
}
}
– (void)nextQuestion {
NSArray *q = [self.questions lastObject];
[self.questions removeLastObject];
SCNNode *dialR = [self.sceneView.scene.rootNode childNodeWithName:@”dial0″ recursively:NO];
SCNNode *dialL = [self.sceneView.scene.rootNode childNodeWithName:@”dial1″ recursively:NO];
float dw = M_PI / 5.5;
int a = [q[0] intValue];
int b = [q[1] intValue];
[dialR runAction:[SCNAction rotateToX:dw * (11 – a) y:0 z:0 duration:0.6]];
[dialL runAction:[SCNAction rotateToX:dw * (11 – b) y:0 z:0 duration:0.6]];
self.currentAB = q;
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint p = [[touches anyObject] locationInView:self.sceneView];
SCNNode *hit = [[self.sceneView hitTest:p options:@{SCNHitTestSortResultsKey : @YES}].firstObject node];
if ([hit.name hasPrefix:@”btn”]) {
int input = [[hit.name componentsSeparatedByString:@” “][1] intValue];
[self.sceneView.scene.rootNode.childNodes enumerateObjectsUsingBlock:^(SCNNode *b, NSUInteger idx, BOOL *stop) {
if ([b.name hasPrefix:@”btn”]) {
int n = [[b.name componentsSeparatedByString:@” “][1] intValue];
if (n <= input) {
b.geometry.firstMaterial.diffuse.contents = [UIColor orangeColor];
} else {
b.geometry.firstMaterial.diffuse.contents = [UIColor lightGrayColor];
}
}
}];
int ans = [self.currentAB[0] intValue] + [self.currentAB[1] intValue];
if (input == ans) {
[self nextQuestion];
}
}
}
@end