
Viewを引っ張るとびよびよするようなiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SpriteKit;
@interface ViewController () <SKSceneDelegate>
@property (nonatomic, weak) SKView *spriteView;
@property (nonatomic, weak) UIView *gumView;
@property (nonatomic, weak) SKNode *touched;
@property (nonatomic) CGPoint touchPoint;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [self color:0];
[self createGumView];
}
– (void)createGumView {
UIView *baseView = [[UIView alloc] initWithFrame:self.view.bounds];
baseView.backgroundColor = [self color:1];
baseView.center = CGPointMake(CGRectGetMidX(self.view.bounds), –CGRectGetMaxY(self.view.bounds) * 0.2);
baseView.layer.masksToBounds = NO;
[self.view addSubview:baseView];
self.gumView = baseView;
SKView *sv = [[SKView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.view.bounds) – 200, CGRectGetMaxX(self.view.bounds), 400)];
sv.allowsTransparency = YES;
[baseView addSubview:sv];
SKScene *scene = [SKScene sceneWithSize:sv.frame.size];
scene.backgroundColor = [UIColor clearColor];
scene.physicsWorld.gravity = CGVectorMake(0, 0);
scene.delegate = self;
[sv presentScene:scene];
self.spriteView = sv;
float dx = CGRectGetMaxX(self.view.bounds) / 20.0;
SKNode *previous = nil;
for (int i=0; i<20; i++) {
SKShapeNode *n = [SKShapeNode shapeNodeWithCircleOfRadius:dx/2.0];
n.name = @”myobj”;
n.fillColor = [[self color:2] colorWithAlphaComponent:0.5];
n.strokeColor = [self color:4];
n.position = CGPointMake((i + 0.5) * dx, 200);
[scene addChild:n];
n.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:dx/2.0];
SKSpriteNode *anchorNode = [SKSpriteNode spriteNodeWithColor:[UIColor clearColor] size:CGSizeMake(1, 1)];
anchorNode.position = CGPointMake(n.position.x, n.position.y + 100);
[scene addChild:anchorNode];
anchorNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:anchorNode.size];
anchorNode.physicsBody.dynamic = NO;
SKPhysicsJointSpring *sp = [SKPhysicsJointSpring jointWithBodyA:n.physicsBody bodyB:anchorNode.physicsBody anchorA:n.position anchorB:anchorNode.position];
sp.frequency = 3;
sp.damping = 0.1;
[scene.physicsWorld addJoint:sp];
if (previous) {
SKPhysicsJointSpring *sp2 = [SKPhysicsJointSpring jointWithBodyA:n.physicsBody bodyB:previous.physicsBody anchorA:n.position anchorB:previous.position];
[scene.physicsWorld addJoint:sp2];
}
// light (left) side -> stop
if (i==0 || i==19) {
n.name = @””;
n.physicsBody.dynamic = NO;
}
previous = n;
}
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self.spriteView.scene];
SKNode *node = [self.spriteView.scene nodeAtPoint:p];
if ([node.name isEqual:@”myobj”]) {
self.touched = node;
node.physicsBody.dynamic = NO;
self.touchPoint = [[touches anyObject] locationInView:self.view];
}
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self.spriteView.scene];
if (self.touched) {
self.touched.position = p;
self.touchPoint = [[touches anyObject] locationInView:self.view];
}
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.touched) {
self.touched.physicsBody.dynamic = YES;
self.touched = nil;
}
}
– (void)update:(NSTimeInterval)currentTime forScene:(SKScene *)scene
{
__block float lasty = 0;
[scene enumerateChildNodesWithName:@”myobj” usingBlock:^(SKNode *node, BOOL *stop) {
lasty = node.position.y;
}];
CGPoint p = [scene.view convertPoint:CGPointMake(0, lasty) fromScene:scene];
p = [self.view convertPoint:p fromView:scene.view];
self.gumView.layer.position = CGPointMake(CGRectGetMidX(self.view.bounds), p.y – CGRectGetMidY(self.view.bounds));
if (self.touched) {
CGPoint tp = [self.view convertPoint:self.touchPoint toView:scene.view];
tp = [scene.view convertPoint:tp toScene:scene];
self.touched.position = tp;
}
}
#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(0xFF5335);
case 1: return ColorHex(0xB29C85);
case 2: return ColorHex(0x306E73);
case 3: return ColorHex(0x3B424C);
case 4: return ColorHex(0x1D181F);
}
return nil;
}
@end