ページ 1 / 1
8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月24日(月) 18:30
by Chalaza
斜め視点クォータービューのRPGでのキャラクターと地形の当たり判定についてなのですが、
ぴったり1マスづつしか動けないのならマップチップ配列で位置を計算するやり方でできたのですが、
プレイヤーが8方向自由に動けて、マップの微妙な位置(マスの間)にも止まれるようになっている場合でも
配列で計算して通れるか通れないかを決められるのでしょうか?
プレイヤーの当たり判定(ひし形)とマップチップ配列の当たり判定(ひし型)を使って
マップチップが0の地形しか歩けないようにしたいのですが、配列を使わずに菱形と菱形の接触を確認する方法があったりするのでしょうか?
Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月24日(月) 19:46
by softya(ソフト屋)
疑問ですが表示は菱形で良いとしても、マップやマップの当たり判定も菱形でないとマズイのでしょうか?
私の経験からすると四角形のままで出来ると思うのですが。
Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月24日(月) 21:03
by Chalaza
座標の計算用マップチップ配列と表示用マップチップ配列に分けてみたのですが、
この場合計算用マップチップはマス目が正方形で、表示用は菱形なので、移動方向が45度回転していますよね。
ということは計算用マップチップでキャラ座標を上に動かしたら表示座標では左上に動かすというような形で良いのでしょうか?
これだと表示座標の菱形は横に長いので計算用座標の斜め移動がルートになるので座標をdoubleとかにしなければいけませんかね。
Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月24日(月) 21:22
by softya(ソフト屋)
>ということは計算用マップチップでキャラ座標を上に動かしたら表示座標では左上に動かすというような形で良いのでしょうか?
それで良いと思います。
>これだと表示座標の菱形は横に長いので計算用座標の斜め移動がルートになるので座標をdoubleとかにしなければいけませんかね。
マップ上の仮想の座標単位と表示用の座標単位が一対一対応である必要もないと思います。
なのでマップ上の仮想の座標単位はintで√2を掛け算して表示用の座標単位のdouble値を求めれば良いんじゃないでしょうか?
Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月24日(月) 22:42
by Chalaza
まずは試しに表示座標も計算座標も全方向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マス分の大きさをどう組み込めば良いでしょうか?
Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月24日(月) 22:47
by softya(ソフト屋)
マップチップ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) //キャラの右下に障害物
Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月25日(火) 18:49
by Chalaza
作っている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;
}
}
Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月25日(火) 22:12
by softya(ソフト屋)
表示に関しては座標を加算・減算で計算する必要は無いと思います。
表示座標をマップ計算用座標を元に計算できますのでマップ計算用座標から毎回計算してください。
こうすれば、double型の計算誤差の累積を逃れる事ができます。
で表示座標の計算ですが、マップチップの中央と中央を結ぶ線の座標は求められませんか?
これを48等分して使うと現在位置の座標として使えるはずです。
Chalazaさん、クォーターのイメージが分からないのですが、マップパーツの辺は45度の角度ではないのでしょうか?
Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月25日(火) 22:36
by Chalaza
毎時計算して表示するんですね。
そういうことなら実はもう式はできてるんです。
クォータービューのマップを表示する位置は、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の倍数の位置に動かすという感じでよろしいでしょうか?
Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月25日(火) 22:43
by softya(ソフト屋)
48pix後に刺さっているなら移動しない方が簡単だと思います。
つまり、移動開始時に先のマップチップを調べて移動できなければ移動前に移動をキャンセルします。
Re: 8方向自由に動くプレイヤーと菱形地形の当たり判定
Posted: 2011年10月26日(水) 19:44
by Chalaza
刺さらないようにうまくできました。
応用して、ついでに斜めの障害物に縦にぶつかると自動的に斜めに移動する仕組みも完成しました。
ありがとうございました。解決です。