04.キー操作
上:t, 下:b, 左:f, 右:h *操作が反映されない場合、画面部分を一度クリックしてみてください
キー操作
これまでは勝手に絵が動いていましたが、ゲームである以上、やはり操作したいものです。
というわけで、キーイベントを取得して状態を保持できるようにします。
gconsole.js に手を入れるので、gconsole2.js としてこれまでとは違うファイルにしました。
/* 前略 */
const elm = document.querySelector('#gconsole textarea');
const Key = {
code: [70, 84, 72, 66, 90, 88], /* F, T, H, B, Z, X */
map: { L: 1, U: 2, R: 4, D: 8, Z: 16, X: 32 },
evStat: 0,
stat: 0,
update: function() {
this.stat = 0;
this.stat |= this.evStat;
},
};
elm.addEventListener('keydown', function(ev) {
if (Key.code.includes(ev.keyCode)) {
Key.evStat |= (1 << Key.code.indexOf(ev.keyCode));
Key.update();
}
});
elm.addEventListener('keyup', function(ev) {
if (Key.code.includes(ev.keyCode)) {
Key.evStat &= (0xFF ^ (1 << Key.code.indexOf(ev.keyCode)));
Key.update();
}
});
return {
elm: elm,
key: Key,
width: 80,
/* 以下略 */
evStat でワンクッション置いたような感じにしているのは、将来的にゲームパッドに対応したくなったときを想定しています。
ゲームパッドの入力状態とキー入力状態とを結合して stat に持っていけたらいいなという考え。
なお上下左右がよくあるwasdではなくtfbhになっているのは個人的な好みです。
(いにしえの時代に私がやり込んだゲームがそうだったので、もう体がそれで覚えている)
とはいえ世間はwasdでしょうから、そのほうがいい場合は上記の「code:」の中身を書き換えてしまってください。
移動処理
キー状態を取得できるようになりましたので、さっそく移動させましょう。
/* 前略 */
let px = 40, py = 12;
function gameFrame() {
const t = performance.now();
const Key = screen.key;
px += (Key.stat & Key.map.R) ? 1 : ((Key.stat & Key.map.L) ? -1 : 0);
py += (Key.stat & Key.map.D) ? 1 : ((Key.stat & Key.map.U) ? -1 : 0);
if (px < 0) { px = 0; }
if (px > screen.width - img.width) { px = screen.width - img.width; }
if (py < 0) { py = 0; }
if (py > screen.height - img.height) { py = screen.height - img.height; }
screen.clear();
drawImageData(px, py, img);
/* 以下略 */
画面をはみ出ないように判断して、入力方向に1単位移動させています。
実際にはこれでは縦横ナナメの移動速度がすべて違っているように見えますので、ゲームの操作性としては致命的です。
が、これを解消するには実際の座標そのものではなく仮想の座標を使うなどする必要が出てきます。
さらに今は自分(?)だけなので問題ありませんが、多数の画像というかAAを画面に表示して動かす場合はもう少し汎化した仕組みが必要です。
いったんはキー操作できるようになったということで、ここで一段落とします。
リソース
gconsole.css
gconsole2.js
g04.js
関連
00.画面表示
01.文字出力
02.無限ループ
03.画像出力
05.速度を調整
06.敵の配置
07.ゲームにする
08.ゲームパッド