ただ上下するだけのアームでボールを後ろに流してあそぶiPhoneアプリのサンプルコード
#import “ViewController.h”
@import SpriteKit;
@interface ArmScene : SKScene
@property (nonatomic, weak) SKNode *select;
@property (nonatomic) float angle;
@end
@implementation ArmScene
– (void)didMoveToView:(SKView *)view
{
self.backgroundColor = [UIColor yellowColor];
[self createArm];
[self createSlider];
[NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(createBall) userInfo:nil repeats:YES];
}
– (void)createArm
{
SKSpriteNode *armA = [SKSpriteNode spriteNodeWithColor:[SKColor darkGrayColor] size:CGSizeMake(180, 30)];
armA.name = @”armA”;
armA.position = CGPointMake(150, 130);
[self addChild:armA];
armA.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:armA.size];
armA.physicsBody.angularDamping = 1.0;
armA.physicsBody.affectedByGravity = NO;
SKSpriteNode *base = [SKSpriteNode spriteNodeWithColor:[SKColor grayColor] size:CGSizeMake(CGRectGetMaxX(self.frame), 120)];
base.position = CGPointMake(CGRectGetMidX(self.frame), 60);
[self addChild:base];
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:50 startAngle:0 endAngle:1.0*M_PI clockwise:YES];
SKShapeNode *mount = [SKShapeNode node];
mount.name = @”mount”;
mount.path = path.CGPath;
mount.position = CGPointMake(80, 120);
mount.fillColor = base.color;
mount.lineWidth = 0;
[self addChild:mount];
mount.physicsBody = [SKPhysicsBody bodyWithBodies:@[[SKPhysicsBody bodyWithCircleOfRadius:5],[SKPhysicsBody bodyWithEdgeFromPoint:CGPointMake(0, 0) toPoint:CGPointMake(CGRectGetMaxX(self.frame), 0)]]];
mount.physicsBody.dynamic = NO;
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:armA.physicsBody bodyB:mount.physicsBody anchor:CGPointMake(mount.position.x, mount.position.y + 10)];
[self.physicsWorld addJoint:pin];
}
– (void)createBall
{
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:10 startAngle:0 endAngle:2.0*M_PI clockwise:NO];
SKShapeNode *ball = [SKShapeNode node];
ball.path = path.CGPath;
ball.position = CGPointMake(400, 300);
ball.fillColor = [SKColor whiteColor];
[self addChild:ball];
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
ball.physicsBody.density = 0.01;
[ball.physicsBody applyImpulse:CGVectorMake(-0.05, 0)];
[ball runAction:[SKAction sequence:@[[SKAction waitForDuration:4.0], [SKAction runBlock:^{
[ball removeFromParent];
}]]]];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
SKNode *hit = [self nodeAtPoint:p];
if ([hit.name isEqual:@”slider”]) {
self.select = hit;
}
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
if (self.select) {
self.select.position = CGPointMake(p.x, self.select.position.y);
self.angle = p.x / 600.0 – 0.1;
}
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
self.select = nil;
}
– (void)createSlider
{
SKSpriteNode *line = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(400, 3)];
line.position = CGPointMake(CGRectGetMidX(self.frame), 50);
[self addChild:line];
SKSpriteNode *sliderBtn = [SKSpriteNode spriteNodeWithColor:[SKColor orangeColor] size:CGSizeMake(35, 35)];
sliderBtn.name = @”slider”;
sliderBtn.zRotation = M_PI/4.0;
sliderBtn.position = line.position;
[self addChild:sliderBtn];
}
– (void)update:(NSTimeInterval)currentTime
{
SKNode *armA = [self childNodeWithName:@”armA”];
SKNode *mount = [self childNodeWithName:@”mount”];
float dx = armA.position.x – mount.position.x;
float dy = armA.position.y – mount.position.y;
float angle = atan2f(dx, dy);
if (angle < 0) {
angle += 2.0 * M_PI;
} else if (angle > 2.0 * M_PI) {
angle -= 2.0 * M_PI;
}
armA.physicsBody.angularVelocity = 0;
float targetAngle = self.angle * M_PI;
if (fabs(angle – targetAngle) > 0.05) {
float f = (angle – targetAngle) * 5.0;
[armA.physicsBody applyTorque:f];
}
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[ArmScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
@end