くるくる回してボールを迷路の奥まで運ぶiPhoneアプリのサンプルコードを描いてみます。
動かすとこんな感じです
サンプルコード
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
@interface MazeScene : SKScene
@property (nonatomic, strong) NSValue *selected;
@end
typedef enum : int8_t {
CollideTypeBoard = 0x1 << 1,
CollideTypeWall = 0x1 << 2,
CollideTypeBall = 0x1 << 3,
} CollideType;
@implementation MazeScene
– (void)didMoveToView:(SKView *)view
{
[self createSceneContents];
}
– (void)createSceneContents
{
[self createBackBody];
[self createBoard];
[self createWall];
[self createBall];
}
– (void)createBackBody
{
SKSpriteNode *back = [SKSpriteNode spriteNodeWithColor:[self color:0] size:self.size];
back.name = @”back”;
back.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:back];
back.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:back.size];
back.physicsBody.dynamic = NO;
back.physicsBody.categoryBitMask = CollideTypeBoard;
back.physicsBody.collisionBitMask = 0x0;
}
– (void)createBoard
{
SKSpriteNode *board = [SKSpriteNode spriteNodeWithColor:[self color:3] size:CGSizeMake(280, 280)];
board.name = @”board”;
board.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:board];
board.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:board.size];
board.physicsBody.categoryBitMask = CollideTypeBoard;
board.physicsBody.collisionBitMask = 0x0;
board.physicsBody.angularDamping = 1.0;
SKNode *back = [self childNodeWithName:@”back”];
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:board.physicsBody bodyB:back.physicsBody anchor:board.position];
pin.shouldEnableLimits = YES;
pin.upperAngleLimit = M_PI;
pin.lowerAngleLimit = –M_PI;
[self.physicsWorld addJoint:pin];
}
– (void)createWall
{
// frame
CGPoint o = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
CGRect rect[] = {
CGRectMake(o.x – 140, o.y, 10, 280),
CGRectMake(o.x + 140, o.y, 10, 280),
CGRectMake(o.x, o.y – 140, 280, 10),
CGRectMake(o.x, o.y + 140, 280, 10),
CGRectMake(o.x – 85, o.y – 85, 100, 100),
CGRectMake(o.x + 10, o.y – 80, 40, 80),
CGRectMake(o.x + 100, o.y – 75, 80, 80),
CGRectMake(o.x + 50, o.y+40, 180, 20),
CGRectMake(o.x + 100, o.y+80, 10, 60),
CGRectMake(o.x + 40, o.y+80, 10, 60),
CGRectMake(o.x + 70, o.y+110, 10, 60),
CGRectMake(o.x – 20, o.y+80, 10, 60),
CGRectMake(o.x + 10, o.y+110, 10, 60),
};
for (int i=0; i<13; i++) {
SKSpriteNode *wall = [SKSpriteNode spriteNodeWithColor:[self color:4] size:rect[i].size];
wall.position = rect[i].origin;
[self addChild:wall];
wall.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:wall.size];
wall.physicsBody.categoryBitMask = CollideTypeWall;
wall.physicsBody.collisionBitMask = CollideTypeBall;
wall.physicsBody.density = 0.1;
SKNode *board = [self childNodeWithName:@”board”];
SKPhysicsJointFixed *fixed = [SKPhysicsJointFixed jointWithBodyA:wall.physicsBody bodyB:board.physicsBody anchor:wall.position];
[self.physicsWorld addJoint:fixed];
}
}
– (void)createBall
{
UIBezierPath *ballPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-10, –10, 20, 20)];
SKShapeNode *ball = [SKShapeNode node];
ball.path = ballPath.CGPath;
ball.position = CGPointMake(100, 300);
ball.fillColor = [self color:2];
[self addChild:ball];
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:8];
ball.physicsBody.categoryBitMask = CollideTypeBall;
ball.physicsBody.collisionBitMask = CollideTypeWall;
ball.physicsBody.mass = 0.1;
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
SKNode *board = [self childNodeWithName:@”board”];
if ([board containsPoint:p]) {
self.selected = [NSValue valueWithCGPoint:p];
}
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.selected) {
CGPoint p = [[touches anyObject] locationInNode:self];
SKNode *board = [self childNodeWithName:@”board”];
if (p.x > [self.selected CGPointValue].x) {
[board.physicsBody applyTorque:5];
} else if (p.x < [self.selected CGPointValue].x) {
[board.physicsBody applyTorque:-5];
}
}
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
SKNode *board = [self childNodeWithName:@”board”];
board.physicsBody.angularVelocity = 0;
self.selected = nil;
}
#define ColorHex(rgbValue) [SKColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1]
– (SKColor*)color:(int)i
{
switch (i) {
case 0:
return ColorHex(0x191919);
case 1:
return ColorHex(0x696969);
case 2:
return ColorHex(0xC3C3C3);
case 3:
return ColorHex(0xEBCDB4);
case 4:
return ColorHex(0x96734B);
default:
break;
}
return nil;
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[MazeScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
@end