餅をついてるだけのアプリ落書き
(XcodeのiOS6 Simulatorで試しています。)
ポイント
・カスタムUIViewで棒人間が何となくスウェーするように
・杵はうさぎ杵(縦に二つついてるやつ)
・viewへの反映は、UIViewのsetNeedDisplay
ただひたすら棒人間が餅をつき続けるサンプルコード
[StickPerson.h]
@interface StickPerson : UIView {
CGPoint head;
CGFloat headSize;
CGPoint shoulder;
CGPoint body;
CGPoint rhand;
CGPoint lfoot, rfoot;
}
– (void)hand:(CGPoint)point;
@end
[StickPerson.m]
@implementation StickPerson
– (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// 基本設定
// 背景を透過
self.backgroundColor = [UIColor clearColor];
// 基本の長さ(8分割)
float base = frame.size.height / 8.0;
// View内部の中心座標
CGPoint midPoint = [self midPoint];
// 頭の座標
float hx = midPoint.x;
float hy = base * 2.8;
head = CGPointMake(hx, hy);
headSize = base * 0.8;
// 肩の座標
shoulder = CGPointMake(midPoint.x – 10, base * 4.0 – 20);
// 腰の座標
float bx = head.x;
float by = 6 * base;
body = CGPointMake(bx, by);
// 右手
float rhx = shoulder.x – 2 * base * cos(M_PI / 4.0) – 30.0;
float rhy = shoulder.y + 2 * base * sin(M_PI / 4.0);
rhand = CGPointMake(rhx, rhy);
// 左足
float lfx = body.x – base * 0.5;
float lfy = body.y + 1.7 * base;
lfoot = CGPointMake(lfx, lfy);
// 右足
float rfx = body.x + base * 0.5;
float rfy = body.y + 1.7 * base;
rfoot = CGPointMake(rfx, rfy);
}
return self;
}
– (CGPoint)midPoint
{
CGPoint midPoint;
midPoint.x = self.bounds.origin.x + self.bounds.size.width / 2;
midPoint.y = self.bounds.origin.y + self.bounds.size.height / 2;
return midPoint;
}
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
// 塗りつぶしの色をセット
[[UIColor redColor] set];
// 線の色をセット
[[UIColor redColor] setStroke];
CGContextSetLineWidth(context, 5.0);
// 頭
// 丸を塗りつぶし
UIGraphicsPushContext(context);
CGContextBeginPath(context);
CGContextAddArc(context, head.x, head.y, headSize, 0, 2*M_PI, YES);
CGContextFillPath(context);
UIGraphicsPopContext();
// 胴体
CGContextSetLineWidth(context, 60.0);
// 直線を一本ひく
UIGraphicsPushContext(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, head.x, head.y + 30);
CGContextAddLineToPoint(context, body.x, body.y);
CGContextStrokePath(context);
UIGraphicsPopContext();
CGContextSetLineWidth(context, 20.0);
CGContextSetLineCap(context, kCGLineCapRound);
// 手, 足
UIGraphicsPushContext(context);
CGContextBeginPath(context);
// 手
CGContextMoveToPoint(context, shoulder.x, shoulder.y + 10);
CGContextAddLineToPoint(context, rhand.x, rhand.y);
// 足
CGContextMoveToPoint(context, lfoot.x, body.y);
CGContextAddLineToPoint(context, lfoot.x – 10, lfoot.y);
CGContextMoveToPoint(context, rfoot.x, body.y);
CGContextAddLineToPoint(context, rfoot.x + 20, rfoot.y);
CGContextStrokePath(context);
UIGraphicsPopContext();
}
– (void)hand:(CGPoint)point
{
rhand = point;
head.x = [self midPoint].x + point.x * 0.1;
// view のアップデート
[self setNeedsDisplay];
}
@end
[ViewController.m]
#import “ViewController.h”
#import “StickPerson.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController () {
CADisplayLink *timer;
float lastTime;
BOOL kineDown;
}
@property (nonatomic, strong) UIView *usu;
@property (nonatomic, strong) UIView *kine;
@property (nonatomic, strong) StickPerson *syokunin;
@end
#define KineDefault CGPointMake(200, 280);
@implementation ViewController
@synthesize usu, kine, syokunin;
– (void)viewDidLoad
{
[super viewDidLoad];
}
– (void)viewDidAppear:(BOOL)animated
{
// 臼
[self createUsu];
// 杵 (ウサギ杵)
[self createKine];
// 餅をつく人
[self createSyokunin];
[self start];
}
– (void)createUsu
{
self.usu = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
self.usu.backgroundColor = [UIColor brownColor];
self.usu.center = CGPointMake(100, 380);
[self.view addSubview:self.usu];
}
– (void)createKine
{
self.kine = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 160)];
self.kine.backgroundColor = [UIColor clearColor];
self.kine.center = KineDefault;
UIView * kine1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 24, 70)];
kine1.backgroundColor = [UIColor brownColor];
UIView * kine2 = [[UIView alloc] initWithFrame:CGRectMake(7, 70, 10, 20)];
kine2.backgroundColor = [UIColor brownColor];
UIView * kine3 = [[UIView alloc] initWithFrame:CGRectMake(0, 90, 24, 70)];
kine3.backgroundColor = [UIColor brownColor];
[self.kine addSubview:kine1];
[self.kine addSubview:kine2];
[self.kine addSubview:kine3];
[self.view addSubview:self.kine];
}
– (void)createSyokunin
{
self.syokunin = [[StickPerson alloc] initWithFrame:CGRectMake(0, 0, 250, 350)];
self.syokunin.center = CGPointMake(220, 270);
[self.view addSubview:self.syokunin];
}
– (void)start
{
lastTime = 0.0;
kineDown = YES;
timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateDisplay:)];
[timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
– (void)updateDisplay:(CADisplayLink*)sender
{
CGPoint o = KineDefault;
float x = o.x;
float y = o.y;
lastTime = lastTime + sender.duration;
if (kineDown) {
// 振り下ろす
float th = lastTime * M_PI / 2.0;
int num = th / (M_PI / 2.0);
th = th – num * (M_PI / 2.0);
x = – 100.0 * sin(th) + o.x;
y = – 130.0 * cos(th) + o.y;
} else {
// 振り上げる
float th = lastTime * M_PI / 2.0;
int num = th / (M_PI / 2.0);
th = th – num * (M_PI / 2.0) + M_PI * 1.0 ;
x = 100.0 * cos(th) + o.x;
y = 130.0 * sin(th) + o.y;
}
if (lastTime >= 0.9) {
lastTime = 0.0;
kineDown = !kineDown;
}
self.kine.center = CGPointMake(x, y);
[self.syokunin hand:[self.syokunin convertPoint:self.kine.center fromView:self.view]];
}
– (void)viewDidDisappear:(BOOL)animated
{
self.usu = nil;
self.kine = nil;
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end