C言語とSDLでハナハナもどき

C言語SDLを使って、スロットもどきを作ってみました。

Big.c, reguler.c, hanahana.c(これがmain関数)の3つのファイルを使います。

 

<Big.c>

#include <stdlib.h>
#include <stdio.h>
#include <string.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 Big(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;
char atari[2];
char start;
SDL_Event e3;
/* SDL初期化処理呼び出し */
nSdlInit = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
if( 0 != nSdlInit ) { goto EXIT; }

/* ウィンドウタイトル設定 */
SDL_WM_SetCaption("Come into Broom", 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/droid/DroidSansFallbackFull.ttf", 16);
if( NULL == g_ttfFont ) { goto EXIT; }

/* 背景画像,キャラクター画像ファイル読み込み */
g_srfBack = IMG_Load("./hidari.jpeg");
if( NULL == g_srfBack ) { goto EXIT; }
g_srfChar = IMG_Load("./migi.jpeg");
if( NULL == g_srfChar ) { goto EXIT; }

/* 表示文字列画像作成 */
g_srfText = TTF_RenderUTF8_Blended(g_ttfFont, "ラッキー。", g_colTextColor);
if( NULL == g_srfText) { 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);

/*if (e3.type == SDL_MOUSEBUTTONDOWN && e3.button.button == SDL_BUTTON_LEFT)*/
if ((start = getchar()) == '\n')

{

/* 音楽ファイル読み込み */
g_mixMusic = Mix_LoadMUS("./big.ogg");
if( NULL == g_mixMusic ) { goto EXIT; }

/* 音楽ループ再生開始 */
nPlayMusic = Mix_PlayMusic(g_mixMusic, -1);
if( 0 != nPlayMusic ) { goto EXIT; }
}

else {goto EXIT;}

/* 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;
}

 

<reguler.c>

 

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


SDL_Surface* g_srfMain2 = NULL; /* メインサーフェイス */
SDL_Surface* g_srfBack2 = NULL; /* 背景画像用サーフェイス */
SDL_Surface* g_srfChar2 = NULL; /* キャラクター用サーフェイス */
SDL_Surface* g_srfText2 = NULL; /* 文字表示用サーフェイス */
TTF_Font* g_ttfFont2 = NULL; /* フォントファイルハンドル */
Mix_Music* g_mixMusic2 = NULL; /* ミュージックファイルハンドル */
SDL_Color g_colTextColor2 = { 0, 0, 0}; /* 文字の色(黒) */

int reguler(int argc,char *argv)
{
int nSdlInit2 = -1;
int nTtfInit2 = -1;
int nMixInit2 = -1;
int nPlayMusic2 = -1;
SDL_Rect rcCharDst2;
SDL_Rect rcTextDst2;
SDL_Event evEvent2;
int nReturn2 = 1;
char atari2[2];
char start2;
SDL_Event e3;
/* SDL初期化処理呼び出し */
nSdlInit2 = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
if( 0 != nSdlInit2 ) { goto EXIT; }

/* ウィンドウタイトル設定 */
SDL_WM_SetCaption("Come into Broom", NULL);

/* ビデオモードを設定しメインサーフェイスを作成 */
/* 画面設定:640*480 32bit */
/* ソフトウェアサーフェイス,ダブルバッファ使用 */
g_srfMain2 = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE | SDL_DOUBLEBUF);
if( NULL == g_srfMain2 ) { goto EXIT; }

/* SDL_ttf 初期化処理呼び出し */
nTtfInit2 = TTF_Init();
if( 0 != nTtfInit2 ) { goto EXIT; }

/* オーディオデバイスオープン処理呼び出し */
/* デフォルトサンプリング周波数,デフォルト波形サンプル */
/* ステレオ,サウンドバッファサイズ:1024byte */
nMixInit2 = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024);
if( 0 != nMixInit2 ) { goto EXIT; }

/* フォントファイル読み込み */
/* フォントファイル:Takao Pゴシック フォントサイズ:16 */
/* 第一引数に使用するフォントファイルのパスを設定 */
g_ttfFont2 = TTF_OpenFont("/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf", 16);
if( NULL == g_ttfFont2 ) { goto EXIT; }

/* 背景画像,キャラクター画像ファイル読み込み */
g_srfBack2 = IMG_Load("./hidari.jpeg");
if( NULL == g_srfBack2 ) { goto EXIT; }
g_srfChar2 = IMG_Load("./migi.jpeg");
if( NULL == g_srfChar2 ) { goto EXIT; }

/* 表示文字列画像作成 */
g_srfText2 = TTF_RenderUTF8_Blended(g_ttfFont2, "ラッキー。", g_colTextColor2);
if( NULL == g_srfText2 ) { goto EXIT; }


/* キャラクター画像の貼り付け位置,幅高さ設定 */
/* 画面の X=310,Y=0 の位置に 読み込んだ画像の幅高さで貼り付け */
rcCharDst2.x = 310; rcCharDst2.y = 0;
rcCharDst2.w = g_srfChar2->w; rcCharDst2.h = g_srfChar2->h;

/* 文字列の貼り付け位置,幅高さ設定 */
/* 画面の X=370,Y=65 の位置に 文字列画像の幅高さで貼り付け */
rcTextDst2.x = 370; rcTextDst2.y = 65;
rcTextDst2.w = g_srfText2->w; rcTextDst2.h = g_srfText2->h;

/* メインループ処理 */
while(1) {
/* SDLのイベントメッセージ取得 */
SDL_PollEvent(&evEvent2);

/* 終了メッセージかESCキーが押下されたらループ終了 */
if( SDL_QUIT == evEvent2.type ) { break; }
if( SDL_KEYDOWN == evEvent2.type
&& SDLK_ESCAPE == evEvent2.key.keysym.sym ) {
break;
}

/* メインサーフェイスを黒色で塗り潰し */
SDL_FillRect(g_srfMain2, NULL, SDL_MapRGB(g_srfMain2->format, 0, 0, 0));

/* 背景画像をメインサーフェイスに転送 */
SDL_BlitSurface(g_srfBack2, NULL, g_srfMain2, NULL);

/* キャラクター画像の貼り付け位置を指定してメインサーフェイスに転送 */
SDL_BlitSurface(g_srfChar2, NULL, g_srfMain2, &rcCharDst2);

/* 文字列の貼り付け位置を指定してメインサーフェイスに転送 */
SDL_BlitSurface(g_srfText2, NULL, g_srfMain2, &rcTextDst2);

/* メインサーフェイスを画面表示 */
SDL_Flip(g_srfMain2);

/*if (e3.type == SDL_MOUSEBUTTONDOWN && e3.button.button == SDL_BUTTON_LEFT)*/
if *1 == '\n')

{

/* 音楽ファイル読み込み */
g_mixMusic2 = Mix_LoadMUS("./reg.ogg");
if( NULL == g_mixMusic2 ) { goto EXIT; }

/* 音楽ループ再生開始 */
nPlayMusic2 = Mix_PlayMusic(g_mixMusic2, -1);
if( 0 != nPlayMusic2 ) { goto EXIT; }
}

else {goto EXIT;}

/* 0.01秒ウエイト */
SDL_Delay(10);
}

nReturn2 = 0;

EXIT:
/* 音楽再生停止 */
if( 0 == nPlayMusic2 ) { Mix_HaltMusic(); }

/* ミュージックファイルハンドル解放 */
if( NULL != g_mixMusic2 ) { Mix_FreeMusic(g_mixMusic2); }
/* 文字列・画像のサーフェイスバッファ解放 */
if( NULL != g_srfText2 ) { SDL_FreeSurface(g_srfText2); }
if( NULL != g_srfChar2 ) { SDL_FreeSurface(g_srfChar2); }
if( NULL != g_srfBack2 ) { SDL_FreeSurface(g_srfBack2); }

/* フォントファイルハンドルクローズ */
if( NULL != g_ttfFont2 ) { TTF_CloseFont(g_ttfFont2); }

/* オーディオデバイスクローズ処理呼び出し */
if( 0 == nMixInit2 ){ Mix_CloseAudio(); }

/* SDL_ttf終了処理呼び出し */
if( 0 == nTtfInit2 ){ TTF_Quit(); }

/* SDL終了処理呼び出し */
if( 0 == nSdlInit2 ){ SDL_Quit(); }

return nReturn2;
}

基本的にはBig.cとreguler.cは同じ処理で、音楽だけが異なります。

最後にmain関数であるhanahana.cです。

 

<hanahana.c>

/* header files */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "hanahana.h"


/* main */
int main() {
int i, n;

/* 乱数のシードを与える */
srand*2;

for ( i = 0; i <= 299; i++ ) {
/* 1 から 299 までの乱数を発生させる */
n = rand() % 299 + 1;

/* 表示 */
printf("%2d回目 = %3d\n", i + 1, n);

if(n==298)
{printf("BIG\n") ;
Big();}

else if(n==297)
{printf("Reguler\n");
reguler();}
}
return 0;
}

<hanahana.h>

int Big();
int reguler();

 

 

乱数を発生させ(srand関数、とrand関数を使用)、298のときはBig();  297のときはreguler();をそれぞれ呼び出すことでボーナスを演出しています。

出来上がったa.outを端末で実行すると、ハナハナを模擬したヘンテコなプログラムが動きます。音楽もなります。

コンパイルするときは、同一フォルダ内にhanahana.c Big.c reguler.cの3プログラムとともに、リソース(音楽と画像)も一緒に入れておいて下記コマンドでコンパイルとなります。

 

$gcc hanahana.c Big.c reguler.c -lSDL -lSDL_image -lSDL_mixer -lSDL_ttf

$./a.out

 

f:id:katsu3752:20201207225555p:plain

当たると画面に花が出現し、ENTERで音楽が鳴る

 

私はマウスを使って音楽再生をコントロール使用としましたが、うまくいかずにコメントとして残しています。余力があればマウスで操作できるよう改良してみてください。

ビッグもしくはレギュラーが当たると、端末を有効にしてENTERキーを押すことで、音楽が鳴ります。

 

私の力量では中身全てを説明できませんが、やってみてください。

 

 

最新版 12歳からはじめる ゼロからのC言語ゲームプログラミング教室

最新版 12歳からはじめる ゼロからのC言語ゲームプログラミング教室

 

 

*1:start2 = getchar(

*2:unsigned)time(NULL