
二本爪のロボットがボールをゴールまで運ぶようなiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
@interface RoboScene : SKScene
@property BOOL state;
@end
@implementation RoboScene
– (void)didMoveToView:(SKView *)view
{
self.physicsWorld.gravity = CGVectorMake(0, 0);
[self createGoal];
[self createRobo];
}
– (void)createGoal
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(-20, –40)];
[path addLineToPoint:CGPointMake(20, –40)];
[path addLineToPoint:CGPointMake(20, 40)];
[path addLineToPoint:CGPointMake(-20, 40)];
SKShapeNode *goal = [SKShapeNode node];
goal.name = @”goal”;
goal.path = path.CGPath;
goal.strokeColor = [SKColor whiteColor];
goal.lineWidth = 4;
goal.position = CGPointMake(270, CGRectGetMidY(self.frame));
[self addChild:goal];
goal.physicsBody = [SKPhysicsBody bodyWithEdgeChainFromPath:path.CGPath];
}
– (void)createRobo
{
SKNode *robo = [SKNode node];
robo.name = @”robo”;
robo.position = CGPointMake(50, CGRectGetMidY(self.frame));
[self addChild:robo];
NSMutableArray *pBodies = [NSMutableArray array];
SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[SKColor grayColor] size:CGSizeMake(20, 50)];
body.position = CGPointMake(-10, body.position.y);
[robo addChild:body];
[pBodies addObject:[SKPhysicsBody bodyWithRectangleOfSize:body.size center:body.position]];
for (int i=0; i<2; i++) {
float x = 20;
float y = i * 40 – 20;
SKSpriteNode *arm = [SKSpriteNode spriteNodeWithColor:[SKColor grayColor] size:CGSizeMake(20, 5)];
arm.position = CGPointMake(x, y);
[robo addChild:arm];
[pBodies addObject:[SKPhysicsBody bodyWithRectangleOfSize:arm.size center:arm.position]];
}
robo.physicsBody = [SKPhysicsBody bodyWithBodies:pBodies];
robo.physicsBody.angularDamping = 1.0;
robo.physicsBody.density = 5.0;
robo.physicsBody.restitution = 0;
}
– (void)createBall:(CGPoint)p
{
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:10 startAngle:0 endAngle:2.0*M_PI clockwise:NO];
SKShapeNode *ball = [SKShapeNode node];
ball.name = @”ball”;
ball.position = p;
ball.path = path.CGPath;
ball.fillColor = [SKColor orangeColor];
ball.lineWidth = 0;
[self addChild:ball];
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
ball.physicsBody.restitution = 0;
ball.physicsBody.linearDamping = 1.0;
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
[self createBall:p];
}
– (void)update:(NSTimeInterval)currentTime
{
SKNode *ball = [self childNodeWithName:@”ball”];
if (ball) {
switch (self.state) {
case 0:
[self rotateA];
break;
case 1:
[self moveA];
break;
case 2:
[self rotateB];
break;
case 3:
[self moveB];
break;
case 4:
[self rotateC];
break;
case 5:
[self moveC];
break;
default:
break;
}
}
}
– (void)rotateA
{
SKNode *ball = [self childNodeWithName:@”ball”];
SKNode *robo = [self childNodeWithName:@”robo”];
float angle = atan2f(ball.position.x – robo.position.x, robo.position.y – ball.position.y) – M_PI_2;
if (fabs(robo.zRotation – angle) < 0.05) {
self.state = 1;
} else {
robo.zRotation += M_PI * 0.01;
}
}
– (void)moveA
{
SKNode *ball = [self childNodeWithName:@”ball”];
SKNode *robo = [self childNodeWithName:@”robo”];
float l = hypot(ball.position.x – robo.position.x, ball.position.y – robo.position.y);
if (l < 15) {
self.state = 2;
robo.physicsBody.velocity = CGVectorMake(0, 0);
} else {
robo.physicsBody.velocity = CGVectorMake(ball.position.x – robo.position.x , ball.position.y – robo.position.y);
}
}
– (void)rotateB
{
SKNode *robo = [self childNodeWithName:@”robo”];
CGPoint o = CGPointMake(160, CGRectGetMidY(self.frame));
float angle = atan2f(o.x – robo.position.x, robo.position.y – o.y) – M_PI_2;
if (fabs(robo.zRotation – angle) < 0.05) {
self.state = 3;
} else {
robo.zRotation += M_PI * 0.01;
}
}
– (void)moveB
{
SKNode *robo = [self childNodeWithName:@”robo”];
CGPoint o = CGPointMake(160, CGRectGetMidY(self.frame));
float l = hypot(o.x – robo.position.x, o.y – robo.position.y);
if (l < 15) {
self.state = 4;
robo.physicsBody.velocity = CGVectorMake(0, 0);
} else {
robo.physicsBody.velocity = CGVectorMake(o.x – robo.position.x , o.y – robo.position.y);
}
}
– (void)rotateC
{
SKNode *robo = [self childNodeWithName:@”robo”];
float angle = 0;
if (fabs(robo.zRotation – angle) < 0.05) {
self.state = 5;
} else {
robo.zRotation += M_PI * 0.01;
}
}
– (void)moveC
{
SKNode *robo = [self childNodeWithName:@”robo”];
SKNode *goal = [self childNodeWithName:@”goal”];
SKNode *ball = [self childNodeWithName:@”ball”];
float l = hypot(goal.position.x – robo.position.x, goal.position.y – robo.position.y);
if (l < 30) {
robo.physicsBody.velocity = CGVectorMake(0, 0);
ball.name = @””;
[robo removeFromParent];
[self createRobo];
self.state = 0;
} else {
robo.physicsBody.velocity = CGVectorMake(goal.position.x – robo.position.x , goal.position.y – robo.position.y);
}
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[RoboScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
@end