
3Dの輪投げ、iPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@interface ViewController ()
@property (nonatomic, weak) SCNScene *scenen;
@property (nonatomic, weak) UIView *direction;
@property (nonatomic, weak) UIView *power;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithHue:0.6 saturation:0.05 brightness:1 alpha:1];
[self setupScene];
[self createPole];
[self createCamera];
[self createUI];
}
– (void)setupScene {
float w = CGRectGetMaxX(self.view.bounds);
SCNView *sceneView = [[SCNView alloc] initWithFrame:CGRectMake(0, 0, w, w)];
sceneView.backgroundColor = [UIColor colorWithHue:0.15 saturation:0.8 brightness:1 alpha:1];
sceneView.scene = [SCNScene scene];
[self.view addSubview:sceneView];
self.scenen = sceneView.scene;
}
– (void)createPole {
SCNBox *box = [SCNBox boxWithWidth:20 height:1 length:20 chamferRadius:0];
box.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.25 saturation:0.6 brightness:0.6 alpha:1];
SCNNode *boxNode = [SCNNode nodeWithGeometry:box];
[self.scenen.rootNode addChildNode:boxNode];
boxNode.physicsBody = [SCNPhysicsBody staticBody];
boxNode.physicsBody.friction = 1.0;
SCNCylinder *pole = [SCNCylinder cylinderWithRadius:1 height:5];
pole.firstMaterial.diffuse.contents = [UIColor colorWithHue:0.4 saturation:0.6 brightness:0.8 alpha:1];
SCNNode *poleNode = [SCNNode nodeWithGeometry:pole];
poleNode.position = SCNVector3Make(0, 3, 0);
[self.scenen.rootNode addChildNode:poleNode];
poleNode.physicsBody = [SCNPhysicsBody staticBody];
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.camera = [SCNCamera camera];
camera.position = SCNVector3Make(0, 10, 40);
[self.scenen.rootNode addChildNode:camera];
}
– (void)createUI {
UIView *direction = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
direction.layer.cornerRadius = 40;
direction.backgroundColor = [UIColor colorWithHue:0.4 saturation:0.7 brightness:1 alpha:1];
direction.center = CGPointMake(CGRectGetMaxX(self.view.bounds)/4.0, CGRectGetMaxX(self.view.bounds) + 80);
[self.view addSubview:direction];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(-30, –10)];
[path addLineToPoint:CGPointMake(0, –30)];
[path addLineToPoint:CGPointMake(30, –10)];
[path closePath];
[path appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(-5, –10, 10, 50)]];
CAShapeLayer *arrow = [CAShapeLayer layer];
arrow.path = path.CGPath;
arrow.fillColor = [UIColor whiteColor].CGColor;
arrow.position = CGPointMake(40, 40);
[direction.layer addSublayer:arrow];
self.direction = direction;
UIView *power = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 120)];
power.center = CGPointMake(CGRectGetMaxX(self.view.bounds) * 3.0 / 4.0, CGRectGetMaxX(self.view.bounds) + 80);
[self.view addSubview:power];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = power.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor redColor] CGColor], (id)[[UIColor greenColor] CGColor], nil];
[power.layer insertSublayer:gradient atIndex:0];
self.power = power;
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInView:self.view];
if (CGRectContainsPoint(self.direction.frame, p)) {
self.direction.transform = CGAffineTransformRotate(self.direction.transform, M_PI/10.0);
} else if (CGRectContainsPoint(self.power.frame, p)) {
float level = (120 – [[touches anyObject] locationInView:self.power].y) * 0.2;
float angle = [[self.direction.layer valueForKeyPath:@”transform.rotation.z”] floatValue] – M_PI/2.0;
SCNTorus *ring = [SCNTorus torusWithRingRadius:4 pipeRadius:0.3];
ring.firstMaterial.diffuse.contents = [UIColor redColor];
SCNNode *ringNode = [SCNNode nodeWithGeometry:ring];
ringNode.position = SCNVector3Make(0, 0, 30);
[self.scenen.rootNode addChildNode:ringNode];
ringNode.physicsBody = [SCNPhysicsBody dynamicBody];
NSMutableArray *arr = [NSMutableArray array];
NSMutableArray *transforms = [NSMutableArray array];
for (int i=0; i<10; i++) {
SCNBox *boxRing = [SCNBox boxWithWidth:2 height:0.6 length:0.6 chamferRadius:0];
[arr addObject:[SCNPhysicsShape shapeWithGeometry:boxRing options:@{SCNPhysicsShapeTypeKey : SCNPhysicsShapeTypeBoundingBox, SCNPhysicsShapeKeepAsCompoundKey : @YES}]];
float angle = i * M_PI / 5.0;
[transforms addObject:[NSValue valueWithSCNMatrix4:SCNMatrix4MakeTranslation(4.0 * cos(angle), 0, 4.0 * sin(angle))]];
}
ringNode.physicsBody.physicsShape = [SCNPhysicsShape shapeWithShapes:arr transforms:transforms];
float x = cos(angle) * level;
float z = sin(angle) * level;
[ringNode.physicsBody applyForce:SCNVector3Make(x, 15, z) impulse:YES];
}
}
@end