過去ログ 5
過去ログは下にいくほど新しい記事となっております。
※注意:このサイトにあるプログラムのソースコードや、その他の情報はすべて無保証です。やばいと思ったら実行しないでください。コンパイル、実行などによって生じた損害に対する責任は負いませんので、ご了承ください。
フルスクリーン切り替え
8-5-2009
今日のSDL
- SDL Documentation Wiki
- SDL ライブラリ
- SDL_image ライブラリ
- SDL_ttf ライブラリ
- SDL_mixer ライブラリ
- SDL_net ライブラリ
- SDL_gfx ライブラリ
途中でウインドウモードとフルスクリーンモードを切り替える方法
SDL_WM_ToggleFullScrean()を使います。
int SDL_WM_ToggleFullScreen(SDL_Surface *surface);
成功時は0、失敗時は-1が返ります。
フルスクリーン時には解像度が変更されますが、終了時には元に戻ります。
下のプログラム例はキーボードの1を押すとフルスクリーンの切り替えを行い、2を押すと終了するプログラムです。画面サイズは800x600です。
#include <SDL/SDL.h> #include <SDL/SDL_ttf.h> int main(){ SDL_Surface *screen; SDL_Surface *ttf_surface; SDL_Rect rect_scr = {0,0,800,600}; SDL_Rect rect_img = {0,0,200,200}; SDL_Color color = {255, 255, 255}; SDL_Event event; int endflag = 0; TTF_Font *font; SDL_KeyboardEvent *key; /* SDL_Eventのキャスト用 */ SDL_Init(SDL_INIT_EVERYTHING); /* SDL起動 */ TTF_Init(); SDL_WM_SetCaption("タイトル", "たいとる"); SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE); font = TTF_OpenFont("ipag-mona.ttf", 36); screen = SDL_GetVideoSurface(); rect_scr.y = 0; ttf_surface = TTF_RenderUTF8_Blended(font, "1 フルスクリーン切り替え", color); rect_img.w = ttf_surface->w; rect_img.h = ttf_surface->h; SDL_BlitSurface(ttf_surface, &rect_img, screen, &rect_scr); SDL_FreeSurface(ttf_surface); rect_scr.y += 40; ttf_surface = TTF_RenderUTF8_Blended(font, "2 終了する", color); rect_img.w = ttf_surface->w; rect_img.h = ttf_surface->h; SDL_BlitSurface(ttf_surface, &rect_img, screen, &rect_scr); SDL_FreeSurface(ttf_surface); SDL_Flip(screen); while(!endflag){ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: /* ウインドウクローズ */ endflag = 1; break; case SDL_KEYDOWN: /* キーダウン */ key = (SDL_KeyboardEvent*)&event; switch(key->keysym.sym){ case SDLK_1: /* フルスクリーン切り替え */ SDL_WM_ToggleFullScreen(screen); break; case SDLK_2: /* 終了 */ endflag = 1; break; default: break; } break; default: break; } } SDL_Delay(1); } TTF_Quit(); SDL_Quit(); /* SDL終了 */ return 0; }
※コメント、トラックバックはできません。メール、リンクは適当に。
Solarisで遊ぼう
11-5-2009
都合により、しばらくLinuxたんはお休みです。
で、Sunが買収されたときにインストールしたOpenSolarisでしばらく遊びます。
インストールしたOpenSolarisについて
- Windows上のVirtualBox上で動かします。
- 置いた場所は外付けハードディスク上(USB接続。SATA)
- VirtualBoxの設定はデフォルトのまま(いずれ変えるかもしれない)
立ち上げからログオンまで約2分(パスワード入力時間含む)であった。意外に早い?
とりあえず、ソフトウェアのアップデートをします。
※コメント、トラックバックはできません。メール、リンクは適当に。
ジョイスティック
9-5-2009
今日のSDL
- SDL Documentation Wiki
- SDL ライブラリ
- SDL_image ライブラリ
- SDL_ttf ライブラリ
- SDL_mixer ライブラリ
- SDL_net ライブラリ
- SDL_gfx ライブラリ
ジョイスティック操作について
アクションゲームの操作はジョイスティック(パッド)の方が楽です。SDLでジョイスティックを使用する場合は次のような流れになります。
- ジョイスティック初期化 SDL_JoystickOpen()
- ジョイスティックを使用する
- ジョイスティック終了 SDL_JoystickClose()
SDL_Joystick *SDL_JoystickOpen(int index);
indexはジョイスティックの番号。0から始まります。2つ以上ささっている場合は1,2...と続くはずです。失敗したらNULLが返ります。
void SDL_JoystickClose(SDL_Joystick *joystick);
ジョイスティックを終了します。
ジョイスティックのイベントについて
動作確認ジョイスティック→SANWA SUPPLY USBゲームパッド(レッド) (JY-P70UR)
ジョイスティックのイベントは、
- SDL_JoyAxisEvents
- SDL_JoyBallEvents
- SDL_JoyHatEvents
- SDL_JoyButtonEvents
の4種類ですが、上記ゲームパッドでは、このうち、SDL_JoyAxisEvents (十字キー、左のアナログスティック)、SDL_ButtonEvents (その他のボタン) のみ確認できました。
SDL_JoyBallEventsとSDL_JoyHatEventsはもっと違う形状のジョイスティックだと発生するのでしょうか。
サンプルプログラムは昨日のやつを流用しましょう。ボタンが押されたら終了という単純なプログラムです。
#include <SDL/SDL.h> #include <SDL/SDL_ttf.h> int main(){ SDL_Surface *screen; SDL_Surface *ttf_surface; SDL_Rect rect_scr = {0,0,800,600}; SDL_Rect rect_img = {0,0,200,200}; SDL_Color color = {255, 255, 255}; SDL_Event event; SDL_Joystick *joystick; int endflag = 0; TTF_Font *font; SDL_Init(SDL_INIT_EVERYTHING); /* SDL起動 */ joystick = SDL_JoystickOpen(0); TTF_Init(); SDL_WM_SetCaption("タイトル", "たいとる"); SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE); font = TTF_OpenFont("ipag-mona.ttf", 24); screen = SDL_GetVideoSurface(); rect_scr.y = 0; ttf_surface = TTF_RenderUTF8_Blended(font, "キー操作、ジョイスティックボタン押下により終了", color); rect_img.w = ttf_surface->w; rect_img.h = ttf_surface->h; SDL_BlitSurface(ttf_surface, &rect_img, screen, &rect_scr); SDL_FreeSurface(ttf_surface); SDL_Flip(screen); while(!endflag){ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: /* ウインドウクローズ */ case SDL_JOYBUTTONDOWN: /* ジョイスティックボタン押下 */ case SDL_KEYDOWN: /* キーダウン */ endflag = 1; break; default: break; } } SDL_Delay(1); } if(joystick != NULL){ SDL_JoystickClose(joystick); } TTF_Quit(); SDL_Quit(); /* SDL終了 */ return 0; }
※コメント、トラックバックはできません。メール、リンクは適当に。
FTPが変
14-5-2009
サイトタイトルがこんなんだからか知らないけど、WindowsからFTP接続ができたりできなかったり、不安定。
なので、まとめて更新ということがしばらく続くと思います。
Solaris アップグレード (13-5-2009)
OpenSolarisを2008年5月バージョンから2008年11月バージョンにアップグレードした。
アップグレード方法→参照
(※ アップグレード途中、DISK FULLのエラーが発生。原因は不明。30GBの領域を確保しており、また、HD自体の空き容量も1TB近くあるので、容量不足とは考えられない。スナップショットをとって再試行したところ、アップグレード作業が進行した。何だったのだろうか?)
ウインドウ内でスクリーンセーバーが動いているのがちょっと新鮮。
firefoxもバージョン3になった。
IE8 (14-5-2009)
IE8にすると、レイアウトが崩れるサイトがあるらしい、というのは前にIE8をインストールしたときにわかったけど、このサイトはレイアウト崩れなしに表示できるか?というのは試していないからわからない。
一度試してみないといけないな。
(※ このサイトの表示確認はfirefoxで行っています。operaでも一度確認しましたが大丈夫のはず。IEは未確認です。)
※コメント、トラックバックはできません。メール、リンクは適当に。
ねんがんのWindows 7をてにいれたぞ
15-5-2009
と、いうわけで、Windows 7 RCを動かしてみた。
仮想環境だけどサクサク動く。OpenSolarisを動かすよりおもしろい。firefoxもVCもインストールできたし。
midiが普通に演奏できる(vistaでは演奏できないということを聞いたけど、7で復活?)
DirectXは10に対応。でも、デフォルト設定の仮想環境なのでその力は見られず。残念。
あと、細かいところ
- XPと同じく、登録されていない拡張子は表示されないのがデフォルトとなっている。
- 「コンピュータ」→「コンピューター」、「メモリ」→「メモリー」となっている。以前MSがそんなこと言っていたっけ。
- ソリティア、マインスイーパーなんかも「ハードウェアアクセレータを確認」と警告が表示される。でも遊べる。
- ゲームが何か増えているような気がする(XPと比べて)。
- 保護者監視機能がついている。ゲームの制限などの設定ができる。
- フォルダーオプションはコントロールパネルの中。エクスプローラのウインドウのメニューを探しても見つからない。
(※仮想環境の設定 HD 20GB、 RAM 512MB、 VRAM 32MB)
このバージョンでいいから安く売ってくれないかな?
さて、もうすぐFedora11のリリース版が出るので、アップグレードの準備をしなくては・・・。
そういえば今日初めて気がついたけど、Fedora10ってNTFSに書き込みができるのね。
あと、ここまでの話とはまったく関係ないけど、「男の子牧場」はまずいだろう。JK。 まとめサイトらしい→★
※コメント、トラックバックはできません。メール、リンクは適当に。
音楽
16-5-2009
音楽無しのゲーム、特に全画面の音なしゲームはなにか物足りないですよね。今日のSDLは音楽についてです。
今日のSDL
- SDL Documentation Wiki
- SDL ライブラリ
- SDL_image ライブラリ
- SDL_ttf ライブラリ
- SDL_mixer ライブラリ
- SDL_net ライブラリ
- SDL_gfx ライブラリ
音楽を再生する 1
音楽を扱うにはSDL_mixerを使用します。
音楽の演奏方法には2種類あり、1つはストリーミングで流す方法、もう一つはファイルをあらかじめ読み込んでおき、再生する方法です。
使い分けは、長い音楽(メインのBGMなど)はストリーミングで、短い音楽(音声など)はファイルを全部読み込んで再生、という方式をとればいいとおもいます。
今回は前者の方法を紹介します。
大まかな流れは次のようになります。
- 音楽環境のオープン Mix_OpenAudio()
- ファイルの読み込み MixLoadMUS()
- 音楽の再生 Mix_PlayMusic()
- 解放 Mix_FreeMusic()
- 音楽環境のクローズ Mix_CloseAudio()
int Mix_OpenAudio(int frequency, Uint16 format, int channels, int chunksize);
frequencyは周波数、44100Hzなどをセットします。デフォルト値として、MIX_DEFAULT_FREQUENCYが用意されており、これは22050Hzです。
formatは以下の値をセットします。(SDL_audio.hより抜粋)
/* Audio format flags (defaults to LSB byte order) */ #define AUDIO_U8 0x0008 /* Unsigned 8-bit samples */ #define AUDIO_S8 0x8008 /* Signed 8-bit samples */ #define AUDIO_U16LSB 0x0010 /* Unsigned 16-bit samples */ #define AUDIO_S16LSB 0x8010 /* Signed 16-bit samples */ #define AUDIO_U16MSB 0x1010 /* As above, but big-endian byte order */ #define AUDIO_S16MSB 0x9010 /* As above, but big-endian byte order */ #define AUDIO_U16 AUDIO_U16LSB #define AUDIO_S16 AUDIO_S16LSB /* Native audio byte ordering */ #if SDL_BYTEORDER == SDL_LIL_ENDIAN #define AUDIO_U16SYS AUDIO_U16LSB #define AUDIO_S16SYS AUDIO_S16LSB #else #define AUDIO_U16SYS AUDIO_U16MSB #define AUDIO_S16SYS AUDIO_S16MSB #endif
なお、AUDIO_S16SYSがよく使われるとのこと(MIX_DEFAULT_FORMAT = AUDIO_S16SYSとなっている)。また、#ifで分けられているように、環境によってフラグが逆転するので、AUDIO_U16LSBとかをそのまま使うのは好ましくない。
channelsはチャンネル数をセットします。モノラルなら1、ステレオなら2となります。
chunksizeはバッファのサイズです。小さすぎると音飛びしたりするそうです。
成功すると0、失敗すると-1が返ります。
次に音楽ファイルの読み込みを行います。
Mix_Music *Mix_LoadMUS(const char *file);
ファイルはwav、ogg、mid、mp3、など、色々なファイルを読み込めます。(mp3に関してはライセンスの関係上、ディストリビューションによって、扱えないようになっているらしい。その場合はライブラリのコンパイルをしなおす必要がある。)
成功したらMix_Musicが、失敗したらNULLが返ります。
読み込みが終了したら、再生します。
int Mix_PlayMusic(Mix_Music *music, int loops);
*musicはMix_LoadMUSの返り値を、loopsはループ回数をセットします。
ループ回数はループの回数であり、再生回数でないことに注意。loops=0だと、ループ無しの1回再生。loops=1だと、ループ1回の2回再生となります。-1を指定すると無限にループします。
音楽を止めたい場合はMixHoltMusic()、解放する場合はMix_FreeMusic()、終了はMix_CloseAudio()となります。
int Mix_HaltMusic(); void Mix_FreeMusic(Mix_Music *music); void Mix_CloseAudio();
以下にサンプルプログラムを載せます。音楽ファイルは各自用意してください。また、いつものようにエラー処理等入っていないので、まじめにやりたい方は入れてください。
#include <SDL/SDL.h> #include <SDL/SDL_ttf.h> #include <SDL/SDL_mixer.h> int main(){ SDL_Surface *screen; SDL_Surface *ttf_surface; SDL_Rect rect_scr = {0,0,800,600}; SDL_Rect rect_img = {0,0,200,200}; SDL_Color color = {255, 255, 255}; SDL_Event event; SDL_Joystick *joystick; Mix_Music *music; int endflag = 0; TTF_Font *font; SDL_Init(SDL_INIT_EVERYTHING); /* SDL起動 */ TTF_Init(); /* ミュージック初期化 */ Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024); SDL_WM_SetCaption("タイトル", "たいとる"); SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE); font = TTF_OpenFont("ipag-mona.ttf", 24); /* analoguma.oggを開く */ music = Mix_LoadMUS("analoguma.ogg"); if(music == NULL){ return 1; } screen = SDL_GetVideoSurface(); rect_scr.y = 0; ttf_surface = TTF_RenderUTF8_Blended(font, "キー操作により終了", color); rect_img.w = ttf_surface->w; rect_img.h = ttf_surface->h; SDL_BlitSurface(ttf_surface, &rect_img, screen, &rect_scr); SDL_FreeSurface(ttf_surface); SDL_Flip(screen); /* ずっと演奏し続ける */ Mix_PlayMusic(music, -1); while(!endflag){ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: /* ウインドウクローズ */ case SDL_KEYDOWN: /* キーダウン */ endflag = 1; break; default: break; } } SDL_Delay(1); } /* ミュージック終了処理 */ Mix_HaltMusic(); Mix_FreeMusic(music); Mix_CloseAudio(); TTF_Quit(); SDL_Quit(); /* SDL終了 */ return 0; }
コンパイル時には、SDL_mixerライブラリへのリンクが必要です。上のプログラムの場合はSDL_ttfへのリンクも必要になるので、次のようになります
gcc test.c -lSDL -lSDL_ttf -lSDL_mixer
なお、SDL_mixerに関して、SDL Documentation Wikiは情報が大幅に抜けているので、Lazy Foo' Productionsを参考にするといいでしょう。
※コメント、トラックバックはできません。メール、リンクは適当に。
音楽2
17-5-2009
音楽無しのゲーム、特に全画面の音なしゲームはなにか物足りないですよね。今日のSDLは音楽についてです。
今日のSDL
昨日の続きです。
昨日はストリーミング再生する方法を扱いましたが、今日は音楽データをあらかじめすべて取り込んでおいてから再生する方法を扱います。
- 音楽環境のオープン Mix_OpenAudio()
- ファイルの読み込み Mix_LoadWAV()
- 音楽の再生 Mix_PlayChannel()
- 解放 Mix_FreeChunk()
- 音楽環境のクローズ Mix_CloseAudio()
前回とは、MixLoadWAV()〜Mix_FreeChunk()が異なりますが、内容はほぼ同じです。
Mix_Chunk *Mix_LoadWAV(char *file);
Mix_LoadMUS()とほぼ同じです。WAVとありますが、.wav以外の読み込みもできます。
失敗したらNULLが返ります。
int Mix_PlayChannel(int channel, Mix_Chunk *chunk, int loops);
Mix_PlayMusic()とほぼ同じですが、引数にchannelがあるところが違います。
channelに-1を指定すると、空いているチャンネルが自動的に割り当てられます。
成功時には割り当てられたチャンネル番号が、失敗時には-1が返ります。
int Mix_HaltChannel(int channel);
channelで指定されたチャンネルをストップします。-1を指定すると、すべてのチャンネルがストップされます。
void Mix_FreeChunk(Mix_Chunk *chunk);
解放します。Mix_FreeMusic()とほぼ同じです。
以下に使用例を示します。
Mix_LoadWAV()はメディアファイルをすべて取り込むので、大きなサイズのファイルを読み込もうとすると、それだけメモリを使用します。注意しましょう。
#include <SDL/SDL.h> #include <SDL/SDL_ttf.h> #include <SDL/SDL_mixer.h> int main(){ SDL_Surface *screen; SDL_Surface *ttf_surface; SDL_Rect rect_scr = {0,0,800,600}; SDL_Rect rect_img = {0,0,200,200}; SDL_Color color = {255, 255, 255}; SDL_Event event; SDL_Joystick *joystick; Mix_Chunk *chunk; int endflag = 0; TTF_Font *font; SDL_Init(SDL_INIT_EVERYTHING); /* SDL起動 */ TTF_Init(); /* ミュージック初期化 */ Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024); SDL_WM_SetCaption("タイトル", "たいとる"); SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE); font = TTF_OpenFont("ipag-mona.ttf", 24); /* analoguma.oggを開く */ chunk = Mix_LoadWAV("analoguma.ogg"); if(chunk == NULL){ return 1; } screen = SDL_GetVideoSurface(); rect_scr.y = 0; ttf_surface = TTF_RenderUTF8_Blended(font, "キー操作により終了", color); rect_img.w = ttf_surface->w; rect_img.h = ttf_surface->h; SDL_BlitSurface(ttf_surface, &rect_img, screen, &rect_scr); SDL_FreeSurface(ttf_surface); SDL_Flip(screen); /* ずっと演奏し続ける */ Mix_PlayChannel(-1, chunk, 0); while(!endflag){ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: /* ウインドウクローズ */ case SDL_KEYDOWN: /* キーダウン */ endflag = 1; break; default: break; } } SDL_Delay(1); } /* ミュージック終了処理 */ Mix_HaltChannel(-1); Mix_FreeChunk(chunk); Mix_CloseAudio(); TTF_Quit(); SDL_Quit(); /* SDL終了 */ return 0; }
※コメント、トラックバックはできません。メール、リンクは適当に。
音楽3
18-5-2009
今日のSDL
音楽の読み込み/再生は前2回でやりましたが、今回はその他の機能について触れます。
普通の音楽プレーヤーと同様に、音量調節、一時停止等を行うことができます。
音量調節はMix_VolumeMusic()で、一時停止はMix_PauseMusic()で、再開はMix_ResumeMusic()で行います。
int Mix_VolumeMusic(int volume); void Mix_PauseMusic(); void Mix_ResumeMusic();
Mix_VolumeMusicの引数volumeは0から128(MIX_MAX_VOLUME)の間で指定します。値が大きいほど音量が大きくなります。返り値は前の音量となります。
音楽が一時停止状態にあるかどうかはMix_PausedMusic()にて確認できます。
int Mix_PausedMusic();
一時停止状態であれば1が、そうでなければ0が返ります。
それに関連して、音楽が再生されているかどうかをチェックするにはMix_PlayingMusic()を使います。
int Mix_PlayingMusic();
再生中であれば1が、そうでなければ0が返ります。
また、音楽の巻き戻しを行うこともできます。
void Mix_RewindMusic();
使用例です。音量や現在の再生ステータスを表示するようにすればもっと使いやすくなるでしょう。
#include <SDL/SDL.h> #include <SDL/SDL_ttf.h> #include <SDL/SDL_mixer.h> #define VOLUME_STEP (1) #define DEFAULT_VOLUME (64) int main(){ SDL_Surface *screen; SDL_Surface *ttf_surface; SDL_Rect rect_scr = {0,0,800,600}; SDL_Rect rect_img = {0,0,200,200}; SDL_Color color = {255, 255, 255}; SDL_Event event; SDL_KeyboardEvent *key_event; SDL_Joystick *joystick; Mix_Music *music; int endflag = 0; int volume = DEFAULT_VOLUME; int loop; TTF_Font *font; SDL_Init(SDL_INIT_EVERYTHING); /* SDL起動 */ TTF_Init(); /* ミュージック初期化 */ Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024); SDL_WM_SetCaption("タイトル", "たいとる"); SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE); font = TTF_OpenFont("ipag-mona.ttf", 24); /* analoguma.oggを開く */ music = Mix_LoadMUS("analoguma.ogg"); if(music == NULL){ return 1; } screen = SDL_GetVideoSurface(); rect_scr.y = 0; for(loop = 0; loop < 7; loop ++){ switch(loop){ case 0: ttf_surface = TTF_RenderUTF8_Blended(font, "★ キー操作", color); break; case 1: ttf_surface = TTF_RenderUTF8_Blended(font, "ESC : 終了", color); break; case 2: ttf_surface = TTF_RenderUTF8_Blended(font, "上キー : 音量アップ", color); break; case 3: ttf_surface = TTF_RenderUTF8_Blended(font, "下キー : 音量ダウン", color); break; case 4: ttf_surface = TTF_RenderUTF8_Blended(font, "左キー : 巻き戻し", color); break; case 5: ttf_surface = TTF_RenderUTF8_Blended(font, "スペースキー : 一時停止", color); break; case 6: ttf_surface = TTF_RenderUTF8_Blended(font, "Enterキー : 停止", color); break; default: /* 異常 */ return 1; } rect_img.w = ttf_surface->w; rect_img.h = ttf_surface->h; SDL_BlitSurface(ttf_surface, &rect_img, screen, &rect_scr); SDL_FreeSurface(ttf_surface); rect_scr.y += 30; } SDL_Flip(screen); Mix_VolumeMusic(volume); /* ずっと演奏し続ける */ Mix_PlayMusic(music, -1); key_event = (SDL_KeyboardEvent*)&event; while(!endflag){ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: /* ウインドウクローズ */ endflag = 1; break; case SDL_KEYDOWN: /* キーダウン */ switch (key_event->keysym.sym) { case SDLK_ESCAPE: endflag = 1; break; case SDLK_UP: /* 上キー:音量アップ */ volume+=VOLUME_STEP; if(volume > MIX_MAX_VOLUME){ volume = MIX_MAX_VOLUME; } Mix_VolumeMusic(volume); break; case SDLK_DOWN: /* 下キー:音量ダウン */ volume-=VOLUME_STEP; if(volume < 0){ volume = 0; } Mix_VolumeMusic(volume); break; case SDLK_LEFT: /* 左キー:巻き戻し */ Mix_RewindMusic(); break; case SDLK_SPACE: /* スペースキー:一時停止/再開 */ if(Mix_PausedMusic()){ Mix_ResumeMusic(); } else { Mix_PauseMusic(); } break; case SDLK_RETURN: /* スペースキー:停止/再生 */ if(!Mix_PlayingMusic()){ Mix_PlayMusic(music, -1); } else { Mix_HaltMusic(); } break; default: break; } default: break; } } SDL_Delay(1); } /* ミュージック終了処理 */ Mix_HaltMusic(); Mix_FreeMusic(music); Mix_CloseAudio(); TTF_Quit(); SDL_Quit(); /* SDL終了 */ return 0; }
※コメント、トラックバックはできません。メール、リンクは適当に。
昨日の補足
19-5-2009
このサイトの言語的なものは一応、プロを目指さない人向けなので、ちょっと補足を・・・。
文字の出力の部分ですが
/* 該当部分抜粋 */ for(loop = 0; loop < 7; loop ++){ switch(loop){ case 0: ttf_surface = TTF_RenderUTF8_Blended(font, "★ キー操作", color); break; /* 省略 */ } rect_img.w = ttf_surface->w; rect_img.h = ttf_surface->h; SDL_BlitSurface(ttf_surface, &rect_img, screen, &rect_scr); SDL_FreeSurface(ttf_surface); rect_scr.y += 30; }
ループを使っています。
ループを使わずに書くと、
ttf_surface = TTF_RenderUTF8_Blended(font, "★ キー操作", color); rect_img.w = ttf_surface->w; rect_img.h = ttf_surface->h; SDL_BlitSurface(ttf_surface, &rect_img, screen, &rect_scr); SDL_FreeSurface(ttf_surface); rect_scr.y += 30; ttf_surface = TTF_RenderUTF8_Blended(font, "ESC : 終了", color); rect_img.w = ttf_surface->w; rect_img.h = ttf_surface->h; SDL_BlitSurface(ttf_surface, &rect_img, screen, &rect_scr); SDL_FreeSurface(ttf_surface); rect_scr.y += 30; /* 以下省略 */
と、同じ部分(rect_img.w = ttf_surface->w; 〜 rect_scr.y += 30;)を繰り返し記述することになります。こうすると非常に冗長なソースコードになり、見にくくなるため、サンプルではループを使い、共通処理の記述を1つにまとめています。
このようにしておくと、後で追加するときや修正する時に楽になります。
もっとも、文字を画面に表示するような汎用的な処理は本来は一つの関数にまとめておくべきなのですが。
もっと簡単に構造のみを書くと、次のようになります。
for(i = 0; i < 10; i++){ /* 共通処理 */ switch(i){ case 0: /* 処理A */ break; case 1: /* 処理B */ break; /* 省略 */ } /* 共通処理 */ }
共通処理の部分に全処理で共通して行うこと、一般的には例外処理・エラー処理などを入れておけば、それぞれの処理A、処理B・・・では処理の記述が不要になります。
数字はダイレクトに書いてもいいのですが、列挙体を使うことをおすすめします。理由は追加時、挿入時の変更が容易であるからです。(↓「PROC」はprocedureの略)
enum { PROC_START = 0,/* ダミー */ PROC_A, /* 処理A */ PROC_B, /* 処理B */ PROC_C, /* 処理C */ PROC_D, /* 処理D */ PROC_END /* ダミー */ }; /* ---------------- */ for(i = PROC_START; i < PROC_END; i++){ /* 共通処理 */ switch(i){ case PROC_A: /* 処理A */ break; case PROC_B: /* 処理B */ break; /* 省略 */ } /* 共通処理 */ }
というプログラムで、PROC_Gを追加したい時は
enum { PROC_START = 0,/* ダミー */ PROC_A, /* 処理A */ PROC_B, /* 処理B */ PROC_C, /* 処理C */ PROC_D, /* 処理D */ PROC_G, /* 処理G */ PROC_END /* ダミー */ }; /* ---------------- */ for(i = PROC_START; i < PROC_END; i++){ /* 共通処理 */ switch(i){ case PROC_A: /* 処理A */ break; case PROC_B: /* 処理B */ break; /* 省略 */ case PROC_G: /* 処理G */ break; } /* 共通処理 */ }
と、少し追加するだけで済みますし、処理AとBの間にGを入れたい場合は、
enum { PROC_START = 0,/* ダミー */ PROC_A, /* 処理A */ PROC_G, /* 処理G */ PROC_B, /* 処理B */ PROC_C, /* 処理C */ PROC_D, /* 処理D */ PROC_END /* ダミー */ }; /* ---------------- */ for(i = PROC_START; i < PROC_END; i++){ /* 共通処理 */ switch(i){ case PROC_A: /* 処理A */ break; case PROC_G: /* 処理G */ break; case PROC_B: /* 処理B */ break; /* 省略 */ } /* 共通処理 */ }
で、OKです。switch内の処理Gの位置はどこでもいいのですが、せっかく処理順に並んでいるので、AとBの間に入れた方がいいでしょう。ダミーはループ変数のセット、継続条件の指定に使用するために作ったものであり、実際の処理順を入れ替えても、ループの部分は変更することなくプログラムの修正ができます。
PROC_STARTが一回分余分にループを回ることになります。それが困る場合は、PROC_STARTを定義にしておく
#define PROC_START (0) enum { PROC_A = PTOC_START /* 処理A */ PROC_B, /* 処理B */ PROC_C, /* 処理C */ PROC_D, /* 処理D */ PROC_END /* ダミー */ };
か、continueで処理を飛ばしてしまえばOKです。
for(i = PROC_START; i < PROC_END; i++){ /* 共通処理 */ switch(i){ case PROC_START: continue; break; case PROC_A: /* 処理A */ break; case PROC_B: /* 処理B */ break; /* 省略 */ } /* 共通処理 */ }
順番が一定でない場合はwhileやループ変数の足し算のないforを使用します。その場合は毎回処理番号をセットする必要があります。
for(endflag = 0; endflag != 1;){ /* 共通処理 */ switch(i){ case PROC_A: func_a(); /* 処理A */ i = PROC_B; break; case PROC_B: result = func_b(); /* 処理B */ if(result == 1){ /* 処理結果によって分岐 */ i = PROC_C; } else { i = PROC_D; } break; /* 省略 */ case PROC_G: result = func_g(); /* 処理G */ if(result == 1){ /* 処理結果によって分岐 */ endflag = 1; /* 終了 */ } else { i = PROC_A; } break; } /* 共通処理 */ }
みたいな感じです。
※メール、リンクは適当に。
Copyright (c) 2008, 2009 greencap