44783


ピタゴラスの定理の関係で斜めに移動したときに多く移動してしうのでそれを上下に移動したときと同じ移動量の[5]にしたいです、上下左右[5]ですので斜め移動したときの移動量も[5]にしたのですがどうすればいいのでしょうか、数学の知識がないため実装に困ってす。参考書でなんとなく理解したのですがプログラムを組み方？を教えてほしいです。  
数学が苦手なため詳細にお願いしたいです。

[code]

    #include "DxLib.h"
    
    int Key[256];
    int gpUpdateKey() {
        char tmpKey[256];
        GetHitKeyStateAll(tmpKey);
    
        for (int i = 0; i < 256; i++) {
            if (tmpKey[i] != 0) {
                Key[i]++;
            }
            else {
                Key[i] = 0;
            }
        }
        return 0;
    }
    
    // プログラムは WinMain から始まります
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK);//画面モード
    
        int x = 320; int y = 240;
        int Handle = LoadGraph("mario.png");
    
        while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && gpUpdateKey() == 0)
        {
            if (Key[KEY_INPUT_RIGHT] >= 1) {
                x+=5.0;
            }
    
            if (Key[KEY_INPUT_LEFT] >= 1) {
                x-=5.0;
            }
    
            if (Key[KEY_INPUT_UP] >= 1) {
                y-=5.0;
            }
    
            if (Key[KEY_INPUT_DOWN] >= 1) {
                y+=5.0;
            }
    
            DrawRotaGraph(x,y,1.0,0.0,Handle,TRUE);
        }
    
        DxLib_End();        // ＤＸライブラリ使用の終了処理
        return 0;        // ソフトの終了 
    }
    
[/code]


CC BY-SA 4.0
2018-06-15T09:06:39.583
44781
2018-06-16T03:29:17.030
2018-06-15T12:45:40.443
question
c++
「DXライブラリ」斜め移動も上下移動と同じ速度にしたい。


(A)「→」キーだけが押された場合は、x=5、y=0 で全体の移動距離は 5 となります。  
(B)「↑」キーと「→」キーが同時に押された場合にはx=5 Y=5 になってしまい、上より大きな移動距離(=およそ7)となってしまう。

そこで、(B)の場合でも移動距離を「右上方向に5の移動」としたいという解釈とさせてもらいます。  
まず、xもyもint(整数)なので、ぴったりの値にすることは原理的に不可能であることを断っておきます。  
次に、距離の公式が理解できていれば、ありえる値は3か4であることが予測できます。

(1) 点(0,0)から点(5,5)までの距離は sqrt( x * x + y * y) ですので √5*5+5*5
でおよそ7.0710・・・という数値になります。  
(2) これを5に近い値にしたいのですが、xもyもint(整数)ですので小数点付きの値が使えません。可能性があるのは 4 又は 3 となります。  
(3) 4にした場合は、先の公式により移動距離はおよそ5.65。  
(4) 3の場合の移動距離は4.24となります。  
(5) x、y を同値にしなくてよはならば、xを3 yを4にすると、移動距離は5になります。  
(6) どれを使うかは、実際に画面上で違和感のない方法を採用するのが良いかもしれません。

(追加)今の分岐方法だと、それぞれのキーの押下状態毎にxとyが加算されていくので、「あるキーの組み合わせが同時に押された場合」と「単独で押された場合」について、干渉しないように分岐して各々xとyの値を設定した方が簡便だと考えられます。  
つまり、

[code]

    if( ↑だけ押された){
      y -= 5;
    }
    else if( →だけ押された){
      x += 5;
    }
    else if( ←だけ押された){
      x -= 5;
    }
    else if( ↓だけ押された){
      y += 5;
    }
    else if( ↑と→が同時におされた){
      x += 4; y -= 4; // 4を採用した場合
    }
    else if( ・・・・
    
[/code]

こんな感じですかね。


CC BY-SA 4.0
2018-06-15T10:02:41.540
44782
2018-06-15T10:02:41.540
3793
44781
answer


まさに質問を解決している[サイト](https://bituse.info/game/19)がありました。

斜め移動で移動する時のx,y座標は`(移動量) * 1 / √2`で求められます。  
そのため、斜め移動の場合は移動量に`1/√2=0.7071067...≒0.71`を掛けて座標を求めるよう修正してください。

[code]

    while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && gpUpdateKey() == 0)
    {
        float rate = 1.0f;
        //移動量の倍率係数
        if (Key[KEY_INPUT_LEFT] > 0 || Key[KEY_INPUT_RIGHT] > 0) {
            if (Key[KEY_INPUT_UP] > 0 || Key[KEY_INPUT_DOWN] > 0) {
                //斜めの場合は、移動量の倍率係数を０．７１に設定
                rate = 0.71f;
            }
        }
    
        //実際のx,y座標の移動量
        int move = (int)5 * rate;
    
        if (Key[KEY_INPUT_LEFT] > 0) {
            x -= move;
        }
        if (Key[KEY_INPUT_RIGHT] > 0) {
            x += move;
        }
        if (Key[KEY_INPUT_UP] > 0) {
            y -= move;
        }
        if (Key[KEY_INPUT_DOWN] > 0) {
            y += move;
        }
        DrawRotaGraph(x, y, 1.0, 0.0, Handle, TRUE);
    }
    
[/code]


CC BY-SA 4.0
2018-06-15T10:13:00.393
44783
2018-06-16T03:29:17.030
2018-06-16T03:29:17.030
9820
9820
44781
answer