無料でネットを楽しもう無料ゲームプレイレポート無料C++総合環境DirectXゲームプログラミング初心者C++ホームページ作成のコツゲーム質問掲示板ゲームリンク

無料C++










12.敵の描画と構造体
敵を作るのは、プレイヤーを作る要素となんら変わりありません。
必要な要素は、
画像のハンドルを入れる変数
描画X座標
描画Y座標

の3個です。
(ディフェンスや点数やオフェンスも増えていきそうです。)
ただ、プレイヤーと敵には大きな違いがあります。
プレイヤーは一体(多くても2体)ですが、敵の数は今のところ予想できません。
後々、敵を十数個作ることを考えて、構造体を使います。
最終的に、敵管理クラスにする予定で設計します。

敵を描画するC++プログラムソース

struct enemy_set
{
     int graph;       //画像ハンドル(車のハンドルと同じ意味。操作する部分)
     int position_x;  //座標X
     int position_y;  //座標Y
}m_enemy ;


構造体

複数のデータを、ひとまとまりに扱える型を独自に作ることができます。
それが構造体です。

[ struct ][区切り][ 宣言名 ]
[ { ]

     [変数の宣言]

[ } ][構造体の宣言][ ; ]

[ struct ]
構造体を使うためのキーワード

[ 宣言名 ]
作った構造体を宣言するときのキーワード

予約語(intのような型)を自分で作るって感覚と考えると理解しやすいかな?
[変数の宣言]
ひとまとまりにしたい変数(要素)の宣言
{ と } との間に要素を書き込む。

[構造体の宣言]

構造体キーワードを作ると同時に、構造体を宣言できます。
省略して、後々宣言することができます。


[ ; ]
文章の終了。
構造体の宣言を省略すると、関数の癖で文章の終了を忘れることが多いので注意。
struct enemy_set
{
     int graph;       //画像ハンドル(車のハンドルと同じ意味。操作する部分)
     int position_x;  //座標X
     int position_y;  //座標Y
}; 
//ここに注意。省略した場合にも「;」は必要。

構造体の宣言
構造体キーワードを作ることで、いつでも構造体を宣言できるようになります。
struct enemy_set
{
     int graph;       //画像ハンドル(車のハンドルと同じ意味。操作する部分)
     int position_x;  //座標X
     int position_y;  //座標Y
} ;
       ・
   なんたらかんたら    
       ・  
enemy_set m_enemy={ LoadGraph("Enemy.png") , 320 , 100 } ;

[構造体キーワード] [区切り] [;]
と書き、宣言できます。
[構造体キーワード] [区切り] [=] [{] [データ,データ,・・・] [}] [; ]
と初期値も入れることができます。
宣言すると、
enemy.graph
enemy.position_x
enemy.position_y

[enemy] [.] [position_x]
こう書くことで、普通の変数として使用できます。
一度に3個の変数が作れるのです。
enemy_set m_enemy1={ LoadGraph("Enemy.png") , 320 , 100 } ;
と書き足すだけで、また3個の変数ができます。

敵を作ってみよう 敵の描画(表示)
敵グラフィック
*.exeのあるフォルダに
//シューティングゲーム サンプルプログラム 11 見やすくしよう
//ライブラリ宣言
#include "DxLib.h"
//定数の宣言---------------------------------------------------------
#define PLAYER_SIZE                                50
#define PLAYER_SIZE_HALF     PLAYER_SIZE/2
#define PLAYER_MOVE_SPEED                      5
#define MINI_MOVE_PLAYER_RANGE_X       160
#define MINI_MOVE_PLAYER_RANGE_Y           0
#define MAX_MOVE_PLAYER_RANGE_X       480
#define MAX_MOVE_PLAYER_RANGE_Y       480
#define GUN_MOVE_SPEED                         20
#define GUN_SIZE                                      12
#define ENEMY_SIZE                                50
//-------------------------------------------------------------------
//構造体-----------------------------------------------------------
//敵用 構造体 型宣言
struct enemy_set
{
     int graph;       //画像ハンドル(車のハンドルと同じ意味。操作する部分)
     int position_x;  //座標X
     int position_y;  //座標Y
};

//-------------------------------------------------------------------
//自作関数 プロトタイプ宣言---------------------------------------------
int UpdatePlayerPosition(int& player_position_x,int& player_position_y,
             int MOVE_SPEED);
int UpdatePlayerGunPosition( int* p_player_gun_position_x, int* p_player_gun_position_y,
     int player_position_x,int player_position_y,int GUN_SPEED,int f_player_gun_flag);
int PlayerRange(int& player_position_x,int& player_position_y);
//--------------------------------------------------------------------
//WinMain関数
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
     // DXライブラリの設定
     // SetOutApplicationLogValidFlag(TRUE);
     //SetGraphMode(640,480,16);
     ChangeWindowMode( TRUE ) ;
     if( DxLib_Init()==-1) return-1;
     // SetMouseDispFlag( TRUE ) ;
     SetDrawScreen(DX_SCREEN_BACK);
//変数の宣言と初期化---------------------------------------------------
     int player_position_x=320;
     int player_position_y=240;
     int f_player_gun_flag=FALSE;//弾が発射されているか フラグ
     int player_gun_position_x=player_position_x;// 弾の位置 X座標
     int player_gun_position_y=player_position_y;// 弾の位置 Y座標
     int player_graph=LoadGraph("Player.png");                           //自機
     int background_graph=LoadGraph("BackGroundGraph.png");  //背景
     int player_gun_graph=LoadGraph("Gun.png");                        // 弾画像
     enemy_set m_enemy={ LoadGraph("Enemy.png") , 320 , 100 } ;   //敵 構造体
//-------------------------------------------------------------------
     while(ProcessMessage()==0)
     {
//**メインループ ********************************************************
         //ジョイスティック&キー入力 キャラクターの移動
         UpdatePlayerPosition(player_position_x,player_position_y,PLAYER_MOVE_SPEED);
         //プレイヤー移動範囲補正
         PlayerRange(player_position_x,player_position_y);

         //弾の発射 移動
         f_player_gun_flag=UpdatePlayerGunPosition (&player_gun_position_x,
             &player_gun_position_y,player_position_x,player_position_y,
             GUN_MOVE_SPEED,f_player_gun_flag);

         //


           //画像描画
         ClsDrawScreen() ;
         DrawGraph(MINI_MOVE_PLAYER_RANGE_X,
             MINI_MOVE_PLAYER_RANGE_Y, background_graph,TRUE);         
         if(f_player_gun_flag==TRUE)DrawGraph(player_gun_position_x-GUN_SIZE/2,
                player_gun_position_y-GUN_SIZE/2,player_gun_graph,TRUE);
         DrawGraph(player_position_x-PLAYER_SIZE_HALF,
             player_position_y-PLAYER_SIZE_HALF, player_graph,TRUE);
         DrawGraph( m_enemy.position_x-ENEMY_SIZE/2,
             m_enemy.position_y-ENEMY_SIZE/2, m_enemy.graph,TRUE);  
       
         ScreenFlip();
//**メインループ **************************************************
         // ESCキーが押されたらループから抜ける
         if(CheckHitKey(KEY_INPUT_ESCAPE)==TRUE)break;
     }
     //終了処理
     DxLib_End();
     return 0;
}
//自作関数---------------------------------------------------------
//----------------------------------------------------------------
//ジョイスティック&キー 移動入力
//int UpdatePlayerPosition(int& PositionX,int& PositionY,int MOVE_SPEED);
//[ライブラリ] #include "DxLib.h"
//[引数] X座標(参照) ,Y座標(参照) ,1ターンで動くドット 
//[戻り値] なし
//[解説] ジョイスティック入力によってX座標Y座標を更新する
int UpdatePlayerPosition(int& player_position_x,int& player_position_y,
             int MOVE_SPEED)
{
   int joypad_state=GetJoypadInputState(DX_INPUT_KEY_PAD1);
   if((joypad_state&PAD_INPUT_UP)!=0) player_position_y-=MOVE_SPEED;
   if((joypad_state&PAD_INPUT_DOWN)!=0) player_position_y+=MOVE_SPEED;
   if((joypad_state&PAD_INPUT_LEFT)!=0) player_position_x-=MOVE_SPEED;
   if((joypad_state&PAD_INPUT_RIGHT)!=0) player_position_x+=MOVE_SPEED;
   return 0;
}
//-----------------------------------------------------------------
//[ライブラリ] #include "DxLib.h"
//[引数] X座標(アドレス),Y座標(アドレス),発射場所X,発射場所Y,動くドット数,発射フラグ 
//[戻り値] 発射フラグ
//]解説] ジョイスティック入力によって発射。弾の移動処理(X座標Y座標を更新する) 
int UpdatePlayerGunPosition( int* p_player_gun_position_x, int* p_player_gun_position_y,
     int player_position_x,int player_position_y,int GUN_SPEED,int f_player_gun_flag)
{
         int joypad_state=GetJoypadInputState(DX_INPUT_KEY_PAD1);
         if(((joypad_state& PAD_INPUT_A) !=0)&&(f_player_gun_flag==FALSE))
         {
             f_player_gun_flag=TRUE;
             *p_player_gun_position_x= player_position_x ;
             *p_player_gun_position_y= player_position_y ;
         }
         if(f_player_gun_flag==TRUE) *p_player_gun_position_y-=GUN_SPEED;
         if(*p_player_gun_position_y<1) f_player_gun_flag=FALSE;
         return f_player_gun_flag;
}
//-----------------------------------------------------------------
//[ライブラリ] なし
//[引数] X座標(参照),Y座標(参照) 
//[戻り値] なし
//]解説] 移動範囲補正処理(範囲外にX座標Y座標を更新しない) 
int PlayerRange(int& player_position_x,int& player_position_y)
{
         if(player_position_x>MAX_MOVE_PLAYER_RANGE_X-PLAYER_SIZE_HALF)
             player_position_x=MAX_MOVE_PLAYER_RANGE_X-PLAYER_SIZE_HALF;
         if(player_position_x<MINI_MOVE_PLAYER_RANGE_X+PLAYER_SIZE_HALF)
             player_position_x=MINI_MOVE_PLAYER_RANGE_X+PLAYER_SIZE_HALF;
         if(player_position_y>MAX_MOVE_PLAYER_RANGE_Y-PLAYER_SIZE_HALF)
             player_position_y=MAX_MOVE_PLAYER_RANGE_Y-PLAYER_SIZE_HALF;
         if(player_position_y<MINI_MOVE_PLAYER_RANGE_Y+PLAYER_SIZE_HALF)
             player_position_y=MINI_MOVE_PLAYER_RANGE_Y+PLAYER_SIZE_HALF;
         return 0;
}


定数の簡単な解説
#define ENEMY_SIZE                                50
いつものとおり、実際の場所と表示場所を補正しています。

今まで、クラスを使わずにやってきましたが、そろそろ収拾がつかなくなってきました。
このままでも十分ベーシックより読みやすいですし、プログラムの追加も楽ですが。
クラスを使えるようにしたいですが、その前に後一個。配列を勉強しましょう。

ホームページへ
このページのトップへ