ページ 1 / 1
2Dでの座標移動について質問です
Posted: 2013年5月24日(金) 02:03
by アップルミスト
コード:
typedef struct
{
double x,y;
int move1;
double hp;
int shift;
}BODY_PLAYER_t;
BODY_PLAYER_t Player;
void playermove()
{
if(Key[KEY_INPUT_UP]==1)
{
Player.move1=Player.move1*3;
}
if(Key[KEY_INPUT_RIGHT]==1)
{
Player.move1=Player.move1*5;
}
if(Key[KEY_INPUT_LEFT]==1)
{
Player.move1=Player.move1*7;
}
if(Key[KEY_INPUT_DOWN]==1)
{
Player.move1=Player.move1*11;
}
if(Key[KEY_INPUT_LSHIFT]==1)
{
Player.move1=Player.move1*13;
Player.shift=1;
}
//判定
if(Player.move1==3)
{
if(Player.y>0)
Player.y-=4.0f;
}
if(Player.move1==3*5)
{
if(Player.x<630)
Player.x+=2.8f;
if(Player.y>0)
Player.y-=2.8f;
}
if(Player.move1==3*7)
{
if(Player.x>10)
Player.x-=2.8f;
if(Player.y>0)
Player.y-=2.8f;
}
if(Player.move1==7)
{
if(Player.x>10)
Player.x-=4.0f;
}
if(Player.move1==5)
{
if(Player.x<630)
Player.x+=4.0f;
}
if(Player.move1==11)
{
if(Player.y<470)
Player.y+=4.0f;
}
if(Player.move1==7*11)
{
if(Player.x>10)
Player.x-=2.8f;
if(Player.y<470)
Player.y+=2.8f;
}
if(Player.move1==5*11)
{
if(Player.x<630)
Player.x+=2.8f;
if(Player.y<470)
Player.y+=2.8f;
}
//低速
if(Player.move1==3*13)
{
if(Player.y>0)
Player.y-=2.0f;
}
if(Player.move1==3*5*13)
{
if(Player.x<630)
Player.x+=1.4f;
if(Player.y>0)
Player.y-=1.4f;
}
if(Player.move1==3*7*13)
{
if(Player.x>10)
Player.x-=1.4f;
if(Player.y>0)
Player.y-=1.4f;
}
if(Player.move1==7*13)
{
if(Player.x>10)
Player.x-=2.0f;
}
if(Player.move1==5*13)
{
if(Player.x<630)
Player.x+=2.0f;
}
if(Player.move1==11*13)
{
if(Player.y<470)
Player.y+=2.0f;
}
if(Player.move1==7*11)
{
if(Player.x>10)
Player.x-=1.4f;
if(Player.y<470)
Player.y+=1.4f;
}
if(Player.move1==5*11*13)
{
if(Player.x<630)
Player.x+=1.4f;
if(Player.y<470)
Player.y+=1.4f;
}
//低速
Player.move1=1;
}
というふうに場合分けをして移動制御を試みたのですが、移動スピードが
左下>左上>右上>右下
となってしまいます。
右にいくときはx座標のプラスが足りない気がします。
どこが間違っているのかご教授ねがいたいです。
Re: 2Dでの座標移動について質問です
Posted: 2013年5月24日(金) 02:06
by アップルミスト
書き忘れましたが、
Player.move1=1;
と最初にやってあります。
Re: 2Dでの座標移動について質問です
Posted: 2013年5月24日(金) 02:15
by アップルミスト
なんどもごめんなさい
開発環境書き忘れました
Windows Vista
Microsoft C++
DXライブラリ
です
よろしくお願いします
Re: 2Dでの座標移動について質問です
Posted: 2013年5月24日(金) 03:20
by びぎなぁ
このような場合はトリガーを実装し、変数を画面に出力するのが早期解決の手段の一つです。
トリガーならば、その方向に動いた場合一回分の処理を確認できますからね。
で、この問題の原因ですが
120行目にも同じ条件があります
コード:
if(Player.move1==7*11)
{
if(Player.x>10)
Player.x-=1.4f;
if(Player.y<470)
Player.y+=1.4f;
}
左下が速いのは、おそらくこれが原因なんじゃないかと
Re: 2Dでの座標移動について質問です
Posted: 2013年5月24日(金) 03:50
by びぎなぁ
もう一つ。
右斜め移動より左斜め移動のほうが若干早く感じるのは
初期位置が(100,100)であった場合、
右の場合は(102,97),(102,102)になりますが、左の場合は(97,97),(97,102)になります。
実質の移動距離は右下√8、右上√13、左上√13、左上√18です
これは、dobuleを画面のドットに最適化するためにintにキャストしているのが原因だと思います。
Re: 2Dでの座標移動について質問です
Posted: 2013年5月24日(金) 04:01
by びぎなぁ
すいません、左上が二つありますw
左下√13ですね。
長い目で見ると同じ距離を移動するはずですので、気にならないならそのままでもいいのでは?
Re: 2Dでの座標移動について質問です
Posted: 2013年5月25日(土) 03:34
by アップルミスト
ご指摘ありがとうございます。
とりあえず以下のように変更してみました。
コード:
void playermove()
{
if(Key[KEY_INPUT_UP]==1)
{
Player.move1=Player.move1*3;
}
if(Key[KEY_INPUT_RIGHT]==1)
{
Player.move1=Player.move1*5;
}
if(Key[KEY_INPUT_LEFT]==1)
{
Player.move1=Player.move1*7;
}
if(Key[KEY_INPUT_DOWN]==1)
{
Player.move1=Player.move1*11;
}
if(Key[KEY_INPUT_LSHIFT]==1)
{
Player.move1=Player.move1*13;
Player.shift=1;
}
//判定
if(Player.move1==3)
{
if(Player.y>0)
Player.y-=4.0f;
}
if(Player.move1==15)
{
if(Player.x<630)
Player.x+=2.8f;
if(Player.y>0)
Player.y-=2.8f;
}
if(Player.move1==21)
{
if(Player.x>10)
Player.x-=2.8f;
if(Player.y>0)
Player.y-=2.8f;
}
if(Player.move1==7)
{
if(Player.x>10)
Player.x-=4.0f;
}
if(Player.move1==5)
{
if(Player.x<630)
Player.x+=4.0f;
}
if(Player.move1==11)
{
if(Player.y<470)
Player.y+=4.0f;
}
if(Player.move1==77)
{
if(Player.x>10)
Player.x-=2.8f;
if(Player.y<470)
Player.y+=2.8f;
}
if(Player.move1==55)
{
if(Player.x<630)
Player.x+=2.8f;
if(Player.y<470)
Player.y+=2.8f;
}
//低速
if(Player.move1==39)
{
if(Player.y>0)
Player.y-=2.0f;
}
if(Player.move1==195)
{
if(Player.x<630)
Player.x+=1.4f;
if(Player.y>0)
Player.y-=1.4f;
}
if(Player.move1==273)
{
if(Player.x>10)
Player.x-=1.4f;
if(Player.y>0)
Player.y-=1.4f;
}
if(Player.move1==91)
{
if(Player.x>10)
Player.x-=2.0f;
}
if(Player.move1==65)
{
if(Player.x<630)
Player.x+=2.0f;
}
if(Player.move1==143)
{
if(Player.y<470)
Player.y+=2.0f;
}
if(Player.move1==1001)
{
if(Player.x>10)
Player.x-=1.4f;
if(Player.y<470)
Player.y+=1.4f;
}
if(Player.move1==715)
{
if(Player.x<630)
Player.x+=1.4f;
if(Player.y<470)
Player.y+=1.4f;
}
//低速
Player.move1=1;
if(Key[KEY_INPUT_A]==1)
{
Player.hp=0;
}
if(Key[KEY_INPUT_Y]==1)
{
gamestate=2;
Boss.flag=5;
}
if(Key[KEY_INPUT_T]==1)
{
counter=0;
gamestate=3;
}
if(Key[KEY_INPUT_V]==1)
{
gamestate=5;
Boss2.counter=0;
}
if(Key[KEY_INPUT_O]==1)
{
DebugBreak();
}
}
重複はないはずですが、右上への移動のx座標移動が1/2されているようにしか思えません。
左下への移動は逆に3/2されているように見えます。
右下への移動はやはり別の方向とくらべて明らかに遅いです。
このやり方では問題があるのでしょうか?
Re: 2Dでの座標移動について質問です
Posted: 2013年5月25日(土) 17:53
by nil
各方向への移動を場合分けして行なっているようですが、
非常に冗長な上、バグが生まれやすいです。
自分であればこう書く、というのを載せておきますので、
良ければ目を通してください。
コード:
void playermove(){
// 変数定義
int moveX = 0;
int moveY = 0;
double speed = 任意の値;
// 入力の取得
if( Key[ KEY_INPUT_LEFT ] ) moveX -= 1;
if( Key[ KEY_INPUT_RIGHT ] ) moveX += 1;
if( Key[ KEY_INPUT_UP ] ) moveY -= 1;
if( Key[ KEY_INPUT_DOWN ] ) moveY += 1;
if( Key[ KEY_INPUT_LSHIFT] ) Player.shift = 1;
// 低速時
if( Player.shift ){
speed = 任意の値;
}
// 斜め移動時
if( moveX && moveY ){
speed /= 1.41421356237; // √2などの数値は予め定数として定義しておいたほうが良いです。
}
Player.x += moveX * speed;
Player.y += moveY * speed;
// 画面外に出た時 -- この10,470,630などの数値もマジックナンバーではなく予め定数を定義しておきましょう
if ( Player.x < 10 ) Player.x = 10;
else if( Player.x > 630 ) Player.x = 630;
if ( Player.y < 10 ) Player.y = 10;
else if( Player.y > 470 ) Player.y = 470;
// 以下省略
}
コードなどでわからないところや間違っているところがあればいってください。
Re: 2Dでの座標移動について質問です
Posted: 2013年5月26日(日) 13:01
by アップルミスト
やはりこのやり方はだめでしたか・・・
わざわざわかりやすいものを書いていただいて、ありがとうございます。
参考にさせていただきます。
Re: 2Dでの座標移動について質問です
Posted: 2013年5月27日(月) 01:22
by アップルミスト
解決にしてしまった後で申し訳ないのですが、涼雅さんのを参考にして組みなおしたところ、やはり右上への移動のx座標が1/2しか進まず、左下が3/2進んでしまいます。
Player.xで検索をかけて、間違って記述したかもしれないと探しましたが、ここ以外でPlayerの座標に関与しているところはなさそうでした。
リビルドを一応してみましたが、状況が変わりません。
こういうときはどうすればいいですか?
これはもうあきらめるしかないのでしょうか。
Re: 2Dでの座標移動について質問です
Posted: 2013年5月27日(月) 17:57
by nil
こちらの方で省略したコードを書いてみましたが正常な動作を確認致しました。
► スポイラーを表示
コード:
#include <DxLib.h>
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ){
ChangeWindowMode( true );
if( DxLib_Init() != 0 || SetDrawScreen( DX_SCREEN_BACK ) )
return -1;
struct{
double x, y;
double speed;
} player = { 320.0, 240.0, 3.0 };
while( ProcessMessage() == 0 ){
ClearDrawScreen();
clsDx();
// 更新
{
int moveX = 0;
int moveY = 0;
double speed = player.speed;
if( CheckHitKey( KEY_INPUT_LEFT ) ) moveX--;
if( CheckHitKey( KEY_INPUT_RIGHT ) ) moveX++;
if( CheckHitKey( KEY_INPUT_UP ) ) moveY--;
if( CheckHitKey( KEY_INPUT_DOWN ) ) moveY++;
if( CheckHitKey( KEY_INPUT_LSHIFT ) ) speed /= 3;
if( moveX && moveY ) speed /= 1.41421356237;
player.x += moveX * speed;
player.y += moveY * speed;
}
// 描画
{
DrawCircle( (int)player.x, (int)player.y, 5.0, GetColor(255,255,255), true );
printfDx( "x:%f\ny:%f", player.x, player.y );
}
ScreenFlip();
}
DxLib_End();
return 0;
}
>こういうときはどうすればいいですか?
>これはもうあきらめるしかないのでしょうか。
諦める必要はありません。
プログラムが思った通りの動作をしないときには(ほとんどの場合)コードに何らかの原因があります。
なにがしさんの書かれたコードを貼り付けていただければ何らかの原因を見つけることができるかもしれません。
Re: 2Dでの座標移動について質問です
Posted: 2013年5月27日(月) 21:46
by アップルミスト
私も別に作ったもので昨日テストしてみたらちゃんと動作しました。
書き間違いではないですね。
いささか全体のソースが長いので全部張り付けるわけにはいきませんよね・・・
後でどこかにあげるので気が向いたら見て頂ければ幸いです。
雑に書いてしまっています。申し訳ありません。
Re: 2Dでの座標移動について質問です
Posted: 2013年5月28日(火) 23:33
by アップルミスト
Re: 2Dでの座標移動について質問です
Posted: 2013年5月28日(火) 23:59
by nil
始めに掲示頂いたコードでは
BODY_PLAYER_t::x及びyはdouble型となっていますが、
アップロードされたコードではint型になっています。
Re: 2Dでの座標移動について質問です
Posted: 2013年5月29日(水) 00:56
by アップルミスト
本当だ・・・
こんなことですいません><
いちいち確認してくださってありがとうございます。
もう1つだけ質問させてください。
これを直したところ、斜め移動がガクガクしながら動くようになってしまいましたが、これはどうすれば解消できますか?
Re: 2Dでの座標移動について質問です
Posted: 2013年5月29日(水) 21:23
by nil
Re: 2Dでの座標移動について質問です
Posted: 2013年5月29日(水) 23:56
by アップルミスト
なるほど。
涼雅さん、ありがとうございました。