iOSのサンプルとしてふわふわ動くサンタがプレゼントを配るコードのメモ

( Xcode の iOS6 Simulator で試しています。)

ポイント

・絵をフォントの絵文字で代用(サンタとかApple EmojiをUILabelに)

・PanGestureのEndedのtranslate と サンタの位置でプレゼントの動きを決定

指でピッピってプレゼントを配るサンタシューティングゲームのサンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    CADisplayLink *timer;

}

@property (nonatomic, strong) UIView *santa;

@property (nonatomic, strong) NSMutableArray *houses;

@property (nonatomic, strong) NSMutableDictionary *presents;

@end

// Apple Emojiをマクロ定義してみる(ここだけブログ文字化けるから画像。。。)

@implementation ViewController

@synthesize santa, houses;

– (void)viewDidLoad

{

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor blackColor];

}

– (void)viewDidAppear:(BOOL)animated

{

    [self loadData];

    

    [self start];

}

– (void)viewDidDisappear:(BOOL)animated

{

    [timer invalidate];

    santa = nil;

    timer = nil;

    houses = nil;

}

– (void)start

{

    timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateDisplay:)];

    [timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

}

– (void)loadData

{

    [self randomHouseCreate];

    [self loadSanta];

    self.presents = [[NSMutableDictionary alloc] init];

}

– (void)loadSanta

{

    // 透明な枠

    self.santa = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];

    self.santa.backgroundColor = [UIColor brownColor];

    self.santa.layer.cornerRadius = 5.0;

    UILabel *slable = [[UILabel alloc] initWithFrame:CGRectZero];

    slable.text = Santa;

    slable.backgroundColor = [UIColor clearColor];

    [slable sizeToFit];

    

    slable.userInteractionEnabled = YES;

    

    

    [self.santa addSubview:slable];

    [self.view addSubview:self.santa];

    

    // 拡大

    self.santa.transform = CGAffineTransformMakeScale(2.0, 2.0);

    

    // 外側のViewの中心に座標をコンバート

    slable.center = [self.santa convertPoint:self.santa.center fromView:self.view];

    

    

    // add gesture

    [slable addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panSanta:)]];

    

}

– (void)randomHouseCreate

{

    self.houses = [[NSMutableArray alloc] init];

    

    // 以下の範囲にばらまく

    // x point : 画面全体

    // y point : 0 ~ 2/3 * height

    // margin 20 point

    int margin = 20;

    int xMax = self.view.frame.size.width – margin;

    int yMax = self.view.frame.size.height * (2.0 / 3.0) – margin;

    

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

        // margin ~ Max でランダム

        int x = (arc4random() % (xMax – margin)) + margin;

        int y = (arc4random() % (yMax – margin)) + margin;

        // 家のフォント絵文字を配置

        UILabel *h = [[UILabel alloc] initWithFrame:CGRectMake(x, y, 30, 30)];

        // see #define House

        h.text = House;

        h.layer.cornerRadius = 5.0;

        h.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.0 alpha:0.2];

        [self.view addSubview:h];

        [houses addObject:h];

    }

}

– (void)updateDisplay:(CADisplayLink*)sender

{

    static float lastTime = 0.0;

    float timeDelta = 0.0;

    if (lastTime == 0.0) {

        lastTime = sender.timestamp;

    } else {

        timeDelta = sender.timestamp – lastTime;

        lastTime = sender.timestamp;

    }

    

    // サンタの位置

    // 縦の基本位置調整

    self.santa.center = CGPointMake(self.santa.center.x, 350);

    float x = self.santa.center.x + 10.0 * timeDelta;

    float y = self.santa.center.y + 50.0 * sinf(x * 0.1);

    self.santa.center = CGPointMake(x, y);

    

    

    // プレゼント配布

    for (NSNumber *index in self.presents.keyEnumerator) {

        

        NSDictionary *p = [self.presents objectForKey:index];

        UIView *present = [p objectForKey:@”view”];

        CGPoint direction = [[p objectForKey:@”direction”] CGPointValue];

        float px = present.center.x + direction.x * timeDelta;

        float py = present.center.y + direction.y * timeDelta;

        present.center = CGPointMake(px, py);

    }

    

    // 接触確認

    [self collisionCheck];

}

– (void)panSanta:(UIPanGestureRecognizer*)gr

{    

    

//    何回か、思ったが、Panの開始と、タッチした場所はずれるのでなんとかとれないものか。

//    touchBeginを使うのも手。今回は、サンタの顔の中心

//    if (gr.state == UIGestureRecognizerStateBegan) {

//        startPoint = [gr locationInView:self.view];

//    }

    

    if (gr.state == UIGestureRecognizerStateEnded) {

        

        // タッチ開始位置と方向を計算

        NSValue *translate =  [NSValue valueWithCGPoint:[gr translationInView:self.view]];

        

        UILabel *present = [[UILabel alloc] initWithFrame:CGRectZero];

        present.text = Present;

        present.center = self.santa.center;

        [present sizeToFit];

        

        [self.view addSubview:present];

        NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:present, @”view”, translate, @”direction”, nil];

        

        [self.presents setObject:dict forKey:[self counter]];

    }

    

}

– (void)collisionCheck

{

    // プレゼントと家の総当たりチェック

    // 微小時間でかぶらせることもないと思うので、ヒットしたら戻す。

    for (int i=0; i<[self.houses count]; i++) {

        for (NSNumber *index in self.presents.keyEnumerator) {

            

            UIView *house = [self.houses objectAtIndex:i];

            

            NSDictionary *p = [self.presents objectForKey:index];

            UIView *present = [p objectForKey:@”view”];

            

            if(CGRectIntersectsRect(house.frame, present.frame)) {

                // hit

                // house : ライトを明るく、チェックリストから外す

                house.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.0 alpha:0.6];

                [self.houses removeObject:house];

                // present : View消す、チェックリストからも消す

                [self.presents removeObjectForKey:index];

                [present removeFromSuperview];

                return;

            }

            

        }

    }

}

– (NSNumber*)counter

{

    static int number = 0;

    number++;

    return [NSNumber numberWithInt:number];

}

@end