読者です 読者をやめる 読者になる 読者になる

$a(){ a|a& };a

京大生かもしれない

CCDxLib72を使って過去に作ったゲーム3種をAndroidに移植してみた

はじめに

前回の記事で、Cocos2dxで動くDxLibの関数群のライブラリであるCCDxLib72を公開しました!
今回の記事は、それで実際にGooglePlayに出したところまで解説します!chy72.hatenablog.com

完成品

最初に完成品を見せるのが一番だろうということで。

①GreedGreen

GreedGreen - Google Play の Android アプリ
https://lh3.googleusercontent.com/fyqJneg92hJImrRrwKXALhyQpeXOn07YnSZ3-qDwI8ht03HSC_p55jPHMYJ9idDzq88=h900

高校生の後輩がDxLibで作成したゲームです。
全体的にすっきりとしていて、操作ももともとマウス操作なのでスマホにそのまま移植しても綺麗に動きました。
紹介する三作品の中で一番スマホで遊びやすくてオススメです。

②Celestial

Celestial - Google Play の Android アプリ
https://lh3.googleusercontent.com/zyX1fGTCfVDCSXOdmCQHwB_3EkruLHJDsMYC-Fwflq2BNwBr3e-iQVao8_AbPmVGXA=h900

僕が高校3年の頃にDxLibで作成したゲームです。
とりあえずWindows版のまま殆ど手を加えずに移植したので、操作性・見やすさは難ありです。
(絵も音楽も自分で作ったのと、受験期だったという理由で、作品のレベルに関してはご容赦ください)

③日本史クイズ

日本史クイズ - Google Play の Android アプリ
https://lh3.googleusercontent.com/PA0aPALf8wZKA53tjPIDx8Gg8wm0H1dlU-SySnCvSa02ckgmUmU5A0grqoDx1n4qvQ=h900

これも後輩がDxLibで作成したゲームです。
操作はもともとマウス操作だったので、スマホにそのまま移植しても操作はできてよかったのですが、スマホの小さい画面では見づらいかもしれないです。

元となるゲームを用意

github.com
(残り2つの作品は、もともと自分が作ったゲームではない(後輩が作った)ので、コードを公開するのも気が引けるので…)
まずは、元となるDxLibで動くゲームを用意します。

移行

まずは、cocosのプロジェクトを作成します。
最初のHelloWorldSceneがAndroidでも動くところまでは自力でお願いします。
移行した時に躓いたところを中心に列挙します。

コードのリファクタリング

  • Data という名前の変数をもともと使用していました。しかしCocosにもDataというクラスはあるので、そのDataという変数を一括でcDataという名前に置き換えました。
  • ShiftJisでもともとコードを保存していましたが、DrawStringで文字化けが発生するのでUTF-8(コードはBOMあり、読み込むテキストファイルはBOMなし)に変更しました。
  • #define RED とかしていたのですが、それがCocosのColor3Bクラスの REDと競合したので sRED とかに変えました
  • windows.h(ShellExeCuteに利用)など、Windows専用のヘッダーはincludeしないようにしました
  • main.cpp というファイルを使っていたのですが、cocosのmain.cppと競合したので、main2.cppという名前に変更しました。

bmppng

BGMの読み込み

  • 内部ではSimpleAudioEngineというものを利用して音を鳴らしているのですが、メモリに先立って読み込めるのは確か10秒程度までの効果音なので、10秒以下の効果音を読み込む前に SetCreateSoundDataType(DX_SOUNDDATATYPE_MEMNOPRESS) を、10秒以上のBGMを読み込むときはSetCreateSoundDataType(DX_SOUNDDATATYPE_MEMPRESS)を宣言します。

ファイル入出力変更

  • 普通にfopenなどをしたいところですが、Resourcesに同梱してアプリに入れるデータは、読み込みしかできないこと、AndroidのManagerを利用してしか読み込めないということがあるので、それ専用の機能としたFileRead~~ の関数に書き換えます。
  • また、書き換えるデータ(セーブデータなど)は、専用の場所に新しくファイルを作成するため、専用の関数UserDatafopenにfopenを変更します。(移行は普通にfseekとかもできます)fopenをしたくない場合は、getUserDataPath()を利用して、書き換え可能なパスを取得して使います。

操作方法変更

  • Androidにはキーボードはないので、新たに作成したエミュレート用の関数を宣言します。
  • これが一番重要なのですが、ここが一番スマホとパソコンとの大きな違いなので、もともとマウスで操作するゲームをタッチ操作に置きかえるのならともかく、キーボードで操作するゲームをタッチしかないスマホに置きかえると、単純に置き換えただけでは操作性を激しく損なう(このゲームがよく分かる例)ことを注意してください。

ロジック変更

  • InitやCCDxStartやCCDxLoopを使う形に変更します。
  • ProcessMessage,ScreenFlipでループを作って利用しているコードがあると思いますが、CCDxLib72では、ProcessMessageに当たるものがなく、CCDxLoopを抜けるということでしかProcessMessageやScreenFlipすることができません。
  • そういう部分がもしもあれば、ロジックを考えて書き直すしかありません。(通常は、ゲーム全体として一つの大きなループでしかないと思うので、その場合は必要ありません)
  • 理由としては、cocos2dxの方へCCDxLoopを抜けたあとに制御を返して、他の処理(イベント処理やFPS制御やDxLibでいうProcessMessageや他のSceneの処理)をしてもらって描画するという形をとっているからです。
  • ProcessMessageに当たる関数を作成することも考えたのですが、それをすると他のcocos2dxの機能(Widgetなど)が使えなくなったり、バージョンアップで動かなくなったり、マルチプラットフォーム対応が難しくなったりしそうだったので、これに関してはご容赦ください。代わりにただのSceneとしてしかCCDxLibは存在しないので、他のcocosの機能は使い放題だと喜んでください!
  • メモ:この処理をうまく非同期にできれば、可能かもしれません、強い方、実践してください。

完成

以上の変更(cocosの機能に関する変換(png,BGM,UTF8),マルチプラットフォームに関する変換(fopen,Emulate),ProcessMessage)を行い、cocos compile -p android で、コンパイルして、Googleに3000円投げてアカウント開いてGooglePlayにapkを投げて必要事項を記入したらすぐ公開です!

思ったこと

DxLibで作成したゲームは、どうしてもPC用に最適化されていて、コードをそのまま写しただけだとどうしても操作性がやや難になってしまいます。画面も小さくなるので意識していないと見辛くなることもしばしばです。なので、このライブラリでは移植の大部分を手助けすることはできますが、根幹の操作性だとかユーザビリティというところまではどうしても対処できないということを思いました。
やはり、ユーザーのことを考えるなら、苦を覚悟して手をかなり加える必要があるのかもしれません