The next JAVA library(3)

もう少しキー入力について考えてみます。
ゲームでは、押しっぱなしの時に常にtrueを返す、isKeyPress()と、前回が押されていなくて、今回押されたときだけtrueを返す、isKeyPush()が必要になって来ます。
isKeyPress()は、前回のやりかたで取得出来ます。
しかし、isKeyPush()の場合は、前回の入力が何であったかに依存するので、前回の情報を保持しておかないといけません。
isKeyPress()とisKeyPush()の実装は次のようになります。

protected int fixKey;    //_keyUpdate()ごとに変化するキーの情報
protected int oldKey;    //前回のfixKeyの情報
protected int realKey;   //リアルタイムに変化するキーの情報

protected void _keyUpdate(){
    oldKey = fixKey;
    fixKey = realKey;
}

protected boolean _isKeyPress(int k){
    return (fixKey&k)!=0;
}

protected boolean _isKeyPush(int k){
    return ((oldKey&k)==0) && ((fixKey&k)!=0);
}

これで完成ヽ(´ー`)ノ


……と言いたいところですけれども、まだ問題があります。
携帯ゲームは非常に処理が遅いので、1秒間に20フレームが良いところです。
バリバリに描画するような物だと10フレームも出ないことはしばしばあります。
_keyUpdate()を実行した直後にキーが押され、次の_keyUpdate()が実行される前に離されたら、そのキーの情報はどうなるか。
それは、もちろん無視されます。
また、_keyUpdate()を実行する前にキーを押していて、次の_keyUpdate()が実行される前に、離して再び押すとどうなるか。
それは、もちろん押しっぱなしと判断されます。
これがアクションゲームだったりシューティングゲームだったりすると致命的です。
なので、1フレーム内に押されて、離されたキーについては、_keyUpdate()後に離されるようにします。
同様に、1フレーム内に離されて、押されたキーについては、_keyUpdate()後に押されるようにします。

現在、プログラム修正中(;´Д`)

これで1フレーム中に何度もキーの処理が出てきたときの処理は出来上がり!


人生そんな甘くありません(・∀・)


上記のプログラムは、1回目以降のキーの入力を無視しているので、スピーディな操作を要求されるようなゲームでは使えません。
例えば、連打系のゲームを、上記のプログラムでやると、1フレーム中に2回押しても、1回目のキー入力しか判断してくれません。間違いなくクレームが来ます(;´Д`)
これを解決するには、キューを使います。
キーの入力をキューに溜めておいて、メイン側で処理をするときに、そのキューが空になるまで処理をします。
あまりにもキューが多い場合は、最後の方は無視しても構わないかもしれませんね。
あと、もしハードウェアがキーを取りこぼしたら……諦めてください(;´Д`)


ただ、キューが必要になることはほとんどありません。
というか、多分、それぞれそのゲームに合ったキー入力の方式が必要になると思います。
ですから、キーの入力の処理は、必要に応じて、メイン側でオーバーライドしてもらいましょう。
今までは、これを書き換える為に、ライブラリの方に手を加えてたので、継承って便利だなぁって思いましたヽ(´ー`)ノ