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 ;
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() ;
}
}
//敵の制御
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() ; //無効にします。
}
}
//あたり判定
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点プラスにします。
}
}
}
//キャラクタの描画
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++ ;
}