人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

ジャンプ

↑キでジャンプできるようにしてきます。ジャンプをかっこよく見せるには重力を実装する必要があります。

mariolike02.jar

ジャンプ処理

Playerクラスのjump()を見てください。

    /**
     * ジャンプする
     */
    public void jump() {
        if (onGround) {
            // 上向きに速度を加える
            vy = -JUMP_SPEED;
            onGround = false;
        }
    }

ジャンプの基本は上向きに速度を加えることです。JUMP_SPEEDは、

    // ジャンプ力
    private static final int JUMP_SPEED = 24;

と定義してます。つまり、vyを-JUMP_SPEEDというようにマイナスの値にセットしています。図形を描く(2004/9/18)のところでも説明しましたが、Javaの座標系では、上方向=Y座標のマイナス方向になります。vyをマイナスの値にセットすることで上向きの速度が加わります。

基本的にジャンプは地面の上にいないとできません。空中でジャンプできる人はいませんよね。そこで、ジャンプする前に地面にいるかどうか調べています。onGroundがtrueのとき地面の上にいます。ジャンプすると地面の上にいないのでonGroundをfalseにします。

重力の実装

jump()でvyをマイナスの値をセットしましたが、vyをマイナスにしたままでは、ずっっと上の方に移動し続けてしまいます。ご自分でジャンプしてみるとわかりますが、ジャンプすると最初は上に進みますが、やがて止まり、最後は下へ落ちてきます。

f:id:aidiary:20091017221413g:plain

物理で習った方もいると思いますが、これは地上に重力があるためです。ジャンプしてもちゃんと下に戻ってくるように重力を実装してあげましょう。速度は位置を変化させる量であるのに対し、重力は速度を変化させる量です(加速度と呼びます)。重力は下のように定義してます。

    // 重力
    private static final double GRAVITY = 1.0;

「あれっ、重力って9.8じゃなかったっけ」って思った方もいると思います。確かに現実世界で重力の値は9.8m/s^2です。ただ、今作っているのはゲームであってシミュレーションではないので都合のよい値を使えばいいわけです。ゲーム内では1mを何ピクセルで表すとか厳密に定義してないので 9.8をそのまま使うと変な動作をしてしまいます。

次にupdate()を見てください。

    /**
     * プレイヤーの状態を更新する
     */
    public void update() {
        // 重力で下向きに加速度がかかる
        vy += GRAVITY;

        // 速度を元に位置を更新
        x += vx;
        y += vy;
        // 着地したか調べる
        if (y > MainPanel.HEIGHT - HEIGHT) {
            vy = 0;
            y = MainPanel.HEIGHT - HEIGHT;
            onGround = true;
        }
    }

重力がつねに下向きにかかりvy(速度)を変更しています。ジャンプしたときはvyの値がマイナスになりどんどん上に進みますが、プラスの値である GRAVITYがどんどん足されていってやがてvyが0になり、空中で止まります。さらに足されていくとvyの値はプラスになり下へ落ちてきます(上図参照)。これがジャンプの仕組みです。

ジャンプ力や重力の値をいろいろ変えてみると楽しいです。