
くねくねしているピンを何個はじき飛ばせるか!というIPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SpriteKit;
@interface BowlingScene : SKScene <SKPhysicsContactDelegate>
@property (nonatomic) uint8_t move;
@property (nonatomic, weak) SKNode *selected;
@property (nonatomic) CGPoint start;
@end
@implementation BowlingScene
– (void)didMoveToView:(SKView *)view
{
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
self.physicsBody.categoryBitMask = 0x1 << 3;
self.physicsWorld.gravity = CGVectorMake(0, 0);
self.physicsWorld.contactDelegate = self;
[self createLabel];
[self createPin];
[self createBall];
}
– (void)createPin
{
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(-10, –4, 20, 8)];
SKNode *tmp;
for (int i=0; i<30; i++) {
float x = CGRectGetMidX(self.frame);
float y = CGRectGetMaxY(self.frame) – i * 15 – 30;
SKShapeNode *p = [SKShapeNode node];
p.name = (i == 0) ? @”topPin” : @”pin”;
p.position = CGPointMake(x, y);
p.path = path.CGPath;
p.fillColor = [SKColor clearColor];
p.strokeColor = [SKColor yellowColor];
p.lineWidth = 3;
[self addChild:p];
p.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(20, 8)];
p.physicsBody.density = 0.05;
p.physicsBody.categoryBitMask = 0x1 << 1;
p.physicsBody.contactTestBitMask = 0x1 << 1;
SKPhysicsJointSliding *sl = [SKPhysicsJointSliding jointWithBodyA:p.physicsBody bodyB:self.physicsBody anchor:p.position axis:CGVectorMake(1, 0)];
[self.physicsWorld addJoint:sl];
if (tmp) {
SKPhysicsJointSpring *spring = [SKPhysicsJointSpring jointWithBodyA:p.physicsBody bodyB:tmp.physicsBody anchorA:p.position anchorB:tmp.position];
spring.frequency = 0.7;
spring.damping = 1.0;
[self.physicsWorld addJoint:spring];
}
tmp = p;
}
}
– (void)createBall
{
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:15 startAngle:0 endAngle:2.0*M_PI clockwise:NO];
SKShapeNode *ball = [SKShapeNode node];
ball.name = @”ball”;
ball.path = path.CGPath;
ball.position = CGPointMake(CGRectGetMidX(self.frame), 60);
ball.lineWidth = 8;
[self addChild:ball];
}
– (void)createLabel {
SKLabelNode *score = [SKLabelNode node];
score.name = @”score”;
score.text = @”00″;
score.fontColor = [[SKColor whiteColor] colorWithAlphaComponent:0.2];
score.fontSize = 200;
score.position = CGPointMake(160, 300);
[self addChild:score];
}
– (void)update:(NSTimeInterval)currentTime
{
SKNode *pin = [self childNodeWithName:@”topPin”];
if (self.move == 1) {
pin.physicsBody.velocity = CGVectorMake(60, 0);
if (pin.position.x > 300) self.move = 0;
} else {
pin.physicsBody.velocity = CGVectorMake(-60, 0);
if (pin.position.x < 20) self.move = 1;
}
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
SKNode *hit = [self nodeAtPoint:p];
if ([hit.name isEqual:@”ball”]) {
self.selected = hit;
self.start = p;
}
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
self.selected.position = p;
SKShapeNode *guide = (SKShapeNode *)[self childNodeWithName:@”guide”];
if (!guide) {
guide = [SKShapeNode node];
guide.name = @”guide”;
guide.strokeColor = [SKColor purpleColor];
guide.lineWidth = 2;
[self addChild:guide];
}
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.start radius:4 startAngle:0 endAngle:2.0*M_PI clockwise:YES];
[path moveToPoint:self.start];
[path addLineToPoint:p];
guide.path = path.CGPath;
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
CGVector v = CGVectorMake(self.start.x – p.x, self.start.y – p.y);
// v = CGVectorMake(10.0 * v.dx, 10.0 * v.dy);
// ball physicsBody
self.selected.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:13];
self.selected.physicsBody.density = 10.0;
self.selected.physicsBody.categoryBitMask = 0x1 << 2;
self.selected.physicsBody.contactTestBitMask = 0x1 << 1;
[self.selected.physicsBody applyImpulse:v];
self.selected = nil;
}
– (void)didBeginContact:(SKPhysicsContact *)contact
{
if ([contact.bodyA.node.name isEqualToString:@”pin”]) {
[contact.bodyA.joints enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[self.physicsWorld removeJoint:obj];
}];
SKLabelNode *score = (SKLabelNode *)[self childNodeWithName:@”score”];
score.text = [NSString stringWithFormat:@”%d”, [score.text intValue] + 1];
}
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[BowlingScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
@end