SDL2の基本的な使い方

プログラマーの尾関です。

今回はちょっとした2Dゲームのプログラムを書く環境として便利な “SDL2” の基本的な使い方を説明します。

SDL2とは

SDL2 とは “Simple DirectMedia Layer 2” の意味で、ゲームやマルチメディアアプリケーションで使用されるライブラリです。

環境を作る

SDL2 は C言語で書かれていて、様々なプラットフォームで動くのですが、今回は以下の環境でビルドできるようにしてみます。

  • Windows 11
  • Visual Studio 2022

ライブラリのダウンロード

ライブラリは SDL公式ページからダウンロードします。

右上にある “Get the current stable SDL_version” のリンクをクリック。

GitHubのページへ遷移します。環境に合わせてライブラリをダウンロードします。

ここでは、”SDL2-devel-X.XX.X-VC” という名前のZIPファイルをダウンロードしました。

プロジェクトの作成

Visual Studioを起動して “C++” の “コンソールアプリ” でプロジェクトを作成します。

先ほどダウンロードしたライブラリをプロジェクトがあるフォルダにコピーしておきます。

他のプロジェクトでもSDLを使う場合は、プロジェクトに含めずに「C:\SDL2」といった固定のパスにしたほうが良いかもしれませんが、今回はプロジェクトに含めるようにしました。

ライブラリにパスを通したいので、プロジェクトのプロパティを開いて「C/C++ > 全般」から「追加のインクルードディレクトリ」に “$(ProjectDir)sdl2\include” と指定します。

$(ProjectDir) はプロジェクトのフォルダを示す環境変数ですので、これでプロジェクトの場所を移動させてもパスが正しく設定されます。

次にリンクするライブラリの指定です。

リンカー > 全般」から「追加のライブラリディレクトリ」に “$(ProjectDir)sdl2\lib\$(PlatformShortName)” を指定します。

$(PlatformShortName) はビルド時に指定するプラットフォームです。x64 で動作すれば問題ないと思いますが、x86 のライブラリも提供されていたので念のため切り替えられるようにしました。

最後に「リンカー > 入力」の「追加の依存ファイル」に “SDL2.lib” “SDL2main.lib” を指定します。

画像では “SDL2_image.lib” の指定がありますが、画像の読み込みを行わないのであれば不要です。

もし画像ファイルを読み込みたい場合は、以下のページの「GitHub」のリンクから別途SDL2_image をダウンロードする必要があります。

main関数を書く

では SDL を使って main 関数を書いてみます。

これはSDLを初期化して、3秒待ってから終了する…というコードです。

さっそく実行してみると、以下のエラーとなります。

SDL2の実行には SDL2.dll が必要なのですが、それが見つからないため動かせない…というエラーです。

実行ファイルが作られるフォルダに手動でコピーしても良いですが、ビルド後に自動でDLLをコピーすると、プロジェクトを配布した場合でも正常に動かせるので良いと思います。

自動でコピーするにはプロジェクト設定から「ビルドイベント > コマンドライン」に “xcopy” を使ったコマンドを指定します。

“SDL2.dll” は libフォルダにあるので、これをコピーするコマンドです。

  • 補足:もし SDL2_image を使う場合には、”SDL2_image.dll” も同じように自動コピーすると良いです

この状態で実行すると、ウィンドウが3秒表示され、自動で閉じるようになりました。

ウィンドウの表示と描画を行う

ウィンドウの表示や描画を行うには以下の処理が必要となります。

  • SDL_CreateWindow() でウィンドウのインスタンスを生成する
  • SDL_CreateRenderer() でレンダラーのインスタンスを生成する

コード量は増えましたが、ウィンドウと描画のインスタンスを生成して、描画処理を呼び出しているだけです。

生成した後は破棄処理が必要なので、それぞれのインスタンスをstatic変数に保持して破棄処理を共通化しました。

実行すると、黒い画面に赤い矩形が表示されました。

メインループと入力処理を作る

SDL2の入力判定は、対象のキーを「押し続けているかどうか」を取得することしかできません。そのため「そのフレームに押したかどうか」を判定するには「現在のフレームでの入力情報」と「1フレーム前の入力情報」の2つを保持する必要があります。

具体的には以下のstatic変数を定義します。

キーボードの入力情報の更新は以下のように書きます。

注意点として、SDL_GetKeyboardState() で取得したポインタは実体をコピーしないと1フレーム前の情報も消えてしまいます。そのためポインタではなく配列にコピーしています。

これで入力情報が保持できたので、以下のような入力を判定する関数を作ることができます。

キーボード定数は以下のように定義してみました。

SDL1の時代とは入力処理が変わってしまったのか “SDL_SCANCODE_*” 定数を使う必要がある…というのがポイントです。

仕上げとしてメインループに組み入れてみました。

上下左右キーで回転する円を動かすコードとなります。

参考

今回の記事を書くにあたって以下のページを参考にしました。

SDL2の基本的な機能の説明とサンプルコードがまとまっていてオススメです。


■余談

SDLの公式ページを見たら「BABA IS YOU」がSDLで作られているとのことでした。

“BABA IS YOU” みたいなパズルゲームを作ってみたいときには、ゲームエンジンを使うよりも、SDLのようなシンプルな環境を使うのが良いのかもしれませんね(他にも “TOKI TORI”、”VVVVVV”、”うみねこなく頃に”、”Dead Cells”、”UnEpic”、”Don’t Starve”、”CAVE STORY+” などが SDLで作られているようです)。


以上、SDL2の基本的な使い方でした。

(Visited 874 times, 16 visits today)

コメント投稿は締め切りました。