iPhoneボールとアーム

ただ上下するだけのアームでボールを後ろに流してあそぶ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.00.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