Cocos2d-x Advent Calendar 7日目です。
バックキー対応してますか?
ほとんどのcocos2dxで開発してる方はXcodeで開発&iPhoneシミュレータで動作確認してると思いますが、「じゃあAndroidで動かすか」ってなった段階で慌てて対応しがちなのがAndroidのバックキーです。
GoogleはAndroidのバックキーに対応していないアプリをGoogle Play上でフィーチャーしないので、アプリをフィーチャーさせてユーザーを集めたい場合は嫌でも対応する必要があります。
これまで仕事で何度か似たようなコードを書いてきたので、今回は再利用しやすい形でゼロから書きなおしてみました。
そもそもバックキー対応って何すればいいの?(iOSしか触ったことない人向け)
Android端末にはデバイス自体にバックキーが存在します(2.xではハードウェアキー、4.xではソフトウェアキー)。
このキーを押した時にユーザーが期待する挙動は、ざっくり言うと「ひとつ前の状態に戻る」です。
具体的には、
- ひとつ前の画面に戻る
- ダイアログが開いている状態だと、ダイアログを閉じる
- レースゲーム中は、ポーズメニューを表示する
などが挙げられます。
つくった
で、作ったバックキー対応クラスがこちら
ライセンスはpublic domainです。ご自由に持ってってください。
使い方
基底クラスをインポート
上のリポジトリから、
- BaseScene.h
- BaseScene.cpp
- BaseLayer.h
- BaseLayer.cpp
を持ってきて、プロジェクトに追加します。
あとは、cocos2d::Sceneやcocos2d::Layerを継承しているところを、BaseSceneとBaseLayerに置き換えればOK
BaseScene
BaseSceneは、cocos2d::Sceneのサブクラスです。
使い方は通常のSceneと同じなので省略。
DirectorのpushScene, popSceneでシーン遷移してください。
BaseLayer
BaseLayerは、cocos2d::Layerのサブクラスです。
シーンの上に重ねるBaseLayerはバックキーでキャンセルが可能になってます。
ダイアログのようなUIを作るのに使用してください。
簡単な使い方は以下の通り。
addChild, removeChildのかわりにshow, dismissを使用してください。
// MyLayerはBaseLayerのサブクラスです
// 現在のシーンの上に、MyLayerをのせます
auto layer = MyLayer::create();
layer->show();
// MyLayerを取り除きます
layer->dismiss();
バックキーを押した時の挙動を変更する
場合によっては、バックキーを押した時にレイヤーやシーンを消す以外の動作をさせたいことがあると思います。
例えば、レースゲーム中にバックキーを押したらポーズメニューを表示したい、などのケースです。
そんなときは、onAndroidBackKeyPressedをオーバーライドしてください。
void MyScene::onAndroidBackKeyPressed() {
// シーンを戻す代わりに、ポーズメニューを開く
auto pauseLayer = PauseLayer::create();
pauseLayer->show();
}
バックキーで戻せないようにしたい場合
特定のレイヤーやシーンではユーザーにキャンセルさせたくないこともあると思います。
その場合は、setAndroidBackKeyEnabled(bool)でバックキーの有効・無効を指定してください。
bool MyScene::init() {
if (!BaseScene::init()) {
return false;
}
// このシーンはバックキーで戻せません
setAndroidBackKeyEnabled(false);
// ここでUIを初期化(省略)
return true;
}
bool MyLayer::init() {
if (!BaseLayer::init()) {
return false;
}
// このレイヤーはバックキーで戻せません
setAndroidBackKeyEnabled(false);
// ここでUIを初期化(省略)
return true;
}