2012年5月17日木曜日

Androidでcocos2d-xをやり始めた


さて、巷では「cocos2d!cocos2d!」と騒がれています。
しかし、この話は専らiPhoneアプリのお話です。
私もAndroidでcocos2d使いたい!
けど、cocos2d for Androidは死んでいるみたいな噂話もあるからどうしよう…。
そんな私に朗報です。
Androidでも使えるcocos2dがあります。
その名もcocos2d-x
cocos2d-xはクロスプラットフォームで行えるのでとっても便利です。
そして、こまめにアップデートやメンテナンスもされていて素敵です。
これを使うしかないな!ということで使いたいとなって環境構築のお話です。
書いていく言語はC/C++なのがネックですが、頑張ります。

ちなみに参考にしたのはこちらです。
Facebook内のcocos2d Developers Japanというグループで紹介されていた記事
そして我らが@yoichinejiさんがブログに書かれていた記事
この二つを読み解いて、少しずつ環境構築を行っていきましょう。

注意!
私は開発に関わるものは基本的に/Applications内に入れるようにしています。
そのため、サンプルで上げているパスが/Applications始まりになっていますが、パスは各自の環境に合わせて修正をしてください!

1.cocos2d-xをインストールする

まず、Androidでcocos2d-xを使うとなると、AndroidのSDK環境だけではなくNDKの環境が必要となります。
C/C++で書いていきますからね。
AndroidのNDK環境の環境構築に関しては、先達の素晴らしい方々がブログに記事を残していますので、そちらを参考にしてください。
cocos2d-xの箇所から書いていきたいと思います。

まず、cocos2d-xのダウンロードページから、zipファイルを落としてきます。
私は現時点で、最新の安定板としてcocos2d-1.0.1-x-0.12.0.zipを落としてきました。
落としてきたzipファイルを任意の箇所に展開します。
そして、コマンドでcocos2d-xのフォルダに移動します。
$ cd /Applications/cocos2d-1.0.1-x-0.12.0 
この中にcreate-android-project.shというファイルがあります。
このファイルを編集しなければならないのですが、このように編集します。

CotEditor好きなんです
ここで重要になるのは、
  • NDK_ROOT_LOCAL="/Applications/android-ndk-r8"
  • ANDROID_SDK_ROOT_LOCAL="/Applications/android-sdk-macosx"
というものです。
これは各自の環境に合わせてパスを指定してください。
よくAndroidSDKですと、「/Applications/android-sdk-macosx/tools」まで指定することがありますが、今回は必要ないです。
何故かと言いますと、cocos2d-x側で補完してくれます。
この箇所は注意してください。

これでできる!と思ったのでcreate-android-project.shを実行しましたところ、多いにエラーが吐かれました。
しかも,
「AndroidSDKのtools/androidがないよ!」
と怒られていました。
確認したところありました。
うーんうーんと唸りながら色々見ていますと、create-android-project.sh内にNDK_ROOTなるものがあります。
なんだろう?と思いながら、.bash_profileファイルにAndroidNDKのパスをNDK_ROOTに設定しまして、create-android-project.shを実行しましたところ動きました。
よくわからないです。

2.cocos2d-xをビルドしてみる

1の段階で少し触れましたが実際にどのようにビルドを行うのかを書いていきます。
まず、前述した通りにコマンドでcocos2d-xのフォルダに移動します。
次に、create-android-project.shを実行します。
実行コマンドは下記の通りです。
$ ./create-android-project.sh
実行しますとこのようにターミナルに表示されます。
Input package path. For example: org.cocos2dx.exampleと出ていますので、使用するパッケージ名を入力していきます。
ただ、ここで注意したいのはNDKを利用しますので途中でパッケージ名を変えますと、Java側だけではなく、C/C++側に記載したパッケージ名の変更も発生します。
SDKからNDKのメソッドを呼び出すには、NDK側で呼び出されるメソッド名がパッケージ名から始まるのです。
例えば「jp.co.megmegfive.startGame」といったメソッド名にしないと呼べなかったと思います。
そのため、パッケージ名を変更するとなるとリファクタリングの量が多くなってしまいます。
一気にリファクタリングができるかあやふやですが、後々のことを考えますとこの段階でパッケージ名を決定させておくと後々楽になるのではないかとおもいます。
一度NDK周りでこのパッケージ名の変更でとんでもなくはまったことがありますからね…。
あんな思いはしたくないです。

閑話休題。

ずらずらと出てきました!
パッケージ名を入力しますとターゲットの一覧が表示されます。
これはAndroidSDKでインストールしている内容ですので、それぞれが違うと思います。
表示されたidを入力します
input target idとありますので、リストで表示されたidを入力します。

idとプロジェクト名を入力しました。
ターゲットを入力しますと、input your project name:と表示されますので、任意のプロジェクト名を入力して下さい。
ずらずらっとまた出ました。
プロジェクト名を入力して、上記のような画像が表示されたらビルドの成功です!
ここまで辿り着くまでがとても長かったです。

3.Eclipseに読み込む

ビルドが通りましたので、今度はEclipseに読み込んでapkファイルを作成していきます。
先ほどビルドしたものは、cocos2d-x直下に記載したプロジェクト名でフォルダが作成されています。
フォルダの中はこのような構成になっています。
シンプル
これでEclipseに読み込めばOKというとそうではありません。
最初にやってしまいましたが、このままandroidフォルダでプロジェクトを作成しましてもエラーがあるためビルドが通りませんでした。
よくよくみますとlibs/armeabiフォルダがありません。
NDKの場合ですと、この中にある.soファイルを読み取ってAndroidSDKと連携を取っていきます。
では、どうやって.soファイルを作るかと言いますと、まず、コマンドでプロジェクトのandroidフォルダに移動します。
次に、
./build_native.sh
というコマンドを実行します。
このコマンドを実行しますと、nativeのビルドが実行されていきます。
ものすごくログは長いです。
この前に大量のログがあるので一部割愛しています。
注目すべきは最後の7行目からです。
.soファイルの生成に成功したようです。
よかったよかった。

さて、本題のEclipseへの読み込みです。
右クリックをして、
New→Android Projectを選択。
ダイアログが表示されますので、先ほど書きましたプロジェクト名を入力します。
それからCreate project from existing sourceを選択しまして、
cocos2d-xのフォルダ/プロジェクト名/android
をLocationとして選択します。
こんな感じで入力します
次にNextを選びまして、2で選んだビルドターゲットを同じものを選びます。
異なるビルドターゲットを選んで齟齬が起きるんじゃないかと思ってこうしています。
実際はわからないですが、揃えられるのなら揃えていた方が安全な気はします。
私はAPI Level8のものを選んだので、それにしています。
そしてダイアログのFinishボタンを押しますとEclipseにプロジェクトが生成されます。
これでEclipseへの読み込みは完了です。

4.Eclipseからアプリをインストール

ここから先は通常のAndroid アプリと同じです。
新規作成したプロジェクトですので、念のためProject→Cleanを選びます。
これでクリーンビルドは完了です。
次に、プロジェクトを選択してRun As→Android Applicationを選択します。
そうしますと、先ほどビルドを行ったapkファイルが端末にインストールされます。
T-01Cだからfpsが残念すぎる…。
この画面が表示されましたら、無事に環境が整ったということです!
これでcocos2d-xで開発ができますね!

5.まとめ

家でおおいにターゲット一覧が出なくてハマった理由の解消法としまして、

  • AndroidSDKを置いているディレクトリ名を変更した(android-sdk-mac_x86からandroid-sdk-macにしました)
  • パス指定の修正
2番目は凡ミスとしましても、1番目はなんでダメだったんでしょうかね?
よくわからなかったです…。


さて、cocos2d-xやcocos2dもほとんどわかっていないので、これからも情報発信はしていきますが、かなり遅くなると思います。
C/C++もさっぱりわかっていないので、さらに時間がかかりそうではあります。
それでも少しずつやっていこうかと思っていますので、よろしくお願いします。

とりあえず、どなたかに簡単に開発の基礎を教えていただければ嬉しいです!
そのためにもcocos2dのあのイベントには参加しなければ…!

2012年4月23日月曜日

第1回Android開発者のための初めてのiPhoneアプリハンズオン勉強会に参加したよ

参加というか、正確にはチューターとしてひーこら言いながら働いていました。
イベントはこちらで告知されていたものです。

第1回Android開発者のための初めてのiPhoneアプリハンズオン勉強会[女性枠] #andiphone #andronjo

第1回Android開発者のための初めてのiPhoneアプリハンズオン勉強会[男性枠] #andiphone


講師:@corosuke_kさん
講師の模様をメモを取る係:@muo_jpさん
愉快な仲間1号:@yoichinejiさん
愉快な仲間2号:@corruptexさん
愉快な仲間3号:@f_megmeg5(私)

また、こちらでtogetterのまとめがあります。
第1回Android開発者のための初めてのiPhoneアプリハンズオン勉強会

私はイベントの模様は写真を撮っていないのですが、他の方が写真を撮っていると信じています。
というか、あの状況では撮れませぬ…。
色々やっていたのでそういう暇がなかったなんですよね。

さて、本題です。
ハンズオン自体は、ハッシュタグとmup_jpさんのメモやコードをWebサービスを使って表示させていたので、情報共有は強固にできたのではないかと思います。
こちらは参加者の方やmup_jpさんのおかげで本当に助かりました。
コンソールアプリでひたすらログを出す時は、苦戦されている方も多かったようです。
よくよく見ていますと、Android(というよりもJavaかな?)の命名規約とobjective-cの命名規約が異なるので、メソッド名のスペルが合っていても大文字小文字でエラーが出るといったこともありました。
これに関しましては、ソース補間をやれば少しは軽減できたのではないかと思いました。
escボタンでXcodeは補間ができますしね。

実際にiPhoneアプリを作るときになりますと、InterfaceBuilderとクラスの補間能力の違いで楽しんでくれている方が多かったと思います。
私もちゃんとは扱っていなかったのですが、IBOutletやIBActionも先に.hファイルに定義しないでも、みーっと引っ張って、そこで定義を行えば.mや.hに自動的に書かれるんですね!
これは便利すぎます。
ただ、その便利さのおかげで弊害として起きたのは、実はいらないIBOutletをソースから消しても.xibファイルに残っているために、実行時にエラーが起きてしまうパターンにはまっている方も多かったようでした。
ここは今回の経験を活かして、次から気を付けてもらえれば良いのかなってなりました。

チューター組はてんやわんやしていましたが、結構楽しんでもらえたのではないかと思っています。
お約束事はAndroidとiPhoneとでは違うことも多いですから、そこは慣れるしかないですしね。

参加者の方がかなり詰まっていたというか、理解するのに時間がかかっていたなと思ったのはメモリ管理部分です。
JavaですとGCのおかげで、メモリ管理を気にしないですみます。
Androidの場合ですと、GCだけではなく自分で適宜色々やらないといけないですが。
ただobjective-cですと、メモリ管理が重要になります。
iOS5からARCが入ってきましたが、基本的なことですし、ライブラリによってはARCに対応していないものもありますので、どのように行っていくのかが重要になります。
「releaseとautoreleaseの違いはなんだ?」となっている方もいましたし、retainとreleaseの使いどころもよくわからない方も多かったと思います。
今までC関連の言語を扱ったことがある方なら理解しやすかったかもしれませんが、そうではない方ですとチンプンカンプンだったと思います。
私も最初はわかりませんでしたからね…。

このメモリ管理の部分に関しましては、Twitterを見ていたらしい@splhacksさんがハッシュタグ付きで書かれていましたので、参考書として読むのが一番良いと思います。
というか、むしろ会場に来て話してほしかったね、ところすけさんと話していましたw


後、今回の反省点というか次に活かせたら良いのではないのかなとなったことです。

資料やソースコードの共有は早めに行う

これは大事です。
実際に、当日になるまで何をやるのかをチューター組は把握できていませんでした。
また、
「なんでこういう書き方をするんだろう?」
となってしまった部分も多かったですので、そこの理解をチューター側がもてるようにする時間も欲しかったのです。
ころすけさんも忙しいようでしたから高望みなのかもしれませんが、次はもうちょっと余裕を持って準備していけたら良いな!となりました。
そういう面で、私が本当に書き方やちょっとしたテクニックを忘れまくっていて、あばばばばばとなっていたんですよね…。
本当に参加者の方には申し訳なかったです。
さすがに1年以上触っていなくて、まともに最新情報を追えていないと大変なことになることを実感しました。
む、難しかったな…!

ソースコードが見やすい机配置にする

今回、ちょくちょく聞こえたのが、
「ソースが見えにくい」
というものでした。
そのため、次は大きなディスプレイが見やすい位置に机を配置した方が良いのかなとなりました。
途中から、全体的に前に詰めましたしね。


チューターの人数を増やす

今回はチューターが3人でしたが、もう一人二人いてほしかったなーとなりました。
わからない方を長時間放置することになってしまう時もあったので、そういうことを無くすためにも人手が欲しかったです。
ころすけさんの魅力なら人が集まるよ!!!


とりあえずはこんなところです。
立ちっぱなしで疲れもしましたが、参加された方が楽しそうだったので良かったです。
次回もあればお手伝いしたいなと思っています。

2012年4月18日水曜日

TextViewでリンクを付けてみよう

開発中のアプリで、
「テキストの途中にリンクを入れて欲しいなー。ほら、htmlみたいに!」
といったことがありましたので、備忘録です。

TextView内でリンク処理を入れるには大まかに分けて3つのパターンがあります。

  1. Linkify.addLinksで行う
  2. TextViewの属性であるandroid:autoLinkを使う
  3. TextViewにhtmlの文字列を読み込ませる
こんな感じです。
で、最終的には3を使ったのですが、最初に1を使ってはまってしまいました。


1.Linkify.addLinksで行う


TextView textLink = (TextView)findViewById(R.id.textLink);
textLink.setText("頑張ってぐぐるよ!");
Pattern pattern = Pattern.compile("ぐぐる");
String scheme = "https://www.google.co.jp/";
Linkify.addLinks(textLink , pattern, scheme);

これだけです。
これで「ぐぐる」の部分にリンクが表示されます。
まあ、便利。
ただ、Linkifyはちょっとした問題があります。
それは「スキーマで指定したURLの後にパターンで指定した文字列がくっついて表示される」ということです。
これには地味にはまりました。
Applies a regex to the text of a TextView turning the matches into links. If links are found then UrlSpans are applied to the link text match areas, and the movement method for the text is changed to LinkMovementMethod.
と思いっきり「into links」ってあるやん!となってしまいまして、ふりだしに戻りました。

2.TextViewの属性であるandroid:autoLinkを使う

これはよくある方法です。
この中で定義されている「android:autolink」の属性で自動的に読み取ってリンク化してくれます。
とっても便利。
ちなみに設定できる値は下記の通りです。
  • web:リンクにURLを貼り、ブラウザを起動させる
  • email:メールアドレスにリンクを貼り、メーラーを起動させる
  • phone:電話番号にリンクを貼り、電話を起動させる
  • map:住所にリンクを貼り、マップを起動させる
  • all:上記全てにリンクを貼り、各リンクに合わせた挙動を行ってくれる
うん、とっても便利ですね。
でも、これだけですとhtmlのような文字リンクが実現できません。
そのため、最後にこの方法で実現させました。

3.TextViewにhtmlの文字列を読み込ませる

大雑把に言うとこんな感じですので、コードを載せます。

TextView textLink = (TextView)findViewById(R.id.textLink);
CharSequence charSequence = Html.fromHtml("がんばってぐぐるよ!");
MovementMethod mMethod = LinkMovementMethod.getInstance();
textLink.setMovementMethod(mMethod);
textLink.setText(charSequence);  

こんな感じで書いていきますと「ぐぐる」の箇所にリンクが貼れます。
最終的にはこれで行きまして、なんとかうまくいきました。
ただ、2で説明しました「android:autolink」属性をxmlに定義しますと、リンクが表示されなくなってかなりはまってしまいましたので注意してください。

ちょっと長くなりましたが、このようにして私は実装を行ってきました。
そのうちネタが集まったら改めて更新しようっと。

Androidアプリ開発者のためのiPhoneアプリ開発ハンズオンに参加します

来る4/22に渋谷で行われるイベントにチューターとして参加します!

第1回Android開発者のための初めてのiPhoneアプリハンズオン勉強会[女性枠] #andiphone #andronjo

第1回Android開発者のための初めてのiPhoneアプリハンズオン勉強会[男性枠] #andiphone

講師はCoronaSDKのエバンジェリストであるころすけさん(@corosuke_k)です!


ころすけさんと愉快な仲間達でやることになっていますので、お時間のある方はまだ残席があるようですのでぜひぜひー。


今気付いたけど、愉快な仲間達になった経緯はねじさん(@yoichineji)のさいたま勉強会な気がするんだな。
さいたま勉強会は蕨の商工会議所で不定期に行われていますので、もし行われるのでしたら告知しますね。


あああ、頑張ってobjective-cの勉強をしなくっちゃ!

2012年3月6日火曜日

UnityのiOSとAndroidライセンスが無料!?

こんにちは、とってもwktkして仕事が手につきません!
嘘です。
心が折れているだけです。

なのでちょっとした雑談でもしたくなっちゃったのです。
さて、昨日の夜からTLを騒がしているのが表題の件です。
ちなみにここからできるらしいです。
https://store.unity3d.com/

500エラーが発生しちょる・・・。
どうやら世界中からアクセスがあって、どーんと落ちているようですね。
Unityのライセンスの違いは「強火で進め」を書かれているnakamura001さんの記事が参考になります。





ライセンスをゲットして、Unityで遊ぶぞー!