色をつけた点をジョイントで結んでプラプラさせて遊ぶiPhoneアプリのサンプルコードを描いてみます。
動かすとこんなんです。
サンプルコード
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
@interface JointScene : SKScene
@property (nonatomic, weak) SKNode *selected;
@end
@implementation JointScene
– (void)didMoveToView:(SKView *)view
{
[self createSceneContents];
}
– (void)createSceneContents
{
[self createWall];
[self createNodes];
[self createJoints];
}
– (void)createWall
{
SKSpriteNode *wall = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:self.size];
wall.name = @”wall”;
[self addChild:wall];
wall.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
}
– (void)createNodes
{
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-5, –5, 10, 10)];
for (int i=0; i< 100; i++) {
SKShapeNode *n = [SKShapeNode node];
n.path = path.CGPath;
float x = (i % 10) * 20 + 60;
float y = (i / 10) * 20 + 100;
n.position = CGPointMake(x, y);
n.name = [@(i) stringValue];
n.strokeColor = [SKColor colorWithHue:i/100.0 saturation:0.7 brightness:1.0 alpha:1];
n.fillColor = n.strokeColor;
[self addChild:n];
n.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
}
}
– (void)createJoints
{
for (int i=0; i< 90; i++) {
// horizontal
int index = (i % 9) + (i / 9) * 10;
SKNode *na = [self childNodeWithName:[@(index) stringValue]];
SKNode *nb = [self childNodeWithName:[@(index + 1) stringValue]];
SKPhysicsJointSpring *spring = [SKPhysicsJointSpring jointWithBodyA:na.physicsBody bodyB:nb.physicsBody anchorA:na.position anchorB:nb.position];
[self.physicsWorld addJoint:spring];
SKPhysicsJointSpring *l = [SKPhysicsJointSpring jointWithBodyA:na.physicsBody bodyB:nb.physicsBody anchorA:na.position anchorB:nb.position];
l.frequency = 10000;
[self.physicsWorld addJoint:l];
// vertical
int vindex = (i % 10) + (i / 10) * 10;
SKNode *vna = [self childNodeWithName:[@(vindex) stringValue]];
SKNode *vnb = [self childNodeWithName:[@(vindex + 10) stringValue]];
SKPhysicsJointSpring *vspring = [SKPhysicsJointSpring jointWithBodyA:vna.physicsBody bodyB:vnb.physicsBody anchorA:vna.position anchorB:vnb.position];
[self.physicsWorld addJoint:vspring];
SKPhysicsJointSpring *vl = [SKPhysicsJointSpring jointWithBodyA:vna.physicsBody bodyB:vnb.physicsBody anchorA:vna.position anchorB:vnb.position];
vl.frequency = 10000;
[self.physicsWorld addJoint:vl];
}
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
SKNode *wall = [self childNodeWithName:@”wall”];
[self.children enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (obj != wall && [obj containsPoint:p]) {
self.selected = obj;
self.selected.physicsBody.dynamic = NO;
}
}];
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
SKAction *move = [SKAction moveTo:p duration:0.01];
[self.selected runAction:move];
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
self.selected.physicsBody.dynamic = YES;
self.selected = nil;
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[JointScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end