iPhone ひらがな釣り

ひらがなの「さしすせそ」、カタカナの「サシスセソ」一緒はどれだ?というのを子供に覚えてもらうための単純なiPhoneアプリを作ってみます。さかなにはひらがなを書いておいて、魚をタッチするとカタカナが横から出てくるので、同じものを選びましょう。

動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。

ポイント
船、釣り人、釣り竿、魚はUIBezierPathをつかって、三角形、四角形の組み合わせで描いてみました。ゲームスタート時にランダムで魚にひらがなを表示するようにしています。

サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    UIView *fish;

    NSString *hiragana;

    UIView *katakanaBox;

    UIView *fisingRod;

    CGPoint rodTop, rodGrip;

    

    NSArray *hiraganaArr;

    NSArray *katakanaArr;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];

    

    [self createBackground];

    

    [self createFishingRod];

    

    [self createButton];

    

    [self createKatakanaBox];

}

– (void)createBackground

{

    //

    // sea

    //

    UIView *sea = [[UIView alloc] initWithFrame:CGRectMake(0, 400, 320, 168)];

    [self.view addSubview:sea];

    

    UIBezierPath *wavePath = [UIBezierPath bezierPath];

    [wavePath moveToPoint:CGPointMake(0, 0)];

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

        float x = i * 1.0;

        float y = 10 * sin(M_PI/60.0 * i);

        [wavePath addLineToPoint:CGPointMake(x, y)];

    }

    [wavePath addLineToPoint:CGPointMake(320, 168)];

    [wavePath addLineToPoint:CGPointMake(0, 168)];

    [wavePath closePath];

    

    CAShapeLayer *wavesl = [[CAShapeLayer alloc] init];

    wavesl.fillColor = [self color:1].CGColor;

    wavesl.path = wavePath.CGPath;

    

    [sea.layer addSublayer:wavesl];

    

    //

    // ship

    //

    UIView *ship = [[UIView alloc] initWithFrame:CGRectMake(0, 320, 180, 100)];

    [self.view insertSubview:ship belowSubview:sea];

    

    UIBezierPath *shippath = [UIBezierPath bezierPath];

    [shippath moveToPoint:CGPointMake(0, 0)];

    [shippath addLineToPoint:CGPointMake(100/1.618, 0)];

    [shippath addLineToPoint:CGPointMake(100/1.618, 100100/1.618)];

    [shippath addLineToPoint:CGPointMake(100, 100100/1.618)];

    [shippath addLineToPoint:CGPointMake(100/1.618, 100)];

    [shippath addLineToPoint:CGPointMake(0, 100)];

    [shippath closePath];

    

    [shippath appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(10, 10, 40, 30)]];

    CAShapeLayer *shipcl = [[CAShapeLayer alloc] init];

    shipcl.fillColor = [self color:2].CGColor;

    shipcl.path = shippath.CGPath;

    shipcl.fillRule = kCAFillRuleEvenOdd;

    [ship.layer addSublayer:shipcl];

    

    // Angler(釣り人)

    UIView *angler = [[UIView alloc] initWithFrame:CGRectMake(12, 14, 26, 26)];

    [ship addSubview:angler];

    

    UIBezierPath *anglerP = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 26, 13)];

    [anglerP moveToPoint:CGPointMake(13, 8)];

    [anglerP addLineToPoint:CGPointMake(26, 26)];

    [anglerP addLineToPoint:CGPointMake(0, 26)];

    [anglerP closePath];

    

    CAShapeLayer *anglerCL = [[CAShapeLayer alloc] init];

    anglerCL.fillColor = [self color:0].CGColor;

    anglerCL.path = anglerP.CGPath;

    [angler.layer addSublayer:anglerCL];

}

– (void)createFishingRod

{

    rodTop = CGPointMake(220, 180);

    rodGrip = CGPointMake(40, 360);

    

    

    fisingRod = [[UIView alloc] initWithFrame:self.view.bounds];

    [self.view addSubview:fisingRod];

    

    CAShapeLayer *rodCL = [[CAShapeLayer alloc] init];

    rodCL.fillColor = [self color:0].CGColor;

    [fisingRod.layer addSublayer:rodCL];

    

    [self updateFishingRod];

}

– (void)updateFishingRod

{

    CGPoint cp = CGPointMake(100, 100);

    

    UIBezierPath *rodP = [UIBezierPath bezierPath];

    [rodP moveToPoint:rodGrip];

    [rodP addQuadCurveToPoint:rodTop controlPoint:cp];

    [rodP addLineToPoint:CGPointMake(rodTop.x, rodTop.y2)];

    [rodP addQuadCurveToPoint:CGPointMake(rodGrip.x, rodGrip.y10) controlPoint:cp];

    [rodP closePath];

    

    [rodP appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(rodTop.x, rodTop.y, 1, 240)]];

    

    CAShapeLayer *sl = [fisingRod.layer.sublayers objectAtIndex:0];

    sl.path = rodP.CGPath;

    

}

– (void)createButton

{

    // fish

    fish = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 70)];

    fish.center = CGPointMake(rodTop.x, 450);

    [self.view addSubview:fish];

    

    UIBezierPath *fPath = [UIBezierPath bezierPath];

    [fPath moveToPoint:CGPointMake(30, 0)];

    [fPath addLineToPoint:CGPointMake(60, 30)];

    [fPath addLineToPoint:CGPointMake(10, 70)];

    [fPath addLineToPoint:CGPointMake(50, 70)];

    [fPath addLineToPoint:CGPointMake(0, 30)];

    [fPath closePath];

    

    CAShapeLayer *fSlayer = [[CAShapeLayer alloc] init];

    fSlayer.fillColor = [self color:3].CGColor;

    fSlayer.path = fPath.CGPath;

    [fish.layer addSublayer:fSlayer];

    

    // hiragana

    hiraganaArr = [@” componentsSeparatedByString:@” “];

    hiragana = [hiraganaArr objectAtIndex:arc4random() % [hiraganaArr count]];

    

    UILabel *hiraganaL = [[UILabel alloc] initWithFrame:CGRectMake(15, 15, 30, 30)];

    hiraganaL.backgroundColor = [UIColor clearColor];

    hiraganaL.text = hiragana;

    hiraganaL.font = [UIFont boldSystemFontOfSize:30];

    hiraganaL.textAlignment = NSTextAlignmentCenter;

    hiraganaL.textColor = [self color:0];

    [fish addSubview:hiraganaL];

    

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hook)];

    [fish addGestureRecognizer:tap];

}

– (void)hook

{

    [UIView animateWithDuration:0.2 animations:^{

        // down

        rodTop = CGPointMake(rodTop.x, rodTop.y + 10);

        [self updateFishingRod];

        fish.transform = CGAffineTransformMakeTranslation(0, 20);

        

    } completion:^(BOOL finished) {

        // jump

        rodTop = CGPointMake(rodTop.x, rodTop.y10);

        [self updateFishingRod];

        

        [UIView animateWithDuration:0.5 animations:^{

            CGAffineTransform t = CGAffineTransformMakeTranslation(-50, –350);

            fish.transform = CGAffineTransformRotate(t, M_PI);

            

            katakanaBox.transform = CGAffineTransformIdentity;

        } completion:^(BOOL finished) {

            

            // fall 

            [UIView animateWithDuration:6.0 animations:^{

                fish.transform = CGAffineTransformMakeTranslation(0, 100);

            } completion:^(BOOL finished) {

                

                // restart

                [self restart];

                

            }];

        }];

        

    }];

}

– (void)createKatakanaBox

{

    katakanaBox = [[UIView alloc] initWithFrame:CGRectMake(20, 440, 280, 80)];

    katakanaBox.backgroundColor = [self color:4];

    [self.view addSubview:katakanaBox];

    

    

    katakanaArr = [@” componentsSeparatedByString:@” “];

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

        UILabel *katakana = [[UILabel alloc] initWithFrame:CGRectMake(50 * i + 15 , 15, 50, 50)];

        katakana.layer.cornerRadius = 25;

        katakana.text = [katakanaArr objectAtIndex:i];

        katakana.font = [UIFont boldSystemFontOfSize:30];

        katakana.textAlignment = NSTextAlignmentCenter;

        [katakanaBox addSubview:katakana];

        

        katakana.userInteractionEnabled = YES;

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(checkfish:)];

        [katakana addGestureRecognizer:tap];

    }

    

    katakanaBox.transform = CGAffineTransformMakeTranslation(-400, 0);

}

– (void)checkfish:(UITapGestureRecognizer*)gr

{

    gr.view.backgroundColor = [self color:3];

    [self performSelector:@selector(removeHighLight:) withObject:gr.view afterDelay:0.3];

    

    UILabel *katakanaL = (UILabel*)gr.view;

    NSString *katakana = katakanaL.text;

    

    int hiraganaIndex = [hiraganaArr indexOfObject:hiragana];

    int katakanaIndex = [katakanaArr indexOfObject:katakana];

    if (hiraganaIndex == katakanaIndex) {

        UILabel *ok = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];

        ok.text = @”OK”;

        ok.textColor = [self color:1];

        ok.font = [UIFont boldSystemFontOfSize:50];

        ok.center = CGPointMake(160, 200);

        ok.backgroundColor = [UIColor clearColor];

        ok.alpha = 0;

        [self.view addSubview:ok];

        

        [UIView animateWithDuration:1.0 animations:^{

            fish.center = CGPointMake(-200, –200);

            ok.alpha = 0.8;

        } completion:^(BOOL finished) {

            // restart

            [self performSelector:@selector(restart) withObject:nil afterDelay:0.5];

        }];

    }

}

– (void)restart

{

    self.view.layer.sublayers = nil;

    

    fish = nil;

    katakanaBox = nil;

    fisingRod = nil;

    hiraganaArr = nil;

    katakanaArr = nil;

    

    [self createBackground];

    [self createFishingRod];

    [self createButton];

    [self createKatakanaBox];

}

– (void)removeHighLight:(UIView *)v

{

    v.backgroundColor = [UIColor whiteColor];

}

#define UIColorHex(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

– (UIColor*)color:(int)i

{

    switch (i) {

        case 0:

            return UIColorHex(0x2E2D33);

        case 1:

            return UIColorHex(0x40E2E1);

        case 2:

            return UIColorHex(0x90CC3A);

        case 3:

            return UIColorHex(0xD13351);

        case 4:

            return UIColorHex(0xEBC434);

        default:

            break;

    }

    return nil;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end