Ubuntu Weekly Recipe

第268回SDLで夢のオリジナルゲーム開発

怠け者視点から見る季節の巡りというのはとても早いもので、今年は何か新しいことにチャレンジしようと思い、年明けから「よし、今年は頑張る!」と言い続けていた台詞が、もう「よし、今年度から頑張る!」に変わってしまう季節になってしまいました。

そんな自堕落な人生を打開すべく、または春の陽気につられて、おもわず「よし、Ubuntuでゲームでも作ってみるか!」と意気込んでしまった方も、世の中少なからずいるのではと思います。

今回は、マルチメディアAPIライブラリSimple DirectMedia Layer(SDL)を使用したゲームを作るための、開発環境構築レシピをお届けします。

Simple DirectMedia Layerライブラリとは

Simple DirectMedia Layerライブラリは、グラフィックやサウンドなどのマルチメディア関連のAPIを提供するライブラリの一つです。次の補助ライブラリをあわせてインストールすることで、ゲームプログラミングに必要となるであろうAPIを簡単に揃えることができます。各種メディアのインターフェース仕様をあれこれ調べて、APIを自作したくない怠け者にとっては、とても魅力的なライブラリです。

  • SDL_image:各形式の画像ファイル操作機能を提供するライブラリ
  • SDL_mixer:各形式の音声ファイル操作機能を提供するライブラリ
  • SDL_ttf:TrueTypeフォントの文字列描画機能を提供するライブラリ
  • SDL_gfx:図形描画機能を提供するライブラリ
  • SDL_net:ネットワーク機能を提供するライブラリ

SDLライブラリのほとんどはC言語で書かれているため、C言語やC++から使用することができます[1]⁠。また、Windows、Mac OS、FreeBSD等のOSもサポートしており、クロスプラットフォームなゲームアプリケーション開発を検討している方にとっても有用なライブラリと言えるでしょう[2]⁠。

開発環境の構築

さっそく開発環境を構築していきましょう。

端末から次のコマンドを入力し、各SDL開発ライブラリのインストールを行ってください[3]⁠。

$ sudo apt-get install libsdl1.2-dev
$ sudo apt-get install libsdl-image1.2-dev
$ sudo apt-get install libsdl-ttf2.0-dev
$ sudo apt-get install libsdl-mixer1.2-dev

端末画面恐怖症の人は、Ubuntuソフトウェアセンターからインストールを行うとよいでしょう。

図1 UbuntuソフトウェアセンターからSDL開発ライブラリをインストール
図1 UbuntuソフトウェアセンターからSDL開発ライブラリをインストール

機能確認用のアプリケーションを作ってみる

さて、実際にSDLでどんなことができるのでしょうか。とりあえず、画像ファイルを読み込んで表示する、音楽を再生する、日本語の文字列を表示する、あたりができれば明日への希望が見えそうです。

簡単なコードを書いて機能を確認してみましょう[4]⁠。ここではUbuntu 12.10 32bit Desktopの環境でアプリケーションを作成します。

開発言語にはC言語を使用します。任意の場所に作業ディレクトリ[5]を作り、gedit等のエディターで次のソースコードをsdltest.cというファイル名で保存してください。

なお、今回作成するアプリケーションのデータはこちらからダウンロードできます。

#include <stdlib.h>

/* SDLライブラリヘッダーインクルード */
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <SDL/SDL_mixer.h>

SDL_Surface*    g_srfMain        = NULL;         /* メインサーフェイス */
SDL_Surface*    g_srfBack        = NULL;         /* 背景画像用サーフェイス */
SDL_Surface*    g_srfChar        = NULL;         /* キャラクター用サーフェイス */
SDL_Surface*    g_srfText        = NULL;         /* 文字表示用サーフェイス */
TTF_Font*       g_ttfFont        = NULL;         /* フォントファイルハンドル */
Mix_Music*      g_mixMusic       = NULL;         /* ミュージックファイルハンドル */
SDL_Color       g_colTextColor   = { 0, 0, 0};   /* 文字の色(黒) */

int main(int argc,char *argv[])
{
    int nSdlInit = -1;
    int nTtfInit = -1;
    int nMixInit = -1;
    int nPlayMusic = -1;
    SDL_Rect rcCharDst;
    SDL_Rect rcTextDst;
    SDL_Event evEvent;
    int nReturn = 1;
    
    /* SDL初期化処理呼び出し */
    nSdlInit = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
    if( 0 != nSdlInit ) { goto EXIT; }

    /* ウィンドウタイトル設定 */
    SDL_WM_SetCaption("SDL Test", NULL);
    
    /* ビデオモードを設定しメインサーフェイスを作成 */
    /* 画面設定:640*480 32bit */
    /* ソフトウェアサーフェイス、ダブルバッファ使用 */
    g_srfMain = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE | SDL_DOUBLEBUF);
    if( NULL == g_srfMain ) { goto EXIT; }
    
    /* SDL_ttf 初期化処理呼び出し */
    nTtfInit = TTF_Init();
    if( 0 != nTtfInit ) { goto EXIT; }
    
    /* オーディオデバイスオープン処理呼び出し */
    /* デフォルトサンプリング周波数、デフォルト波形サンプル */
    /* ステレオ、サウンドバッファサイズ:1024byte */
    nMixInit = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024);
    if( 0 != nMixInit ) { goto EXIT; }
    
    /* フォントファイル読み込み */
    /* フォントファイル:Takao Pゴシック フォントサイズ:16 */
    /* 第一引数に使用するフォントファイルのパスを設定 */
    g_ttfFont = TTF_OpenFont("/usr/share/fonts/truetype/fonts-japanese-gothic.ttf", 16);
    if( NULL == g_ttfFont ) { goto EXIT; }
    
    /* 背景画像、キャラクター画像ファイル読み込み */
    g_srfBack = IMG_Load("./back.png");
    if( NULL == g_srfBack ) { goto EXIT; }
    g_srfChar = IMG_Load("./char.png");
    if( NULL == g_srfChar ) { goto EXIT; }
    
    /* 表示文字列画像作成 */
    g_srfText = TTF_RenderUTF8_Blended(g_ttfFont, "また、朝になってしまった。", g_colTextColor);
    if( NULL == g_srfText ) { goto EXIT; }
    
    /* 音楽ファイル読み込み */
    g_mixMusic = Mix_LoadMUS("./bgm.ogg");
    if( NULL == g_mixMusic ) { goto EXIT; }
    
    /* 音楽ループ再生開始 */
    nPlayMusic = Mix_PlayMusic(g_mixMusic, -1);
    if( 0 != nPlayMusic ) { goto EXIT; }
    
    /* キャラクター画像の貼り付け位置、幅高さ設定 */
    /* 画面の X=310,Y=0 の位置に 読み込んだ画像の幅高さで貼り付け */
    rcCharDst.x = 310; rcCharDst.y = 0;
    rcCharDst.w = g_srfChar->w; rcCharDst.h = g_srfChar->h;
    
    /* 文字列の貼り付け位置、幅高さ設定 */
    /* 画面の X=370,Y=65 の位置に 文字列画像の幅高さで貼り付け */
    rcTextDst.x = 370; rcTextDst.y = 65;
    rcTextDst.w = g_srfText->w; rcTextDst.h = g_srfText->h;
    
    /* メインループ処理 */
    while(1) {
        /* SDLのイベントメッセージ取得 */
        SDL_PollEvent(&evEvent);
        
        /* 終了メッセージかESCキーが押下されたらループ終了 */
        if( SDL_QUIT == evEvent.type ) { break; }
        if( SDL_KEYDOWN == evEvent.type
            && SDLK_ESCAPE == evEvent.key.keysym.sym ) {
            break;
        }
        
        /* メインサーフェイスを黒色で塗り潰し */
        SDL_FillRect(g_srfMain, NULL, SDL_MapRGB(g_srfMain->format, 0, 0, 0));
        
        /* 背景画像をメインサーフェイスに転送 */
        SDL_BlitSurface(g_srfBack, NULL, g_srfMain, NULL);
        
        /* キャラクター画像の貼り付け位置を指定してメインサーフェイスに転送 */
        SDL_BlitSurface(g_srfChar, NULL, g_srfMain, &rcCharDst);
        
        /* 文字列の貼り付け位置を指定してメインサーフェイスに転送 */
        SDL_BlitSurface(g_srfText, NULL, g_srfMain, &rcTextDst);
        
        /* メインサーフェイスを画面表示 */
        SDL_Flip(g_srfMain);
            
        /* 0.01秒ウエイト */
        SDL_Delay(10);
    }
    
    nReturn = 0;
    
EXIT:
    /* 音楽再生停止 */
    if( 0 == nPlayMusic ) { Mix_HaltMusic(); }
    
    /* ミュージックファイルハンドル解放 */
    if( NULL != g_mixMusic ) { Mix_FreeMusic(g_mixMusic); }
    
    /* 文字列・画像のサーフェイスバッファ解放 */
    if( NULL != g_srfText ) { SDL_FreeSurface(g_srfText); }
    if( NULL != g_srfChar ) { SDL_FreeSurface(g_srfChar); }
    if( NULL != g_srfBack ) { SDL_FreeSurface(g_srfBack); }
    
    /* フォントファイルハンドルクローズ */
    if( NULL != g_ttfFont ) { TTF_CloseFont(g_ttfFont); }
    
    /* オーディオデバイスクローズ処理呼び出し */
    if( 0 == nMixInit ){ Mix_CloseAudio(); }
    
    /* SDL_ttf終了処理呼び出し */
    if( 0 == nTtfInit ){ TTF_Quit(); }
    
    /* SDL終了処理呼び出し */
    if( 0 == nSdlInit ){ SDL_Quit(); }
    
    return nReturn;
}

端末を起動させ、ソースコードファイルがあるディレクトリ内に移動し、次のコンパイルコマンドを実行してください[6]⁠。

$ gcc -o sdltest sdltest.c -lSDL -lSDL_image -lSDL_ttf -lSDL_mixer

sdltestという名前のアプリケーション実行ファイルが作成されれば、コンパイル成功です。

動かしてみる

できあがったアプリケーションを動かしてみましょう。

まずは、アプリケーションで使用する次のファイルを用意します。

  • 画像サイズ640×480の背景用画像ファイル(back.png)
  • 背景を透過した画像サイズ250×480のキャラクター用画像ファイル(char.png。注7
  • BGMファイル(bgm.ogg。注8
図2 背景用画像ファイル(back.png)
図2 背景用画像ファイル(back.png)
図3 キャラクター用画像ファイル(char.png)
図3 キャラクター用画像ファイル(char.png

用意したファイルを先ほど作成した実行ファイルと同じディレクトリ内に配置します。

図4 用意したファイルを配置
図4 用意したファイルを配置

準備ができたら、アプリケーションを実行してみましょう。用意した各画像と、文字列「また、朝になってしまった。」が表示され、スピーカーから音楽が流れれば成功です。

図5 アプリケーション実行結果
図5 アプリケーション実行結果

表示された芸術的な画面を眺めながら、素敵な音楽を聞いていると、あれこれと夢が膨らみますね。

参考文献

実際の開発にあたっては、次のサイトのドキュメントなどが開発の手助けになるはずです。

今月末には大型連休も控えており、まとまった時間も取れそうです。休日のお供にオリジナルゲーム製作などはいかがでしょうか?

おすすめ記事

記事・ニュース一覧