★プレイヤーキャラクター 弾を動かす★


次は発射した弾を動かしましょう。

前回の最初に書いたように「右」に移動させる事にします。

キャラクターを右に移動させるには「転送先X座標」を増やせば良かったですね。

同じように、弾の「転送先X座標」を増やす事で右に移動させる事が出来ます。


弾の移動


まずは「Shot.h」を開き、publicメンバ関数として「Update関数」を、privateメンバ関数として「Move関数」の宣言を追加します。

class Shot {
public:

    Shot();

    //初期化
    void Initialize();

    //発射
    void Shoot(const int x, const int y);

    //更新
    void Update();

    //描画
    void Draw(Engine *pEngine);

private:

    const int WIDTH;
    const int HEIGHT;

    const int SPEED;

    bool m_bShooting;

    int m_x;
    int m_y;

    RECT m_sour;
    RECT m_dest;

    //移動
    void Move();
};

「Shot.cpp」を開き「Shoot関数」の下に「Update関数」の本体を追加します。

void Shot::Update()
{
    Move();
}

さらに「Draw関数」の下に「Move関数」の本体を追加します。

void Shot::Move()
{
    if (m_bShooting) {

        m_x += SPEED;
    }
}

ここでも「発射中フラグ」がONの場合だけ座標を変更します。


「SceneGame.cpp」を開き、「Update関数」から「Shotクラス」の「Update関数」を呼び出します。

void SceneGame::Update()
{
    m_player.Update(m_pEngine, m_shot);

    m_shot.Update();
}

それでは実行してみましょう。

発射した弾が右へ移動していけばOKです。


次の弾の発射


弾は無事に移動しましたが、1発撃ったらお終いで2発目の弾は撃てません。

「発射中フラグ」がOFFの時にしか弾は撃てませんから、どこかで「発射中フラグ」をOFFにしないといけません。

2Dゲームでは「画面外」の世界はほぼ「無い事」になっています。

発射した弾が画面外でもずっと進んでいる事はありませんし、画面外の敵に弾が命中する事もありません。

つまり「画面外に出た時点で弾は消えている」と考えて良いと思います。

そこで「Shot.cpp」を開き、「Move関数」を次のように変更しましょう。

void Shot::Move()
{
    if (m_bShooting) {

        m_x += SPEED;

        if (m_x >= WindowSetting::WINDOW_WIDTH) {

            m_bShooting = false;
        }
    }
}

「転送先X座標」が画面端(WINDOW_WIDTH)を越えたら「発射中フラグ」をOFFにします。


実行して確かめてみましょう。

弾が画面外に出たら、次の弾が発射出来るようになりました。


発射位置の調整


とりあえず弾の基本は出来た訳ですが、少し調整をしたいと思います。

弾の発射位置をよく見ると、プレイヤーキャラクターの左上から発射されています。

これは「Player.cpp」の「Shoot関数」に原因があります。

void Player::Shoot(Engine *pEngine, Shot &refShot)
{
    if (pEngine->GetKeyState(DIK_Z)) {

        refShot.Shoot(m_x, m_y);
    }
}

「Shotクラス」の「Shoot関数」に渡している引数を見てください。

「m_x」「m_y」はプレイヤーキャラクターの「転送先座標」です。

当然、プレイヤーキャラクターの「左上」の座標ですから、弾の初期座標もキャラクターの「左上」になってしまっているのです。

例えば、プレイヤーキャラクターの「中心」から弾を発射したいと考えた場合、キャラクターのサイズと弾のサイズを元に次のようにします。

 プレイヤーキャラクターの幅 32ピクセル

 弾の幅 16ピクセル

 (32 − 16) ÷ 2 = 8

プレイヤーキャラクターのX座標から8ピクセル移動させる事で横方向の中心の位置が求まります。

同じように縦方向も計算する事が出来ます。


これを実現させるには、弾の幅と高さを「Playerクラス」で使えるようにならないといけません。

「Shot.h」を開き、getter関数を追加しましょう。

class Shot {
public:

    Shot();

    //初期化
    void Initialize();

    //発射
    void Shoot(const int x, const int y);

    //更新
    void Update();

    //描画
    void Draw(Engine *pEngine);

    //幅の取得
    int GetWidth() const;

    //高さの取得
    int GetHeight() const;

private:

    const int WIDTH;
    const int HEIGHT;

    const int SPEED;

    bool m_bShooting;

    int m_x;
    int m_y;

    RECT m_sour;
    RECT m_dest;

    //移動
    void Move();
};

「Shot.cpp」を開き、「Draw関数」の下にgetter関数の本体を追加します。

//幅の取得
int Shot::GetWidth() const
{
    return WIDTH;
}

//高さの取得
int Shot::GetHeight() const
{
    return HEIGHT;
}

次に「Player.cpp」を開き、「Shoot関数」を変更します。

void Player::Shoot(Engine *pEngine, Shot &refShot)
{
    if (pEngine->GetKeyState(DIK_Z)) {

        int adjustX = (WIDTH - refShot.GetWidth()) / 2;
        int adjustY = (HEIGHT - refShot.GetHeight()) / 2;

        refShot.Shoot(m_x + adjustX, m_y + adjustY);
    }
}

上の計算式を使って、プレイヤーキャラクターの「中心」を弾の初期座標にしました。


それでは実行してみましょう。

よく見ないと分からないかも知れませんが、プレイヤーキャラクターの「中心」から弾が発射されるようになりました。


描画順について


最後に描画順について考えてみましょう。

今は「プレイヤーキャラクター」「弾」の順番で画像を表示しています。

「SceneGame.cpp」の「Draw関数」を見れば分かりますね。

void SceneGame::Draw()
{
    m_back.Draw(m_pEngine);

    m_player.Draw(m_pEngine);

    m_shot.Draw(m_pEngine);
}

この順番なので、プレイヤーキャラクターの上に弾の画像が表示されるのです。

もし、プレイヤーキャラクターの裏に弾の画像を表示したい場合、描画順を変える必要があります。

void SceneGame::Draw()
{
    m_back.Draw(m_pEngine);

    m_shot.Draw(m_pEngine);

    m_player.Draw(m_pEngine);
}

実行してみます。

微妙ですが、プレイヤーキャラクターの後ろから弾が発射されています。


ゲームを作る際に大事な事の1つは、「遊ぶ人がどう感じるか」と言う微妙な感覚です。

微妙ですが、何か違和感があるとスムーズに遊べなくなります。

特に自分で作ったゲームに対しては、自分では違和感を持てないものです。

他の人にテストプレイをしてもらう事、問題点を指摘してもらう事は非常に大事な事ですから、どんどん他人にプレイしてもらうようにしてみてください。


次へ

戻る

目次へ