× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。 |
元々あるプロジェクトを元に
新しいプロジェクトを作る場合の手順。git-hub使用。 側かえのような場合。 0. 新しいプロジェクトのiOS dev center アカウント、バンドルIDなど決めておく。 必要ならprovisioning profileも用意しておく。 1. git-hubに行き、新しいプロジェクト用のリモートgitリポジトリを作る 2. 元プロジェクトのgitに行き、新しいプロジェクトをリモートに追加する $ git remote add new_name new_repository 3. 元プロジェクトの中身を新リポジトリにpush $ git push new_name master 4. git-hubで新プロジェクトを作る 5. 新プロジェクトを作るディレクトリに行き、git clone。 6. 新プロジェクトでpull $ git pull origin master ここで一度ビルドできるか確認しても良い 7. (必要なら)ディレクトリ名を変更し、コミット $ git mv old_dir_name/ new_dir_name/ $ git commit 8. プロジェクト設定の変更 ・プロジェクト名の変更 ・スキーム名の変更 ・バンドルIDの変更 ・provisioning profileの設定 9. その他変更 ・アプリ名変更 ・アプリアイコン変更 ・スプラッシュ変更 ・不要なライブラリパスなどを変更・削除 など 10. ビルドして実行できることを確認 11. commitしてpushする $ git add $ git commit $ git push origin master 12. 過去プロジェクトのコミットログが不要の場合は、コミットをまとめてしまってもよい。 $ git rebase -i --root で最初のコミットから全部rebaseできる。 PR |
Intentには設定できるプロパティがいろいろある。
action Intent.ACTION_VIEWなど data type MIME data type とか class Intent呼び出し時に使用するクラスを指定。そのクラスは onReceive(Context, Intent) メソッドをオーバーライドしていて、その中でextraなどを取得して処理を行う category Actionの振る舞いを明確にする。Intent.CATEGORY_BROWSABLEなど flag 呼び出される側の起動する振る舞い。例えばバックグラウンドで呼び出される場合はIntent.FLAG_FROM_BACKGROUND extra 付加情報。例えばIntent.EXTRA_TEXTを使えば、twitterクライアントを起動したとき、本文として表示させたいテキストなどをセットする 参考
PendingIntentは時間差でIntentを作るクラス。 calendar には起動させたい時刻が入っているとする。 LocalNotificationReceiver というクラスに onReceive() メソッドが定義されている。 これによってローカル通知が実装できることになる。 |
twitterに投稿したい。
手軽なので、Intentを使いたい。 ◯テキストだけの場合 めちゃ簡単。
◯画像も投稿する場合 twitterにテキストと画像を投稿する参考 |
Fileクラスの
createNewFile()……IOExceptionが投げられる mkdirs()……falseが返る などが実行できないとき マニフェストに を書くこと。 権限をアプリに持たせないと、外部ストレージに書き込みができない。 |
ttfファイルをどこかからダウンロード。
PROD_DIR/proj.android/assets/fonts/XXX.ttf に配置。 EclipseのPackageExplorerで F5 を押してrefreshすると、表示される。 Label::createで "fonts/XXX.ttf" を指定。ファイル名やフォント名でなく、assets以下のフルパスで指定することに注意。 これで表示されるようになる。 簡単。 なお、iOSではフォント名での指定なので、OSによって変える必要がある。 イケてないね。 |
Xcodeで作っていたcocosプロジェクトを、androidで動かそうとしたときにエラー。
とか言われる。 調べてみると 参考 libcurlというライブラリが問題らしい。 コンパイルオプションをつけると解決できるとか、NDKのバージョンを戻すと治るとか治らないとか情報が交錯しているが、 cocos2d-x 3.3rc2 以降だとlibcurlの問題が解決しているらしく、 最新のcocos2d-xをダウンロードして、 cocos2d-x-3.3rc2/external/curl/ ディレクトリをまるっとコピペしたら治った。 |
cocos2d-xで、スクロールビューの中身にメニューを配置したい。
簡単なことのようだが、実は問題がある。 メニューのアイテムをタッチすると、画面がスクロールできないのである。 つまり、アイテムの配置されていない箇所に指を触れてからスワイプしないと、画面がスクロールさせられないのである。 これは不便だしかっこわるい。 どうしてこうなっているのかというと… メニュー(Menu)にtouchBeganイベントが処理されると、イベントが飲み込まれ、ScrollViewのtouchBeganイベントが処理されなくなるのである。 ◯優先度について cocos2d-xでは、EventDispatcherクラスにタッチイベントを登録する際(タッチ以外にも、マウスやキーボードイベントなども登録できる)、優先度を指定して登録する。 2種類の方法がある。
1つめの方法は、シーングラフの優先度と同じ優先度になる。 つまり、描画順序と同じく、シーン上の親から子への順序でイベントが処理される。 2つめの方法は、第2引数で指定した固定優先度で実行される。値が小さいほど優先度が高い。マイナス値も使えるので、-INT_MAXが一番優先度が高くなる。 混ぜて使う場合、 固定優先度がマイナス値のもの。-INT_MAX→-1 ↓ シーングラフ優先度が高いものから低いもの ↓ 固定優先度が0またはプラス値のもの。0→INT_MAX という順番で処理される。 実装はEventDispatcher::dispatchEventToListeners()にある。 さて、メニューとスクロールビュー、どちらのタッチイベントが先に処理されるかというと、この優先度順序に依る訳である。 実装部分を見てみると、
という風に、どちらもシーングラフの優先度通りに実行されるようになっている。 当然といえば当然なのだが、これだと困る。 どんなときでも常にメニューが優先されるからだ(スクロールビューよりメニューが手前に表示されるはずなので)。 だからメニューのアイテム上をタッチしたときは、touchBeganイベントはスクロールビューに回ってこない。 メニューをタップしたいときはこれでいいが、スクロールしたいときは困る。 「メニューをタップしてそのまま離したときは、メニューのtouchBegan,touchEndedを処理。 メニューをタップして指を滑らしたときは、スクロールビューのtouchBegan,touchMoved,touchEndedを処理」 というふうにしたいのだ。 ということは、touchBeganの時点では、スクロールビューとメニューの両方で処理を走らせる必要がある。 ◯swallow設定 cocos2d-xのイベントには、スワローというメンバ変数がある。 スワローの意味は「飲み込む」。 複数のイベントリスナーが登録されているとき、1つのイベントは上記で見た優先度順に処理されていく訳だが、 その途中でswallowがtrueになっているイベントリスナーがあると、そこで処理が終了してしまう。それ以降のイベントリスナーには処理がわたらないようになっている(これが飲み込む、の意) で、もう一度さっきの実装コードを見てみると、メニューは touchListener->setSwallowTouches(true); と描いている。 つまり、タッチイベントはメニューに処理されると、それ以降他のノードには渡されなくなるのだ。もちろんスクロールビューにも、である。 なるほど、だからメニュー上をタップするとスクロールしないのか。 逆に、スクロールビューではスワロー設定をしていないので、デフォルトのfalseのままである。 ということは、 「メニューより先にスクロールビューでタッチイベントを処理すればいい」 のである。 スクロールビューで処理しても、優先度が低いイベントリスナーにも処理を渡すからだ。 ということで、スクロールビューのイベント登録部分を改造する。
優先度値はマイナス値ならとりあえず何でもいい。 これで試してみると、メニューをタップしてもちゃんとスクロールするようになる!! ◯メニュータップのタッチ処理を止める しかし、ちょっと動かしてみると少し違和感がある。 確かにメニュー上をタップしてもスクロールするようになるのだが、 スクロールしたあと指を離したときに、メニューアイテムが押されるのである。 指をメニューアイテムの無い場所で離せば何も起きないが、 要するにメニューのタッチイベントがまだ生きているのである。 よく見てみれば、タップしたメニューアイテムはselected状態のスプライトが表示されたままに鳴っている。 メニューのtouchBeganで始まった処理が有効で、指を離したときにtouchEndedが発生すると、その通りメニューアイテムを選択してしまうのである。 これはちょっといやだ。 スクロールした時点で、メニューのタッチイベントは終わらせたい。 そういう処理はなかったか? もちろんある。 onTouchCancelledだ。 これはタッチイベントが中断されたときに呼び出されるメソッドだ。 本来はタップ中に電話がかかってきてアプリが中断されたときとかに呼ばれる想定だが、今回の目的はまさにこのメソッドを呼ぶことにある。 つまり、「スクロールビューのスクロールが発生した時点で、登録されている他のすべてのイベントリスナーのonTouchCancelledを呼び出す」 ということである。 onTouchMovedやonTouchEndedは呼び出させないのだ。 さてどうするか。 そもそもonTouch***系を呼び出している部分のコードを見てみる。
dispatchEventToListeners()の中で、優先度順のループが3つあり(固定優先度がマイナス値のもの、シーングラフ優先度のもの、固定優先度がプラス値のもの)、順番にonEventメソッドを呼んでいる。 onEventメソッドの実体はdispatchTouchEventの中のonTouchEvent というラムダ関数で、 この中でイベントリスナーを処理し、それぞれonTouchXXX関数を呼び出している。 スクロールビューのonTouchMovedの中でスクロールが発生したと判断したときに、 それ以降のイベントリスナーについてはすべてonTouchCancelledを呼び出すようにすればいい。 ということで、EventDispatcherクラスに_touchEventForceCancelled というフラグを用意し、以下のように改造する。
とする。 解説。ScrollViewのonTouchMovedで、スクロール発生と判断されたタイミングで、EventDispatcherに、「以降のタッチイベントをすべてキャンセルさせろ」というフラグを立てる。 すると、それ以降のEventDispatcher::dispatchTouchEvent()内の処理で、タッチイベントはすべてEventTouch::EventCode::CANCELLEDに強制的に書き換える、ということである。 これで、メニュー上をタップしても、指を滑らせてスクロールすると、メニューのタッチイベントはキャンセルされる。 スプライトは選択状態のものから通常状態のものに戻るし、指を離してもアイテムは選択されない。 ◯スクロールビューの無効化 スクロールビューにはもう一つバグがある。それは 「不可視状態でもタッチイベントが処理され、スクロールしている」 ということである。 正確なことを言うと、 スクロールビュー自体にsetVisible(false) を呼び出していれば処理されないのだが、 スクロールビューの祖先ノードでsetVisible(false)をしていて、スクロールビュー自体の_isVisibleがtrueのままの場合、処理されてしまう。 普通、他の種類のクラス(メニューとか)だと、親が_isVisible==falseなら処理しないようになっているので(普通に考えてそれが正しい)、スクロールビューがバグっている。 スクロールビューはextension扱いだし、どうもこういう不具合がまだ多い。 これに対処するのは割と簡単で、 onTouchXXX()系のすべての関数の先頭に以下のコードを書き足せば良い。
このコードは、Menu.cppからコピペしたものである。 |
swiftで通信を行うフレームワークと言えばAlamofire。
これをプロジェクトに追加する手順。 基本はgit-hubのREADMEの通りにやればよい。 git-hub 文字だけで分かりにくいので、画像付きで。 まず、プロジェクトのトップディレクトリで以下のコマンドを実行 $ git submodule add https://github.com/Alamofire/Alamofire.git これで、Alamofire/ というディレクトリができ、中にフレームワークがひとそろい配置される 次に、中のAlamofire.xcodeprojをドラッグ&ドロップして自分のプロジェクトに追加 AlamofireのPROJECTペインを選択し(自分のプロジェクトではない)、DeploymentTargetのOSバージョンを設定する。 ここ重要。 ここで設定したOSメジャーバージョン以上の端末でしか動作しなくなる。 自分のプロジェクト側の Build Settings でそれより低いメジャーバージョンを設定すると… ビルドエラーになる。 注意すること さらに、自分のプロジェクトの Build Phases を選び、 Target Dependincies にAlamofire.frameworkを追加。 左上の「+」ボタンから、新たに「CopyFramework 」という名前のフェーズを作成し、そこにもAlamofire.frameworkを追加。 これにてAlamofireが使えるようになる。 |
cocos2d-xにあるSpriteBatchNodeクラス。
複数のスプライトを効率よく描画したいときに使う。 例えば同じ絵のキャラを大量にわらわらと表示させたいとき。 SpriteBatchNodeクラスのインスタンスのノードを作り、このクラスにテクスチャを登録する。 その子ノードに同じテクスチャを貼ったスプライトを大量に付ける。 すると、一度の描画命令で子ノードが全部描画できる。 ポイントは、SpriteBatchNodeクラスに登録したテクスチャと 「同じテクスチャ」を持つノードしか子ノードにできないこと。 テクスチャでなく、SpriteFrameでも良い。アニメーションする場合や、複数の絵を子ノードに並べたいときはSpriteFrameを使うことになるだろう。 実際に描画回数が減っているかどうかは、 画面左下に出ている。 GL calls が描画回数、 GL verts が頂点数。 GL callsがテクスチャ数より少なくなっていれば、効いている…はず 詳しいところはもう少しコードを追いかけてみる。 ちなみにLabelクラスはSpriteBatchNodeの子クラスである。 …といったところで、 v3.xでは標準でドローをまとめる機能がついたらしく、SpriteBatchNodeは非推奨になったとかなんとか。 参考 |