ページ 11

サンプルプロジェクトを分割コンパイルすると正常に動作しません...

Posted: 2014年2月20日(木) 17:04
by syrk
初めて投稿します、よろしくお願いします。
サンプルプログラム(http://dixq.net/g/01_01.html)をダウンロードし
RPGを作りたいと思い機能ごとに分割しました。
以下がソースになりますが本来ならば右キー入力時にキャラが歩くはずなのですが
キャラクタの画像すら表示されません。
プログラミング歴が浅いので初歩的な間違い、もしくはタブーを犯している可能性があるので
ここで質問させていただきました。
ご指摘よろしくお願いします。

>> main.cpp

コード:

#include <stdio.h>
#include "DxLib.h"
#include "Player.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int CmdShow )
{

		if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == 1 ) return -1;
		

				while( !ProcessMessage() && !ClearDrawScreen())
				{
					
					// デバッグ用
					DrawFormatString( 200, 130, GetColor(0, 255, 0), "OK! -> 01");
						//--------------------------------------------------------------------------------------------
						// キャラクタの移動と表示( Player.cpp )
						//--------------------------------------------------------------------------------------------
						f_MoveDrowCharacter();


						ScreenFlip();
				}




		DxLib_End();
		return 0;
	
} 
>>Player.cpp

コード:

#include "DxLib.h"

typedef struct
{
	int x;
	int y;
	char img;
}ch_t;

char Key[256];

void f_MoveDrowCharacter(void)
{
		ch_t ch;

			int image[12];
			ch.x            = 32;
			ch.y            = 160;
			SetDrawScreen( DX_SCREEN_BACK );
			LoadDivGraph( "画像/image.png", 12, 3, 4, 32, 32, image );
			ch.img=image[2];

			////////// デバッグ用
			DrawFormatString( 200, 155, GetColor(0, 255, 0), "OK! -> 02");

			if( Key[ KEY_INPUT_RIGHT ] == 1 )
			{
					ch.x++;
			}

			else if( ch.x % 32 != 0 )
			{
					ch.x++;
							
					// 移動画像の選択
					if (ch.x % 32 == 0 ) ch.img = image[7];

								else if( ch.x % 32 ==  1 ) ch.img = image[8];
								else if( ch.x % 32 ==  2 ) ch.img = image[8];
								else if( ch.x % 32 ==  3 ) ch.img = image[8];
								else if( ch.x % 32 ==  4 ) ch.img = image[8];
								else if( ch.x % 32 ==  5 ) ch.img = image[8];
								else if( ch.x % 32 ==  6 ) ch.img = image[8];
								else if( ch.x % 32 ==  7 ) ch.img = image[8];
								else if( ch.x % 32 ==  8 ) ch.img = image[8];

								else if( ch.x % 32 ==  9 ) ch.img = image[6];
								else if( ch.x % 32 == 10 ) ch.img = image[6];
								else if( ch.x % 32 == 11 ) ch.img = image[6];
								else if( ch.x % 32 == 12 ) ch.img = image[6];
								else if( ch.x % 32 == 13 ) ch.img = image[6];
								else if( ch.x % 32 == 14 ) ch.img = image[6];
								else if( ch.x % 32 == 15 ) ch.img = image[6];
								else if( ch.x % 32 == 16 ) ch.img = image[6];

								else if( ch.x % 32 == 17 ) ch.img = image[8];
								else if( ch.x % 32 == 18 ) ch.img = image[8];
								else if( ch.x % 32 == 19 ) ch.img = image[8];
								else if( ch.x % 32 == 20 ) ch.img = image[8];
								else if( ch.x % 32 == 21 ) ch.img = image[8];
								else if( ch.x % 32 == 22 ) ch.img = image[8];
								else if( ch.x % 32 == 23 ) ch.img = image[8];
								else if( ch.x % 32 == 24 ) ch.img = image[8];

								else if( ch.x % 32 == 25 ) ch.img = image[7];
								else if( ch.x % 32 == 26 ) ch.img = image[7];
								else if( ch.x % 32 == 27 ) ch.img = image[7];
								else if( ch.x % 32 == 28 ) ch.img = image[7];
								else if( ch.x % 32 == 29 ) ch.img = image[7];
								else if( ch.x % 32 == 30 ) ch.img = image[7];	
								else if( ch.x % 32 == 31 ) ch.img = image[7];
						}

					DrawGraph( ch.x, ch.y, ch.img, TRUE);


			////////// デバッグ用
			DrawFormatString( 200, 180, GetColor(0, 255, 0), "OK! -> 03");

			ScreenFlip();
}
>>Player.h

コード:

#ifndef DEF_PLAYER_H

#define DEF_PLAYER_H

typedef struct ch_t;

//----------------------------------------------
// キャラクタの移動と表示
//----------------------------------------------
void f_MoveDrowCharacter();


#endif

Re: サンプルプロジェクトを分割コンパイルすると正常に動作しません...

Posted: 2014年2月20日(木) 17:43
by softya(ソフト屋)
インデントが狂っているので、このままだとバグりやすいので注意して下さいね。
さて問題点ですが。
・ScreenFlip();が連続で2回呼ばれています。 ゲームプログラミングの館にも有る「書いてはいけない4つの処理 」に該当しますのでScreenFlip()はWinMainに限定すべきです。
・SetDrawScreen( DX_SCREEN_BACK );は基本として初期化にあるべきなので毎ループ呼ぶものではありません。理解して使う分には良いですが。
・LoadDivGraph( "画像/image.png", 12, 3, 4, 32, 32, image );は毎フレーム呼び出すと前の画像が残るので画像がメモリに溜まり続けます。初期化時のみでメインループに基本入れません。
・ ch_t ch;と int image[12];はローカル変数なので、関数を抜けるときに内容が破棄されます。つまり、常に保持するには向きません。
・代入である ch.x = 32;などは関数を呼び出される度にしていますので実質移動できません。
・計算で出来そうなら処理
else if( ch.x % 32 == 1 ) ch.img = image[8];
else if( ch.x % 32 == 2 ) ch.img = image[8];
else if( ch.x % 32 == 3 ) ch.img = image[8];
は式を考えたほうがバグも少なく効率的です。
って所でしょうか。まだ見逃しているところがあるかもしれません。

Re: サンプルプロジェクトを分割コンパイルすると正常に動作しません...

Posted: 2014年2月20日(木) 18:21
by syrk
返信ありがとうございます。
関数呼び出しごとに座標が定義されているので移動できないなどは盲点でした。
最初の座標初期化に加えグローバル変数を各関数が利用できる方法はないのでしょうか。
main関数側に ch.x を書くと Player.cpp で共有できなく Player.cpp 側に ch.x の初期化を書くと
指摘されたように実質的に移動できなくなってしまいます。

Re: サンプルプロジェクトを分割コンパイルすると正常に動作しません...

Posted: 2014年2月20日(木) 18:57
by usao
分割コンパイルとかに挑戦する前に,
変数の寿命や通用範囲,関数間での情報の受け渡し方法等,Cの基礎的な事柄を復習されたほうが良いように見受けます.

コード:

void f( int *p ){  *p = 5;  }

int main()
{
  int a = 0;
  f( &a );
  printf( "%d", a );  //何と表示されるでしょう?
  return 0;
}

Re: サンプルプロジェクトを分割コンパイルすると正常に動作しません...

Posted: 2014年2月20日(木) 20:27
by softya(ソフト屋)
ゲームプログラミングの館で言えば、「ゲームプログラミング設計」を参考にされたほうが良いと思います。