[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
もう一度0からゲームを作って行こうと思って、まずは自機移動プログラムを作ってみました。
今まで、一番の悩みどころだったのが変数の扱い方。
グローバル変数とローカル変数の使い分けがイマイチ良く判ってなくて
例えば、自機や敵の移動関数を作って移動させる処理を関数の中だけで終わらせてしまうと
当たり判定を別の関数で行おうと思った時に、自機や敵の位置を知る為の変数が必要ですが
敵や自機の移動をローカル変数で行っている場合、当たり判定関数からは敵&自機位置の変数を
参照出来ないので、どうすれば???となっていました。
グローバル変数を使えば問題無いのですが、そうするとグロバール変数を使いまくらないと
いけなくなりそうで、プログラムが肥大化した時に大変そうです。
ちなみに
グローバル変数は一度宣言すれば、プログラムが終了するまで有効。
ローカル変数は関数のなかだけでしか有効ではない。
と言った感じだと思います。
で、色々と調べたりしてみたのですが良く判らないので、考えるよりも自分がわかる方法
(グローバル変数を使う)で作って行こうと思った訳です。
で、まずこんなプログラムを作ってみました↓
**************************************************************
#include "DxLib.h"
typedef struct{//自機構造体
int x,y,img;
}ch_t;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
int image[16];//自機画像配列変数宣言
char Key[256];//キー情報
int katamuki;//自機傾き用変数宣言
ch_t ch;//構造体用
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
ch.x =300;//自機初期位置x
ch.y =360;//自機初期位置y
katamuki=4;//傾き初期位置
SetDrawScreen( DX_SCREEN_BACK ) ; //描画先を裏画面に設定
LoadDivGraph( "ship.png" , 9 , 9 , 1 , 48 , 48 , image ) ;//画像を分割してimage配列に保存
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されると終了
int color_white;
color_white= GetColor( 255 , 255 , 255 ) ;//色取得
static int gtime;//ゲームカウンタ
gtime++;
////////////////////////自機移動////////////////////////////////////////////////////////////////
if( Key[ KEY_INPUT_UP ] == 1 ) //上ボタンが押されたら
ch.y=ch.y-4; //上向きフラグを立てる
if( Key[ KEY_INPUT_LEFT ] == 1 ) //左ボタンが押されたら
{ ch.x=ch.x-4; //左向きフラグを立てる
if(gtime%4 == 0) katamuki--;}else//傾ける
{if(katamuki<4)
if(gtime%4 == 0) katamuki++;}//ボタンが押されてなくて傾いていたら戻す
if( Key[ KEY_INPUT_DOWN ] == 1 ) //下ボタンが押されたら
ch.y=ch.y+4; //下向きフラグを立てる
if( Key[ KEY_INPUT_RIGHT] == 1 ) //右ボタンが押されたら
{ ch.x=ch.x+4; //右向きフラグを立てる
if(gtime%4 == 0) katamuki++;}else//傾ける
{if(katamuki>4)
if(gtime%4 == 0) katamuki--;} //ボタンが押されてなくて傾いていたら戻す
if( ch.x<140 ) { ch.x=140; }//画面からはみ出さないようにする処理
if( ch.x>452 ) { ch.x=452; }
if( ch.y<0 ) { ch.y=0; }
if( ch.y>432 ) { ch.y=432; }
if( katamuki<0 ) {katamuki=0;}//傾き過ぎないようにする処理
if( katamuki>8 ) {katamuki=8;}
ch.img=image[katamuki];
//SetDrawBlendMode( DX_BLENDMODE_NOBLEND , 0 ) ;
DrawGraph( ch.x , ch.y , ch.img , TRUE ) ;
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////fps表示////////////////////////////////////////////////////////////
static int FpsTime[2]={0,},FpsTime_i=0;
static double Fps=0.0;
if(FpsTime_i== 0)
FpsTime[0]=GetNowCount(); //1周目の時間取得
if(FpsTime_i==49){
FpsTime[1]=GetNowCount(); //50周目の時間取得
Fps = 1000.0f / ((FpsTime[1] - FpsTime[0]) / 50.0f);//測定した値からfpsを計算
FpsTime_i=0;
}
else
FpsTime_i++; //現在何周目かカウント
if(Fps != 0)
DrawFormatString(520,440,color_white,"FPS %.1f",Fps); //fpsを表示
////////////////////////////////////////////////////////////////////////////////////////
ScreenFlip();
}
DxLib_End();
return 0;
}
**************************************************************
とりあえずメインループに全ての処理を書いています。
ただ、これだとプログラムが大きくなってくると訳がわからなくなって困るので
処理ごとに関数化したのがコレ↓
**************************************************************
#include "DxLib.h"
typedef struct{//自機構造体
int x,y,img;
}ch_t;
//変数宣言&初期化//
int g_image[16];//自機画像配列変数宣言
char Key[256];//キー情報
int g_katamuki=4;//自機傾き用変数宣言
static int g_gtime=0;//ゲームカウンタ
ch_t ch;//自機構造体用
////////////////////////////
//関数のプロトタイプ宣言//
void haikei0();
void jikimove();
void fps();
////////////////////////////
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
SetDrawScreen( DX_SCREEN_BACK ) ; //描画先を裏画面に設定
ch.x =300;//自機初期位置x
ch.y =360;//自機初期位置y
LoadDivGraph( "ship.png" , 9 , 9 , 1 , 48 , 48 , g_image ) ;//画像を分割してg_image配列に保存
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されると終了
haikei0();
jikimove();
fps();
g_gtime++;
ScreenFlip();
}
DxLib_End();
return 0;
}
////////////////////////背景表示////////////////////////////////////////////////////////////////
//引数 なし
//返値 なし
void haikei0(){
int color_haikei;
color_haikei= GetColor( 0 , 105 , 105 ) ;//色取得
DrawBox ( 140 , 0 , 500 , 480 , color_haikei , TRUE) ; // 四角形を描画
}
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////自機移動////////////////////////////////////////////////////////////////
//引数 なし
//返値 なし
void jikimove(){
if( Key[ KEY_INPUT_UP ] == 1 ) //上ボタンが押されたら
ch.y=ch.y-4; //上向きフラグを立てる
if( Key[ KEY_INPUT_LEFT ] == 1 ) //左ボタンが押されたら
{ ch.x=ch.x-4; //左向きフラグを立てる
if(g_gtime%4 == 0) g_katamuki--;}else//傾ける
{if(g_katamuki<4)
if(g_gtime%4 == 0) g_katamuki++;}//ボタンが押されてなくて傾いていたら戻す
if( Key[ KEY_INPUT_DOWN ] == 1 ) //下ボタンが押されたら
ch.y=ch.y+4; //下向きフラグを立てる
if( Key[ KEY_INPUT_RIGHT] == 1 ) //右ボタンが押されたら
{ ch.x=ch.x+4; //右向きフラグを立てる
if(g_gtime%4 == 0) g_katamuki++;}else//傾ける
{if(g_katamuki>4)
if(g_gtime%4 == 0) g_katamuki--;} //ボタンが押されてなくて傾いていたら戻す
if( ch.x<140 ) { ch.x=140; }//画面からはみ出さないようにする処理
if( ch.x>452 ) { ch.x=452; }
if( ch.y<0 ) { ch.y=0; }
if( ch.y>432 ) { ch.y=432; }
if( g_katamuki<0 ) {g_katamuki=0;}//傾き過ぎないようにする処理
if( g_katamuki>8 ) {g_katamuki=8;}
ch.img=g_image[g_katamuki];
//SetDrawBlendMode( DX_BLENDMODE_NOBLEND , 0 ) ;
DrawGraph( ch.x , ch.y , ch.img , TRUE ) ;
}
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////fps表示////////////////////////////////////////////////////////////
//引数 なし
//返値 なし
void fps(){
int color_white;
color_white= GetColor( 255 , 255 , 255 ) ;//色取得
static int FpsTime[2]={0,},FpsTime_i=0;
static double Fps=0.0;
if(FpsTime_i== 0)
FpsTime[0]=GetNowCount(); //1周目の時間取得
if(FpsTime_i==49){
FpsTime[1]=GetNowCount(); //50周目の時間取得
Fps = 1000.0f / ((FpsTime[1] - FpsTime[0]) / 50.0f);//測定した値からfpsを計算
FpsTime_i=0;
}
else
FpsTime_i++; //現在何周目かカウント
if(Fps != 0)
DrawFormatString(520,440,color_white,"Fps %.1f",Fps); //fpsを表示
DrawFormatString(520,420,color_white,"g_gtime %1d",g_gtime); //g_gtimeを表示
}
////////////////////////////////////////////////////////////////////////////////////////
**************************************************************
FPSの表示方法はC言語何でも質問サイトさんのを丸写しです。
メイン関数で宣言されているのは
haikei0();
jikimove();
fps();
g_gtime++;
ScreenFlip();
だけなので、後でチェックする時にわかりやすかと思います。
で、これを分割してコンパイル出来るようにしようと思っているのですが
どういう風に分割するかで悩み中です^^;
10 | 2024/11 | 12 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
好きなSTGは、怒首領蜂大往生、エスプガルーダ(2)等の弾幕STGやら雷電シリーズなんかの非弾幕、バトルガレッガ、グラディウスシリーズ、R-TYPE等、STGなら何でも好きです。
音楽がカッコイイSTGが特に好きで、並木学氏は最高!