パンチメダルをガンガンとばしてあそぶiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SpriteKit;
@interface PunchScene : SKScene
@property (nonatomic) float value;
@end
@implementation PunchScene
– (void)didMoveToView:(SKView *)view
{
self.backgroundColor = [SKColor colorWithRed:0.7 green:0.7 blue:0.3 alpha:1];
[self createMeter];
[self createBall];
[self createFist];
}
– (void)createMeter
{
SKSpriteNode *meter = [SKSpriteNode spriteNodeWithColor:[SKColor colorWithRed:0 green:0.6 blue:0 alpha:1] size:CGSizeMake(260, 60)];
meter.name = @”meter”;
meter.position = CGPointMake(160, 400);
[self addChild:meter];
meter.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:meter.size];
meter.physicsBody.dynamic = NO;
SKShapeNode *arrow = [SKShapeNode node];
arrow.name = @”arrow”;
arrow.position = CGPointMake(30, meter.position.y);
arrow.fillColor = [SKColor redColor];
[self addChild:arrow];
[self updateArrow];
}
– (void)updateArrow
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, –20)];
[path addLineToPoint:CGPointMake(self.value, –20)];
[path addLineToPoint:CGPointMake(self.value + 10, 0)];
[path addLineToPoint:CGPointMake(self.value, 20)];
[path addLineToPoint:CGPointMake(0, 20)];
[path closePath];
SKShapeNode *arrow = (SKShapeNode *)[self childNodeWithName:@”arrow”];
arrow.path = path.CGPath;
}
– (void)createBall
{
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:60 startAngle:0 endAngle:2.0*M_PI clockwise:NO];
SKShapeNode *ball = [SKShapeNode node];
ball.name = @”ball”;
ball.path = path.CGPath;
ball.fillColor = [SKColor colorWithRed:0.9 green:0 blue:0 alpha:1];
ball.strokeColor = [SKColor colorWithRed:0.8 green:0 blue:0 alpha:1];
ball.position = CGPointMake(160, 200);
[self addChild:ball];
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:60];
ball.physicsBody.density = 0.2;
SKNode *meter = [self childNodeWithName:@”meter”];
SKPhysicsJointLimit *limit = [SKPhysicsJointLimit jointWithBodyA:ball.physicsBody bodyB:meter.physicsBody anchorA:ball.position anchorB:meter.position];
[self.physicsWorld addJoint:limit];
}
– (void)createFist
{
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:20 startAngle:0 endAngle:2.0*M_PI clockwise:NO];
SKShapeNode *fist = [SKShapeNode node];
fist.path = path.CGPath;
fist.name = @”fist”;
fist.position = CGPointMake(160, 50);
fist.strokeColor = [SKColor redColor];
float hue = (arc4random() % 10) * 0.1;
fist.fillColor = [SKColor colorWithHue:hue saturation:0.6 brightness:0.7 alpha:1];
[self addChild:fist];
fist.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:20];
fist.physicsBody.dynamic = NO;
fist.physicsBody.categoryBitMask = 0x1;
fist.physicsBody.collisionBitMask = 0x2;
for (int i=0; i<5; i++) {
CGPoint p = CGPointMake(i * 7 – 18, 2);
CGSize size = CGSizeMake(5, 15);
if (i == 0) {
p = CGPointMake(-4, –10);
size = CGSizeMake(11, 5);
}
SKSpriteNode *finger = [SKSpriteNode spriteNodeWithColor:[[SKColor whiteColor] colorWithAlphaComponent:0.5] size:size];
finger.position = p;
[fist addChild:finger];
}
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
[self enumerateChildNodesWithName:@”fist” usingBlock:^(SKNode *fist, BOOL *stop) {
if ([fist containsPoint:p] && fist.physicsBody.dynamic == NO) {
fist.physicsBody.dynamic = YES;
[fist.physicsBody applyImpulse:CGVectorMake(0, 60)];
[self createFist];
return;
}
}];
}
– (void)update:(NSTimeInterval)currentTime
{
SKNode *ball = [self childNodeWithName:@”ball”];
self.value = MAX(MAX(self.value – 3, 0), ball.physicsBody.velocity.dy / 3.0);
[self updateArrow];
}
– (void)didSimulatePhysics
{
[self enumerateChildNodesWithName:@”fist” usingBlock:^(SKNode *node, BOOL *stop) {
if (node.position.y < 0) {
[node removeFromParent];
}
}];
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[PunchScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
@end