iPhone歯車繋いで

動いてる歯車の上に、歯車をドンドン追加してあそぶiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface GearScene : SKScene

@end

@implementation GearScene

– (void)didMoveToView:(SKView *)view

{

    self.backgroundColor = [self color:0];

    self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];

    self.physicsBody.dynamic = NO;

    self.physicsBody.categoryBitMask = 0x2;

    self.physicsBody.collisionBitMask = 0x2;

    

    [self createMainGear];

}

– (void)createMainGear

{

    SKNode *mainGear = [self createGear:60];

    mainGear.name = @”mainGear”;

    mainGear.position = CGPointMake(CGRectGetMidX(self.frame), 10);

    

    SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:mainGear.physicsBody bodyB:self.physicsBody anchor:mainGear.position];

    [self.physicsWorld addJoint:pin];

}

– (SKNode *)createGear:(float)r

{

    SKNode *gear = [SKNode node];

    NSMutableArray *bodies = [NSMutableArray array];

    

    for (int i=0; i<4; i++) {

        UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(-r, -r/10, r*2.0, r/5)];

        [path applyTransform:CGAffineTransformMakeRotation(i * M_PI/4.0)];

        SKShapeNode *t = [SKShapeNode node];

        t.path = path.CGPath;

        t.fillColor = [self color:4];

        [gear addChild:t];

        

        SKPhysicsBody *body = [SKPhysicsBody bodyWithPolygonFromPath:path.CGPath];

        [bodies addObject:body];

    }

    

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:r*0.75 startAngle:0 endAngle:2.0*M_PI clockwise:NO];

    SKShapeNode *cover = [SKShapeNode node];

    cover.path = path.CGPath;

    cover.fillColor = [[self color:4] colorWithAlphaComponent:0.8];

    [gear addChild:cover];

    

    SKPhysicsBody *body = [SKPhysicsBody bodyWithPolygonFromPath:path.CGPath];

    [bodies addObject:body];

    

    UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:r/3.0 startAngle:0 endAngle:2.0*M_PI clockwise:NO];

    SKShapeNode *hole = [SKShapeNode node];

    hole.path = path2.CGPath;

    hole.fillColor = [self color:0];

    [gear addChild:hole];

    

    [self addChild:gear];

    gear.physicsBody = [SKPhysicsBody bodyWithBodies:bodies];

    gear.physicsBody.friction = 0;

    return gear;

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    CGPoint p = [[touches anyObject] locationInNode:self];

    

    SKNode *gear = [self createGear:40];

    gear.position = p;

}

– (void)update:(NSTimeInterval)currentTime

{

    SKNode *mainGear = [self childNodeWithName:@”mainGear”];

    mainGear.physicsBody.angularVelocity = 5;

}

#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.0]

– (UIColor*)color:(NSInteger)i

{

    switch (i) {

        case 0:

            return ColorHex(0x7DDA7E);

        case 1:

            return ColorHex(0xF1EB6D);

        case 2:

            return ColorHex(0xD70553);

        case 3:

            return ColorHex(0x74023A);

        case 4:

            return ColorHex(0x260E22);

        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 = [[GearScene alloc] initWithSize:spriteView.frame.size];

    [spriteView presentScene:scene];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end