今日のiPhoneアプリのサンプルコードは空中ブランコをする四角形。
動かすとこんな感じです
サンプルコード
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
@interface TrapezeScene : SKScene <SKPhysicsContactDelegate>
@property BOOL contentCreated;
@property (nonatomic, weak) SKShapeNode *ropeLayer;
@property (nonatomic, weak) SKNode *currentNode;
@end
@implementation TrapezeScene
– (void)didMoveToView:(SKView *)view
{
if (!self.contentCreated) {
[self createSceneContents];
self.contentCreated = YES;
}
}
– (void)createSceneContents
{
self.physicsWorld.contactDelegate = self;
[self createPin];
[self createJumper];
[self createButtons];
}
– (void)createPin
{
UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-5, –5, 10, 10)];
float p[] = {80, 160, 250, 300, 80, 450};
for (int i=0; i<sizeof(p)/(2*sizeof(float)); i++) {
float x = p[2*i];
float y = p[2*i+1];
SKShapeNode *pin = [SKShapeNode node];
pin.name = @”pin”;
pin.path = circle.CGPath;
pin.position = CGPointMake(x, y);
[self addChild:pin];
pin.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:5];
pin.physicsBody.dynamic = NO;
SKSpriteNode *node = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(5, 5)];
node.name = [NSString stringWithFormat:@”node%d”, i];
node.position = CGPointMake(x, y – 80);
node.zPosition = 2;
[self addChild:node];
node.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:node.size];
node.physicsBody.categoryBitMask = 0x1 << 2;
node.physicsBody.contactTestBitMask = 0x1 << 1;
SKPhysicsJointLimit *rope = [SKPhysicsJointLimit jointWithBodyA:pin.physicsBody bodyB:node.physicsBody anchorA:pin.position anchorB:node.position];
[self.physicsWorld addJoint:rope];
}
}
– (void)createJumper
{
SKNode *startNode = [self childNodeWithName:@”node0″];
self.currentNode = startNode;
SKSpriteNode *jumper = [SKSpriteNode spriteNodeWithColor:[SKColor orangeColor] size:CGSizeMake(30, 30)];
jumper.name = @”jumper”;
jumper.position = CGPointMake(startNode.position.x, startNode.position.y);
jumper.zPosition = 1;
[self addChild:jumper];
jumper.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:jumper.size];
jumper.physicsBody.linearDamping = 1.0;
jumper.physicsBody.angularDamping = 1.0;
jumper.physicsBody.categoryBitMask = 0x1 << 1;
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:jumper.physicsBody bodyB:startNode.physicsBody anchor:startNode.position];
[self.physicsWorld addJoint:pin];
}
– (void)createButtons
{
SKSpriteNode *btn1 = [SKSpriteNode spriteNodeWithColor:[SKColor lightGrayColor] size:CGSizeMake(40, 40)];
btn1.name = @”btn1″;
btn1.position = CGPointMake(240, 20);
[self addChild:btn1];
SKSpriteNode *btn2 = [SKSpriteNode spriteNodeWithColor:[SKColor lightGrayColor] size:CGSizeMake(40, 40)];
btn2.name = @”btn2″;
btn2.position = CGPointMake(290, 20);
[self addChild:btn2];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
SKNode *btn1 = [self childNodeWithName:@”btn1″];
SKNode *btn2 = [self childNodeWithName:@”btn2″];
SKNode *jumper = [self childNodeWithName:@”jumper”];
CGPoint p = [[touches anyObject] locationInNode:self];
if ([btn1 containsPoint:p]) {
// move
[jumper.physicsBody applyImpulse:CGVectorMake(30, 0)];
} else if ([btn2 containsPoint:p]) {
// detach
[jumper.physicsBody.joints enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[self.physicsWorld removeJoint:obj];
}];
[jumper.physicsBody applyImpulse:CGVectorMake(0, 20)];
}
}
– (void)didSimulatePhysics
{
SKNode *jumper = [self childNodeWithName:@”jumper”];
if (jumper.position.y < –20) {
[jumper removeFromParent];
[self createJumper];
}
if (!self.ropeLayer) {
self.ropeLayer = [SKShapeNode node];
[self addChild:self.ropeLayer];
}
UIBezierPath *path = [UIBezierPath bezierPath];
[self enumerateChildNodesWithName:@”pin” usingBlock:^(SKNode *pin, BOOL *stop) {
[path moveToPoint:pin.position];
SKPhysicsJoint *joint = pin.physicsBody.joints[0];
[path addLineToPoint:joint.bodyB.node.position];
}];
self.ropeLayer.path = path.CGPath;
}
– (void)didBeginContact:(SKPhysicsContact *)contact
{
SKNode *jumper, *node;
if (contact.bodyA.categoryBitMask == 0x1<<1) {
jumper = contact.bodyA.node;
node = contact.bodyB.node;
} else if (contact.bodyA.categoryBitMask == 0x1<<2) {
jumper = contact.bodyB.node;
node = contact.bodyA.node;
}
if (node != self.currentNode) {
self.currentNode = node;
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:jumper.physicsBody bodyB:node.physicsBody anchor:contact.contactPoint];
[self.physicsWorld addJoint:pin];
}
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidAppear:(BOOL)animated
{
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[TrapezeScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
@end