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

無料C++










8.移動範囲の設定と関数[関数の説明2]
移動範囲を限定するプログラム。全体は最後に。

#define MOVE_PLAYER_RANGE_X 640
#define MOVE_PLAYER_RANGE_Y 480

     if(player_position_y>MOVE_PLAYER_RANGE_Y-PLAYER_SIZE_HALF)
         player_position_y=MOVE_PLAYER_RANGE_Y-PLAYER_SIZE_HALF;
     if(player_position_y<PLAYER_SIZE_HALF)
         player_position_y=PLAYER_SIZE_HALF;
     if(player_position_x>MOVE_PLAYER_RANGE_X-PLAYER_SIZE_HALF)
         player_position_x=MOVE_PLAYER_RANGE_X-PLAYER_SIZE_HALF;
     if(player_position_x<PLAYER_SIZE_HALF)
         player_position_x=PLAYER_SIZE_HALF;


DXライブラリ関数の説明
#define MOVE_PLAYER_RANGE_X 640
#define MOVE_PLAYER_RANGE_Y 480

定数の宣言です。
画面の広さが640*480なので、定数にしました。
Rangeは範囲という意味です。
見ただけで何をあらわしてるのかわかりますね^^。
このムーブ範囲は変更の可能性大です。
横スクロールなら横長にすぐ変更できます。
変更するときラクしましょう^^。
    if(player_position_x>MOVE_PLAYER_RANGE_X-PLAYER_SIZE_HALF)
         player_position_x=MOVE_PLAYER_RANGE_X-PLAYER_SIZE_HALF;

if文です。
画面からはみ出ると画面の端に補正されます。
この文章を、上下左右4個作っています。
PLAYER_SIZE_HALF定数が使えるので楽ですね^^。

[関数の説明2]関数の宣言と呼び出し

型 関数名(型 引数A、型 引数B、・・・)

//アルゴリズム
     return 戻り値;
}      
     //「;」はいらない

関数も変数のように宣言します。
関数の名前は、大文字で始まる文字列が推奨されています。
引数は、関数内に持っていく数字です。

持ってきた引数を使ってアルゴリズムを処理します。
最後に、return; で帰ってきます。
戻り値は、関数が終了したときに持って帰る数字です。
文章の終わり「;」はいりません。
型 関数名()
変数の宣言とそっくりですね。
関数もある意味変数のようなものです
。関数も変数のようにオブジェクトといえます。
もちろんこの変数は値をもてます。それが戻り値です
ですので、型宣言は戻り値と同じ型にしなければなりません

( )内は、
([型][区切り][引数][,][型][区切り][引数][,]・・・)
[引数]の部分はただの[変数]です。
[型][区切り][変数]ってことです。
見てわかるとおり、変数の宣言です。
( )の正体は
(変数の宣言1,変数の宣言2,・・・)
ってことです。

引数を持ってきたとき、その引数を入れる変数がありません。
なので、引数を入れる変数を宣言しているだけなのです。
関数内で 宣言した変数に、順番に引数(初期値)を入れていきます。
関数内で宣言しているので、この関数内だけで使えるただのローカル変数です。
(変数のページを参照)

関数の呼び出し
関数を呼び出すには、呼び出される前に、関数を宣言しなければなりません。
main関数より前に、全文かプロトタイプ宣言(仮宣言)かを書かなければなりません。
プロトタイプ宣言が見やすいのでお勧めします。
型 関数名(型 引数A、型 引数B、・・・);
と書きます。

呼び出す方法は、
関数名(引数A、引数B、・・・);
と書くだけです。

引数は持っていくパラメータです。
数字(1,2・・)でも変数(A,B・・)でも関数の型以外のものでも何でも持っていけます。
呼出しの時には、intがいらないことに注意。
当然ですよね。関数に引数を書く場合、すでにある変数のはずです。

[例]関数を作ろう
今回は例として、X座標変更入力関数を作ってみましょう。 InputAndChangeX()
X座標の入力と移動を、ひとまとまりの関数にします。
     //ジョイスティック&キー入力
     joypad_state=GetJoypadInputState(DX_INPUT_KEY_PAD1);
     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;


上、アルゴリズム 下 関数
int InputAndChangeX(int player_position_x)
{
     int joypad_state=0;
   //ジョイスティック&キー入力
     joypad_state=GetJoypadInputState(DX_INPUT_KEY_PAD1);
     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;

      return player_position_x ;
}

()内で新しくローカル変数player_position_xを使うよ〜と宣言しています。
ジョイスティックの状態を入れるjoypad_stateを宣言。
後は、上のアルゴリズムを下にコピーして、
returnn player_position_x ;を付け加えただけです。
関数の呼び出し場所に戻ります。
return player_position_x; player_position_xが戻り値だとわかりますね。
注意
main()関数内のplayer_position_xとInputAndChangeX()関数内のplayer_position_xは別の変数です。
ややこしいので下にnMovePositionXに変更した関数を作ります。
上のプログラムと動作はまったく同じです。

int InputAndChangeX(int nMovePositionX)
{
     int joypad_state=0;
   //ジョイスティック&キー入力
     joypad_state=GetJoypadInputState(DX_INPUT_KEY_PAD1);
     if((joypad_state&PAD_INPUT_UP)!=0)nMovePositionX-=PLAYER_MOVE_SPEED;
     if((joypad_state&PAD_INPUT_DOWN)!=0)nMovePositionX+=PLAYER_MOVE_SPEED;

      return nMovePositionX ;
}

関数を呼び出すには
InputAndChangeX(player_position_x);
だけでいけます。intは書かないでください。
player_position_xはもうmain関数内で宣言されています。
重複して変数を作ったことになりエラーになります。
まだ宣言されていない変数なら関数の()内でも宣言できます。


あと、もって帰ってきた変数を受け取らないといけません
player_position_x=InputAndChangeX(player_position_x);
となります。
下が、完成です。

//ライブラリ宣言
#include "DxLib.h"
//定数の宣言
#define PLAYER_SIZE 50
#define PLAYER_SIZE_HALF PLAYER_SIZE/2
#define PLAYER_MOVE_SPEED 5
#define MOVE_PLAYER_RANGE_X 640
#define MOVE_PLAYER_RANGE_Y 480


int InputAndChangeX(int player_position_x)
{

     int joypad_state=0;
     //ジョイスティック&キー入力
     joypad_state=GetJoypadInputState(DX_INPUT_KEY_PAD1);
     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;
      return player_position_x ;

}
//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 player_graph=LoadGraph("Player.png");
     int joypad_state=0;
     //メインループ
     while(ProcessMessage()==0)
     {
         //ジョイスティック&キー入力
         player_position_x=InputAndChangeX(player_position_x);
         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(player_position_y>MOVE_PLAYER_RANGE_Y-PLAYER_SIZE_HALF)
             player_position_y=MOVE_PLAYER_RANGE_Y-PLAYER_SIZE_HALF;
         if(player_position_y<PLAYER_SIZE_HALF)
             player_position_y=PLAYER_SIZE_HALF;
         if(player_position_x>MOVE_PLAYER_RANGE_X-PLAYER_SIZE_HALF)
             player_position_x=MOVE_PLAYER_RANGE_X-PLAYER_SIZE_HALF;
         if(player_position_x<PLAYER_SIZE_HALF)
             player_position_x=PLAYER_SIZE_HALF;


         //キャラの描画
         ClsDrawScreen() ;
         DrawGraph(player_position_x-PLAYER_SIZE_HALF,
             player_position_y-PLAYER_SIZE_HALF, player_graph,TRUE);
         ScreenFlip();
         // ESCキーが押されたらループから抜ける
         if(CheckHitKey(KEY_INPUT_ESCAPE)==TRUE)break;
     }
     //終了処理
     DxLib_End();
     return 0;
}

プロトタイプ宣言
関数も変数のようなものと言いましたが、変数なら使う前に宣言しなければなりません。
関数も同じです。使う前に宣言しなければなりません。
main関数の中で使うので、main関数の前で宣言しなければなりません。
宣言だけ先にすることもできます。(プロトタイプ宣言)
下のように書くこともできるのです。

移動範囲の設定 C++サンプルプログラムソース

//ライブラリ宣言
#include "DxLib.h"
//定数の宣言
#define PLAYER_SIZE 50
#define PLAYER_SIZE_HALF PLAYER_SIZE/2
#define PLAYER_MOVE_SPEED 5
#define MOVE_PLAYER_RANGE_X 640
#define MOVE_PLAYER_RANGE_Y 480
//自作関数 プロトタイプ宣言
int InputAndChangeX(int player_position_x);


//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 player_graph=LoadGraph("Player.png");
     int joypad_state=0;
     //メインループ
     while(ProcessMessage()==0)
     {
         //ジョイスティック&キー入力
         player_position_x=InputAndChangeX(player_position_x);
         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(player_position_y>MOVE_PLAYER_RANGE_Y-PLAYER_SIZE_HALF)
             player_position_y=MOVE_PLAYER_RANGE_Y-PLAYER_SIZE_HALF;
         if(player_position_y<PLAYER_SIZE_HALF)
             player_position_y=PLAYER_SIZE_HALF;
         if(player_position_x>MOVE_PLAYER_RANGE_X-PLAYER_SIZE_HALF)
             player_position_x=MOVE_PLAYER_RANGE_X-PLAYER_SIZE_HALF;
         if(player_position_x<PLAYER_SIZE_HALF)
             player_position_x=PLAYER_SIZE_HALF;

         //キャラの描画
         ClsDrawScreen() ;
         DrawGraph(player_position_x-PLAYER_SIZE_HALF,
             player_position_y-PLAYER_SIZE_HALF, player_graph,TRUE);
         ScreenFlip();
         // ESCキーが押されたらループから抜ける
         if(CheckHitKey(KEY_INPUT_ESCAPE)==TRUE)break;
     }
     //終了処理
     DxLib_End();
     return 0;
}
//X座標の移動 ジョイスティック&キー入力
int InputAndChangeX(int player_position_x)
{

     int joypad_state=0;
     //ジョイスティック&キー入力
     joypad_state=GetJoypadInputState(DX_INPUT_KEY_PAD1);
     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;
      return player_position_x ;
}


関数を使うことにより、メインループ内をすっきりさせることができます。
プログラムの全体像がわかりやすくなります。
プログラムが大きくなればなるほど、ありがたさがわかると思います。
関数を覚えていないと、中途挫折の原因になる可能性も大です。
また、この関数はグローバル変数を使っていないので、普通の関数と同じように使うことができます。ただし、#define PLAYER_SIZE などの定数名は統一しなければなりません。
次は、もっと実用的な関数を作ります。

関数を作ると他にもよいところがあります。
関数一覧に切り替えることで、全体像がもっとわかりやすくなります。






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