
板から丸と三角を抜き出すような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 createBoard];
[self createCamera];
[self createLight];
}
– (void)setupScene {
float w = CGRectGetMaxX(self.view.bounds);
SCNView *sceneView = [[SCNView alloc] initWithFrame:CGRectMake(0, 0, w, w)];
sceneView.scene = [SCNScene scene];
sceneView.backgroundColor = [self color:4];
[self.view addSubview:sceneView];
self.sceneView = sceneView;
}
– (void)createBoard {
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:8 startAngle:0 endAngle:2.0 * M_PI clockwise:NO];
UIBezierPath *triangle = nil;
CGPoint o = CGPointZero;
for (int i=0; i<3; i++) {
float angle = (2.0 * M_PI / 3.0) * i;
float x = 8 * cos(angle) + o.x;
float y = 8 * sin(angle) + o.y;
if (!triangle) {
triangle = [UIBezierPath bezierPath];
[triangle moveToPoint:CGPointMake(x, y)];
}
[triangle addLineToPoint:CGPointMake(x, y)];
}
[triangle closePath];
UIBezierPath *board = [UIBezierPath bezierPathWithRect:CGRectMake(-20, –30, 40, 60)];
board.usesEvenOddFillRule = YES;
[board appendPath:circlePath];
CGAffineTransform translation = CGAffineTransformMakeTranslation(10, 20);
CGPathRef movedTrianglePath = CGPathCreateCopyByTransformingPath(triangle.CGPath, &translation);
[board appendPath:[UIBezierPath bezierPathWithCGPath:movedTrianglePath]];
SCNShape *base = [SCNShape shapeWithPath:board extrusionDepth:5.0];
base.firstMaterial.diffuse.contents = [self color:1];
SCNNode *baseNode = [SCNNode nodeWithGeometry:base];
baseNode.physicsBody = [SCNPhysicsBody staticBody];
baseNode.physicsBody.physicsShape = [SCNPhysicsShape shapeWithGeometry:base options:@{SCNPhysicsShapeTypeKey : SCNPhysicsShapeTypeConcavePolyhedron}];
[self.sceneView.scene.rootNode addChildNode:baseNode];
SCNShape *circle = [SCNShape shapeWithPath:circlePath extrusionDepth:5.0];
circle.firstMaterial.diffuse.contents = [self color:2];
SCNNode *circleNode = [SCNNode nodeWithGeometry:circle];
circleNode.name = @”shape”;
circleNode.transform = SCNMatrix4MakeScale(0.99, 0.99, 1.0);
circleNode.physicsBody = [SCNPhysicsBody staticBody];
[self.sceneView.scene.rootNode addChildNode:circleNode];
SCNShape *tri = [SCNShape shapeWithPath:triangle extrusionDepth:5.0];
tri.firstMaterial.diffuse.contents = [self color:3];
SCNNode *triNode = [SCNNode nodeWithGeometry:tri];
triNode.name = @”shape”;
triNode.transform = SCNMatrix4MakeScale(0.99, 0.99, 1.0);
triNode.transform = SCNMatrix4Translate(triNode.transform, 10, 20, 0);
triNode.physicsBody = [SCNPhysicsBody staticBody];
[self.sceneView.scene.rootNode addChildNode:triNode];
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.camera = [SCNCamera camera];
camera.position = SCNVector3Make(20, 0, 80);
[self.sceneView.scene.rootNode addChildNode:camera];
camera.rotation = SCNVector4Make(0, 1, 0, 0.1);
}
– (void)createLight {
SCNLight *light = [SCNLight light];
light.type = SCNLightTypeOmni;
SCNNode *lightNode = [SCNNode node];
lightNode.light = light;
lightNode.position = SCNVector3Make(0, 0, 50);
[self.sceneView.scene.rootNode addChildNode:lightNode];
}
– (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) {
SCNHitTestResult *hit = hits.firstObject;
if ([hit.node.name isEqual:@”shape”]) {
hit.node.physicsBody = [SCNPhysicsBody dynamicBody];
[hit.node.physicsBody applyForce:SCNVector3Make(0, 0, 5) atPosition:SCNVector3Make(0, 3, 0) impulse:YES];
}
}
}
#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 {
switch (i) {
case 0: return ColorHex(0x0E0E0E);
case 1: return ColorHex(0x263248);
case 2: return ColorHex(0x7E8AA2);
case 3: return ColorHex(0xFAFAFA);
case 4: return ColorHex(0xFF9800);
default:
break;
}
return nil;
}
@end