iPhoneカセットテープ

カセットテープをくるくる再生するiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SpriteKit;

@interface ViewController () <SKSceneDelegate>

@property (nonatomic, weak) SKScene *scene;

@property (nonatomic, strong) NSMutableArray *tapesize;

@property (nonatomic) BOOL playing;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    

    [self setupScene];

    [self createCassette];

    [self createButton];

}

– (void)setupScene {

    SKView *sv = [[SKView alloc] initWithFrame:self.view.bounds];

    SKScene *scene = [SKScene sceneWithSize:sv.frame.size];

    scene.backgroundColor = [self color:0];

    scene.delegate = self;

    [sv presentScene:scene];

    [self.view addSubview:sv];

    

    self.scene = sv.scene;

}

– (void)createCassette {

    float w = CGRectGetMaxX(self.view.bounds) * 0.8;

    float h = w /1.6;

    SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[self color:1] size:CGSizeMake(w, h)];

    body.name = @”body”;

    body.position = CGPointMake(CGRectGetMaxX(self.view.bounds)/2.0, h);

    [self.scene addChild:body];

    

    self.tapesize = [@[@20.0, @5.0] mutableCopy];

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

        SKShapeNode *tape = [SKShapeNode shapeNodeWithCircleOfRadius:[self.tapesize[i] floatValue] + 20];

        tape.name = [NSString stringWithFormat:@”tape%d”, i];

        tape.fillColor = [self color:3];

        tape.strokeColor = [UIColor clearColor];

        tape.position = CGPointMake(-70 + 140 * i, 0);

        [body addChild:tape];

        

        SKShapeNode *tapein = [SKShapeNode shapeNodeWithCircleOfRadius:20];

        tapein.fillColor = [self color:0];

        [tape addChild:tapein];

        

        float r = 16.0;

        for (int j=0; j<6; j++) {

            float angle = j * M_PI / 3.0;

            float x = r * cos(angle);

            float y = r * sin(angle);

            SKSpriteNode *bar = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:CGSizeMake(6, 6)];

            bar.position = CGPointMake(x, y);

            bar.zRotation = angle;

            [tapein addChild:bar];

        }

    }

}

– (void)createButton {

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path moveToPoint:CGPointMake(-40, 40)];

    [path addLineToPoint:CGPointMake(40, 0)];

    [path addLineToPoint:CGPointMake(-40, –40)];

    [path closePath];

    SKShapeNode *btn = [SKShapeNode shapeNodeWithPath:path.CGPath];

    btn.name = @”btn”;

    btn.fillColor = [self color:2];

    btn.position = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds) + 50);

    [self.scene addChild:btn];

}

– (void)update:(NSTimeInterval)currentTime forScene:(SKScene *)scene

{

    SKNode *body = (SKShapeNode *)[self.scene childNodeWithName:@”body”];

    SKShapeNode *tL = (SKShapeNode *)[self.scene childNodeWithName:@”body/tape0″];

    SKShapeNode *tR = (SKShapeNode *)[self.scene childNodeWithName:@”body/tape1″];

    

    SKNode *oldline = [self.scene childNodeWithName:@”body/line”];

    [oldline removeFromParent];

    

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path moveToPoint:CGPointMake(tL.position.x, tL.position.y – [self.tapesize[0] floatValue] – 19)];

    [path addLineToPoint:CGPointMake(tR.position.x, tR.position.y – [self.tapesize[1] floatValue] – 19)];

    SKShapeNode *line = [SKShapeNode shapeNodeWithPath:path.CGPath];

    line.name = @”line”;

    line.strokeColor = [self color:3];

    line.lineWidth = 2;

    [body addChild:line];

    

    if (self.playing) {

        if ([self.tapesize[0] floatValue] > 2) {

            self.tapesize[0] = @([self.tapesize[0] floatValue] – 0.04);

            self.tapesize[1] = @(25.0 – [self.tapesize[0] floatValue]);

            tL.path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:[self.tapesize[0] floatValue] + 20 startAngle:0 endAngle:2.0*M_PI clockwise:NO].CGPath;

            tR.path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:[self.tapesize[1] floatValue] + 20 startAngle:0 endAngle:2.0*M_PI clockwise:NO].CGPath;

        } else {

            self.playing = false;

            

            SKShapeNode *btn = (SKShapeNode*)[self.scene childNodeWithName:@”btn”];

            btn.fillColor = [self color:2];

            [btn removeAllActions];

            [tL removeAllActions];

            [tR removeAllActions];

        }

        

    }

}

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

{

    self.playing = !self.playing;

    

    SKShapeNode *tL = (SKShapeNode *)[self.scene childNodeWithName:@”body/tape0″];

    SKShapeNode *tR = (SKShapeNode *)[self.scene childNodeWithName:@”body/tape1″];

    

    SKShapeNode *btn = (SKShapeNode*)[self.scene childNodeWithName:@”btn”];

    if (self.playing) {

        btn.fillColor = [[self color:3] colorWithAlphaComponent:0.2];

        [btn runAction:[SKAction repeatActionForever:[SKAction sequence:@[[SKAction fadeInWithDuration:0.5], [SKAction fadeOutWithDuration:0.5]]]]];

        [tL runAction:[SKAction repeatActionForever:[SKAction rotateByAngle:M_PI duration:1.0]]];

        [tR runAction:[SKAction repeatActionForever:[SKAction rotateByAngle:M_PI duration:1.0]]];

        

    } else {

        btn.fillColor = [self color:2];

        [btn removeAllActions];

        [tL removeAllActions];

        [tR removeAllActions];

    }

}

#define ColorHex(rgb) [UIColor colorWithRed:((rgb & 0xFF0000) >> 16)/255.0 green:((rgb & 0xFF00) >> 8)/255.0 blue:(rgb & 0xFF)/255.0 alpha:1.0]

– (UIColor *)color:(int)i {

    switch (i) {

        case 0: return ColorHex(0xD3CBBD);

        case 1: return ColorHex(0xEB5937);

        case 2: return ColorHex(0x456F74);

        case 3: return ColorHex(0x1C1919);

    }

    return nil;

}

@end