クォーターの当たり判定とスクロール

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

クォーターの当たり判定とスクロール

#1

投稿記事 by イマダニ » 6年前

ロックマンエグゼのマップ移動。キングダムハーツCOMのマップ移動。BASTIONの移動。

これらの”クォーター視点のステージをキャラが縦横無尽に動き回る”

それの当たり判定とスクロール方法ってどうなっているんだろう?
今回はそんな質問をしに来ました。

ついこの前、クォーターでの描画方法をここで教えてもらい、その後、教えてもらった方法で描画したマップの上をキャラが走るようにしてみました。
これがそのプログラムです。

コード:

#include"DxLib.h"
#include"Key.h"

//画面の大きさ
#define SCREEN_WIDTH 640;
#define SCREEN_HEIGHT 480;
//チップの枚数
#define CHIP_NUMBER_X 20
#define CHIP_NUMBER_Y 16

//プレイヤー構造体
typedef struct{
	bool walkflag;//歩きフラグ
	int img,cnt,muki;//画像、カウンタ、向き
	int x,y;//座標
}PLAY;

//マップデータ
int MapData[ CHIP_NUMBER_Y ][ CHIP_NUMBER_X ] =
{
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 
};

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);

	//構造体宣言
	PLAY p;

	//画像変数
	int player[54];
	int map;
	
	//画像の読み込み
	map    = LoadGraph("img/mapchip01.bmp");
	LoadDivGraph("img/player.png",54,9,6,64,64,player);
	
	//構造体要素の初期化
	memset(&p,0,sizeof(PLAY));
	
	//プレイヤー座標の初期化
	p.x=160;
	p.y=80;

	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && updatekey()==0 ){

		//プレイヤー移動アニメーションのためのカウント
		p.cnt++;

		//移動プログラム
		if( checkkey(KEY_INPUT_LEFT)>0 ){//左
			p.muki=1;
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_RIGHT)>0 ){//右
			p.muki=2;
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_UP)>0 ){//上
			p.muki=3;
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_DOWN)>0 ){//下
			p.muki=4;
			p.walkflag=true;
		}else{
			p.walkflag=false;//上記以外
		}

		//歩きフラグ分岐
		if(p.walkflag==true){//歩きフラグがたってる時
			if(p.muki==1){//左
				p.x-=4;//左へ
				p.img=10+(p.cnt/4)%8;//左へ走るアニメーション
			}if(p.muki==2){//右
				p.x+=4;
				p.img=19+(p.cnt/4)%8;
			}if(p.muki==3){//上
				p.y-=4;
				p.img=28+(p.cnt/4)%8;
			}if(p.muki==4){//下
				p.y+=4;
				p.img=1+(p.cnt/4)%8;
			}
		}if(p.walkflag==false){//歩きフラグがたってない時
			if(p.muki==1){//左だったら
				p.img=9;//左向いて立っている画像
			}if(p.muki==2){//右
				p.img=18;//右向いて
			}if(p.muki==3){//上
				p.img=27;
			}if(p.muki==4){//下
				p.img=0;
			}
		}

		//マップ描画
		for(int y=0;y<CHIP_NUMBER_Y;y++){
			for(int x=0;x<CHIP_NUMBER_X;x++){
				if(MapData[y][x]==1){//1なら表示
					DrawGraph(32*(x-y), 17*(x+y), map,TRUE);//ここの部分
				}
			}
		}
		//プレイヤー描画
		DrawGraph(p.x,p.y,player[p.img],TRUE);
	}

	DxLib_End();

	return 0;
}
ここからまずは当たり判定をつけてみようかなと思ったのですが、そこで初めに書いた疑問に行きつきました。

”クォーター視点のステージをキャラが縦横無尽に動き回る”

この際の当たり判定はゲームプログラミングの館にある「行けないところを作る」のようなものなのでしょうか?
もしそうだと仮定してそこに載ってる

MapData[x/32-1][y/32]

のカッコ内の計算式がどう変わるのか?
ヒントをください。

スクロールについてはアクションゲームに実装はした経験はありますが、サンプルを流用しただけで理解はまったくできていません。
よくわからず放置してます……

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#2

投稿記事 by softya(ソフト屋) » 6年前

見た目の描画がクォータなだけですから、当たり判定はそのままです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#3

投稿記事 by イマダニ » 6年前

コード:

#include"DxLib.h"
#include"Key.h"

//画面の大きさ
#define SCREEN_WIDTH 640;
#define SCREEN_HEIGHT 480;
//チップの枚数
#define CHIP_NUMBER_X 20
#define CHIP_NUMBER_Y 16

//プレイヤー構造体
typedef struct{
	bool walkflag;//歩きフラグ
	int img,cnt,muki;//画像、カウンタ、向き
	int x,y;//座標
}PLAY;

//マップデータ
int MapData[ CHIP_NUMBER_Y ][ CHIP_NUMBER_X ] =
{
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 
};

//いけない所判定する関数
int CheckWalk(int x,int y,int muki){
	if(muki==1)
		if(MapData[y/32][x/32-1]==0)
			return 1;
	if(muki==2)
		if(MapData[y/32][x/32+1]==0)
			return 1;
	if(muki==3)
		if(MapData[y/32-1][x/32]==0)
			return 1;
	if(muki==4)
		if(MapData[y/32+1][x/32]==0)
			return 1;

	return 0;
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);

	//構造体宣言
	PLAY p;

	//画像変数
	int player[54];
	int map;
	
	//画像の読み込み
	map    = LoadGraph("img/mapchip01.bmp");
	LoadDivGraph("img/player.png",54,9,6,64,64,player);
	
	//構造体要素の初期化
	memset(&p,0,sizeof(PLAY));
	
	//プレイヤー座標の初期化
	p.x=160;
	p.y=80;

	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && updatekey()==0 ){

		//プレイヤー移動アニメーションのためのカウント
		p.cnt++;

		//移動プログラム
		if( checkkey(KEY_INPUT_LEFT)>0 ){//左
			p.muki=1;
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_RIGHT)>0 ){//右
			p.muki=2;
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_UP)>0 ){//上
			p.muki=3;
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_DOWN)>0 ){//下
			p.muki=4;
			p.walkflag=true;
		}else{
			p.walkflag=false;//上記以外
		}


		//当たり判定
		if(p.walkflag==true)
			if(CheckWalk(p.x,p.y,p.muki)==1)//1だったら
				p.walkflag=false;//歩かせない


		//歩きフラグ分岐
		if(p.walkflag==true){//歩きフラグがたってる時
			if(p.muki==1){//左
				p.x-=4;//左へ
				p.img=10+(p.cnt/4)%8;//左へ走るアニメーション
			}if(p.muki==2){//右
				p.x+=4;
				p.img=19+(p.cnt/4)%8;
			}if(p.muki==3){//上
				p.y-=4;
				p.img=28+(p.cnt/4)%8;
			}if(p.muki==4){//下
				p.y+=4;
				p.img=1+(p.cnt/4)%8;
			}
		}if(p.walkflag==false){//歩きフラグがたってない時
			if(p.muki==1){//左だったら
				p.img=9;//左向いて立っている画像
			}if(p.muki==2){//右
				p.img=18;//右向いて
			}if(p.muki==3){//上
				p.img=27;
			}if(p.muki==4){//下
				p.img=0;
			}
		}

		//マップ描画
		for(int y=0;y<CHIP_NUMBER_Y;y++){
			for(int x=0;x<CHIP_NUMBER_X;x++){
				if(MapData[y][x]==1){
					DrawGraph(32*(x-y), 17*(x+y), map,TRUE);//ここの部分
				}
			}
		}
		//プレイヤー描画
		DrawGraph(p.x,p.y,player[p.img],TRUE);
	}

	DxLib_End();

	return 0;
}
int CheckWalkという丸パクリの行けないところを判定する関数を追加しましたが、
描画されたマップの外側、0の部分にあたり判定ができず、画面の枠に沿う形で当たり判定ができてしまいます。

文字だけではわかりにくいのでスキャンした画像でも貼りたいのですが、この掲示板ってそういうことができるのでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#4

投稿記事 by softya(ソフト屋) » 6年前

画像は投稿画面の下に有るファイル添付から添付できます。

【補足】
プレイヤー描画がクォーターに成っていないことに気づきました。

↓ プレーヤーもクォーター座標系に変換しないとダメですよ。
DrawGraph(p.x,p.y,player[p.img],TRUE);
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#5

投稿記事 by イマダニ » 6年前

プレイヤー座標をクォーターに?
マップは配列の要素数を足したり引いたりして変えましたが、
配列要素の無いプレイヤー座標をどうやって変えるんです?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#6

投稿記事 by softya(ソフト屋) » 6年前

イマダニ さんが書きました:プレイヤー座標をクォーターに?
マップは配列の要素数を足したり引いたりして変えましたが、
配列要素の無いプレイヤー座標をどうやって変えるんです?
また、あの図を書いて考えてみましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#7

投稿記事 by イマダニ » 6年前

すいません、返信が遅くなりました。
ひとまず方眼用紙にあの図を書いてみましたが、
そこからどうしたらいいかわかりません……
前はp01を求めよという課題があったため、なにをどうすればいいのか大体把握できたのですが
今回はこの図をどう利用するかが見当がつきません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#8

投稿記事 by softya(ソフト屋) » 6年前

そこを考えるのが思考法のトレーニングなんですが、ヒントを提示します。
あの図を書いて、具体的な数字でP00からP12などの座標をまず書いてみてください。P00は(a,0)じゃなくて具体的に(32,0)と仮定します。
で、マップパーツの中心にPleyerキャラクタが立っていると仮定した場合の[0][0]ブロックのPleyerキャラクタの座標は(999,999)であると書きだしてみてください。
それとクォータビューではないDrawGraph(p.x,p.y,player[p.img],TRUE);の座標として扱った場合の座標もその横に書き出します。

参考。前回の質問
「クォータービューについて • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?t=12748#p101962
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#9

投稿記事 by イマダニ » 6年前

>>で、マップパーツの中心にPleyerキャラクタが立っていると仮定した場合の[0][0]ブロックのPleyerキャラクタの座標は(999,999)であると書 きだしてみてください。
それとクォータビューではないDrawGraph(p.x,p.y,player[p.img],TRUE);の座標として扱った場合の座標もその横に書き出します。

(999,999) (64,20)

こういった感じですか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#10

投稿記事 by softya(ソフト屋) » 6年前

(999,999) (64,20)となりますが、左はクォーター画面での座標です。右はクォーター回転していないマップにおける仮想的な座標です。
まぁ、仮想的といってもその人のさじ加減でどうにでもなるのですが分かりやすいほうが良いでしょう。64x64の仮想的なマップパーツということにしましょう。
と言うことでマップパーツの中央はパーツ左上端から(+32,+32)です。

例を書くとP00が(32,0)だと想定した条件の上で
-----------------------------------------------------------
マップ配列 クォータマップ中央座標 変換前マップ中央座標
-----------------------------------------------------------
[0][0] (?,?) (?,?)
を埋めてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#11

投稿記事 by イマダニ » 6年前

[0][0] (999,999) (64,32)

ですか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#12

投稿記事 by softya(ソフト屋) » 6年前

[0][0] (999,999) ←(1) (64,32) ←(2)

(1)この値(999,999)は私が仮に書いたものなのでデタラメですの引用しないでくださいね。全部(999,999)なら意味ないじゃないですか。
例の図を書いて考える必要がありますが、クォータビューのマップパーツの中央座標値は前回の話で座標の計算式は知っているはずです。

(2)64x64のマップパーツの中央は(64,32)にはなりません。
こちらはクォータビューではなくトップビュー表示した場合の座標ですので、素直に考えれば良いです。

出来れば見ないでほしい(1)の大ヒント:
► スポイラーを表示
書いてて心配になって来ましたが、トップビュー表示でキャラクターの移動とかプログラムは理解できているのでしょうか?
これが分かっていないと意味が無いのですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#13

投稿記事 by イマダニ » 6年前

すいません、少し勘違いしてました

[0][0]
(64,32)
(32,32)

です。

>>書いてて心配になって来ましたが、トップビュー表示でキャラクターの移動とかプログラムは理解できているのでしょうか?
これが分かっていないと意味が無いのですが。

ゲームプログラミングの館の一区間歩かせる、行けないところを作るなどのことですか?
そこなら一応理解はしてるつもりです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#14

投稿記事 by softya(ソフト屋) » 6年前

残念ですが、クォータビューのP00が(32,0)だと想定した条件の上でマップパーツ[0][0]の中央座標は(64,32)ではありません。トップビューの座標は合っています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#15

投稿記事 by イマダニ » 6年前

中心座標は

(32,0)かな?

(64,32)は[0][1]の中心座標です。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#16

投稿記事 by softya(ソフト屋) » 6年前

イマダニ さんが書きました:中心座標は
(32,0)かな?
(64,32)は[0][1]の中心座標です。
yが0は無いですよ。
ちゃんと図に座標を書いてますか?
前回はヒントを出しすぎたので、そのため自分で考えなかった分だけ理解が不十分だったと思います。

今回は図に座標を書いてみてください。
それを写真でもペイントで書いたものでも、投稿でファイル添付で添付してください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#17

投稿記事 by イマダニ » 6年前

画像うまくはれてるかな?

最初、p00が配列要素の左上端っこにあったら、(64,32)だとおもったんですが、

画像のように考えれば(32,32)なのかなと
添付ファイル
クォー2.png
クォー2.png (16.08 KiB) 閲覧数: 2644 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#18

投稿記事 by softya(ソフト屋) » 6年前

P00は前の図と同じ位置です。 → 今回移動しています。
あとクォータービューのマップパーツは現在使用している64x40のものです。
64x64は仮想的なトップビューのマップパーツのほうで、それを45度回転させたものがクォータビューです。
なので、クォータービューのマップパーツの中央のyが32になることはありません。

今回考えることは、仮想的なトップビューで移動するキャラクタをクォータービューの座標に変換する方法です。
図をちゃんと書くとイメージ出来るはずなんですけどね。 ※ ゲーム作りはイメージ力です。

と言うことで参考図です。トップピューで[1][1]のマップにいるキャラクタはクォータだと何処に立つべきでしょうか?
クォー2x.png
クォー2x.png (22.81 KiB) 閲覧数: 2640 回
これを元に足らない部分を埋めてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#19

投稿記事 by イマダニ » 6年前

なるほどそういうことだったのか
トップとクォーターごちゃまぜにしてました

埋めてみよということでこんな感じに埋めてみました
どうでしょう?
添付ファイル
クォー3.png
クォー3.png (50.58 KiB) 閲覧数: 2632 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#20

投稿記事 by softya(ソフト屋) » 6年前

ケアレスミスだと思いますが、トップビューの[0][2]と[1][2] の中央X座標が違っています。
他はOKです。

トップビューの[0][2]と[1][2] の中央X座標を直した上で、全部を書きだしてみてください。
[0][0] (?,?) (?,?)
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#21

投稿記事 by イマダニ » 6年前

マップ配列 クォータマップ中央座標 変換前マップ中央座標

[0][0] (64,20) (32,32)

[0][1] (96,40) (96,32)

[0][2] (128,60) (160,32)

[1][0] (32,40) (32,96)

[1][1] (64,60) (96,96)

[1][2] (96,80) (160,96)

どうですか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#22

投稿記事 by softya(ソフト屋) » 6年前

そうですね。そういう関連性になります。
さて、トップビューからクォータビューへの変換ですが前回の式と全く関連性がないわけではありません。
前のマップパーツの式はこうでした。
drawx=a+32(mapx-mapy) 訂正。
drawy=20(mapx+mapy)
これを展開。
drawx=a+32*mapx-32*mapy 訂正。
drawy=20*mapx+20*mapy
となります。これを頭の隅に置いておいてください。

では、今書いてもらった座標の関連を分かりやすくまとめてみます。

コード:

マップ	トップ		クォータ
(0,0)	(32,32)		(64,20)	
(1,0)	(96,32)		(96,40)	
(2,0)	(160,32)	(128,60)
(0,1)	(32,96)		(32,40)	
(1,1)	(96,96)		(64,60)	
(2,1)	(160,96)	(96,80)	
これでトップの座標の変化とクォータの座標の変化の関連を書きだしてみましょう。

前回の関連はこうでしたが、今回は少数が入ります。
drawx は mapxが1増えると 32 づつ減少し、mapyが1増えると 32 づつ増加します。訂正。
drawx は mapyが1増えると 32 づつ減少し、mapxが1増えると 32 づつ増加します。
drawy は mapyが1増えると 20 づつ増加し、mapxが1増えると 20 づつ増加します。
ですね。

[訂正した理由]
前回の答えで式間違っていたかもしれません。現在再検討中。
訂正版で確定。すいません。前の答えは間違っています。
drawx=a+32(mapx-mapy)
drawy=20(mapx+mapy)
が正解です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#23

投稿記事 by イマダニ » 6年前

トップビューの座標を(topx,topy)

クォーターの座標を(quotax,quotay) として

コード:


マップ   トップ       クォータ
(0,0)   (32,32)     (64,20) 
(1,0)   (96,32)     (96,40) 
(2,0)   (160,32)    (128,60)
(0,1)   (32,96)     (32,40) 
(1,1)   (96,96)     (64,60) 
(2,1)   (160,96)    (96,80) 


quotaxはtopxが64増えると32づつ増える、topyが64増えると32づつ減る

quotayはtopxが64増えると20づつ増える、topyが64増えると20づつ増える


こんな感じですかといいたいところですが、少数が入ってない……

少数が入るというのは式の段階からということでいいんでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#24

投稿記事 by softya(ソフト屋) » 6年前

イマダニ さんが書きました: quotaxはtopxが64増えると32づつ増える、topyが64増えると32づつ減る
quotayはtopxが64増えると20づつ増える、topyが64増えると20づつ増える
こんな感じですかといいたいところですが、少数が入ってない……
少数が入るというのは式の段階からということでいいんでしょうか?
OKですよ。その通りです。
少数が入るのは式にした時ですね。64に対して32なので32/64になります。じゃあ式にしてみましょう。
ただしですね。
式でマップの場合にdrawx=a+だった部分がdrawx=(a+32)+になります。
理由は図を見ると分かりますが、赤いマップ区分のトップビュー四角の(0,0)の位置がクォータービュー菱型の(a+32,0)になるからです。
※ 前回の失敗の反省で必ず検算して確認をお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#25

投稿記事 by イマダニ » 6年前

できました!

drawx=(a+64)+32/64(topx-topy)

drawy=20/64(topx+topy)

この式で以下のものを計算すると
[0][0] (32,32) (64,20)

drawx = (a+64)+32/64(32-32) = (a+64)+0 = a+64

drawy = 20/64(32+32) = 20/64(64) = 20

drawxの(a+64)は(a+32)だとどうしても32たらない座標が出てしまったので64にしました
どうでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#26

投稿記事 by softya(ソフト屋) » 6年前

aは32と言う想定だったので、そうすると32+64で96になりますが大丈夫ですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#27

投稿記事 by イマダニ » 6年前

aが32ならこれで大丈夫ですね。

drawx=(a+32)+32/64(topx-topy)

drawy=20/64(topx+topy)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#28

投稿記事 by softya(ソフト屋) » 6年前

じゃあ、それでキャラクタを表示して歩かせてみてください。
ただし、キー入力をどう処理するかは悩みどころですけどね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#29

投稿記事 by イマダニ » 6年前

移動の部分がくっそ汚いですけど、こんな感じで書いてみたところ

コード:

#include"DxLib.h"
#include"Key.h"

//画面の大きさ
#define SCREEN_WIDTH 640;
#define SCREEN_HEIGHT 480;
//チップの枚数
#define CHIP_NUMBER_X 20
#define CHIP_NUMBER_Y 16

//プレイヤー構造体
typedef struct{
	bool walkflag;//歩きフラグ
	int img,cnt,muki;//画像、カウンタ、向き
	int x,y;//座標
}PLAY;

//マップデータ
int MapData[ CHIP_NUMBER_Y ][ CHIP_NUMBER_X ] =
{
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 
};

//いけない所作る関数
int CheckWalk(int x,int y,int muki){
	if(muki==1)
		if(MapData[y/32][x/32-1]==0)
			return 1;
	if(muki==2)
		if(MapData[y/32][x/32+1]==0)
			return 1;
	if(muki==3)
		if(MapData[y/32-1][x/32]==0)
			return 1;
	if(muki==4)
		if(MapData[y/32+1][x/32]==0)
			return 1;

	return 0;
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);

	//構造体宣言
	PLAY p;

	//画像変数
	int player[72];
	int map;
	
	//画像の読み込み
	map    = LoadGraph("img/mapchip01.bmp");
	LoadDivGraph("img/player1.png",72,9,8,64,64,player);
	
	//構造体要素の初期化
	memset(&p,0,sizeof(PLAY));
	
	//プレイヤー座標の初期化
	p.x=160;
	p.y=96;

	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && updatekey()==0 ){

		//プレイヤー移動アニメーションのためのカウント
		p.cnt++;

		//キー入力判定
		if( checkkey(KEY_INPUT_LEFT)>0 && checkkey(KEY_INPUT_UP)>0  ){
			p.muki=5;	//左上
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_LEFT)>0 && checkkey(KEY_INPUT_DOWN)>0 ){
			p.muki=6;	//左下
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_RIGHT)>0 && checkkey(KEY_INPUT_UP)>0 ){
			p.muki=7;	//右上
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_RIGHT)>0 && checkkey(KEY_INPUT_DOWN)>0 ){
			p.muki=8;	//右下
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_LEFT)>0 ){
			p.muki=1;	//左
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_RIGHT)>0 ){
			p.muki=2;	//右
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_UP)>0 ){
			p.muki=3;	//上
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_DOWN)>0 ){
			p.muki=4;	//下
			p.walkflag=true;
		}else{
			p.walkflag=false;
		}

		
		//当たり判定
		if(p.walkflag==true)
			if(CheckWalk(p.x,p.y,p.muki)==1)//1だったら
				p.walkflag=false;//歩かせない


		//歩きフラグの分岐
		if(p.walkflag==true){//フラグがたってる時
			if(p.muki==1){	//左へ
				p.x-=3;     //走る
				p.img=10+(p.cnt/5)%8;//それのアニメーション
			}if(p.muki==2){	//右
				p.x+=3;
				p.img=19+(p.cnt/5)%8;
			}if(p.muki==3){	//上
				p.y-=3;
				p.img=28+(p.cnt/5)%8;
			}if(p.muki==4){	//下
				p.y+=3;
				p.img=1+(p.cnt/5)%8;
			}if(p.muki==5){	//左上斜め
				p.x-=3;
				p.y-=3;
				p.img=37+(p.cnt/5)%8;
			}if(p.muki==6){	//左下斜め
				p.x-=3;
				p.y+=3;
				p.img=55+(p.cnt/5)%8;
			}if(p.muki==7){	//右上斜め
				p.x+=3;
				p.y-=3;
				p.img=46+(p.cnt/5)%8;
			}if(p.muki==8){ //左上斜め
				p.x+=3;
				p.y+=3;
				p.img=64+(p.cnt/5)%8;
			}
		}if(p.walkflag==false){//フラグが建ってない時
			//それぞれの向きの立っている絵にする
			if(p.muki==1){
				p.img=9;
			}if(p.muki==2){
				p.img=18;
			}if(p.muki==3){
				p.img=27;
			}if(p.muki==4){
				p.img=0;
			}if(p.muki==5){
				p.img=36;
			}if(p.muki==6){
				p.img=54;
			}if(p.muki==7){
				p.img=45;
			}if(p.muki==8){
				p.img=63;
			}
		}

		//マップ描画
		for(int y=0;y<CHIP_NUMBER_Y;y++){
			for(int x=0;x<CHIP_NUMBER_X;x++){
				if(MapData[y][x]==1){
					DrawGraph(32*(x-y), 17*(x+y), map,TRUE);//ここの部分
				}
			}
		}
		//プレイヤー描画
		DrawGraph(32/64*(p.x-p.y),20/64*(p.x+p.y),player[p.img],TRUE);
	}

	DxLib_End();

	return 0;
}
キャラが画像の立っている場所から動かなくなりました。
あにめ-しょんはするんですけど動きません。
添付ファイル
ゲーム画面.png
ゲーム画面.png (12.37 KiB) 閲覧数: 2550 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#30

投稿記事 by softya(ソフト屋) » 6年前

詰まる人に多いのですが機能を一度に入れ過ぎで動作確認出来ていないことが多いんです。
横移動とか単純な機能から順番にデバッガで動作を確認して組み込んでいってください。
あと仮想トップビューは64x64のサイズにしたはずですが?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#31

投稿記事 by イマダニ » 6年前

printfでのデバッグをしたところ各変数には問題が無かったため、
プレイヤー描画の計算の部分に問題があると思い、
以下のように変えたところ

コード:

DrawGraph(32/64*(p.x-p.y) , 20/64*(p.x+p.y) , player[p.img] , TRUE);
↓
DrawGraph(0.5*(p.x-p.y) , 0.27*(p.x+p.y) , player[p.img] , TRUE);
キャラがちゃんと動きました。
以下がコードの全体になります。

コード:

#include"DxLib.h"
#include"Key.h"

//画面の大きさ
#define SCREEN_WIDTH 640;
#define SCREEN_HEIGHT 480;
//チップの枚数
#define CHIP_NUMBER_X 10
#define CHIP_NUMBER_Y 8

//プレイヤー構造体
typedef struct{
	bool walkflag;//歩きフラグ
	int img,cnt,muki;//画像、カウンタ、向き
	double x,y;//座標
}PLAY;

//マップデータ
int MapData[ CHIP_NUMBER_Y ][ CHIP_NUMBER_X ] =
{
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};

//いけない所作る関数
int CheckWalk(int x,int y,int muki){
	if(muki==1)//左
		if(MapData[y/64][x/64-1]==0)
			return 1;
	if(muki==2)//右
		if(MapData[y/64][x/64+1]==0)
			return 1;
	if(muki==3)
		if(MapData[y/64-1][x/64]==0)
			return 1;
	if(muki==4)
		if(MapData[y/64+1][x/64]==0)
			return 1;

	return 0;
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);

	AllocConsole();
    freopen("CONOUT$", "w", stdout); //標準出力をコンソールにする
	//  printf( "これでprintfが使えます\n" );   //←お試し用

	//構造体宣言
	PLAY p;

	//画像変数
	int player[72];
	int map;
	
	//画像の読み込み
	map    = LoadGraph("img/mapchip01.bmp");
	LoadDivGraph("img/player1.png",72,9,8,64,64,player);
	
	//構造体要素の初期化
	memset(&p,0,sizeof(PLAY));
	
	//プレイヤー座標の初期化
	p.x=64;
	p.y=64;

	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && updatekey()==0 ){

		//プレイヤー移動アニメーションのためのカウント
		p.cnt++;

		//キー入力判定
		if( checkkey(KEY_INPUT_LEFT)>0 ){
			p.muki=1;   //左向きで
			p.walkflag=true;  //フラグが建つよ
		}else if( checkkey(KEY_INPUT_RIGHT)>0 ){
			p.muki=2;	//右
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_UP)>0 ){
			p.muki=3;	//右
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_DOWN)>0 ){
			p.muki=4;
			p.walkflag=true;
		}else{			//それ以外
			p.walkflag=false;  //フラグ建ってないよ
		}

		//とりあえずコメントアウト
		/*if(p.walkflag==true)
			if(CheckWalk(p.x,p.y,p.muki)==1)
				p.walkflag=false;*/

		//歩きフラグの分岐
		if(p.walkflag==true){//フラグがたってる時
			if(p.muki==1){	//左へ
				p.x-=4;		//走る
				p.y+=4;     /*クォータの座標に変えたため、
                                                      X座標だけ変動しても斜めに移動するため
							  y座標も変えた*/
				p.img=10+(p.cnt/5)%8;
			}
			if(p.muki==2){	//右へ
				p.x+=4;     //走る
				p.y-=4;
				p.img=19+(p.cnt/5)%8;//それのアニメーション
			}
			if(p.muki==3){ //上へ
				p.y-=6;
				p.x-=6;
				p.img=28+(p.cnt/5)%8;
			}
			if(p.muki==4){ //下へ
				p.y+=6;
				p.x+=6;
				p.img=1+(p.cnt/5)%8;
			}
		}if(p.walkflag==false){//フラグが建ってない時
			//それぞれの向きの立っている絵にする
			if(p.muki==1) p.img=9;
			if(p.muki==2) p.img=18;
			if(p.muki==3) p.img=27;
			if(p.muki==4) p.img=0;
		}

		//マップ描画
		for(int y=0;y<CHIP_NUMBER_Y;y++){
			for(int x=0;x<CHIP_NUMBER_X;x++){
				if(MapData[y][x]==1){
					DrawGraph(32*(x-y), 17*(x+y), map,TRUE);//ここの部分
				}
			}
		}
		//プレイヤー描画
		DrawGraph(0.5*(p.x-p.y),0.27*(p.x+p.y),player[p.img],TRUE);
	}

	DxLib_End();

	return 0;
}
問題は当たり判定がうまくいかないところです。
今の当たり判定のコードは、キャラが64づつきっちり動くキャラ用の
当たり判定ですから、キャラが自由に動くぼくのコードでは
当たり判定がめちゃくちゃです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#32

投稿記事 by softya(ソフト屋) » 6年前

書き忘れました。それはint型の問題ですね。少数が切り捨てられるので、ちゃんと計算出来ないのです。
DrawGraph(32/64*(p.x-p.y) , 20/64*(p.x+p.y) , player[p.img] , TRUE);
なので、これでも良いのですが誤差が心配です。 あと20/64って0.3125では?
DrawGraph((p.x-p.y)*32/64 , (p.x+p.y)*20/64 , player[p.img] , TRUE);
とするのも方法です。 → 計算順番で少数が切り捨てられても問題なし。
問題は当たり判定がうまくいかないところです。
今の当たり判定のコードは、キャラが64づつきっちり動くキャラ用の
当たり判定ですから、キャラが自由に動くぼくのコードでは
当たり判定がめちゃくちゃです。
移動前の座標を覚えておいて、当たり判定を移動後に行います。あたったら移動前の座標に戻します。
そうすれば、if(MapData[y/64][x/64-1]==0)の-1の様なものが不要になります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#33

投稿記事 by イマダニ » 6年前

そっかintのせいだったんですね。

>>あと20/64って0.3125では?

コード:

//マップ描画
for(int y=0;y<CHIP_NUMBER_Y;y++){
	for(int x=0;x<CHIP_NUMBER_X;x++){
		if(MapData[y][x]==1){
			DrawGraph(32*(x-y), 17*(x+y), map,TRUE);
             }
}
マップ描画が17だったので合わせなきゃまずいかなと思い
17/64としてました。

>>移動前の座標を覚えておいて、当たり判定を移動後に行います。あたったら移動前の座標に戻します。

oldx,oldyという二つの変数を用意し、それに前もってプレイヤー座標を代入、記録し、当たり判定のところでoldを代入するようにしてみました。
まんまDXlib本家のサンプルのパクリですけど……

コード:


while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && updatekey()==0 ){

		//プレイヤー移動アニメーションのためのカウント
		p.cnt++;

		//座標を記録
		p.oldx=p.x;
		p.oldy=p.y;

		//キー入力判定
		if( checkkey(KEY_INPUT_LEFT)>0 ){
			p.muki=1;   //左向きで
			p.walkflag=true;  //フラグが建つよ
		}else if( checkkey(KEY_INPUT_RIGHT)>0 ){
			p.muki=2;	//右
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_UP)>0 ){
			p.muki=3;	//右
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_DOWN)>0 ){
			p.muki=4;
			p.walkflag=true;
		}else{			//それ以外
			p.walkflag=false;  //フラグ建ってないよ
		}

		//歩きフラグの分岐
		if(p.walkflag==true){//フラグがたってる時
			if(p.muki==1){	//左へ
				p.x-=4;		//走る
				p.y+=4;     /*クォータの座標に変えたため、X座標だけ変動しても斜めに移動するため
							  y座標も変えた*/
				p.img=10+(p.cnt/5)%8;
			}
			if(p.muki==2){	//右へ
				p.x+=4;     //走る
				p.y-=4;
				p.img=19+(p.cnt/5)%8;//それのアニメーション
			}
			if(p.muki==3){ //上へ
				p.y-=6;
				p.x-=6;
				p.img=28+(p.cnt/5)%8;
			}
			if(p.muki==4){ //下へ
				p.y+=6;
				p.x+=6;
				p.img=1+(p.cnt/5)%8;
			}
		}if(p.walkflag==false){//フラグが建ってない時
			//それぞれの向きの立っている絵にする
			if(p.muki==1) p.img=9;
			if(p.muki==2) p.img=18;
			if(p.muki==3) p.img=27;
			if(p.muki==4) p.img=0;
		}

		//いけない所だったら
		if( MapData[p.y/64][p.x/64]==0 ){
				p.x=p.oldx; //移動前の座標を代入
				p.y=p.oldy;
		}

		//マップ描画
		for(int y=0;y<CHIP_NUMBER_Y;y++){
			for(int x=0;x<CHIP_NUMBER_X;x++){
				if(MapData[y][x]==1){
					DrawGraph(32*(x-y), 17*(x+y), map,TRUE);
				}
			}
		}
		//プレイヤー描画
		DrawGraph((p.x-p.y)*32/64,(p.x+p.y)*20/64,player[p.img],TRUE);
	}

これで前みたいにでたらめな当たり判定にはなりませんでしたが、
添付画像のようにニマスずれが生じます。
プレイヤー描画の32/64、20/64の32、20の部分の数値を変えるとずれの位置が変わります。
なぜなんでしょう?
添付ファイル
ゲーム画面.png
ゲーム画面.png (9.94 KiB) 閲覧数: 953 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#34

投稿記事 by softya(ソフト屋) » 6年前

あれ? マップパーツの縦サイズ 34なんですか? 失礼!40だと思い込んで、それは見逃していました。
そうですね。こういう害を防ぐために定数化しましょうか。

#define MAP_PARTS_HSIZEX 32 /*マップパーツの横サイズ(半分)*/
#define MAP_PARTS_HSIZEY 17 /*マップパーツの縦サイズ(半分)*/
#define VTOP_PARTS_SIZEX 64 /*仮想トップビューのマップパーツの横サイズ*/
#define VTOP_PARTS_SIZEY 64 /*仮想トップビューのマップパーツの縦サイズ*/

こう使います。
DrawGraph(MAP_PARTS_HSIZEX*(x-y), MAP_PARTS_HSIZEY*(x+y), map,TRUE);

DrawGraph((p.x-p.y)*MAP_PARTS_HSIZEX/VTOP_PARTS_SIZEX,(p.x+p.y)*MAP_PARTS_HSIZEY/VTOP_PARTS_SIZEY,player[p.img],TRUE);

【追記】
補正が抜けてる!
aやらa+32が消えているのが問題ですね。
#define MAP_VIEW_OFFSET 32 /*式で出てきたaです*/

マップパーツは
DrawGraph(MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX*(x-y), MAP_PARTS_HSIZEY*(x+y), map,TRUE);

キャラは
DrawGraph((MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX)+(p.x-p.y)*MAP_PARTS_HSIZEX/VTOP_PARTS_SIZEX,(p.x+p.y)*MAP_PARTS_HSIZEY/VTOP_PARTS_SIZEY,player[p.img],TRUE);
となります。

【補足の補足】
元の式を無闇に変えないでください。意味があるんですから。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#35

投稿記事 by イマダニ » 6年前

定数ってやっぱ便利ですね。変えてみました。

コード:


#define MAP_PARTS_HSIZEX 32 /*マップパーツの横サイズ(半分)*/
#define MAP_PARTS_HSIZEY 17 /*マップパーツの縦サイズ(半分)*/

#define VTOP_PARTS_SIZEX 64 /*仮想トップビューのマップパーツの横サイズ*/
#define VTOP_PARTS_SIZEY 64 /*仮想トップビューのマップパーツの縦サイズ*/


//マップ描画
		for(int y=0;y<CHIP_NUMBER_Y;y++){
			for(int x=0;x<CHIP_NUMBER_X;x++){
				if(MapData[y][x]==1){
					DrawGraph(MAP_PARTS_HSIZEX*(x-y), MAP_PARTS_HSIZEY*(x+y), map,TRUE);
				}
			}
		}
		//プレイヤー描画
		DrawGraph((p.x-p.y)*MAP_PARTS_HSIZEX/VTOP_PARTS_SIZEX,(p.x+p.y)*MAP_PARTS_HSIZEY/VTOP_PARTS_SIZEY,player[p.img],TRUE);
	}

	DxLib_End();

	return 0;
今度は一マスずれてますね……

>>あれ? マップパーツの縦サイズ 34なんですか? 失礼!40だと思い込んで、それは見逃していました。

いやそうじゃないんです。誤解させまくってすいません!
チップ画像は64×40です。
ただ20/32だとチップが階段みたいになるので、17に調整したところ、
きれいに並んだのでそうしました。
貼っときますね。
ゲームに使用してるのはbmpなんですけど、bmp貼れないのでpngなってます。
添付ファイル
mapchip01.png
mapchip01.png (501 バイト) 閲覧数: 951 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#36

投稿記事 by softya(ソフト屋) » 6年前

あっともう一ついい忘れてました。
この変換は足元の座標に使うべきもなので、キャラクタの表示だとX座標はキャラクタのxサイズ/2を引いて欲しいのとy座標はキャラクタのyサイズを引いてください。
DrawGraph( (MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX)+(p.x-p.y)*MAP_PARTS_HSIZEX/VTOP_PARTS_SIZEX -キャラクタのxサイズ/2
,(p.x+p.y)*MAP_PARTS_HSIZEY/VTOP_PARTS_SIZEY - キャラクタのyサイズ
,player[p.img]
,TRUE);
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#37

投稿記事 by イマダニ » 6年前

MAP_VIEW_OFFSETってなんですか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#38

投稿記事 by softya(ソフト屋) » 6年前

MAP_VIEW_OFFSETってaのことですよ。
つまり、[0][0]のマップを画面の何処に表示するかx方向のオフセットです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#39

投稿記事 by イマダニ » 6年前

ああ、すいません!追記に気づいてませんでした。

コード:

//オフセット定数
#define MAP_VIEW_OFFSET 32

//マップ描画
for(int y=0;y<CHIP_NUMBER_Y;y++){
	for(int x=0;x<CHIP_NUMBER_X;x++){
		if(MapData[y][x]==1){
		   DrawGraph(MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX*(x-y), MAP_PARTS_HSIZEY*(x+y), map,TRUE);
		}
	}
}

//プレイヤー描画
DrawGraph((MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX)+(p.x-p.y)*MAP_PARTS_HSIZEX/VTOP_PARTS_SIZEX - CHAR_PARTS_SIZEX/2
				  ,(p.x+p.y)*MAP_PARTS_HSIZEY/VTOP_PARTS_SIZEY - CHAR_PARTS_SIZEY
				  ,player[p.img],TRUE);
	}
このように補正を追加してみたところ思い通りにうごきました。
これで当たり判定は大丈夫そうです。
ありがとうございます。そしてお疲れ様です。ほんとうに。
長かった……

次はスクロールですが、トップやサイドとやり方は変わらないのでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#40

投稿記事 by softya(ソフト屋) » 6年前

キャラクタのクォータビュー座標変換で画面の何処に位置しているか求める以外は、トップやサイドとやり方は変わらないと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#41

投稿記事 by イマダニ » 6年前

スクロールできました!

コード:

#include"DxLib.h"
#include"Key.h"

//画面の大きさ
#define SCREEN_WIDTH 640  /*画面の幅*/
#define SCREEN_HEIGHT 480 /*画面の高さ*/

//チップの枚数
#define CHIP_NUMBER_X 30 /*横の数*/
#define CHIP_NUMBER_Y 24 /*縦の数*/

#define MAP_PARTS_HSIZEX 32 /*マップパーツの横サイズ(半分)*/
#define MAP_PARTS_HSIZEY 16 /*マップパーツの縦サイズ(半分)*/

#define VTOP_PARTS_SIZEX 64 /*仮想トップビューのマップパーツの横サイズ*/
#define VTOP_PARTS_SIZEY 64 /*仮想トップビューのマップパーツの縦サイズ*/

#define CHAR_PARTS_SIZEX 64 /*キャラの横サイズ*/
#define CHAR_PARTS_SIZEY 48 /*キャラの縦サイズ*/

#define MAP_VIEW_OFFSET 32  /*[0][0]の位置*/


//プレイヤー構造体
typedef struct{
	bool walkflag;//歩きフラグ
	int img,cnt,muki;//画像、カウンタ、向き
	int x,y;         //座標
	int oldx,oldy;   //移動前の座標を記録する座標
	int draw_x,draw_y; //描画される位置座標
	int camera_x,camera_y; //カメラの座標
}PLAY;

//マップデータ
int MapData[ CHIP_NUMBER_Y ][ CHIP_NUMBER_X ] =
{
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,

	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,

	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);

	AllocConsole();
    freopen("CONOUT$", "w", stdout); //標準出力をコンソールにする
	//  printf( "これでprintfが使えます\n" );   //←お試し用

	//構造体宣言
	PLAY p;

	//画像変数
	int player[72]; /*プレイヤー*/
	int map;        /*マップチップ*/
	
	//画像の読み込み
	LoadDivGraph("img/player1.png",72,9,8,64,64,player);
	map    = LoadGraph("img/mapchip01.bmp");
	
	//構造体要素の初期化
	memset(&p,0,sizeof(PLAY));/*全部0に*/
	
	//プレイヤー座標の初期化
	p.x=560;
	p.y=560;

	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && updatekey()==0 ){

		//プレイヤー移動アニメーションのためのカウント
		p.cnt++;

		//座標を記録
		p.oldx=p.x;
		p.oldy=p.y;

		//キー入力判定

		
		if( checkkey(KEY_INPUT_LEFT)>0 && checkkey(KEY_INPUT_UP)>0  ){
			p.muki=5;	//左上
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_LEFT)>0 && checkkey(KEY_INPUT_DOWN)>0 ){
			p.muki=6;	//左下
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_RIGHT)>0 && checkkey(KEY_INPUT_UP)>0 ){
			p.muki=7;	//右上
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_RIGHT)>0 && checkkey(KEY_INPUT_DOWN)>0 ){
			p.muki=8;	//右下
			p.walkflag=true;
		
		
		}else if( checkkey(KEY_INPUT_LEFT)>0 ){
			p.muki=1;   //左向きで
			p.walkflag=true;  //フラグが建つよ
		}else if( checkkey(KEY_INPUT_RIGHT)>0 ){
			p.muki=2;	//右
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_UP)>0 ){
			p.muki=3;	//上
			p.walkflag=true;
		}else if( checkkey(KEY_INPUT_DOWN)>0 ){
			p.muki=4;   //下
			p.walkflag=true;
			
		}else{			//それ以外
			p.walkflag=false;  //フラグ建ってないよ
		}

		//歩きフラグの分岐
		if(p.walkflag==true){//フラグがたってる時
			if(p.muki==1){	//左へ
				p.x-=4;		//走る
				p.y+=4;     /*クォータの座標に変えたため、X座標だけ変動しても斜めに移動するため
							  y座標も変えた*/
				p.img=10+(p.cnt/5)%8;
			}if(p.muki==2){	//右へ
				p.x+=4;     //走る
				p.y-=4;
				p.img=19+(p.cnt/5)%8;//それのアニメーション
			}
			if(p.muki==3){ //上へ
				p.y-=6;
				p.x-=6;
				p.img=28+(p.cnt/5)%8;
			}if(p.muki==4){ //下へ
				p.y+=6;
				p.x+=6;
				p.img=1+(p.cnt/5)%8;
			}
			
			if(p.muki==5){	//左上
				p.x-=6;
				p.img=37+(p.cnt/5)%8;
			}if(p.muki==6){	//左下
				p.y+=6;
				p.img=55+(p.cnt/5)%8;
			}if(p.muki==7){	//右上
				p.y-=6;
				p.img=46+(p.cnt/5)%8;
			}if(p.muki==8){ //右下
				p.x+=6;
				p.img=64+(p.cnt/5)%8;
			}
			

		}if(p.walkflag==false){//フラグが建ってない時
			//それぞれの向きの立っている絵にする
			if(p.muki==1) p.img=9;  //左
			if(p.muki==2) p.img=18; //右
			if(p.muki==3) p.img=27; //上
			if(p.muki==4) p.img=0;  //下
			
			if(p.muki==5) p.img=36; //左上
			if(p.muki==6) p.img=54; //左下
			if(p.muki==7) p.img=45; //右上
			if(p.muki==8) p.img=63; //右下
			
		}

		//いけない所だったら
		if( MapData[p.y/64][p.x/64]==0 ){
				p.x=p.oldx; //移動前の座標を代入
				p.y=p.oldy;
		}

		//カメラ座標
		/*カメラのx座標 = プレイヤー座標(クォーター変化)- 画面の半分*/
		p.camera_x = ((MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX) + (p.x-p.y) * MAP_PARTS_HSIZEX/VTOP_PARTS_SIZEX - CHAR_PARTS_SIZEX/2) - SCREEN_WIDTH/2;
		p.camera_y = ((p.x+p.y)*MAP_PARTS_HSIZEY/VTOP_PARTS_SIZEY - CHAR_PARTS_SIZEY) - SCREEN_HEIGHT/2;

		//カメラ移動制御(x方向)
		if(p.camera_x < -1920) 
			p.camera_x = -1920;
		if(p.camera_x > ((CHIP_NUMBER_X*VTOP_PARTS_SIZEX)-SCREEN_WIDTH))
			p.camera_x = ((CHIP_NUMBER_X*VTOP_PARTS_SIZEX)-SCREEN_WIDTH);
		
		//カメラ移動制御(y方向)
		if(p.camera_y < -1536) 
			p.camera_y = -1536;
		if(p.camera_y > ((CHIP_NUMBER_Y*VTOP_PARTS_SIZEY)-SCREEN_HEIGHT))
			p.camera_y = ((CHIP_NUMBER_Y*VTOP_PARTS_SIZEY)-SCREEN_HEIGHT);

		//プレイヤー描画位置
		p.draw_x = ((MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX)+(p.x-p.y)*MAP_PARTS_HSIZEX/VTOP_PARTS_SIZEX - CHAR_PARTS_SIZEX/2) - p.camera_x;
		p.draw_y = ((p.x+p.y)*MAP_PARTS_HSIZEY/VTOP_PARTS_SIZEY - CHAR_PARTS_SIZEY) - p.camera_y;

		//マップ描画
		for(int y=0;y<CHIP_NUMBER_Y;y++){
			for(int x=0;x<CHIP_NUMBER_X;x++){
				if(MapData[y][x]==1){
					DrawGraph(MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX*(x-y)-p.camera_x, MAP_PARTS_HSIZEY*(x+y)-p.camera_y, map,TRUE);
				}
			}
		}
		//プレイヤー描画
		DrawGraph(p.draw_x,p.draw_y,player[p.img],TRUE);
	}

	DxLib_End();

	return 0;
}
どうでしょう?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#42

投稿記事 by softya(ソフト屋) » 6年前

自分でテストして問題は無かったのでしょうか?
こちらでは全ソースとデータがないので動作確認できません。
それとムダにコードが多いのは確かなので、配列などを駆使すると凄く短いコードに纏められると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#43

投稿記事 by イマダニ » 6年前

>>自分でテストして問題は無かったのでしょうか?

はい問題ないです。

コード:

//カメラ座標
/*カメラのx座標 = プレイヤー座標(クォーター変化)- 画面の半分*/
p.camera_x = ((MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX) + (p.x-p.y) * MAP_PARTS_HSIZEX/VTOP_PARTS_SIZEX /*- CHAR_PARTS_SIZEX/2*/) - SCREEN_WIDTH/2;
p.camera_y = ((p.x+p.y)*MAP_PARTS_HSIZEY/VTOP_PARTS_SIZEY/* - CHAR_PARTS_SIZEY*/) - SCREEN_HEIGHT/2;
このカメラ座標の部分に足元修正の計算を入れてたためカメラがキャラの座標からずれておりましたが、修正したので大丈夫です。

>>こちらでは全ソースとデータがないので動作確認できません。

ソフト屋さんさえよければ、プロジェクトファイルを渡しますよ。

>>それとムダにコードが多いのは確かなので、配列などを駆使すると凄く短いコードに纏められると思います。

配列かー、マップ描画の際とか、文字入力の際とか、LoadDivGraphなど、そういう要求されてる時にしか使わず、自主的に使うという発想はなかったです。
なので、いまいちどう使うかわからないんですが、
聞いてしまっては勉強にならないので、ちょっと自分ひとりでやってみます。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: クォーターの当たり判定とスクロール

#44

投稿記事 by softya(ソフト屋) » 6年前

ヒントはmukiを添え字に使い構造体配列を上手く使うですかね。
あとcheckkeyのところも配列化できます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

イマダニ
記事: 145
登録日時: 7年前

Re: クォーターの当たり判定とスクロール

#45

投稿記事 by イマダニ » 6年前

プライベートの関係で、少し放置気味になってしまいました。すいません……
スクロールと当たり判定が、汚いとはいえ実装できましたし、ひとまずこれで解決とします。
softyaさん、図を用いたわかりやすい説明、ありがとうございます!

本当に助かりました。マジで。

ちょっと忙しくて手つかずなんですが、softyaさんのヒントをもとに改良を行ってみます。
それでなにかあったり、また別の疑問があったらまたここを利用させていただきます。
今回もありがとうございました!

閉鎖

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