Ubuntu Weekly Recipe

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

この記事を読むのに必要な時間:およそ 4 分

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

そんな自堕落な人生を打開すべく,または春の陽気につられて,おもわず「よし,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)⁠

注1
ライブラリのインターフェース部分はJava,Python,Rubyなどにも移植されており,各言語のインターフェースからSDLを使用することも可能です。
注2
Windowsで使用できることもあり,日本語のノウハウがそこそこ充実しているのも魅力の一つです。

開発環境の構築

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

端末から次のコマンドを入力し,各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開発ライブラリをインストール

注3
このレシピでは,SDLの図形描画機能とネットワーク機能を利用しないため,SDL_gfx(libsdl-gfx1.2-dev)とSDL_net(libsdl-net1.2-dev)の開発ライブラリはインストールを行いません。

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

さて,実際に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という名前のアプリケーション実行ファイルが作成されれば,コンパイル成功です。

注4
今回のレシピは開発環境構築の紹介のため,SDL APIの詳細な説明は省いています。処理の内容に興味を持たれた方は,後述のサイトに各APIの説明が記載されていますので,そちらを参照してください。
注5
当レシピでは,ホームディレクトリの下にsdlprojectと言う名前のディレクトリを作成して,作業を行っています。
注6
端末画面恐怖症の方は,Eclipse,Anjuta,Qt Creator等のIDEを使用してコンパイルを行うとよいでしょう。

著者プロフィール

芝田静間(しばたしずま)

どこにでもいる一介の日曜プログラマー。主にUbuntu Japanese Teamが参加するイベントのお手伝いなどをしている。

Linuxのウィンドウアプリケーション開発が日本でもっと盛んになることを常日頃から願っている。

コメント

コメントの記入