Skip to content
第01回 全体構成と目標

2 / 4 フレームワークの構成 ​

このステップの目的

処理の担当と、入力から更新・描画までのつながり

主要コンポーネントの解説 ​

完成サンプルの主要コンポーネントと、それぞれの役割を解説します。
ゲームは大きく分けて、ゲームのルールを管理するコアロジックと、コアロジックを支えるフレームワークに分かれています。

ゲーム体験の多くはコアロジック側の実装によって決まりますが、手当たり次第に改造を進めるとフレームワークの動作を破壊し、意図した動作を導き出せなくなってしまうかもしれません。
どこを拡張すれば目的を達成できるのかを意識しながら、スマートに改造を進めていきましょう。

Game クラスと GameModel クラス ​

Gameクラスは入力・モデル更新・描画・音声を準備提供し、ゲームの全体を包含して管理します。
一方で、GameModelクラスはゲーム本体にあたり、戦闘・経験値・強化・勝敗といったゲームルールの管理を担当します。

この二つのクラスが、ゲームの動作の中核を担っています。
Gameがフレームワーク側の処理を担当し、GameModelがコアロジックを担当する形です。

Source/AutoShooter/Game.cpp(抜粋)cpp
void Game::Update(float seconds)
{
    model.Update(ReadFrameInput(), seconds);
    HandleEvents(model.GetEvents(), seconds);
}

void Game::Draw() const
{
    renderer.Draw(model);
}

入力・描画・音声の担当クラス ​

Inputクラスはキー入力、Rendererクラスはゲーム状態の描画、SoundManagerクラスは音声の管理を担当します。
例えば効果音の発声は、GameModelで起きた発射・命中などのイベントをGameが音声再生につなげて行われます。

これらはクラスはゲーム内容によって異なるものと、様々なゲームで再利用可能なものが混在しています。
自身のゲームで何が再利用できるかを考えながら、必要な要素を追加していきましょう。

プレイヤー・敵・武装と各管理クラス ​

Player、Enemy、Weaponといったゲームを構成する各要素は、それぞれ個別のクラスに分割されています。
その上でEnemyManager、AttackManager、PickupManagerなどのマネージャークラスがオブジェクトを生成・更新しています。

ゲームの動作基盤 ​

起動・初期化・終了とメインループ ​

main.cppでDxLibを初期化し、Game::Runで素材読み込みとメインループを実行します。
終了時はGameを破棄してからDxLib_Endを呼びます。

Source/main.cppcpp
#include <DxLib.h>
#include "AutoShooter/Application.h"
#include "AutoShooter/Game.h"

// アプリケーションのエントリーポイントとしてDXライブラリとゲームを実行する
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    if (!dxgame::autoshooter::InitializeDxLib())
        return 1;

    int result = 0;

    // DxLib_Endを呼ぶ前にGameを破棄し、画像や音声のハンドルを安全に解放する
    {
        dxgame::autoshooter::Game game;

        if (!game.Run())
            result = -1;
    }

    DxLib_End();

    return result;
}

入力の取得・時間の管理・更新・描画の流れ ​

Game::MainLoopでは入力を取得し、更新、描画、画面の切り替えを繰り返します。
今回、フレームレートはリフレッシュレートに依存せず、固定の更新間隔でゲームを進行させる方式を採用しています。

Source/AutoShooter/Game.cpp(MainLoopの抜粋)cpp
Update(config::DeltaTime);
Draw();
ScreenFlip();

画像・マップ・音声の読み込み ​

Game::InitializeからRenderer::LoadAllとSoundManager::LoadAllを呼び、画像・マップ・音声を読み込みます。
素材の読み込みに失敗した場合は、ゲームループへ進まずエラーを表示します。

オブジェクトの生成・更新・再利用 ​

攻撃などは固定長配列の空き要素を使って生成します。
活動を終えた要素は、次の生成で再利用します。

Source/AutoShooter/Objects/AttackManager.cpp(抜粋)cpp
bool AttackManager::SpawnShot(Vector2 position, Vector2 velocity, Weapon::Type type, const Weapon::Stats& stats)
{

    for (auto& shot : shots)
    {
        if (shot.IsActive())
            continue;

        shot.Spawn(position, velocity, type, stats);

        return true;
    }

    return false;
}
チェックリスト
  • 主要コンポーネントの役割とつながり
  • ゲームの実行を支える処理とゲームルールの区別