棒の端っこにジャンプするパネルをつけてボールを上に飛ばしていくiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SpriteKit;
@interface ViewController () <SKPhysicsContactDelegate>
@property (nonatomic) SKScene *scene;
@property (nonatomic) BOOL jumping;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
[self setupScene];
[self createBar];
[self createBall];
}
– (void)setupScene {
SKView *sv = [[SKView alloc] initWithFrame:self.view.bounds];
SKScene *s = [SKScene sceneWithSize:sv.frame.size];
s.physicsWorld.contactDelegate = self;
s.backgroundColor = [UIColor colorWithHue:0 saturation:0.1 brightness:1 alpha:1];
[sv presentScene:s];
[self.view addSubview:sv];
self.scene = s;
}
– (void)createBar {
for (int i=0; i<4; i++) {
SKSpriteNode *bar = [SKSpriteNode spriteNodeWithColor:[UIColor brownColor] size:CGSizeMake(CGRectGetMaxX(self.view.bounds) * 0.7, 10)];
bar.position = CGPointMake(CGRectGetMidX(self.view.bounds) + ((i%2 == 0) ? 50 : –50), i * 80 + 20);
bar.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bar.frame.size];
bar.physicsBody.dynamic = NO;
[self.scene addChild:bar];
SKSpriteNode *jumpPanel = [SKSpriteNode spriteNodeWithColor:[UIColor grayColor] size:CGSizeMake(40, 20)];
jumpPanel.name = [NSString stringWithFormat:@”jump %d”, i];
jumpPanel.anchorPoint = CGPointMake((i%2) ? 1 : 0, 1);
jumpPanel.position = CGPointMake((i%2) ? CGRectGetMinX(bar.frame) + 40 : CGRectGetMaxX(bar.frame) – 40, bar.position.y + 5.01);
jumpPanel.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:jumpPanel.frame.size center:CGPointMake((i%2) ? –20 : 20, –10)];
jumpPanel.physicsBody.categoryBitMask = 0x1 << 1;
jumpPanel.physicsBody.contactTestBitMask = 0x1 << 2;
[self.scene addChild:jumpPanel];
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:jumpPanel.physicsBody bodyB:bar.physicsBody anchor:jumpPanel.position];
if (i % 2 == 0) {
pin.lowerAngleLimit = –0.3;
pin.upperAngleLimit = 0;
} else {
pin.lowerAngleLimit = 0;
pin.upperAngleLimit = 0.3;
}
pin.shouldEnableLimits = YES;
[self.scene.physicsWorld addJoint:pin];
}
}
– (void)createBall {
SKShapeNode *ball = [SKShapeNode shapeNodeWithCircleOfRadius:10];
ball.name = @”ball”;
ball.fillColor = [UIColor redColor];
ball.position = CGPointMake(CGRectGetMidX(self.view.bounds), 50);
[self.scene addChild:ball];
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
ball.physicsBody.density = 3.0;
ball.physicsBody.categoryBitMask = 0x1 << 2;
ball.physicsBody.friction = 0;
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
SKNode *ball = [self.scene childNodeWithName:@”ball”];
[ball.physicsBody applyForce:CGVectorMake(200, 0)];
}
– (void)didBeginContact:(SKPhysicsContact *)contact {
if (self.jumping) {
return;
}
self.jumping = YES;
SKPhysicsBody *jumppanel;
SKPhysicsBody *ball;
if ([contact.bodyA.node.name hasPrefix:@”jump”]) {
jumppanel = contact.bodyA;
ball = contact.bodyB;
} else if ([contact.bodyB.node.name hasPrefix:@”jump”]) {
jumppanel = contact.bodyB;
ball = contact.bodyA;
}
if (jumppanel != nil) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.02 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
int num = [[jumppanel.node.name componentsSeparatedByString:@” “][1] intValue];
if (num % 2 == 0) {
[ball applyImpulse:CGVectorMake(-25, 30)];
[jumppanel applyImpulse:CGVectorMake(0, –5) atPoint:CGPointMake(10, 0)];
} else {
[ball applyImpulse:CGVectorMake(25, 30)];
[jumppanel applyImpulse:CGVectorMake(0, 5) atPoint:CGPointMake(-10, 0)];
}
});
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.jumping = NO;
});
}
@end