ゆうなんとかさんの雑記帳的な。

Twitterで踊ったり音ゲーしたりしてるあの名前がよくわからない人が書いてるらしいよ。

8方向移動はじめました

例のゲームっぽい何かの更新です。

今までは4方向の移動しかできなかったのですが、今回の更新で8方向への移動に対応させました*1
2つのキーを同時に押したとき、最初はkeydownイベントが両方のキーで発火するのですが、一度発火すると次からはどちらか片方だけしか発火しないようです。ためしに、

<html><head>
<meta charset="UTF-8">
    <script type="text/javascript">
    onkeyup = function(e) {
        console.log("keyup: " + e.keyCode);
    };
    onkeydown = function(e) {
        console.log("keydown: " + e.keyCode);
    };
    </script>
</head></html>

という内容のHTMLファイルを読ませるせると、Google Chromeの場合、

keydown: 39 test.html:11
keydown: 40 test.html:11
keydown: 40 test.html:11
keydown: 40 test.html:11
keydown: 40 test.html:11
(中略)
keydown: 40 test.html:11
keydown: 40 test.html:11
keydown: 40 test.html:11
keyup: 40 test.html:8
keyup: 39 test.html:8

という感じのログが得られます。
そこで、keydownイベントが発火したらon、keyupイベントが発火したらoffという感じでビットを立てるための変数を用意し、あとはビット演算で論理積を取り、0でなければ押されたキーに対応した方向へ動くというふうにしました。少しめんどくさいですが、こうすると8方向への移動ができるようになりました。
今まではキーが押されているときに、
キーコードを取得→それに応じて自機の座標を動かす
という感じでしたが、今回からはキーを押したか離したかしたときに、
キーコードを取得→それに応じて自機の移動方向ビットを立てる/下ろす→フレーム更新時に座標を更新
という感じに処理が変わります。要所のコードはこんな感じです。

/* Playerクラス内 */
    var p = this;
    // 移動する方向
    this.moving = {
        //左方向
        1 : function(canvas) {
            if (p.x > p.itemRadius) {
                p.x = p.x - p.dmove;
            }
        },
    // 上みたいなのがあと3方向分ある
    };
    // 移動する
    this.nextFrame = function(canvas) {
        for (var i = 0; i < 4; i++) {
            if ((this.direction & 1 << i) != 0) {
                this.moving[(1 << i).toString()](canvas);
            }
        }
    };
    // 移動方向を変える
    this.changeDirection = function(direction, isMove) {
        this.direction = isMove ? (this.direction | direction)
                                : (this.direction ^ direction);
        };
/* window.loadイベントハンドラ内 */
  $(window).keydown(function(e) {
        console.log("keydown: " + e.keyCode);
        switch (e.keyCode){
        case 87:
        case 37:
        case 100:
            //左方向
            player.changeDirection(1<<0, true);
            break;
        //こんな感じのコードがあと3方向分ある
        default:
            break;
        }
    }).keyup(function(e) {
        console.log("keyup: " + e.keyCode);
        switch(e.keyCode) {
        case 74:
        case 32:
        case 96:
            //自爆
            player.bomb();
            break;
        case 87:
        case 37:
        case 100:
            //左方向
            player.changeDirection(1<<0, false);
            break;
        // こんな感じのコードが(ry
        default:
            break;
        }
    });

それにしても個人的なプログラムでビット演算使うのは初めてかもしれない
冒頭に紹介したものとほぼ同じものをファイル分割してgithubにも置いてありますので気が向いたら見てみてください。

*1:ついでにしれっとasdwでの移動にも対応させました