シンプルな「わなげ」であそぶiPhoneゲームのサンプルコードを描いてみます。
サンプルを動かすとこんな感じです
サンプルコード
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
typedef enum int8_t {
RingHoleCategory = 0x1 << 1,
RingEdgeCategory = 0x1 << 2,
PoleCategory = 0x1 << 3,
OtherCategory = 0x1 <<4,
} ObjectCategory;
@interface QuoitsScene : SKScene
@property BOOL contentCreated;
@property BOOL ready;
@property CGPoint lastPoint;
@end
@implementation QuoitsScene
– (void)didMoveToView:(SKView *)view
{
if (!self.contentCreated) {
[self createSceneContents];
self.contentCreated = YES;
}
}
– (void)createSceneContents
{
[self createGround];
[self createRing];
[self createPole];
}
– (void)createGround
{
SKSpriteNode *ground = [SKSpriteNode spriteNodeWithColor:[SKColor brownColor] size:CGSizeMake(CGRectGetMaxX(self.frame), 10)];
ground.position = CGPointMake(CGRectGetMidX(self.frame), 10);
[self addChild:ground];
ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ground.size];
ground.physicsBody.dynamic = NO;
ground.physicsBody.categoryBitMask = OtherCategory;
}
– (void)createRing
{
UIBezierPath *ringPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-40, –10, 80, 20)];
SKShapeNode *ring = [SKShapeNode node];
ring.name = @”ring”;
ring.path = ringPath.CGPath;
ring.strokeColor = [SKColor redColor];
ring.lineWidth = 6;
ring.position = CGPointMake(50, CGRectGetMidY(self.frame));
[self addChild:ring];
SKAction *up = [SKAction moveToY:CGRectGetMaxY(self.frame)*0.9 duration:2.0];
SKAction *down = [SKAction moveToY:CGRectGetMaxY(self.frame)*0.1 duration:2.0];
[ring runAction:[SKAction repeatActionForever:[SKAction sequence:@[up, down]]]];
self.ready = YES;
}
– (void)createPole
{
SKSpriteNode *pole = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(10, 80)];
pole.position = CGPointMake(CGRectGetMaxX(self.frame) * 0.8, 50);
[self addChild:pole];
pole.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:pole.size];
pole.physicsBody.dynamic = NO;
pole.physicsBody.categoryBitMask = PoleCategory;
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
self.lastPoint = p;
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.ready) {
CGPoint p = [[touches anyObject] locationInNode:self];
float distance = hypot(p.x – self.lastPoint.x, p.y – self.lastPoint.y);
if (distance > 10) {
self.ready = NO;
SKNode *ring = [self childNodeWithName:@”ring”];
[self setRingPhysics:ring];
ring.name = @””;
[ring.physicsBody applyImpulse:CGVectorMake(15 + distance * 0.2, 10)];
}
self.lastPoint = p;
}
}
– (void)setRingPhysics:(SKNode*)node
{
[node removeAllActions];
SKPhysicsBody *holeBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(80, 10)];
node.physicsBody = holeBody;
node.physicsBody.categoryBitMask = RingHoleCategory;
node.physicsBody.collisionBitMask = OtherCategory;
SKSpriteNode *left = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(10, 10)];
left.position = CGPointMake(-30, 0);
[node addChild:left];
SKPhysicsBody *bodyA = [SKPhysicsBody bodyWithCircleOfRadius:3];
left.physicsBody = bodyA;
left.physicsBody.categoryBitMask = RingEdgeCategory;
SKSpriteNode *right = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(10, 10)];
right.position = CGPointMake(30, 0);
[node addChild:right];
SKPhysicsBody *bodyB = [SKPhysicsBody bodyWithCircleOfRadius:3];
right.physicsBody = bodyB;
right.physicsBody.categoryBitMask = RingEdgeCategory;
SKPhysicsJointFixed *jointA = [SKPhysicsJointFixed jointWithBodyA:holeBody bodyB:left.physicsBody anchor:CGPointMake(node.position.x, node.position.y)];
[self.physicsWorld addJoint:jointA];
SKPhysicsJointFixed *jointB = [SKPhysicsJointFixed jointWithBodyA:holeBody bodyB:right.physicsBody anchor:CGPointMake(node.position.x, node.position.y)];
[self.physicsWorld addJoint:jointB];
[self performSelector:@selector(createRing) withObject:nil afterDelay:3];
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
}
– (void)viewDidAppear:(BOOL)animated
{
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[QuoitsScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end