SDLでボンバーマン風ゲームを作ってみる5
今回は、タイトル画像を追加してみました。
ソースコードはこちら
http://www.geocities.jp/finnissy/data/090810.zip
snd.c
#include "main.h" #include "game.h" #include "import.h" #include "libttf.h" #include "gfx.h" #include "snd.h" #include "color.h" #include <stdio.h> #include <ctype.h> #define MVAL (2) //移動量 #define ID_BALL (0) // blit image ID #define FUNC_MAX (10) //同時に実行する関数の最大値 #define MENU01_X (180) #define MENU01_Y (150) #define MENU01_ID (20) #define MENU02_X (180) #define MENU02_Y (200) #define MENU02_ID (21) #define MENU03_X (180) #define MENU03_Y (250) #define MENU03_ID (22) #define FONT_SIZE_MENU (FONT_SIZE+8) /****************************************************/ /* private method */ /****************************************************/ static void title_event(void); static void menu_blit(void); static void proc_event(void); static void key_event(SDLKey key); static void notify_end(void); static void notify_state(gstate state); static void wait(void); static void frame_blit(void); static void move_abs(int x,int y,int mval); static void move_pos(int x,int y); static boolean dec_keys(SDLKey key); static void proc_keys(SDLKey key); /****************************************************/ /* private member */ /****************************************************/ /************************/ /* flags */ /************************/ static boolean active; //ゲームフラグ static boolean pressed; //押下 static boolean flg_bomm; //爆弾フラグ static int game_state; //状態 /************************/ /* parameter */ /************************/ static Uint32 elapsed_ms; //経過ミリ秒 static SDLKey key_state; //Key Code static Sint16 screenX = 7*BLOCK_SIZE; static Sint16 screenY = 7*BLOCK_SIZE; static Sint16 move_state; static Sint8 key_count = 0; static Uint16 level = 1; static Sint8 now_menu; static struct game_func{ void (*f[FUNC_MAX])(void); int numfunc; } games; /****************************************************/ /* private method */ /****************************************************/ static void title_event(void) { SDL_Event ev; while( SDL_PollEvent(&ev) ) { switch(ev.type) { case SDL_QUIT: /*ウィンドウの[×]ボタン*/ notify_end(); notify_state(STATE_END); break; case SDL_KEYDOWN: /*キーダウン*/ switch( ev.key.keysym.sym ) { case SDLK_UP: key_state = SDLK_UP; break; case SDLK_DOWN: key_state = SDLK_DOWN; break; case SDLK_RETURN: key_state = SDLK_RETURN; break; default: return; //------abort } pressed = TRUE; break; case SDL_KEYUP: break; case SDL_MOUSEBUTTONDOWN: /*マウスダウン*/ break; default: break; } } } static void menu_blit(void) { if( pressed ) { switch( key_state ) { case SDLK_UP: now_menu = (now_menu-1) < 0 ? 0 : now_menu-1; break; case SDLK_DOWN: now_menu = (now_menu+1) % (STATE_MAX-1); break; //unused state_quit case SDLK_RETURN: notify_end(); if(now_menu == 0) notify_state(STATE_PLAY); else if(now_menu == 1) notify_state(STATE_PLAY); else //notify_state(STATE_OPTION); else if(now_menu == 2) notify_state(STATE_END); break; default: break; } switch(now_menu) { case 0: blit_text(MENU01_X,MENU01_Y,COL_RED,COL_PINK,"START",MENU01_ID); blit_text(MENU02_X,MENU02_Y,COL_BLUE,COL_AQUA,"OPTION",MENU02_ID); blit_text(MENU03_X,MENU03_Y,COL_WHITE,COL_GRAY,"END",MENU03_ID); break; case 1: blit_text(MENU01_X,MENU01_Y,COL_AQUA,COL_ORANGE,"START",MENU01_ID); blit_text(MENU02_X,MENU02_Y,COL_RED,COL_PINK,"OPTION",MENU02_ID); blit_text(MENU03_X,MENU03_Y,COL_WHITE,COL_GRAY,"END",MENU03_ID); break; case 2: blit_text(MENU01_X,MENU01_Y,COL_AQUA,COL_ORANGE,"START",MENU01_ID); blit_text(MENU02_X,MENU02_Y,COL_BLUE,COL_AQUA,"OPTION",MENU02_ID); blit_text(MENU03_X,MENU03_Y,COL_RED,COL_PINK,"END",MENU03_ID); break; default: break; } pressed = FALSE; } } static void proc_event(void) { SDL_Event ev; while( SDL_PollEvent(&ev) ) { switch(ev.type) { case SDL_QUIT: /*ウィンドウの[×]ボタン*/ // printf("QUIT\n"); notify_end(); notify_state(STATE_END); break; case SDL_KEYDOWN: /*キーダウン*/ // printf("KeyDonw\n"); proc_keys( ev.key.keysym.sym ); break; case SDL_KEYUP: // printf("KeyUp\n"); if( dec_keys(ev.key.keysym.sym) ) { pressed = FALSE; key_count = 0; } break; case SDL_MOUSEBUTTONDOWN: /*マウスダウン*/ // printf("MouseDonw\n"); break; default: break; } } } static void frame_blit(void) { int i; for(i = 0;i < games.numfunc;i++) { if(games.f[i] != NULL) games.f[i](); } if(flg_bomm) { bomm_start(screenX,screenY); flg_bomm = FALSE; } else if(pressed) { key_event(key_state); } blit(screenX, screenY, images.ball, ID_BALL); } static void key_event(SDLKey key) { switch(key) { case SDLK_ESCAPE: notify_end(); notify_state(STATE_END);break; case SDLK_RIGHT: move_abs(1,0,MVAL); break; case SDLK_LEFT: move_abs(-1,0,MVAL); break; case SDLK_UP: move_abs(0,-1,MVAL); break; case SDLK_DOWN: move_abs(0,1,MVAL); break; default: break; } } static boolean dec_keys(SDLKey key) { switch(key) { case SDLK_RIGHT: key_count--; break; case SDLK_LEFT: key_count--; break; case SDLK_UP: key_count--; break; case SDLK_DOWN: key_count--; break; default: return FALSE; } return key_count <= 0 ? TRUE : FALSE; } static void proc_keys(SDLKey key) { switch(key) { case SDLK_ESCAPE: key_state = key; case SDLK_RIGHT: key_state = key; key_count++; break; case SDLK_LEFT: key_state = key; key_count++; break; case SDLK_UP: key_state = key; key_count++; break; case SDLK_DOWN: key_state = key; key_count++; break; case SDLK_SPACE: flg_bomm = TRUE; return; default: return; } pressed = TRUE; } static void move_abs(int x,int y,int mval) { int x_dumy; int y_dumy; int x_flg; int y_flg; int now_state; x_dumy = (screenX + x*mval) <= -BLOCK_SIZE ? FRAME_WIDTH - BLOCK_SIZE : (screenX + x*mval) % FRAME_WIDTH; y_dumy = (screenY + y*mval) <= -BLOCK_SIZE ? FRAME_HEIGHT - BLOCK_SIZE : (screenY + y*mval) % FRAME_HEIGHT; x_flg = screenX - x_dumy; y_flg = screenY - y_dumy; now_state = (x_flg > 0) ? MV_LEFT : (x_flg < 0) ? MV_RIGHT : (y_flg > 0) ? MV_UP : (y_flg < 0) ? MV_DOWN : MV_LEFT; //printf("%d : %d\n",x_dumy,y_dumy); if( map_calc(x_dumy, y_dumy, now_state) ) //進行方向にトライ { move_state = now_state; screenX = x_dumy; screenY = y_dumy; } else if(move_state != now_state) //前回と今回が同じ進行方向は無理 { //前回の進行方向にトライ switch( move_state ) { case MV_LEFT: if( map_calc(screenX - MVAL,screenY,move_state) ) screenX -= MVAL; break; case MV_RIGHT: if( map_calc(screenX + MVAL,screenY,move_state) ) screenX += MVAL; break; case MV_UP: if( map_calc(screenX,screenY - MVAL,move_state) ) screenY -= MVAL; break; case MV_DOWN: if( map_calc(screenX,screenY + MVAL,move_state) ) screenY += MVAL; break; default: break; } } } static void move_pos(int x,int y) { screenX = (x < 0) ? 0 : x % FRAME_WIDTH; screenY = (y < 0) ? 0 : y % FRAME_HEIGHT; } static void notify_end(void) { active = FALSE; } static void notify_state(gstate state) { game_state = state; } static void wait(void) { Uint32 ms; const Uint8 frate = 16; ms = SDL_GetTicks() - elapsed_ms; if(ms < frate) { SDL_Delay(frate - ms); //printf("wait() : %d\n", frate - ms); } elapsed_ms = SDL_GetTicks(); } /************************************************/ /* Public Method */ /************************************************/ gstate proc_title(void) { active = TRUE; play_bgm(sounds.opening); ttf_resize(FONT_SIZE_MENU); blit_text(MENU01_X,MENU01_Y,COL_AQUA,COL_ORANGE,"START",MENU01_ID); blit_text(MENU02_X,MENU02_Y,COL_BLUE,COL_AQUA,"OPTION",MENU02_ID); blit_text(MENU03_X,MENU03_Y,COL_WHITE,COL_GRAY,"END",MENU03_ID); while(active) { title_event(); menu_blit(); draw(); update(); wait(); } return game_state; } gstate proc_play(void) { active = TRUE; draw_scene(STATE_PLAY); play_bgm(sounds.play); while(active) { proc_event(); frame_blit(); fps(elapsed_ms,FRAME_RATE); draw(); update(); wait(); } return game_state; } gstate proc_end(void) { return STATE_QUIT; } void add_func(void (*f)(void)) { int i; for(i = 0;i < games.numfunc;i++) { if(games.f[i] == f) { i = -1; break; } } if(i >= 0 && games.numfunc < FUNC_MAX) { games.f[games.numfunc] = f; games.numfunc++; } } void del_func(void (*f)(void)) { int i; for(i = 0;i < games.numfunc;i++) { if(games.f[i] == f) { int idx = i + 1; while(idx < games.numfunc) { games.f[i] = games.f[idx]; i++; idx++; } games.f[i] = NULL; games.numfunc--; break; } } } Uint16 get_level(void) { return level % MAX_LEVEL; } |