メーターの赤いところに近いほど強インパクトで箱を叩く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 = 200 – 300 * 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