iPhoneインパクト計

メーターの赤いところに近いほど強インパクトで箱を叩くiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface ImpactScene : SKScene

– (void)impact:(float)a;

@end

@implementation ImpactScene

– (void)didMoveToView:(SKView *)view

{

    self.backgroundColor = [SKColor darkGrayColor];

    self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.view.bounds];

    

    SKSpriteNode *box = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(25, 25)];

    box.name = @”box”;

    box.position = CGPointMake(100, 100);

    [self addChild:box];

    box.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:box.size];

}

– (void)impact:(float)a

{

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

    [box.physicsBody applyImpulse:CGVectorMake(0, -a)];

}

@end

@interface ViewController ()

@property (nonatomic, weak) UIView *needle;

@property (nonatomic) float angle;

@property (nonatomic, weak) NSTimer *timer;

@property (nonatomic, weak) ImpactScene *scene;

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor colorWithRed:1 green:1 blue:0.4 alpha:1.0];

    [self createMeter];

    [self createNeedle];

    [self createStopButton];

    

    SKView *spriteView = [[SKView alloc] initWithFrame:CGRectMake(30, 50, 260, 200)];

    [self.view addSubview:spriteView];

    ImpactScene *scene = [[ImpactScene alloc] initWithSize:spriteView.frame.size];

    [spriteView presentScene:scene];

    self.scene = scene;

}

– (void)createMeter

{

    float r = 180;

    float sAngle = –M_PI * 0.7;

    float eAngle = –M_PI * 0.3;

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path moveToPoint:CGPointMake(r * cos(sAngle), r * sin(sAngle))];

    [path addArcWithCenter:CGPointZero radius:r startAngle:sAngle endAngle:eAngle clockwise:YES];

    [path addLineToPoint:CGPointMake(0.7 * r * cos(eAngle), 0.7 * r * sin(eAngle))];

    [path addArcWithCenter:CGPointZero radius:0.7 * r startAngle:eAngle endAngle:sAngle clockwise:NO];

    [path closePath];

    

    CAShapeLayer *sl = [CAShapeLayer layer];

    sl.position = CGPointMake(160, 500);

    sl.path = path.CGPath;

    sl.lineWidth = 2;

    sl.strokeColor = [UIColor grayColor].CGColor;

    sl.fillColor = [UIColor greenColor].CGColor;

    [self.view.layer addSublayer:sl];

    

    CALayer *redZone = [CALayer layer];

    redZone.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.7].CGColor;

    redZone.frame = CGRectMake(0, 0, 40, 60);

    redZone.position = CGPointMake(0, -r * 0.85);

    [sl addSublayer:redZone];

}

– (void)createNeedle

{

    UIView *needle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 180)];

    needle.backgroundColor = [UIColor darkGrayColor];

    needle.center = CGPointMake(160, 520);

    needle.layer.cornerRadius = 2.5;

    needle.layer.anchorPoint = CGPointMake(0.5, 0.95);

    [self.view addSubview:needle];

    self.needle = needle;

    

    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(swing) userInfo:nil repeats:YES];

}

– (void)swing

{

    if (self.needle.tag == 0) {

        self.angle += 0.02;

        self.needle.transform = CGAffineTransformMakeRotation(self.angle);

        if (self.angle > M_PI * 0.2) {

            self.needle.tag = 1;

        }

    } else {

        self.angle -= 0.02;

        self.needle.transform = CGAffineTransformMakeRotation(self.angle);

        if (self.angle < –M_PI * 0.2) {

            self.needle.tag = 0;

        }

    }

}

– (void)createStopButton

{

    UIButton *stop = [UIButton buttonWithType:UIButtonTypeCustom];

    stop.frame = CGRectMake(0, 0, 120, 40);

    stop.backgroundColor = [UIColor redColor];

    stop.titleLabel.textColor = [UIColor whiteColor];

    stop.titleLabel.font = [UIFont boldSystemFontOfSize:20];

    stop.center = CGPointMake(160, CGRectGetMaxY(self.view.bounds) – 20);

    [stop setTitle:@”STOP” forState:UIControlStateNormal];

    [self.view addSubview:stop];

    

    [stop addTarget:self action:@selector(stop:) forControlEvents:UIControlEventTouchUpInside];

}

– (void)stop:(UIButton *)sender

{

    [self.timer invalidate];

    self.timer = nil;

    

    float impact = 200300 * fabs(self.angle);

    [self.scene impact:impact];

    

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(swing) userInfo:nil repeats:YES];

    });

}

@end