この質問。
そういえば昔私もかなり無理やりアニメーションさせてたなぁって、
その時は関数化しか出来なかった(今もそうだが)のでコードもグチャグチャ、スパパパパゲッティー状態でした(今もそうだが)
ゲームループ全体でリアルタイムに変化させていかないといけないって難しいんですね、
ゲームプログラミングとかより普通にプログラミング(?)したほうが楽そう。
今現在としてもオブジェクト指向への理解が大分ゴミな感じなので頑張らなくては...
例のスパパパパゲッティー
► スポイラーを表示
#include
#include
#include
typedef struct{
int right;
int left;
int up;
int down;
int shift;
}KeyIn; //キー監視の構造体
void Init(SDL_Surface **scr,SDL_Surface **image,SDL_Rect *m_rect,SDL_Rect *scr_m_rect,SDL_Rect *s_rect,SDL_Rect *scr_s_rect);
int CheckEvent(SDL_Event event); //イベントチェック
bool Draw(SDL_Surface *image,SDL_Rect m_rect,SDL_Rect scr_m_rect,SDL_Surface *scr);
bool Animation(SDL_Rect *m_rect); //アニメーションさせる
void chara_ani(int *ani); //自機のアニメーション
void Move(SDL_Rect *scr_m_rect); //画像の移動
void M_shot();
KeyIn sek; //キー状態格納変数
Uint8* keys; //キー状態を受け取る変数
int a_i; //アニメーションの変数
int main(int argc, char* argv[])
{
/************* 変数の宣言 ************/
SDL_Surface *image,*scr; //画像ハンドル
SDL_Rect m_rect, scr_m_rect, fsc = {0 ,0 ,640 ,480}; //画像位置情報 (自機)
SDL_Rect s_rect, scr_s_rect; //ショットの画像位置
SDL_Event event;//eventk; //イベントの監視
int quit; //イベント結果の返り値
a_i = 0;
/***************ここまで**************/
Init(&scr,&image,&m_rect,&scr_m_rect,&s_rect,&scr_s_rect); //初期化に画像ハンドルと位置情報を渡す
while(1) //とりあえず無限ループ
{
Move(&scr_m_rect);
Draw(image,m_rect,scr_m_rect,scr);
//SDL_BlitSurface(image, &m_rect, scr, &scr_m_rect); //画像描画
SDL_Delay(16.66666f); //だいたい60FPSぶんぐらい待つ
SDL_Flip(scr); //表に出す
SDL_FillRect(scr, &fsc, SDL_MapRGB(scr->format, 0,0,0)); //画面のクリア
quit = CheckEvent(event);
if(quit) return 0;
}
SDL_FreeSurface(image); //画像の開放
SDL_Quit(); //終了処理
return 0;
}
void Init(SDL_Surface **scr,SDL_Surface **image,SDL_Rect *m_rect,SDL_Rect *scr_m_rect,SDL_Rect *s_rect,SDL_Rect *scr_s_rect)
{
SDL_Init(SDL_INIT_EVERYTHING); //SDL初期化処理
SDL_WM_SetCaption("東方試作っぽいなにか", NULL); // タイトルを設定する
*scr = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE); //ウィンドウ作成
//画像読み込み
*image = IMG_Load("image/Marisa.png");
if(*image == NULL)
{
printf("画像がロードできていないようです。");
} else {
printf("ロード完了"); //ココから自機の位置初期化
m_rect->x = 0;
m_rect->y = 0;
m_rect->w = 50;
m_rect->h = 50;
scr_m_rect->x = 0;
scr_m_rect->y = 0;
s_rect->x = 0;
s_rect->y = 0;
s_rect->w = 0;
s_rect->h = 0;
scr_s_rect->x = 0;
scr_s_rect->y = 0;
}
}
int CheckEvent(SDL_Event event)
{
// すべてのイベントを処理する
while (SDL_PollEvent(&event))
{
// QUIT イベントが発生するか、ESC キーが押されたら終了する
if ((event.type == SDL_QUIT) ||
(event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE))
return 1;
}
return 0;
}
void Move(SDL_Rect *scr_m_rect)
{
keys = SDL_GetKeyState(NULL); //キー監視
sek.left = keys[SDLK_LEFT]; /* [←]*/
sek.up = keys[SDLK_UP]; /* [↑]*/
sek.right = keys[SDLK_RIGHT]; /* [→]*/
sek.down = keys[SDLK_DOWN]; /* [↓]*/
sek.shift = keys[SDLK_LSHIFT];
//移動させる
if (sek.down)
{
scr_m_rect->y += 6;
if (sek.shift) scr_m_rect->y -= 3; //shift押されてたら低速移動
}
if (sek.up)
{
scr_m_rect->y -= 6;
if (sek.shift) scr_m_rect->y += 3;
}
if (sek.left)
{
scr_m_rect->x -= 6;
if (sek.shift) scr_m_rect->x += 3;
}
if (sek.right)
{
scr_m_rect->x += 6;
if (sek.shift) scr_m_rect->x -= 3;
}
if (sek.up && sek.left) //斜め移動なら移動速度を更に1下げる
{
scr_m_rect->y += 1;
scr_m_rect->x += 1;
}
if (sek.up && sek.right)
{
scr_m_rect->y += 1;
scr_m_rect->x -= 1;
}
if (sek.down && sek.left)
{
scr_m_rect->y -= 1;
scr_m_rect->x += 1;
}
if (sek.down && sek.right)
{
scr_m_rect->y -= 1;
scr_m_rect->x -= 1;
}
}
bool Draw(SDL_Surface *image,SDL_Rect m_rect,SDL_Rect scr_m_rect,SDL_Surface *scr)
{
Animation(&m_rect); //アニメーション関数呼ぶ
SDL_BlitSurface(image, &m_rect, scr, &scr_m_rect); //画像描画
return true;
}
bool Animation(SDL_Rect *m_rect)
{
int ani;
a_i++;
chara_ani(&ani);
switch(ani) //今のフレームで表示すべき画像
{
case 1:
m_rect->x = 0;
m_rect->y = 0;
break;
case 2:
m_rect->x = 50;
m_rect->y = 0;
break;
case 3:
m_rect->x = 100;
m_rect->y = 0;
break;
case 4:
m_rect->x = 150;
m_rect->y = 0;
break;
case 5:
m_rect->x = 0;
m_rect->y = 50;
break;
case 6:
m_rect->x = 50;
m_rect->y = 50;
break;
case 7:
m_rect->x = 100;
m_rect->y = 50;
break;
case 8:
m_rect->x = 150;
m_rect->y = 50;
break;
case 9:
m_rect->x = 0;
m_rect->y = 100;
break;
case 10:
m_rect->x = 50;
m_rect->y = 100;
break;
case 11:
m_rect->x = 100;
m_rect->y = 100;
break;
case 12:
m_rect->x = 150;
m_rect->y = 100;
break;
}
return true;
}
void chara_ani(int *ani)
{
sek.left = keys[SDLK_LEFT]; /* [←]*/
sek.up = keys[SDLK_UP]; /* [↑]*/
sek.right = keys[SDLK_RIGHT]; /* [→]*/
if (sek.right) //右が押されていたら
{
switch((a_i/6)) //右用のアニメーション
{
case 0:
*ani = 5;
break;
case 1:
*ani = 6;
break;
case 2:
*ani = 7;
break;
case 3:
*ani = 8;
a_i = 0;
break;
}
} else
if (sek.left) //右が押されてなくて左が押されていたら
{
switch((a_i/6)) //左用アニメーション
{
case 0:
*ani = 9;
break;
case 1:
*ani = 10;
break;
case 2:
*ani = 11;
break;
case 3:
*ani = 12;
a_i = 0;
break;
}
}
else
switch((a_i/6)) //そうでなくて何も押されていなければ通常のアニメーション
{
case 0:
*ani = 1;
break;
case 1:
*ani = 2;
break;
case 2:
*ani = 3;
break;
case 3:
*ani = 4;
a_i = 0;
break;
}
}