モグラたたきを作ってみる。
(XcodeのiOS6 Simulatorで試しています。)
ポイント
・UIViewを仕掛け絵本みたいに組み合わせることで
モグラを巣穴に出したり入れたりする
・モグラの上下にはtransformを利用し、
位置判定用に現時点のCALayer.transform translateの値を
CALayer valueForKeyPathで取得する。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
typedef enum{
MOGU_HOLE,
MOGU_UP,
MOGU_DOWN,
MOGU_SHOW,
} StateMogu;
@interface ViewController () {
CADisplayLink *timer;
}
@property (nonatomic, strong) NSMutableArray *mogu;
@property (nonatomic, strong) UILabel *score;
@end
@implementation ViewController
@synthesize mogu, score;
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor brownColor];
// 仕掛け絵本みたいに
// 巣穴とモグラをサンドイッチして隠れるようにする
mogu = [[NSMutableArray alloc] init];
[self createGround];
[self start];
// スコア
score = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 200, 40)];
score.backgroundColor = [UIColor blackColor];
score.layer.cornerRadius = 5.0;
score.font = [UIFont boldSystemFontOfSize:30];
score.text = @”000000″;
score.textAlignment = 1;
score.textColor = [UIColor orangeColor];
[self.view addSubview:score];
}
– (void)createGround
{
// モグラの上にくるように、穴と芝、仕掛け絵本みたいにかぶせて隠す
float widht = self.view.bounds.size.width * 0.9;
float x = self.view.bounds.size.width * 0.05;
float y = self.view.bounds.size.height * ((sqrt(2) – 1) / sqrt(2));
// 一列目のモグラと芝、穴のサンドイッチ
// 穴 モグラの裏に配置
[self createGrass:CGRectMake(x, y, widht, 80) isFront:NO];
// モグラ
[self createMogura:CGRectMake(50, 150, 50, 50 * sqrt(2))];
[self createMogura:CGRectMake(130, 150, 50, 50 * sqrt(2))];
[self createMogura:CGRectMake(210, 150, 50, 50 * sqrt(2))];
// モグラのかくれる芝
[self createGrass:CGRectMake(x, y + 80, widht, 80) isFront:YES];
[self createGrass:CGRectMake(x, y + 130, widht, 50) isFront:NO];
[self createMogura:CGRectMake(50, 250, 50, 50 * sqrt(2))];
[self createMogura:CGRectMake(130, 250, 50, 50 * sqrt(2))];
[self createMogura:CGRectMake(210, 250, 50, 50 * sqrt(2))];
[self createGrass:CGRectMake(x, y + 180, widht, 80) isFront:YES];
[self createGrass:CGRectMake(x, y + 230, widht, 50) isFront:NO];
[self createMogura:CGRectMake(50, 350, 50, 50 * sqrt(2))];
[self createMogura:CGRectMake(130, 350, 50, 50 * sqrt(2))];
[self createMogura:CGRectMake(210, 350, 50, 50 * sqrt(2))];
[self createGrass:CGRectMake(x, y + 280, widht, 80) isFront:YES];
}
– (void)createMogura:(CGRect)frame
{
// mogura body
float width = frame.size.width * 0.8;
float height = frame.size.height * 0.8;
float x = frame.origin.x + frame.size.width * 0.5;
float y = frame.origin.y + frame.size.height * 0.8;
UIView *mogura = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
mogura.center = CGPointMake(x, y);
mogura.backgroundColor = [UIColor brownColor];
mogura.layer.cornerRadius = width * 0.2;
mogura.layer.borderWidth = 3.0;
mogura.layer.borderColor = [UIColor darkGrayColor].CGColor;
[self.view addSubview:mogura];
// mogura eye
UILabel *left = [[UILabel alloc] init];
float lx = width * 1/sqrt(2) * (1 – 1 / sqrt(2));
left.text = @”●”;
left.backgroundColor = [UIColor clearColor];
[left sizeToFit];
left.center = CGPointMake(lx, 10);
[mogura addSubview:left];
UILabel *right = [[UILabel alloc] init];
float rx = width – lx;
right.text = @”●”;
right.backgroundColor = [UIColor clearColor];
[right sizeToFit];
right.center = CGPointMake(rx, 10);
[mogura addSubview:right];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
[mogura addGestureRecognizer:tap];
[self.mogu addObject:mogura];
}
– (void)createGrass:(CGRect)frame isFront:(BOOL)front
{
float width = frame.size.width * 0.2;
UIView *grass = [[UIView alloc] initWithFrame:frame];
grass.backgroundColor = [UIColor greenColor];
grass.clipsToBounds = YES;
[self.view addSubview:grass];
// hole
float point[] = {60, 140, 220};
for (int i=0; i<3; i++) {
float y = front ? 0 : frame.size.height;
float x = point[i];
UIView *hole = [[UIView alloc] initWithFrame:CGRectMake(0,0, width, width)];
hole.center = CGPointMake(x, y);
hole.backgroundColor = [UIColor blackColor];
hole.layer.cornerRadius = hole.bounds.size.width * 0.5;
[grass addSubview:hole];
}
}
– (void)start
{
timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateGame:)];
[timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
UILabel *startLabel = [[UILabel alloc] init];
startLabel.text = @”start”;
startLabel.textColor = [UIColor darkGrayColor];
startLabel.backgroundColor = [UIColor clearColor];
startLabel.font = [UIFont boldSystemFontOfSize:50];
[startLabel sizeToFit];
startLabel.center = CGPointMake(500, 100);
[self.view addSubview:startLabel];
[UIView animateWithDuration:1.0 animations:^{
startLabel.center = CGPointMake(160, 100);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5 animations:^{
startLabel.center = CGPointMake(-300, 100);
} completion:^(BOOL finished) {
[startLabel removeFromSuperview];
}];
}];
for (UIView *m in mogu) {
m.tag = MOGU_DOWN;
}
}
– (void)updateGame:(CADisplayLink*)sender
{
int rand = arc4random() % 270;
// ランダムでモグラを出す
if (rand % 30 == 0) {
UIView *m = [mogu objectAtIndex:rand / 30];
m.tag = MOGU_UP;
}
// モグラを動かす
for (UIView *m in mogu) {
if (m.tag == MOGU_DOWN)
{
CGAffineTransform form = m.transform;
m.transform = CGAffineTransformTranslate(form, 0, 1);
CALayer *layer = m.layer.presentationLayer;
float currentY = [[layer valueForKeyPath:@”transform.translation.y”] floatValue];
if (currentY >= 80.0 ) {
m.tag = MOGU_HOLE;
}
}
else if (m.tag == MOGU_UP)
{
CGAffineTransform form = m.transform;
m.transform = CGAffineTransformTranslate(form, 0, –1);
CALayer *layer = m.layer.presentationLayer;
float currentY = [[layer valueForKeyPath:@”transform.translation.y”] floatValue];
if (currentY <= 0.0) {
m.tag = MOGU_SHOW;
}
}
else if (m.tag == MOGU_SHOW)
{
int stay = arc4random() % 50;
if (!stay) {
m.tag = MOGU_DOWN;
}
}
}
}
– (void)tap:(UIGestureRecognizer*)gr //(UIView*)m
{
UIView *m = gr.view;
float x = m.center.x;
float y = m.center.y – m.frame.size.height * 0.5;
// 叩かれて星を出す
for (int i=0; i<5; i++) {
UIView *star = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
star.center = CGPointMake(x, y);
star.backgroundColor = [UIColor yellowColor];
[self.view addSubview:star];
[UIView animateWithDuration:0.5 animations:^{
float th = – i * M_PI / 4.0;
star.center = CGPointMake(50 * cos(th) + x, 50 * sin(th) + y);
} completion:^(BOOL finished) {
[star removeFromSuperview];
}];
}
// お目めを×に
for (UILabel *l in m.subviews) {
l.text = @”×”;
}
[UIView animateWithDuration:0.5 delay:0.5 options:UIViewAnimationCurveLinear animations:^{
m.transform= CGAffineTransformMakeTranslation(0, 80);
} completion:^(BOOL finished) {
// 目を戻す
for (UILabel *l in m.subviews) {
l.text = @”●”;
}
}];
// スコアアップ
score.text = [NSString stringWithFormat:@”%07d”, [score.text intValue] + 100];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end