Created
September 2, 2015 14:03
-
-
Save mzsima/20a61894770e1a67316b to your computer and use it in GitHub Desktop.
eraser shot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.m | |
// EraserShot | |
// | |
// Created by MizushimaYusuke on 9/2/15. | |
// Copyright (c) 2015 MizushimaYusuke. All rights reserved. | |
// | |
#import "ViewController.h" | |
@import SceneKit; | |
@interface ViewController () | |
@property (nonatomic, weak) SCNView *sceneView; | |
@end | |
@implementation ViewController | |
- (void)viewDidLoad { | |
[super viewDidLoad]; | |
[self setupScene]; | |
[self createDesk]; | |
[self createEraser]; | |
[self createPurpleShot]; | |
[self createCamera]; | |
} | |
- (void)setupScene { | |
SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds]; | |
sv.scene = [SCNScene scene]; | |
sv.autoenablesDefaultLighting = YES; | |
sv.allowsCameraControl = YES; | |
[self.view addSubview:sv]; | |
self.sceneView = sv; | |
} | |
- (void)createDesk { | |
SCNBox *desk = [SCNBox boxWithWidth:20 height:0.1 length:20 chamferRadius:0]; | |
desk.firstMaterial.diffuse.contents = [self color:1]; | |
SCNNode *deskNode = [SCNNode nodeWithGeometry:desk]; | |
deskNode.name = @"desk"; | |
deskNode.physicsBody = [SCNPhysicsBody staticBody]; | |
[self.sceneView.scene.rootNode addChildNode:deskNode]; | |
} | |
- (void)createEraser { | |
SCNNode *eraser = [SCNNode node]; | |
eraser.name = @"eraser"; | |
SCNBox *partA = [SCNBox boxWithWidth:0.5 height:0.5 length:2 chamferRadius:0]; | |
partA.firstMaterial.diffuse.contents = [self color:0]; | |
SCNNode *partANode = [SCNNode nodeWithGeometry:partA]; | |
partANode.position = SCNVector3Make(0.5, 0, 0); | |
[eraser addChildNode:partANode]; | |
SCNBox *partB = [SCNBox boxWithWidth:1.45 height:0.49 length:2.6 chamferRadius:0]; | |
partB.firstMaterial.diffuse.contents = [self color:2]; | |
SCNNode *partBNode = [SCNNode nodeWithGeometry:partB]; | |
partBNode.position = SCNVector3Make(0, 0, 0.31); | |
[eraser addChildNode:partBNode]; | |
SCNBox *partC = [SCNBox boxWithWidth:0.5 height:0.5 length:2 chamferRadius:0]; | |
partC.firstMaterial.diffuse.contents = [self color:3]; | |
SCNNode *partCNode = [SCNNode nodeWithGeometry:partC]; | |
partCNode.position = SCNVector3Make(-0.5, 0, 0); | |
[eraser addChildNode:partCNode]; | |
eraser.position = SCNVector3Make(0, 1, 0); | |
eraser.physicsBody = [SCNPhysicsBody dynamicBody]; | |
[self.sceneView.scene.rootNode addChildNode:eraser]; | |
} | |
- (void)createPurpleShot { | |
SCNNode *shot = [SCNNode node]; | |
shot.name = @"shot"; | |
SCNBox *partA = [SCNBox boxWithWidth:1 height:0.4 length:0.6 chamferRadius:0]; | |
partA.firstMaterial.diffuse.contents = [self color:4]; | |
SCNNode *partANode = [SCNNode nodeWithGeometry:partA]; | |
partANode.position = SCNVector3Make(0, 0, 0.2); | |
partANode.name = @"shotbody"; | |
[shot addChildNode:partANode]; | |
SCNBox *partB = [SCNBox boxWithWidth:0.4 height:0.4 length:1 chamferRadius:0]; | |
partB.firstMaterial.diffuse.contents = [self color:4]; | |
SCNNode *partBNode = [SCNNode nodeWithGeometry:partB]; | |
partBNode.name = @"shotbody"; | |
[shot addChildNode:partBNode]; | |
shot.position = SCNVector3Make(0, 0.3, 3); | |
[self.sceneView.scene.rootNode addChildNode:shot]; | |
SCNNode *eraser = [self.sceneView.scene.rootNode childNodeWithName:@"eraser" recursively:NO]; | |
SCNLookAtConstraint *lc = [SCNLookAtConstraint lookAtConstraintWithTarget:eraser]; | |
lc.gimbalLockEnabled = YES; | |
shot.constraints = @[lc]; | |
} | |
- (void)createCamera { | |
SCNNode *camera = [SCNNode node]; | |
camera.camera = [SCNCamera camera]; | |
camera.position = SCNVector3Make(0, 10, 20); | |
camera.rotation = SCNVector4Make(1, 0, 0, -0.5); | |
[self.sceneView.scene.rootNode addChildNode:camera]; | |
} | |
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { | |
CGPoint p = [[touches anyObject] locationInView:self.sceneView]; | |
SCNHitTestResult *hit = [self.sceneView hitTest:p options:@{SCNHitTestSortResultsKey : @YES}].firstObject; | |
if (hit) { | |
SCNNode *shot = [self.sceneView.scene.rootNode childNodeWithName:@"shot" recursively:NO]; | |
if ([hit.node.name isEqual:@"desk"]) { | |
shot.position = SCNVector3Make(hit.worldCoordinates.x, hit.worldCoordinates.y + 0.25, hit.worldCoordinates.z); | |
} else if ([hit.node.name isEqual:@"shotbody"]) { | |
SCNNode *eraser = [self.sceneView.scene.rootNode childNodeWithName:@"eraser" recursively:NO]; | |
SCNBox *b = [SCNBox boxWithWidth:0.5 height:0.5 length:0.5 chamferRadius:0.1]; | |
b.firstMaterial.diffuse.contents = [self color:2]; | |
SCNNode *bNode = [SCNNode nodeWithGeometry:b]; | |
bNode.position = shot.position; | |
bNode.physicsBody = [SCNPhysicsBody dynamicBody]; | |
[self.sceneView.scene.rootNode addChildNode:bNode]; | |
float dx = eraser.presentationNode.position.x - shot.presentationNode.position.x; | |
float dz = eraser.presentationNode.position.z - shot.presentationNode.position.z; | |
float u = sqrt(pow(dx, 2) + pow(dz, 2)); | |
[bNode.physicsBody applyForce:SCNVector3Make(10 * dx / u, 0, 10 * dz / u) 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.0] | |
- (UIColor *)color:(int)i { | |
if (i > 4) return nil; | |
int code[] = {0x0F0F0D, 0xA3969D, 0xFEFEFE, 0x1B286C, 0x8E1E9C}; | |
return ColorHex(code[i]); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment