みなさんこんにちは。Yuta Fujii(@HofuCamera)です。
今回は「鳴き声足し算ゲームiPhoneアプリ」を作成していきたいと思います。このアプリは、ある数字が表示されたあと、何と何を足したらその数字になるか考えるゲームです。また、数字を選択するときにかわいい音もならしてみたいと思います。この音をイヌやネコにすることでキッズ向けアプリケーションにもなります。
そして、よくアプリを新しく開始する際にみるイントロダクション部分も作成していきたいと思います。
それでははじめていきましょう!
↓Xcodeの環境構築がまだの方はこちら↓
Cocoa Podsを使用してみよう
今回のアプリでは、アプリがよりリッチになる便利なツールを使いながら進めていきたいと思います。
まず、以下のURLを見ていきましょう。
このCocoa Controlsとは、便利なツールを検索したり、自分のプロジェクトに取り込むためにはどうしたらよいのかなどが書かれてあります。それでは、イントロダクション(アプリのはじめに出てくる説明)をこれを用いてつくっていきたいと思います。まず、検索窓にintroと入れます。
すると、たくさんイントロダクションに関するサンプルが出てきます。
今回は、EAIntroViewを使ってみたいと思います。EAIntroViewと書かれた場所をクリックしてください。すると、詳細ページに飛びます。
右上のDownload Sourceと書かれたところをクリックします。
すると、このようなページが出てきます。
下部へ行くとCocoaPodsと書かれた書かれた箇所があるかと思います。
使い方を順に説明していきます。
CocoaPodsをインストールする
それでは、プロジェクトを作成していきます。
Xcodeを立ち上げ、Create a New Xcode projectをクリックします。
以下のように進めていきます。
名前はnumberGameとします。
ターミナルを使ってみる
続いて右上赤い部分の検索マークをクリックして、「ターミナル」検索してエンターを押します。
すると、このような画面が出てきます。
続いて、sudo gem install cocoapodsと入力してエンターを押します。次に、pod setupと入力してエンターを押します。すると、CocoaPodsを使う準備が完了します。
Xcodeに戻り、赤い部分を選択した状態で、File→New→Fileを選択していきます。
普段であれば、左側にあるようにSourceという箇所を使用しますが、
今回はOtherを選択します。
Emptyを選択し、Nextをクリックします。
ファイル名をPodfileとします。(ここの名前が重要です)
そしてCreateを押します。
すると、Podfileというファイルが作成されます。今は何も記述されていません。
ここで、先ほどのサイトへ戻ります。赤い部分に注目してください。
ここがこのイントロダクションパーツの使い方になります。
それでは何が書かれているか順に説明していきます。
まず、1行目に先ほど作成したPodfileへ記述しなければならない項目が書かれています。
ここでは、pod ‘EAIntroView’, ‘~> 2.8.0’がそれにあたります。
これを先ほど作成したPodfileへ記述します。
2行目、pod installと書かれた部分があります。これは先ほどのターミナルで実行するものになります。詳しい記述方法は後ほど説明します。
3行目にはファイルにインポートする際にどう書くべきかが記述されています。
最後はデリゲートを指定する際の書き方が説明されてあります。
それではターミナルに戻りましょう。
ここで、cd とまず記入します。これはチェンジディレクトリの略で、今から次のファイルある所まで移動しますという意味になります。
このcdのあとに続いて、numberGameというファイルをドラッグ&ドロップします。
すると以下のようになります。
ここでエンターを押します。
するとプロジェクトファイルのある位置まで移動することができました。
ここでpod installと記述してエンターを押します。
次々と処理が進みます。
最後まで終わったらexitと記述してターミナルを終了します。
すると、numberGameのプロジェクトを開こうとした際に白いnumberGame.xcworkspaceというものが出来上がっているのがわかります。
これをダブルクリックしてプロジェクトを開始します。
赤い部分をクリックしてファイル郡を開きます。
あとはいつも通りMain.stroyboardをクリックして、iPhone4.7-inchを選択してプログラムファイルを開きます。
ここで、以前のサイトへまた戻ります。
下記のマニュアル通り
[objc]
#import “EAIntroView.h”
[/objc]
と記述します。
これで先ほどのイントロダクションを使用する準備が整いました。
デリゲートも記述して、
ここをコピー&ペーストします。
[objc]
// custom
EAIntroPage *page2 = [EAIntroPage page];
page2.title = @”This is page 2″;
page2.titleFont = [UIFont fontWithName:@”Georgia-BoldItalic” size:20];
page2.titlePositionY = 220;
page2.desc = sampleDescription2;
page2.descFont = [UIFont fontWithName:@”Georgia-Italic” size:18];
page2.descPositionY = 200;
page2.titleIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@”title2″]];
page2.titleIconPositionY = 100;
[/objc]
すると、エラーがでました。
ここは、descと書かれてあります。おそらくディスクリプション(文章)のことだと思うので、
こんな感じで変更します。
続いてイントロダクションの背景になる画像を取り込みます。
ドラッグ&ドロップして、Finishします。
全体的に以下のように変更します。
[objc]
// custom
EAIntroPage *page1 = [EAIntroPage page];
page1.title = @”このようにつかいます1″;
page1.titleFont = [UIFont fontWithName:@”Georgia-BoldItalic” size:20];
page1.desc = @”これは使い方1のページです”;
page1.descFont = [UIFont fontWithName:@”Georgia-Italic” size:18];
page1.bgImage = [UIImage imageNamed:@”intro1.jpg”];
// custom
EAIntroPage *page2 = [EAIntroPage page];
page2.title = @”このようにつかいます2″;
page2.titleFont = [UIFont fontWithName:@”Georgia-BoldItalic” size:20];
page2.desc = @”これは使い方2のページです”;
page2.descFont = [UIFont fontWithName:@”Georgia-Italic” size:18];
page2.bgImage = [UIImage imageNamed:@”intro2.jpg”];
// custom
EAIntroPage *page3 = [EAIntroPage page];
page3.title = @”このようにつかいます3″;
page3.titleFont = [UIFont fontWithName:@”Georgia-BoldItalic” size:20];
page3.desc = @”これは使い方3のページです”;
page3.descFont = [UIFont fontWithName:@”Georgia-Italic” size:18];
page3.bgImage = [UIImage imageNamed:@”intro3.jpg”];
// custom
EAIntroPage *page4 = [EAIntroPage page];
page4.title = @”このようにつかいます4″;
page4.titleFont = [UIFont fontWithName:@”Georgia-BoldItalic” size:20];
page4.desc = @”これは使い方4のページです”;
page4.descFont = [UIFont fontWithName:@”Georgia-Italic” size:18];
page4.bgImage = [UIImage imageNamed:@”intro4.jpg”];
EAIntroView *intro = [[EAIntroView alloc] initWithFrame:self.view.bounds andPages:@[page1,page2,page3,page4]];
[intro setDelegate:self];
[intro showInView:self.view animateDuration:0.0];
[/objc]
続いてサイトを参考に、
記述します。
ここでエラーが出ています。
page2、page3 、page4がありませんということです。
なので作ります。
するとエラーが消えました。
またサイトを参考に、以下を加えます。
そして、全体的に以下のように変更します。(必要なところだけ記述します。)
さらに、全てをviewDidLoad内に書くのは見づらいので、showIntroというメソッドを新しくつくってみます。
このメソッドの中に先ほど書いたコードをそのままコピー&ペーストして、viewDidLoad内のコードは消去します。
そして、この新しく作成したshowIntroをviewDidLoad内で呼び出してあげます。
シミュレーターで確認してみよう
それではシミュレーターで確認してみましょう。
左上の▶ボタンをクリックしてシミュレーターを立ち上げます。
すると、このようにイントロダクションが出るようになりました。
シミュレーターの画面を横にスライドさせると次のページへと進んでいきます。
さらに、右下のSkipボタンをクリックすると、
何もパーツを載せていない画面が現れます。
【イントロ部分の改変】イントロダクション部分を1回だけの表示にする
前回、cocoa Podsを使用して、イントロダクションを取り込みました。
通常イントロダクションは、はじめてアプリをインストールして起動した際に1回のみ表示され、その後は表示されないというのが一般的かと思います。
まずは、イントロダクション部分を1回表示したらその後はアプリを起動しても表示しないという機能を実装していきたいと思います。
NSUserDefaultsを使用して管理する
前回までの講座でアプリ内にデータを半永久的に保存する「NSUserdefaults」の使い方についても見てきたと思います。今回この中にデータを入れて、もしイントロダクションが表示されたら次回からはイントロダクションを表示しないという形で作成していきます。
まず、下記のようにNSUserdefaultを使用することを宣言します。
[objc]
NSUserDefaults *ud;
[/objc]
[objc]
ud = [NSUserDefaults standardUserDefaults];
[/objc]
さらに、次のように記述します。
[objc]
BOOL flag = [ud boolForKey:@”intro”];
if (flag != YES) {
[self showIntro];
[ud setBool:YES forKey:@”intro”];
}
[/objc]
順を追って説明していきます。
まず、NSUserDefaultsの変数である、udからキー値introでbool値(YES or NO)を取り出しています。デフォルト状態ではYESではないので(何も値をintroというキー値で入れていないので)、
[objc]
if (flag != YES) {
[/objc]
もし、flagの中身がYESでなかったら
[objc]
[self showIntro];
[ud setBool:YES forKey:@”intro”];
[/objc]
showIntroメソッドを呼ぶ、つまりイントロダクションを出します。
次に、introというキー値でYESを入れます。
すると、次回からintroというキー値でBool値を取り出した際、YESであるので、このif文の中にはプログラムは入ってきません。
このBool値は半永久的に保存されるのでイントロダクションはその後表示されなくなります。
問題を作成していく
それでは、問題の数字が入るようint型の変数を準備します。
[objc]
int question;
[/objc]
さらに、このquestionという変数の中に乱数で発生させた数字を入れます。
[objc]
question = (int)arc4random()%10;
[/objc]
次に、Storyboard上にラベルを配置します。
このラベルはquestionの数字を表示することになります。
文字を変更します。
さらに、数字を入力するテキストフィールドも画面の上にのせます。
+というラベルものせて
もう1つテキストフィールドを画面にのせます。
Cocoa Podsを使用する【キーボードを準備する】
ここで再度、cocoa podsを使用します。
今回は、キーボードを扱います。
通常のキーボードとは別に数字に特化したものを使用します。
Podfileに以下のように記述します。
pod ‘MMNumberKeyboard’
次にターミナルを開いて、前回同様cd→ドラッグ&ドロップでプロジェクトのある階層まで行きます。
最後に pod installと書いて、エンターを押します。するとプロジェクトへの取り込みが開始されます。
とりこむ処理が開始されます。
全て終わったらexitと打ってターミナルを終了させます。
今回使用したものは下記のMMNumberKeyboard for iOSというものになります。
https://github.com/matmartinez/MMNumberKeyboard
続いて、このMMNumberKeyboardをプログラムへ取り込みます。
[objc]
#import “MMNumberKeyboard.h”
[/objc]
説明を参考にデリゲートも書きます。
さらに、MMNumberKeyboardの使い方に書いてあるように、以下のようにコードを記述していきます。
[objc]
// Create and configure the keyboard.
MMNumberKeyboard *keyboard = [[MMNumberKeyboard alloc] initWithFrame:CGRectZero];
keyboard.allowsDecimalPoint = YES;
keyboard.delegate = self;
[/objc]
続いて画面のパーツをプログラムに認識させていきます。
下記のようにテキストフィールドを選択して、commandを押しながらドラッグ&ドロップしていきます。ここではtextfield1という名前をつけました。
もう一方のテキストフィールドも同じ方法で認識させていきます。
こちらはtextfield2と名づけました。
さらに、MMNumberKeyboardもデリゲートメソッドも記述します。
[objc]
– (BOOL)numberKeyboardShouldReturn:(MMNumberKeyboard *)numberKeyboard
{
// Do something with the done key if neeed. Return YES to dismiss the keyboard.
return YES;
}
[/objc]
さらに、テキストフィールドの体裁を整えていきます。
以下のようにtextfield1、textfield2ともに記述していきます。
ただ、ここは後ほど変更していきます。
変更後のプログラムは以下になります。
[objc]
textField1.inputView = keyboard;
textField1.text = @””;
textField1.placeholder = @”数字1″;
textField1.font = [UIFont systemFontOfSize:24.0f];
textField1.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
textField2.inputView = keyboard;
textField2.text = [NSString stringWithFormat:@”%d”,number];
textField2.placeholder = @”数字2″;
textField2.font = [UIFont systemFontOfSize:24.0f];
textField2.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
[/objc]
次に、答え合わせボタンを画面上へ置きます。
さらに、プログラムへ認識させます。
answerという名前をつけました。
現在textfield2でnumberという箇所にエラーが出ているかと思います。
このnumberは今から作成しますが、問題の数字が乱数によって生成され、ラベルに表示された後、テキストフィールド2にも乱数によって生成した数字を記入します。
ゲームのルールを、問題の数字にはテキストフィールド2にある数字と何を足したらなるのかということで正誤判定をしていきたいと思います。
正誤判定は答え合わせボタンをタップしたときに行います。
それでは、テキストフィールド2のなかに入れておくための箱を準備します。
[objc]
int number;
[/objc]
そしてnumberへ乱数を発生させた数字を入れておきます。(ここも後ほど変更します)
続いて、数字を文字列へ変換します。これをキャストといいます。
さらに問題正誤判定が終わったあと、問題をリセットする場所を作成します。
ボタンを画面の上へ置き、リセットと名前をつけメソッドの名前をresetとしました。
ここに、リセットボタンが押されたときの処理を記述していきます。
ここで行っているのは、numberへ乱数を再びいれて新しくした後、textfield1の文字列を空にします。次に、textfield2のテキストをnumberとします。
また、問題の数字というラベルをプログラムへ認識させていきます。
resultLabelと名づけました。
続いて、問題の数字のラベルへ乱数を発生させた数字を反映させていきます。
questionに乱数を発生させた後、その数字を文字列にキャストしてラベルの文字として反映させます。
[objc]
resultLabel.text = [NSString stringWithFormat:@”%d”,question];
[/objc]
さらに、リセットが押されたときも同様に問題の数字を新しくします。
[objc]
resultLabel.text = [NSString stringWithFormat:@”%d”,question];
[/objc]
乱数へ範囲を設ける
ここで乱数に関して範囲をもうけていきたいと思います。
viewDidLoad内を変更します。
[objc]
int question2 = 5.0 + arc4random() % 6; //5から10までの乱数を取得
question = question2;
[/objc]
次に、numberも同様に範囲を指定します。
[objc]
int number2 = rand()%3 + 1; //1から3までの乱数を取得
number = number2;
[/objc]
リセットボタンの箇所も同様に変更します。
[objc]
int question2 = 5.0 + arc4random() % 6; //5から10までの乱数を取得
question = question2;
[/objc]
[objc]
int number2 = rand()%3 + 1; //1から3までの乱数を取得
number = number2;
[/objc]
最後に正誤判定用に数字を入れておく箱を準備します。
[objc]
int result;
[/objc]
answerの部分へ以下のように記述します。
[objc]
result = number + [textField1.text intValue];
if (result == question) {
resultLabel.text = @”正解!”;
}else{
resultLabel.text = @”間違い!”;
}
[/objc]
まず、textfield2で用いるnumberとtextfield1で入力された文字列を数字へ変換したものを足し算してresultへ入れます。
そして、もしresultの中の数字と問題の数字、つまりquestionの値が同じであれば、
resultlabelのテキストを正解、そうでなければ間違いとします。
シミュレーターで確認してみよう
それでは左上の▶ボタンをクリックしてシミュレーターを立ち上げて確認してみましょう。
試しに、間違ってみます。
2 + 2 = 8となるかどうか試しています。
答え合わせボタンをタップすると、間違い!と判定されました。
次に、3 + 2 = 5となるか確認してみます。
正解と表示されました。
音声ファイルをプロジェクトへ取り込む
それでは、音声ファイルを取り込んでいきたいと思います。
mp3の音源を準備し、それをプロジェクトへドラッグ&ドロップしてください。
音源が必要な方はこちらから
ここでは、neko.mp3を取り込みました。
音声用フレームワークを導入する
今までの講座の中で、フレームワークを導入して処理を行うことをしてきたと思います。
ここでも同様に音声用のフレームワークを使用して音声を鳴らしてみたいと思います。
まず。赤い部分を選択した状態で、
下へスクロールすると、赤い部分に+と書かれた箇所があるのでそこをクリックします。
検索窓が出てきますので、AVFoundation.frameworkを選択し、Addをクリックします。
下のように導入されたら準備完了です。
とりこんできたもののプログラムを確認する
今回は、外部からとりこんだ数字のみのキーボードに対して、数字をタップすると音を鳴らすという処理をしていきます。
ということは、cocoa podsを用いて取り込んだもののプログラムを改変しなければなりません。
そのプログラムの見つけ方について説明します。
まず、下記のようにデリゲートの箇所をcommandをクリックしながら選択します。
すると、そのプログラムの.hファイルへ行きました。
ただ、具体的な処理が記述されているのは実装ファイルである.mファイルなので、
赤い部分をクリックして、
.mファイルを選択すると、ロックがかかっています。
赤い部分をクリックして、ロックを解除します。
すると、実装ファイルを確認することができました。
次に、キーボードをタップした時に反応する場所を探していくのですが、その前にフレームワークを使えるようにインポートしておきます。
[objc]
#import <AVFoundation/AVFoundation.h>
[/objc]
次に音声再生ようの変数を準備します。
[objc]
AVAudioPlayer *audioPlayer
[/objc]
そして、下記のようにボタンをタップしたときに反応する箇所を見つけました。
ここに音声を再生するプログラムを書いていきます。
下記のように記述します。
[objc]
NSError *error = nil;
// 再生する audio ファイルのパスを取得
NSString *path = [[NSBundle mainBundle] pathForResource:@"neko" ofType:@"mp3"];
// パスから、再生するURLを作成する
NSURL *url = [[NSURL alloc] initFileURLWithPath:path];
// auido を再生するプレイヤーを作成する
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
[audioPlayer play];
[/objc]
以上で完成です。
シミュレーターで確認してみよう
それでは、本当にタップしたときに音がなるかためしてみてください。
このように連続でクリックしてもにゃーという音がなるのがわかります。
鳴き声足し算ゲームのまとめ
いかがでしたか?
もし今日にのある方はキッズアプリのように、背景に画像をつけてみましょう。
画像の素材はこちらからダウンロードしてみてください。
画像をドラッグ&ドロップして、プロジェクトへ導入したあと、イメージビューを置いてそこに設定します。
イメージビューは最下部へ配置しなおして完成です。
背景画像をセットして、音をつけてあげて、かつキーボードやイントロダクションを外部から取り込むことで、子供が喜びそうな本格的な知育系アプリにしてみたいと思います。
ぜひオリジナルアプリをつくるときに参考にしてみてください。