ゲームを作っていると様々な問題が発生する。ツクールMVをベースにオリジナルシーンを一つ作っているだけでも多くの問題が発生している。
隠れているはずのボタンを押せてしまう
Z座標的に、より前面にコンテナがあれば、奥にあるコンテナに配置したボタンは押せないと思い込んでいたけど全然そんなことなかった。前面に表示中のコンテナがあれば~という判定は難しそうな気がしたので、あるコンテナを表示すると奥にまわることになるコンテナを明示的に非表示にすることにした。こうしておけば Sprite_Button.isActive() が親ノードを参照したときに false を返すようになるのでボタンが誤動作することは避けられる。
ボタンの無効状態やホバー状態を表現できない
ツクールMVの Sprite_Button では、ボタンが見えているけど押せない「無効状態」や、ボタンの上にカーソルを合わせたときにボタンを強調表示する「ホバー状態」を表現することができなかった。ソースコードを覗いてみると、押されていない状態(Cold)と、押されている状態(Hot)しか用意されていなかったので、既存コードをコピペして「無効状態」と「ホバー状態」を増設した。しかし「ホバー状態」がうまく動いてくれない。原因は TouchInput から現在座標(x, y)を取得できていないからだった。なぜ現在座標を取得できていないかと言うと、TouchInput の座標はボタンを押しているときしか更新していないから。嫌がらせかな?
TouchInput._onMouseMove = function(event) { if (this._mousePressed) { var x = Graphics.pageToCanvasX(event.pageX); var y = Graphics.pageToCanvasY(event.pageY); this._onMove(x, y); } }; TouchInput._onMove = function(x, y) { this._events.moved = true; this._x = x; this._y = y; };
“TouchInput\.[xy]”を grep して出てきたものを眺めたところ TouchInput の座標を常に更新するように変更しても問題なさそうに思えたが、実はこういうケースでは問題が生じることがありましたーみたいな見落としがあると面倒なので、マウスを動かしたときに常に更新する mouseX と mouseY というプロパティを増設することにした。
ボタンが動かない
ボタンが動かない。PIXI.Container の上に配置していたからだった。Scene_XXX は毎フレーム updateChildren を実行して Scene(≒PIXI.Application.stage) に追加した子供達の状態を更新している。ツクールMVのオブジェクトのみで組んでいれば Scene > Container > Sprite と処理が伝わっていくのだけど、PIXI.Container には子供達の update を実行する機能が備わっていないので PIXI.Container に置いたボタンは動かなかった。ツクールMVに使えるオブジェクトがあるかもしれないけど今回は PIXI.Container を継承して update を追加しただけのコンテナを用意した。探すのめんどくさいから。
コンボボックスがない
いや、あると思うけど、私にも使えそうなものを見つけることが出来なかった。仕方がないので今回使う機能だけ有したコンボボックスもどきを作った。コンボボックスの値を変更したときに指定 function を実行する仕組みについては Sprite_Button の setClickHandler や callClickHandler あたりを参考にした。オリジナルイベントとか addEventListener は必要なかった。
なんとなくできているように見えるけど、自分が使う機能しか実装していないのでいろいろ足りない。項目を減らすことすらできない。増やすのみ。
コンボボックスを作ってから思ったけど、コンボボックスだと状態を変更するのに開いて選択するという 2 アクション必要になるので、選択肢が少ない場合はラジオボタンを用意するか、ボタンを単純に並べても良かったなと思った。まあ設定画面なんてそんなに触らないからコンボボックスでも良しとしておこう。
コンテナをスクロールできない
これもそういう部品や実装が見つかっても良さそうだけど、私にも使えそうなものを見つけることが出来なかった。仕方がないので PIXI.Container を継承してマウスホイールで動かすことのできるコンテナを作った。ホイールの値の取り方については Window_Selectable の processWheel を参考にした。
Window_Selectable.prototype.processWheel = function() { if (this.isOpenAndActive()) { var threshold = 20; if (TouchInput.wheelY >= threshold) { this.scrollDown(); } if (TouchInput.wheelY <= -threshold) { this.scrollUp(); } } };
データを保存できない
よく分からないけど下記のような json を DataManager に読みこませて、そのまま DataManager.makeSaveContents をいじって出力させると "Cannot read property 'name' of undefined" て言われた。
[ {“name”:”a”,”value”:0}, {“name”:”b”,”value”:1} ]
$dataSystem を同様に出力しても再現しなかったので、私が用意した json の一番外の [] が悪さをしているのかもしれない。Actors.json を参考にしたつもりだったけど何かミスったかな。ちなみにエラーは次の箇所で出ていた。
JsonEx._getConstructorName = function(value) { var name = value.constructor.name;
プログラムはそのままに、エラーが出ないようデータを加工して対応した。
素材を用意できない
最初は適当にいろんなところをフラフラしていた。これはどうにも埒が明かないということで、センスがいいと思っている鳥の人こと『白井リス』さんの『カラスノオタカラ』のクレジット的なものを参考に探すことにした。すると無料とは思えない超絶クオリティの素材がゴロゴロ見つかった。この人達は一体何を考えているんだ・・・と思ったけど供給過多なのだろうということにしておいた。捜索を続けていると『DLSite』というところに辿りついた。
『DLSite』にはクオリティの高い素材が転がっている。特に使う予定はないけど気に入ったものを 5 点ほど購入。しかし販売数少ないな・・・素材は購入する人が限定的すぎるので販売数はだいたい 1~2 桁といったところ。ゲームは老舗の『犬と猫』さんの作品ですら 4 桁。となると、これはもうあまり知られていない人がここに出してもあまり売れないだろう。実際『RPGアツマール』で見かけてよく出来ていると思った『天使はお金にきたない』でも 3 桁いくかどうかってところ。厳しいね。
game.nicovideo.jp
キャラクターを動かせない
キャラクターを動かせない。まだ勉強してないけどプログラムの方はなんとかできると思ってる。画像を用意できない。
歩きスマフォしてる人の左手をデトロイトスタイルのかたちにして歩きながらフリッカージャブを放つという絵を作りたかったけど画像を用意できなかったので諦めた。
ゲームがすぐに遅くなる
適当な図形でゲームを作っているときに起きていたことで、描画領域を黒で塗りつぶしてからいくつかの四角を描くということを毎フレーム実行していたらすぐに重くなっていた。PIXI.Graphics.clear() で初期化するようにすることで解消した。どうやら何か描く度にインスタンスを生成しているようだ。どこかのメモリを更新していると思っていたけど違った。