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