1区間移動について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
村人Cに昇格
記事: 7
登録日時: 12年前

1区間移動について

#1

投稿記事 by 村人Cに昇格 » 10年前

大学入試のためしばらくプログラミングを離れてしまっていたので忘れないようにRPGをつくろうとしているのですがすごく初歩的なところで躓いています。^^;

キャラクターの画像素材が縦横の向きで16個あり合計120*184(1体30*46)の1枚の連結画像となっています。
こちらの画像を4*4で分割して歩行させようとしています。
また、移動中にキーを離してもすぐ止まらずに1区間(32ピクセル)に到達するまで歩かせたいのです。

キャラクターの画像素材の配置としては上から正面、左向き、右向き、後ろ向きとなっており、
左から順に左足を前に出している絵、両足揃えている絵、右足を前に出している絵、両足を揃えている絵、となっております。

分割例)
0  1  2  3
4  5  6  7
8  9  10 11
12 13 14 15

画像の分割読み込みには成功しているのですが、
どうも「キーを離したときに両足を揃えている絵になるまで歩かせる(1区間に到達するまで歩かせる)」というのがうまくコーディングできません・・・
ゲームプログラミングの館のほうにも足を向けて、理論などは理解したのですが、なかなか・・・

私が書いたコードを掲載します。
CharaX,CharaY はキャラクターのXY座標です。
PNum はキャラクターの画像素材を分割読み込みした時の管理番号です。
ゆっくり歩かせたいため移動値は0.25fとさせて頂いております。

コード:

void CharacterToDoInfo(void){
	//DOWN
	if (CheckHitKey(KEY_INPUT_DOWN) != 0){
		//整数値ならPNum(向きを管理している番号を増やして歩いているように見せる)
		if (fmodf(CharaY, 1) == 0) {
			PNum = ((fmodf(CharaY, 40) / 10) + 0);
		}
		CharaY = (CharaY - 0.25f);
		if (fmodf(CharaY, 30) != 0) {
			CharaY++;
		}
	}
	//EFT
	if (CheckHitKey(KEY_INPUT_LEFT) != 0){
		if (fmodf(CharaX, 1) == 0){
			PNum = ((fmodf(CharaX, 40) / 10) + 4);
		}
		CharaX = (CharaX - 0.25f);
		if (fmodf(CharaX, 30) != 0){
			CharaX--;
		}
	}
	//RIGHT
	if (CheckHitKey(KEY_INPUT_RIGHT) != 0){
		if (fmodf(CharaX, 1) == 0){
			PNum = ((fmodf(CharaX, 40) / 10) + 8);
		}
		CharaX = (CharaX + 0.25f);
		if (fmodf(CharaX, 30) != 0){
			CharaX++;
		}
	}
	//UP
	if (CheckHitKey(KEY_INPUT_UP) != 0){
		if (fmodf(CharaY, 1) == 0){
			PNum = ((fmodf(CharaY, 40) / 10) + 12);
		}
		CharaY = (CharaY - 0.25f);
		if (fmodf(CharaY, 30) != 0){
			CharaY--;
		}
	}
}

アバター
amehirune
記事: 181
登録日時: 11年前
住所: どっか
連絡を取る:

Re: 1区間移動について

#2

投稿記事 by amehirune » 10年前

こういう書き方はどうでしょうか? ※重要な部分を忘れていたので追加しました

コード:

	for(int i=0;i<4;i++){		//4方向分のキーループ	
		if(ch.cnt!=0)	break;	//キャラが移動中ならばbreak;
		if(GetKey[i]>0){	//上下左右の入力処理

			/* ----------------------------------------
			   ここに適切な処理を加えてください!
			   ---------------------------------------- */

			ch.cnt = 1;	//移動フラグを立てる
		}
	}

	//移動中ならば
	if(ch.cnt!=0){

		/* 実際に移動させてみよう */

		//0~15までのループ式カウントアップ
		ch.cnt = ( ch.cnt+1 ) % MOVE_MAX;
	}
オフトピック
GetKey配列には、キー番号を引数とし、そのキーの入力されているカウント数が格納してあるものとしています。

コード:

void gpUpdateKey(){	

	int inputpad[4];	//入力状態を格納する配列
    inputpad[0]=CheckStatePad(configpad.left);	 inputpad[1]=CheckStatePad(configpad.right);
    inputpad[2]=CheckStatePad(configpad.down);	 inputpad[3]=CheckStatePad(configpad.up);	//それぞれの入力状態を入れる

	for(int i=0;i<4;i++){
		if(inputpad[i]>0)	GetKey[i]++;
		else				GetKey[i]=0;
	}

}
最後に編集したユーザー amehirune on 2015年8月07日(金) 12:56 [ 編集 2 回目 ]
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 1区間移動について

#3

投稿記事 by みけCAT » 10年前

amehirune さんが書きました:

コード:

	for(int i=0;i<4;i++)		//4方向分のキーループ	
		if(ch.cnt!=0)	break;	//キャラが移動中ならばbreak;
		if(GetKey[i]>1){	//上下左右の入力処理

			/* ----------------------------------------
			   ここに適切な処理を加えてください!
			   ---------------------------------------- */

			ch.cnt = 1;	//移動フラグを立てる
		}
	}

	//移動中ならば
	if(ch.cnt!=0){

		/* 実際に移動させてみよう */

		//0~15までのループ式カウントアップ
		ch.cnt = ( ch.cnt+1 ) % MOVE_MAX;
	}
・最初のfor分の行の最後(コメントの前)に{が抜けている気がします。
・なぜキーを押して最初の1フレームは移動処理をしない仕様にしたのですか?(これは批判ではなく疑問です)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

村人Cに昇格
記事: 7
登録日時: 12年前

Re: 1区間移動について

#4

投稿記事 by 村人Cに昇格 » 10年前

引き続きお世話になります。
amehirune 様
CheckStatePadなどの関数を読み出す際に適切なヘッダーファイルのディレクトリのパスをお教えいただけますでしょうか?
※検索で引っかかるブログ様などによく記載されている ../include/VG.h は試しました。
DxLibとは別のところでしょうか?
※DxLibはC直下に設置しております。
初歩的ですいません^^;
amehirune さんが書きました:こういう書き方はどうでしょうか? ※重要な部分を忘れていたので追加しました

コード:

	for(int i=0;i<4;i++)		//4方向分のキーループ	
		if(ch.cnt!=0)	break;	//キャラが移動中ならばbreak;
		if(GetKey[i]>1){	//上下左右の入力処理

			/* ----------------------------------------
			   ここに適切な処理を加えてください!
			   ---------------------------------------- */

			ch.cnt = 1;	//移動フラグを立てる
		}
	}

	//移動中ならば
	if(ch.cnt!=0){

		/* 実際に移動させてみよう */

		//0~15までのループ式カウントアップ
		ch.cnt = ( ch.cnt+1 ) % MOVE_MAX;
	}
オフトピック
GetKey配列には、キー番号を引数とし、そのキーの入力されているカウント数が格納してあるものとしています。

コード:

void gpUpdateKey(){	

	int inputpad[4];	//入力状態を格納する配列
    inputpad[0]=CheckStatePad(configpad.left);	 inputpad[1]=CheckStatePad(configpad.right);
    inputpad[2]=CheckStatePad(configpad.down);	 inputpad[3]=CheckStatePad(configpad.up);	//それぞれの入力状態を入れる

	for(int i=0;i<4;i++){
		if(inputpad[i]>0)	GetKey[i]++;
		else				GetKey[i]=0;
	}

}

アバター
amehirune
記事: 181
登録日時: 11年前
住所: どっか
連絡を取る:

Re: 1区間移動について

#5

投稿記事 by amehirune » 10年前

みけCAT さんが書きました:・最初のfor分の行の最後(コメントの前)に{が抜けている気がします。
・なぜキーを押して最初の1フレームは移動処理をしない仕様にしたのですか?(これは批判ではなく疑問です)
本当ですね。抜けてました^^;
あと、2つ目に関しても私のミスです。訂正させていただきました^^;
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※

アバター
amehirune
記事: 181
登録日時: 11年前
住所: どっか
連絡を取る:

Re: 1区間移動について

#6

投稿記事 by amehirune » 10年前

村人Cに昇格 さんが書きました:引き続きお世話になります。
amehirune 様
CheckStatePadなどの関数を読み出す際に適切なヘッダーファイルのディレクトリのパスをお教えいただけますでしょうか?
※検索で引っかかるブログ様などによく記載されている ../include/VG.h は試しました。
DxLibとは別のところでしょうか?
※DxLibはC直下に設置しております。
CheckStatePad関数は自作関数であり、DXライブラリに標準搭載されていないものです。
これに関してはプログラミングの館に記載されていたので説明は不要かと思い、省略させていただいておりました。
【龍神録プログラミングの館】第8章:キーコンフィグに対応させてみように詳しい解説が載っています。
私が説明するよりもはるかにわかりやすいと思うので、一度ご参照ください。
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※

村人Cに昇格
記事: 7
登録日時: 12年前

Re: 1区間移動について

#7

投稿記事 by 村人Cに昇格 » 10年前

amehirune 様
回答ありがとうございます。

今さらっとリンク先見てきました。

自作関数ですか、なるほど。
これはいわゆる龍神録プロジェクトに同梱されているファイルということですね?
できればその、あまり別のヘッダーファイルや人様のソースファイルを利用する形ではなくこのvoid(私が書いたCharacterToDoInfo)をうまく改変してこの中で完結させることはできないでしょうか?

ワガママだとは思いますがお力添えください...

なお、amehirune 様のソースをヒントにほんのすこし書きなおしてはいるのですがなんとも...

コード:

void CharacterToDoInfo(void){
	//DOWN
	if (CheckHitKey(KEY_INPUT_DOWN) != 0) {
		PlayerMoveState = 1;
		if (fmodf(CharaY, 1) == 0) {
			PNum = ((fmodf(CharaY, 40) / 10) + 0);
		}
		CharaY = (CharaY - 0.25f);
	} else {
		if (PlayerMoveState = 1) {
			if (fmodf(CharaY, 30) != 0) {
				CharaY++;
			} else {
				PlayerMoveState = 0;
			}
		}
	}
	//EFT
	if (CheckHitKey(KEY_INPUT_LEFT) != 0) {
		PlayerMoveState = 2;
		if (fmodf(CharaX, 1) == 0) {
			PNum = ((fmodf(CharaX, 40) / 10) + 4);
		}
		CharaX = (CharaX - 0.25f);
		if (fmodf(CharaX, 30) != 0) {
			CharaX--;
		}
	} else {
		if (PlayerMoveState = 2) {
			if (fmodf(CharaX, 30) != 0) {
				CharaX--;
			} else {
				PlayerMoveState = 0;
			}
		}
	}
	//RIGHT
	if (CheckHitKey(KEY_INPUT_RIGHT) != 0) {
		PlayerMoveState = 3;
		if (fmodf(CharaX, 1) == 0) {
			PNum = ((fmodf(CharaX, 40) / 10) + 8);
		}
		CharaX = (CharaX + 0.25f);
	} else {
		if (PlayerMoveState = 3) {
			if (fmodf(CharaX, 30) != 0) {
				CharaX++;
			} else {
				PlayerMoveState = 0;
			}
		}
	}
	//UP
	if (CheckHitKey(KEY_INPUT_UP) != 0) {
		PlayerMoveState = 4;
		if (fmodf(CharaY, 1) == 0) {
			PNum = ((fmodf(CharaY, 40) / 10) + 12);
		}
		CharaY = (CharaY - 0.25f);
	} else {
		if (PlayerMoveState = 4) {
			if (fmodf(CharaY, 30) != 0) {
				CharaY--;
			}
			else {
				PlayerMoveState = 0;
			}
		}
	}
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 1区間移動について

#8

投稿記事 by みけCAT » 10年前

村人Cに昇格 さんが書きました:なお、amehirune 様のソースをヒントにほんのすこし書きなおしてはいるのですがなんとも...
10行目、29行目、45行目、61行目のif文の条件式で不自然な代入操作をしていますが、大丈夫ですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 1区間移動について

#9

投稿記事 by みけCAT » 10年前

村人Cに昇格 さんが書きました:なお、amehirune 様のソースをヒントにほんのすこし書きなおしてはいるのですがなんとも...
また、0.25fずつ足すともしかしたら誤差が出ないのかもしれないですが、
5行目、11行目、21行目、25行目、30行目、40行目、46行目、56行目、61行目で浮動小数点数の厳密な一致判定をしているのも心配になりました。
データは4倍の値を整数で格納し、描画するときに4.0fで割る、という実装のほうがいいかもしれません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

村人Cに昇格
記事: 7
登録日時: 12年前

Re: 1区間移動について

#10

投稿記事 by 村人Cに昇格 » 10年前

みけCAT 様

不自然な代入…
ありがとうございます。
ミスタイプをコピーしていたようです^^;

また、浮動小数点での計算、ご指摘の通りやはり演算中に奇妙な数値が入り、予期せぬ数値が入っていたのがバグの要因のようです><;
使用中のすべての浮動小数点を整数へ書き換えたところ正常動作いたしました!

amehirune 様、みけCAT 様、
長らくお教えいただき、ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る