STGサンプルプログラム(?)  1年 金武
ここでは僕の作ったSTGのサンプルプログラムを示したいとおもいます。
プログラムを始めて少しですが僕は何かを教えるだけの知識はありませんし稚拙なプログラムですが
ゲームを作りたいけど作ったことがないというような人の参考になったら幸いです。
開発環境としてコンパイラはMicrosoft Visual C++6.0、他にDirectX8.1 SDKとSimpleXを使ってます。
DirectX SDKはDirectXを使ったプログラム開発のためにSimpleXはそれを簡単に出来るために必要です。
今回はそのSimpleXを使って作ったゲームのサンプルプログラムです。
どんなプログラムかというとシンプルに敵が左から出てきてプレーヤー1発ずつしか弾が撃てないSTGです。

敵に関する部分は赤色自機、自弾に関する部分は緑で表示してあります。


#define FULLSCREEN
#include<SimpleX.h>

CSprite jiki , tama ; //自機および自弾の宣言
CSprite en[30] ; //上下左右からの敵の宣言

//全体で使う変数の宣言
int frm=0 , scr ;

//自機、自弾に使う変数の宣言
float targ ;

//敵に使う変数の宣言
int rnd[6] ;
int n=0 ;

下では敵や自機の設定をします。上で言ったようには色は変えてません。StartUp()の範囲で色を変えています。
StartUp()では画像のロードとかゲームに使う素材を用意したりします。
void StartUp()
{
	SetFPS(60) ;				//下のMainLoop()を1秒間に60回繰り返します。
	//自機、自弾、敵のビットマップをロード
	LoadBmp(0 , "jiki.bmp") ;
	LoadBmp(1 , "tama.bmp") ;
	LoadBmp(2 , "teki.bmp") ;
	
	//自機、自弾の初期設定
	jiki.SetAnim(0 , 1 , 32 , 32) ;
	jiki.SetMargin(0 , 6 , 6 , 6 , 6) ;
	jiki.SetPos(240 , 320) ;

	tama.SetAnim(1 , 1 , 16 , 16) ;
	tama.SetMargin(0 , 0 , 0 , 0 , 0) ;
	tama.Disable() ;

	//敵の初期設定
	for(int i=0 ; i<30 ; i++){
		
		en[i].SetAnim(2 , 1 , 32 , 32) ;
		en[i].SetMargin(0, 4 , 4 , 4 , 4) ;
		en[i].Disable() ;
	}
}

ここでは敵の出現を制御します。といってもただ単に1秒ごとにランダムで0〜5体出てくるだけですが・・・
基本的にfor文で繰り返して条件が満たされたら敵が出現します。
MainLoop()でここを1秒間に繰り返します。
//敵の制御
void Teki()  //----------------------------------------MainLoop()で呼び出されます
{
	for(int i=0 ; i<=4 ; i++){
		rnd[i]=Random(2) ;			//ここでrnd[i]にランダムの数値(0〜2)を与えて
		
		if(rnd[i]==0){			//0が出たら敵が出てきます。つまり一箇所につき1/3の確立で出てきます。
						//あるいは違う条件を入れればランダムじゃないのもできますね。

			while(en[n].IsEnable())	//ここではen[n]が有効(ゲームの画面に出てる)かを判定して有効なだけwhileを繰り返します。
				n++ ;		//同じ名前のものは同時に有効にはできないので無効になってて若い番号のものを有効にします。

			if(n<30){					//en[n]のnは29以下なので30以上になったらen[n]を呼ばないようにします。
				en[n].SetPos(-32 , 10+96*i) ;	//画面左端ぎりぎりのところに最初に敵を配置します。
								//高さは96ドットごとになります。
				en[n].Enable() ;
			}
			n=0 ;			//for文で繰り返すので次のためにnは0にしておきます。
		}
	}
}

ここからは自機と自弾の移動についてですが、やっぱり大したことやってません。
//自機の移動
void Move_jiki()  //----------------------------------------MainLoop()で呼び出されます		
{
	if(GetKey(VK_UP)>=INP_PUSH &&jiki.Y()>0)
		jiki.MoveY(-2) ;
	if(GetKey(VK_DOWN)>=INP_PUSH && jiki.Y()<448)
		jiki.MoveY(2) ;
	if(GetKey(VK_LEFT)>=INP_PUSH && jiki.X()>0)
		jiki.MoveX(-2) ;
	if(GetKey(VK_RIGHT)>=INP_PUSH && jiki.X()<618)
		jiki.MoveX(2) ;
}

//自弾の移動
void Move_tama()  //----------------------------------------MainLoop()で呼び出されます
{
	if(GetKey('Z')==INP_PUSH){
		if(!tama.IsEnable()){				//zが押されたとき弾が無効だったら有効にします。
			tama.Enable() ;				//弾は1つしか有効にできません。
								//複数有効にするには敵のところでやったみたいにすると出来ると思います。
			tama.SetPos(jiki.X()-16 , jiki.Y()+8) ;
			targ=180 ;
		}
	}

	tama.Move(targ , 3) ;
	
	if(tama.X()<0 || tama.X()>640 || tama.Y()<0 || tama.Y()>480)	//弾が画面から出たら
		tama.Disable() ;					//無効にします。
}

ここでは上で出した敵を移動させます。敵だけは出現と移動を別にしています。
//敵の移動
void Move_teki()  //----------------------------------------MainLoop()で呼び出されます
{
	for(int i=0 ; i<30 ; i++){
		if(! en[i].IsEnable()) continue ;	//無効になっている敵は移動させる必要は無いので飛ばします。
		en[i].MoveX(2) ;
		en[i].Render() ;
		if(en[i].X()>640)		//画面から出たら
			en[i].Disable() ;	//無効にします。
	}
}

ここであたり判定をします。有効になってる敵を基準にしてそれに自機があたるか自弾があたるかで判定します。
上と同様にfor文で移動させます。
//あたり判定
void Hit()  //----------------------------------------MainLoop()で呼び出されます
{
	for(int i=0 ; i<30 ; i++){
		if(! en[i].IsEnable()) continue ;	//上と同様に無効になってる敵のあたり判定を考える必要は無いので飛ばします。

		if(en[i].HitTest(&jiki))		//自機とのあたり判定をしてあたっていたら
			jiki.Disable() ;		//自機を無効にします。

		if(en[i].HitTest(&tama)){		//自弾とのあたり判定をしてあたっていたら
			en[i].Disable() ;		//その敵を無効にして
			tama.Disable() ;		//自弾も無効にします。
			scr+=100 ;			//そしてスコアを100点プラスにします。
		}
	}
}

SimpleXでは(他では分かりませんが)この描画をしないと画面に表示がされません。そのための関数です。ここもあまり大したことありません。
//キャラクタの描画
void Render()  //----------------------------------------//MainLoop()で呼び出されます
{
    
	//自機の描画
	jiki.Render() ;

	//自弾の描画
	tama.Render() ;

    
	//敵の描画
	for(int i=0 ; i<30 ; i++)	//ここも上と同様に無効な敵は飛ばしてもよいのでしょうね。
		en[i].Render() ;
    
}

void MainLoop()	//上の関数をここで繰り返します。
{
	Clear(RGB(0 , 0 , 50)) ;
    
	if(frm==60){
		frm=0 ;
		Teki() ;    //MainLoop()を1秒間に60回繰り返すので1秒ごとに敵を呼びます。
	}
    
	Move_jiki() ;

	Move_tama() ;
    
	Move_teki() ;
    
	Hit() ;

	Render() ;

	Text(400 , 10 , "%d" , scr) ;
    
	if(!jiki.IsEnable())
		EndLoop() ;    //自機が無効になったらゲームを終わらせます。ここを変えれば終わらせずに違ったこともさせることが出来ると思います。
    
	frm++ ;
}


いかがでしたか?大したプログラムではないですけど、この程度のプログラムでSTGもどきを作ることが出来ます。
最初は大したことのないプログラムでもやってみればいろいろと分かることがあると思います。がんばってくださいね・・・

とはいっても自分も大したこと無いですけどねw