17.C++プログラムソースの分割 |
|
ファイルを分割する必要はありません。
しかし、分割することで、いくつかのメリットがあります。
プログラムが大きくなると、コンパイルの時間もバカになりません。
分割することで、更新したプログラムだけをコンパイルできます。
せっかく作ったプログラムです。再利用できたらいいですね。
分割することで、ほかのプログラムでも使用可能になります。
一番いいことはやはりプログラムのメンテナンスが楽になることでしょう。
簡単に言うと 見やすくなるってことです。
|
BCC DeveloperによるC++プログラムソースの分割方法 |
|
新規作成を押します。
下のウィンドが開きます。
C/C++ファイルを選択します(下のマウスカーソルの位置)
ディレクトリ名は、今のところ同じ場所にしておきましょう。
ファイル名は、好きな名前でOKです。**.h(ヘッダファイル)にするのが普通です。
今回は、ShootingMove.cpp にしておきましょう。
OKを押してください。 |
|
|
分割はコピーするだけ
|
分割は簡単です。分割しなくてもいいのですが、簡単なのでなるべくしていきましょう。
クラスをコピーします。
一番上に
#include "DxLib.h"
を書き足しましょう。
なくても大丈夫ですが、あっても邪魔にはなりません。
あとは、メインプログラムの#include "DxLib.h"の次に、#include "ShootingMove.cpp"と書くだけです。
移動クラスは、小さい上、これから更新の可能性が少ないのでひとつにまとめました。
|
シューティングゲームの移動部分を分割したC++プログラムソース |
//シューティング用プレイヤー移動クラス-----------------------------------
//ShootingMove.cpp
#include "DxLib.h"
class MovePlane
{
private:
//変数
int player_position_x; //プレイヤー座標X
int player_position_y; //プレイヤー座標Y
int PLAYER_SIZE; //プレイヤー画像の大きさ
int PLAYER_MOVE_SPEED; //1ターンあたりの移動ドット数
int MINI_MOVE_PLAYER_RANGE_X; //プレイヤー移動範囲最小X
int MINI_MOVE_PLAYER_RANGE_Y; //プレイヤー移動範囲最小Y
int MAX_MOVE_PLAYER_RANGE_X; //プレイヤー移動範囲最大X
int MAX_MOVE_PLAYER_RANGE_Y; //プレイヤー移動範囲最大Y
int player_graph; //プレイヤー画像ハンドル
public:
MovePlane() //初期値
{
player_position_x=320;
player_position_y=450;
PLAYER_SIZE=50;
PLAYER_MOVE_SPEED=4;
MINI_MOVE_PLAYER_RANGE_X=160;
MINI_MOVE_PLAYER_RANGE_Y=0;
MAX_MOVE_PLAYER_RANGE_X=480;
MAX_MOVE_PLAYER_RANGE_Y=480;
player_graph=LoadGraph("Player.png");
}
//関数
//変数の出力
getposition_x() { return player_position_x; } //プレイヤー座標Xを参照する
getposition_y() { return player_position_y; } //プレイヤー座標Yを参照する
//[解説] ジョイスティック入力によってX座標Y座標を更新する
int inputAndUpdate();
//]解説] 移動範囲補正処理(範囲外にX座標Y座標を更新しない)
int reviseRange();
//自機の表示
int drawPlane(); //描画
};
//**メンバ関数*****************************************************
//**飛行機 移動 クラス*****************************************
//ジョイスティック&キー 移動入力
//[解説] ジョイスティック入力によってX座標Y座標を更新する
int MovePlane::inputAndUpdate()
{
int joypad_state=GetJoypadInputState(DX_INPUT_KEY_PAD1);
if((joypad_state&PAD_INPUT_UP)!=0) player_position_y-=PLAYER_MOVE_SPEED;
if((joypad_state&PAD_INPUT_DOWN)!=0) player_position_y+=PLAYER_MOVE_SPEED;
if((joypad_state&PAD_INPUT_LEFT)!=0) player_position_x-=PLAYER_MOVE_SPEED;
if((joypad_state&PAD_INPUT_RIGHT)!=0) player_position_x+=PLAYER_MOVE_SPEED;
reviseRange();
return 0;
}
//-----------------------------------------------------------------
//]解説] 移動範囲補正処理(範囲外にX座標Y座標を更新しない)
int MovePlane::reviseRange()
{
if(player_position_x>MAX_MOVE_PLAYER_RANGE_X-PLAYER_SIZE/2)
player_position_x=MAX_MOVE_PLAYER_RANGE_X-PLAYER_SIZE/2;
if(player_position_x<MINI_MOVE_PLAYER_RANGE_X+PLAYER_SIZE/2)
player_position_x=MINI_MOVE_PLAYER_RANGE_X+PLAYER_SIZE/2;
if(player_position_y>MAX_MOVE_PLAYER_RANGE_Y-PLAYER_SIZE/2)
player_position_y=MAX_MOVE_PLAYER_RANGE_Y-PLAYER_SIZE/2;
if(player_position_y<MINI_MOVE_PLAYER_RANGE_Y+PLAYER_SIZE/2)
player_position_y=MINI_MOVE_PLAYER_RANGE_Y+PLAYER_SIZE/2;
return 0;
}
//-----------------------------------------------------------------
//自機を表示する
int MovePlane::drawPlane()
{
DrawGraph(player_position_x-PLAYER_SIZE/2,
player_position_y-PLAYER_SIZE/2, player_graph,TRUE);
return 0;
}
|
クラスの2分割(ヘッダファイルと実行ファイル) |
クラスを作ることで、自作関数を標準関数のように使うことが出来るようになりました。
これを ブラックボックス(中身を考えなくてもいい、ひとつの命令として扱える。)と言います。
命令の内部は隠して、関数の説明書だけあればいいですよね。
そのために説明書部分と、関数プログラム部分とに分けることが推奨されています。
プログラム説明部分をヘッダファイルといいます。
DxLib.hもヘッダファイルです。**.hと書きます。
関数プログラム部分は、ヘッダファイルと同じファイル名で、拡張子を.cppにしましょう。
新規作成で、普通にコピーするだけの作業です。
実際に作ってみましょう。
|
シューティングゲーム用 弾を扱うクラス C++プログラムソース |
まずはヘッダファイル。
コピーするだけの作業です。
ヘッダファイルは、クラスの説明書を書く気分で書きましょう。 |
#include "DxLib.h"
//----------------------------------------------------------------
//シューティング用 弾 発射 移動 クラス
class PlaneGun
{
private:
int f_player_gun_flag; //弾が発射されているか フラグ
int player_gun_position_x; // 弾の位置 X座標
int player_gun_position_y; // 弾の位置 Y座標
int player_gun_graph; // 弾画像
int GUN_MOVE_SPEED; //弾の1ターンあたりの移動量(ドット)
int GUN_SIZE; //キャラのサイズ
public:
PlaneGun() //初期値
{
f_player_gun_flag=FALSE;
player_gun_position_x=10;
player_gun_position_y=10;
player_gun_graph=LoadGraph("Gun.png");
GUN_MOVE_SPEED=10;
GUN_SIZE=12;
}
//関数
//変数の出力
getposition_x() { return player_gun_position_x; } //プレイヤー座標Xを参照する
getposition_y() { return player_gun_position_y; } //プレイヤー座標Yを参照する
//弾の発射と移動
//[ 引数 ] 弾 発射初期位置 X座標 Y座標
int inputAndUpdate(int player_position_x,int player_position_y);
//弾の表示
int drawGun(); //描画
};
|
クラスの処理部分をコピーします |
プログラムからクラスの関数部分をコピーして、ヘッダファイルを登録するだけの作業です。 |
#include "ShootingGun.h"
//**飛行機 機銃 クラス*****************************************
//-----------------------------------------------------------------
//]解説] ジョイスティック入力によって発射。弾の移動処理(X座標Y座標を更新する)
int PlaneGun::inputAndUpdate(int player_position_x,int player_position_y)
{
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;
player_gun_position_x= player_position_x ;
player_gun_position_y= player_position_y ;
}
if(f_player_gun_flag==TRUE)player_gun_position_y-=GUN_MOVE_SPEED;;
if(player_gun_position_y<1) f_player_gun_flag=FALSE;
return f_player_gun_flag;
}
//-----------------------------------------------------------------
//弾を表示する
int PlaneGun::drawGun()
{
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);
return 0;
}
|
すべてを分割してみました C++サンプルプログラムソース |
ShootingMove.cpp |
|
//シューティング用プレイヤー移動クラス-----------------------------------
//ShootingMove.cpp
#include "DxLib.h"
class MovePlane
{
private:
//変数
int player_position_x; //プレイヤー座標X
int player_position_y; //プレイヤー座標Y
int PLAYER_SIZE; //プレイヤー画像の大きさ
int PLAYER_MOVE_SPEED; //1ターンあたりの移動ドット数
int MINI_MOVE_PLAYER_RANGE_X; //プレイヤー移動範囲最小X
int MINI_MOVE_PLAYER_RANGE_Y; //プレイヤー移動範囲最小Y
int MAX_MOVE_PLAYER_RANGE_X; //プレイヤー移動範囲最大X
int MAX_MOVE_PLAYER_RANGE_Y; //プレイヤー移動範囲最大Y
int player_graph; //プレイヤー画像ハンドル
public:
MovePlane() //初期値
{
player_position_x=320;
player_position_y=450;
PLAYER_SIZE=50;
PLAYER_MOVE_SPEED=4;
MINI_MOVE_PLAYER_RANGE_X=160;
MINI_MOVE_PLAYER_RANGE_Y=0;
MAX_MOVE_PLAYER_RANGE_X=480;
MAX_MOVE_PLAYER_RANGE_Y=480;
player_graph=LoadGraph("Player.png");
}
//関数
//変数の出力
getposition_x() { return player_position_x; } //プレイヤー座標Xを参照する
getposition_y() { return player_position_y; } //プレイヤー座標Yを参照する
//[解説] ジョイスティック入力によってX座標Y座標を更新する
int inputAndUpdate();
//]解説] 移動範囲補正処理(範囲外にX座標Y座標を更新しない)
int reviseRange();
//自機の表示
int drawPlane(); //描画
};
//**メンバ関数*****************************************************
//**飛行機 移動 クラス*****************************************
//ジョイスティック&キー 移動入力
//[解説] ジョイスティック入力によってX座標Y座標を更新する
int MovePlane::inputAndUpdate()
{
int joypad_state=GetJoypadInputState(DX_INPUT_KEY_PAD1);
if((joypad_state&PAD_INPUT_UP)!=0) player_position_y-=PLAYER_MOVE_SPEED;
if((joypad_state&PAD_INPUT_DOWN)!=0) player_position_y+=PLAYER_MOVE_SPEED;
if((joypad_state&PAD_INPUT_LEFT)!=0) player_position_x-=PLAYER_MOVE_SPEED;
if((joypad_state&PAD_INPUT_RIGHT)!=0) player_position_x+=PLAYER_MOVE_SPEED;
reviseRange();
return 0;
}
//-----------------------------------------------------------------
//]解説] 移動範囲補正処理(範囲外にX座標Y座標を更新しない)
int MovePlane::reviseRange()
{
if(player_position_x>MAX_MOVE_PLAYER_RANGE_X-PLAYER_SIZE/2)
player_position_x=MAX_MOVE_PLAYER_RANGE_X-PLAYER_SIZE/2;
if(player_position_x<MINI_MOVE_PLAYER_RANGE_X+PLAYER_SIZE/2)
player_position_x=MINI_MOVE_PLAYER_RANGE_X+PLAYER_SIZE/2;
if(player_position_y>MAX_MOVE_PLAYER_RANGE_Y-PLAYER_SIZE/2)
player_position_y=MAX_MOVE_PLAYER_RANGE_Y-PLAYER_SIZE/2;
if(player_position_y<MINI_MOVE_PLAYER_RANGE_Y+PLAYER_SIZE/2)
player_position_y=MINI_MOVE_PLAYER_RANGE_Y+PLAYER_SIZE/2;
return 0;
}
//-----------------------------------------------------------------
//自機を表示する
int MovePlane::drawPlane()
{
DrawGraph(player_position_x-PLAYER_SIZE/2,
player_position_y-PLAYER_SIZE/2, player_graph,TRUE);
return 0;
} |
ShootingGun.h |
//シューティング用 弾 発射 移動 クラス
#include "DxLib.h"
//----------------------------------------------------------------
class PlaneGun
{
private:
int f_player_gun_flag; //弾が発射されているか フラグ
int player_gun_position_x; // 弾の位置 X座標
int player_gun_position_y; // 弾の位置 Y座標
int player_gun_graph; // 弾画像
int GUN_MOVE_SPEED; //弾の1ターンあたりの移動量(ドット)
int GUN_SIZE; //キャラのサイズ
public:
PlaneGun() //初期値
{
f_player_gun_flag=FALSE;
player_gun_position_x=10;
player_gun_position_y=10;
player_gun_graph=LoadGraph("Gun.png");
GUN_MOVE_SPEED=10;
GUN_SIZE=12;
}
//関数
//変数の出力
getposition_x() { return player_gun_position_x; } //プレイヤー座標Xを参照する
getposition_y() { return player_gun_position_y; } //プレイヤー座標Yを参照する
//弾の発射と移動
//[ 引数 ] 弾 発射初期位置 X座標 Y座標
int inputAndUpdate(int player_position_x,int player_position_y);
//弾の表示
int drawGun(); //描画
}; |
ShootingGun.cpp |
#include "ShootingGun.h"
//**飛行機 機銃 クラス*****************************************
//-----------------------------------------------------------------
//]解説] ジョイスティック入力によって発射。弾の移動処理(X座標Y座標を更新する)
int PlaneGun::inputAndUpdate(int player_position_x,int player_position_y)
{
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;
player_gun_position_x= player_position_x ;
player_gun_position_y= player_position_y ;
}
if(f_player_gun_flag==TRUE)player_gun_position_y-=GUN_MOVE_SPEED;;
if(player_gun_position_y<1) f_player_gun_flag=FALSE;
return f_player_gun_flag;
}
//-----------------------------------------------------------------
//弾を表示する
int PlaneGun::drawGun()
{
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);
return 0;
} |
ShootingEnemy.h |
//----------------------------------------------------------------
//
#include "DxLib.h"
//切り離されてない部分です
//そのうち切り離しましょう
#define MINI_RANGE_X 160 //画面の大きさと位置 横最小座標
#define MINI_RANGE_Y 0 //画面の大きさと位置 横最小座標
#define MAX_RANGE_X 480 //画面の大きさと位置 横最大座標
#define MAX_RANGE_Y 480 //画面の大きさと位置 横最大座標
class MoveEnemy
{
private: //変数
int ENEMY_SIZE;
int graph; //画像ハンドル(車のハンドルと同じ意味。操作する部分)
int position_x; //座標X
int position_y; //座標Y
int has_enemy;
public: //関数
MoveEnemy()
{
ENEMY_SIZE=50;
graph=LoadGraph("Enemy.png");
position_x=320;
position_y=-50;
has_enemy=FALSE;
}
//
int MoveEnemyFall();
//敵の表示
int drawEnemy(); //描画
}; |
ShootingEnemy.cpp |
//敵 移動パターン1 上から落ちてくる
//
#include "ShootingEnemy.h"
int MoveEnemy::MoveEnemyFall()
{
if(has_enemy==FALSE)
{
position_x=MINI_RANGE_X+ENEMY_SIZE/2+
GetRand(MAX_RANGE_X-MINI_RANGE_X- ENEMY_SIZE );
has_enemy=TRUE;
}
if(has_enemy==TRUE)position_y+=5;
if(MAX_RANGE_Y<position_y)
{
has_enemy=FALSE;
position_y=-50;
}
}
//-----------------------------------------------------------------
//敵の表示
int MoveEnemy::drawEnemy()
{
DrawGraph( position_x-ENEMY_SIZE/2,position_y-ENEMY_SIZE/2,graph,TRUE);
return 0;
} |
C++メインプログラムソース |
//シューティングゲーム サンプルプログラム 17 ファイル分割
//ライブラリ宣言
#include "DxLib.h"
#include "ShootingMove.cpp"
#include "ShootingGun.h"
#include "ShootingEnemy.h"
//定数の宣言---------------------------------------------------------
#define MINI_RANGE_X 160 //画面の大きさと位置 横最小座標
#define MINI_RANGE_Y 0 //画面の大きさと位置 横最小座標
#define MAX_RANGE_X 480 //画面の大きさと位置 横最大座標
#define MAX_RANGE_Y 480 //画面の大きさと位置 横最大座標
//-------------------------------------------------------------------
//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);
SRand(640);
//クラスのオブジェクト(実体)を作る
MovePlane Player;
PlaneGun Gun;
MoveEnemy Enemy;
//変数の宣言と初期化----------------------------------------------
int background_graph=LoadGraph("BackGroundGraph.png"); //背景
//-------------------------------------------------------------------
while(ProcessMessage()==0)
{
//**メインループ ********************************************************
//ジョイスティック&キー入力 キャラクターの移動
Player.inputAndUpdate();
//弾の発射 移動
Gun.inputAndUpdate(Player.getposition_x(),Player.getposition_y());
//敵の移動
Enemy.MoveEnemyFall();
//画像描画
ClsDrawScreen() ;
DrawGraph(MINI_RANGE_X,MINI_RANGE_Y, background_graph,TRUE);
Gun.drawGun();
Player.drawPlane();
Enemy.drawEnemy();
//デバッグ用
int c= GetColor(255,255,255);
DrawFormatString( 0, 0, c, "%05d",Player.getposition_x() ) ;
DrawFormatString( 0, 20, c, "%05d",Player.getposition_y() ) ;
DrawFormatString( 0, 40, c, "%05d",Gun.getposition_x() ) ;
DrawFormatString( 0, 60, c, "%05d",Gun.getposition_y() ) ;
ScreenFlip();
//**メインループ **************************************************
// ESCキーが押されたらループから抜ける
if(CheckHitKey(KEY_INPUT_ESCAPE)==TRUE)break;
}
//終了処理
DxLib_End();
return 0;
}
|
BCC Developerの機能説明 |
|
ファイルを分割することで、タブ表示できるようになります。
メンテナンスがよりいっそう楽になります。 |