8方向自由に動くプレイヤーと菱形地形の当たり判定

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Chalaza

8方向自由に動くプレイヤーと菱形地形の当たり判定

#1

投稿記事 by Chalaza » 14年前

斜め視点クォータービューのRPGでのキャラクターと地形の当たり判定についてなのですが、
ぴったり1マスづつしか動けないのならマップチップ配列で位置を計算するやり方でできたのですが、
プレイヤーが8方向自由に動けて、マップの微妙な位置(マスの間)にも止まれるようになっている場合でも
配列で計算して通れるか通れないかを決められるのでしょうか?
プレイヤーの当たり判定(ひし形)とマップチップ配列の当たり判定(ひし型)を使って
マップチップが0の地形しか歩けないようにしたいのですが、配列を使わずに菱形と菱形の接触を確認する方法があったりするのでしょうか?

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

Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定

#2

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

疑問ですが表示は菱形で良いとしても、マップやマップの当たり判定も菱形でないとマズイのでしょうか?
私の経験からすると四角形のままで出来ると思うのですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Chalaza

Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定

#3

投稿記事 by Chalaza » 14年前

座標の計算用マップチップ配列と表示用マップチップ配列に分けてみたのですが、
この場合計算用マップチップはマス目が正方形で、表示用は菱形なので、移動方向が45度回転していますよね。
ということは計算用マップチップでキャラ座標を上に動かしたら表示座標では左上に動かすというような形で良いのでしょうか?
これだと表示座標の菱形は横に長いので計算用座標の斜め移動がルートになるので座標をdoubleとかにしなければいけませんかね。

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

Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定

#4

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

>ということは計算用マップチップでキャラ座標を上に動かしたら表示座標では左上に動かすというような形で良いのでしょうか?

それで良いと思います。

>これだと表示座標の菱形は横に長いので計算用座標の斜め移動がルートになるので座標をdoubleとかにしなければいけませんかね。

マップ上の仮想の座標単位と表示用の座標単位が一対一対応である必要もないと思います。
なのでマップ上の仮想の座標単位はintで√2を掛け算して表示用の座標単位のdouble値を求めれば良いんじゃないでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Chalaza

Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定

#5

投稿記事 by Chalaza » 14年前

まずは試しに表示座標も計算座標も全方向1づつ動かせるようにしてみて、計算座標と斜めに表示座標を動かすようにしてみたのですが、
ここから計算座標のマップチップとキャラの当たり判定の式を作るところなのですが…
計算用座標がMapHit[MAP_HEIGHT][MAP_WIDTH](縦横10)だとすると、キャラの右に障害物がある場合を表すには、

コード:

if( InputCount->RIGHT > 0 &&  //右を押している間
		MapHit[(FPlayer->HitY+12)][(FPlayer->HitX+36)]==1 && //キャラの右上に障害物
		MapHit[(FPlayer->HitY+36)][(FPlayer->HitX+36)]==1)  //キャラの右下に障害物
 
このままでは駄目なのですが、計算用マップチップの1マス分の大きさをどう組み込めば良いでしょうか?

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

Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定

#6

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

マップチップ1つ辺り計算用座標では上下ともに32仮想単位離れているとしてはどうでしょうか?
移動は、その仮想単位で行います。

コード:

if( InputCount->RIGHT > 0 &&  //右を押している間
        MapHit[(FPlayer->HitY+12)/32][(FPlayer->HitX+36)/32]==1 && //キャラの右上に障害物
        MapHit[(FPlayer->HitY+36)/32][(FPlayer->HitX+36)/32]==1)  //キャラの右下に障害物
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Chalaza

Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定

#7

投稿記事 by Chalaza » 14年前

作っているRPGが48pix単位なので48にして、使わせてもらったところ当たり判定は問題なさそうなのですが、
計算座標も画像で表示してみたところ、斜め移動の式がうまくいっていませんでした。
表示キャラが右上に歩く場合に、表示座標のXを+2、Yを-1してうまくマップの1列を歩けるようにしているのですが、
その場合計算用のキャラ座標は真上に動くときに、速さは(2*2+1*1)の平方根のルート5だと思うんですが、
それを式にしてみたところ、半分くらいの距離しか計算座標が動いてくれません。
(2*2+1*1)をいったん、変数Rootに代入してからsqrt( Root )で平方根を出しています。

コード:

// 動きを計算する
void FPlayer_Calc( FPlayer_t *FPlayer , InputCount_t *InputCount ){
	double sqrt( double x );
	int Root;

	if( InputCount->UP > 0 && InputCount->RIGHT > 0 ){	//右上に歩く
		FPlayer->Muki=1;
		FPlayer->X+=2;
		FPlayer->Y-=1;
		Root = (2*2+1*1);	//計算座標
		FPlayer->HitY -= sqrt( Root );
		WalkCount++;
		FPlayer->Image = FPlayerImage[(WalkCount%32)/8+16];
	}else if( InputCount->UP > 0 && InputCount->LEFT > 0 ){	//左上に歩く
		FPlayer->Muki=7;
		FPlayer->X-=2;
		FPlayer->Y-=1;
		Root = (2*2+1*1);	//計算座標
		FPlayer->HitX -= sqrt( Root );
		WalkCount++;
		FPlayer->Image = FPlayerImage[(WalkCount%32)/8+20];
	}else if( InputCount->DOWN > 0 && InputCount->RIGHT > 0 ){	//右下に歩く
		FPlayer->Muki=3;
		FPlayer->X+=2;
		FPlayer->Y+=1;
		Root = (2*2+1*1);	//計算座標
		FPlayer->HitX += sqrt( Root );
		WalkCount++;
		FPlayer->Image = FPlayerImage[(WalkCount%32)/8+24];
	}else if( InputCount->DOWN > 0 && InputCount->LEFT > 0 ){	//左下に歩く
		FPlayer->Muki=5;
		FPlayer->X-=2;
		FPlayer->Y+=1;
		WalkCount++;
		Root = (2*2+1*1);	//計算座標
		FPlayer->HitY += sqrt( Root );
		FPlayer->Image = FPlayerImage[(WalkCount%32)/8+28];	
	}else if( InputCount->UP > 0 ){	//上に歩く
		FPlayer->Muki=0;
		WalkCount++;
		FPlayer->Y-=1;
		FPlayer->HitY-=2;	//計算座標
		FPlayer->HitX-=2;	//計算座標
		FPlayer->Image = FPlayerImage[(WalkCount%32)/8];
	}else if( InputCount->DOWN > 0 ){	//下に歩く
		FPlayer->Muki=4;
		WalkCount++;
		FPlayer->Y+=1;
		FPlayer->HitY+=2;	//計算座標
		FPlayer->HitX+=2;	//計算座標
		FPlayer->Image = FPlayerImage[(WalkCount%32)/8+4];
	}else if( InputCount->RIGHT > 0 &&	//右を押している間
        IramudukiHit[((int)FPlayer->HitY+12)/48][((int)FPlayer->HitX+36)/48]==0 &&	//キャラの右上に障害物
        IramudukiHit[((int)FPlayer->HitY+36)/48][((int)FPlayer->HitX+36)/48]==0){	//キャラの右下に障害物 
			//右に歩く
		FPlayer->Muki=2;
		WalkCount++;
		FPlayer->X+=2;
		FPlayer->HitY-=2;	//計算座標
		FPlayer->HitX+=2;	//計算座標
		FPlayer->Image = FPlayerImage[(WalkCount%32)/8+8];
	}else if( InputCount->LEFT > 0 ){	//左に歩く
		FPlayer->Muki=6;
		WalkCount++;
		FPlayer->X-=2;
		FPlayer->HitY+=2;	//計算座標
		FPlayer->HitX-=2;	//計算座標
		FPlayer->Image = FPlayerImage[(WalkCount%32)/8+12];
	}else if(FPlayer->Muki==0){
		FPlayer->Image = FPlayerImage[0];
		WalkCount=0;
	}else if(FPlayer->Muki==1){
		FPlayer->Image = FPlayerImage[16];
		WalkCount=0;
	}else if(FPlayer->Muki==2){
		FPlayer->Image = FPlayerImage[8];
		WalkCount=0;
	}else if(FPlayer->Muki==3){
		FPlayer->Image = FPlayerImage[24];
		WalkCount=0;
	}else if(FPlayer->Muki==4){
		FPlayer->Image = FPlayerImage[4];
		WalkCount=0;
	}else if(FPlayer->Muki==5){
		FPlayer->Image = FPlayerImage[28];
		WalkCount=0;
	}else if(FPlayer->Muki==6){
		FPlayer->Image = FPlayerImage[12];
		WalkCount=0;
	}else if(FPlayer->Muki==7){
		FPlayer->Image = FPlayerImage[20];
		WalkCount=0;
	}
	
}

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

Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定

#8

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

表示に関しては座標を加算・減算で計算する必要は無いと思います。
表示座標をマップ計算用座標を元に計算できますのでマップ計算用座標から毎回計算してください。
こうすれば、double型の計算誤差の累積を逃れる事ができます。

で表示座標の計算ですが、マップチップの中央と中央を結ぶ線の座標は求められませんか?
これを48等分して使うと現在位置の座標として使えるはずです。

Chalazaさん、クォーターのイメージが分からないのですが、マップパーツの辺は45度の角度ではないのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Chalaza

Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定

#9

投稿記事 by Chalaza » 14年前

毎時計算して表示するんですね。
そういうことなら実はもう式はできてるんです。
クォータービューのマップを表示する位置は、x,yをマップチップ座標として、

コード:

X=24*12+((12-y)*(48/2)+(x*24)-24);
Y=12*12+((x+y)*12);
これできれいにマップも障害物も並べられました。だからキャラの表示座標は、48pix単位の計算座標XとYをを48で割って、
その座標数値を上の式に入れたら綺麗に同じように動いてくれました。

コード:

FPlayer->X= 24*12+((12-(FPlayer->HitY)/48)*(48/2)+((FPlayer->HitX)/48*24)-24);
FPlayer->Y= 12*12+(((FPlayer->HitX)/48+(FPlayer->HitY)/48)*12);
これで計算座標と表示座標の同期はできたわけなのですが、このままだと位置補正をしていないので障害物にめしこんでしまいます。
位置補正は、プレイヤーの座標がマップチップの通れない場所に入ったら、一番近い48pixの倍数の位置に動かすという感じでよろしいでしょうか?

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

Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定

#10

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

48pix後に刺さっているなら移動しない方が簡単だと思います。
つまり、移動開始時に先のマップチップを調べて移動できなければ移動前に移動をキャンセルします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Chalaza

Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定

#11

投稿記事 by Chalaza » 14年前

刺さらないようにうまくできました。
応用して、ついでに斜めの障害物に縦にぶつかると自動的に斜めに移動する仕組みも完成しました。
ありがとうございました。解決です。

閉鎖

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