1

私は小惑星のクローンを作ろうとしていますが、これまでのところ、自分の船を飛ばすことができました. ただし、速度は FPS にも依存します。そのため、制御変数に deltaTime (正しく収集した場合のフレーム間の時間) を乗算する必要があることを読んだことを軽減するために。しかし、それを実行しようとすると、船は動きませんでした。暗黙の 0 への丸め (int への変換?) が原因であると考えましたが、警告は発行されません。私は何を間違っていますか?

コードは次のようになります。

sf::Vector2f newPosition(0,0);
sf::Vector2f velocity(0,0);
float acceleration = 3.0f;
float angle = 0;
float angularVelocity = 5;
float velDecay = 0.99f;


sf::Clock deltaClock;

window.setFramerateLimit(60);
while (window.isOpen())
{
    sf::Time deltaTime = deltaClock.restart();
    sf::Event event;
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed || ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
            window.close();
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
    {
        if(velocity.x < 10)velocity.x += acceleration * deltaTime.asSeconds();
        if(velocity.y < 10)velocity.y += acceleration * deltaTime.asSeconds();
        angle = player.getRotation() - 90;
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
    {
        if(velocity.x > 0)velocity.x -= acceleration * deltaTime.asSeconds();
        else velocity.x = 0;
        if(velocity.y > 0)velocity.y -= acceleration * deltaTime.asSeconds();
        else velocity.y = 0;
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
    {
        player.rotate(-angularVelocity);
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
    {
        player.rotate(angularVelocity);
    }

    newPosition.x = player.getPosition().x + (velocity.x * cos(angle * (M_PI / 180.0))) * deltaTime.asSeconds();
    newPosition.y = player.getPosition().y + (velocity.y * sin(angle * (M_PI / 180.0))) * deltaTime.asSeconds();    
    player.setPosition(newPosition);

    velocity.x *= velDecay;
    velocity.y *= velDecay;

    window.clear();
    window.draw(background);
    window.draw(player);
    window.draw(debugText);
    window.display();
}
4

1 に答える 1

4

コードを実行できないため、100% 確実とは言えませんが、次のコードは正しくないようです。

速度の計算

velocity.x = (player.getPosition().x + (acceleration * cos(angle * (M_PI / 180.0)) * deltaTime.asSeconds()));
velocity.y = (player.getPosition().y + (acceleration * sin(angle * (M_PI / 180.0)) * deltaTime.asSeconds()));   

次のように変更してみてください。

velocity.x = (player.getVelocity().x + (acceleration * cos(angle * (M_PI / 180.0)) * deltaTime.asSeconds()));
velocity.y = (player.getVelocity().y + (acceleration * sin(angle * (M_PI / 180.0)) * deltaTime.asSeconds()));   

これは、単純な物理方程式 vf = vi + a*t を利用していますが、ax,y 成分の方法です。私は、Position.x と Position.y を使用すると、その方程式が完全に崩れると思います。

注: 構文に関しては、私が提供したコードは機能しない可能性があります。player.getVelocity().xX 方向のプレーヤーの現在の速度を取得するコードをそこに入れます。Y 方向についても同じことを行います。

新しい位置の設定

適切かどうかplayer.setPosition(velocity);はわかりません。setPosition 関数が次の処理を行う場合:

newPosition.x = oldPosition.x + (velocity.x/dt)

x方向とy方向の両方で、それはうまくいくはずです。

しかし、単純に実行している場合:

newPosition.x = velocity.x

それでは、これは間違っていて、不適切なシミュレーションになると思います。

全体

コードに他の数学的なエラーがある可能性があります。特に加速度の計算方法について。私はこれを再確認しておらず、現時点では時間がありません。私が言及した調整を行ってもまだ機能しない場合は、コメントを投げてください。時間があれば、もっと調べてみることができます. 私は今取り組まなければならない自分のゲームを持っています。

編集1:

あなたのコードはずっと良く見えます。ここから、加速度を変更するコードを追加します。w キーを押すと「スラスター」がオンになり、2 の加速度が得られるとします。キーが押されていない場合、時間の経過とともに加速度が低下します (ゼロに戻ります)。フレームごとではありません。フレームごとに .99 を掛ける前に。つまり、120 fps を取得している場合、加速は 0.5 秒でゼロになる可能性があります (このような単純なゲームでは完全に可能です)。dt 変数に基づいて劣化させる必要があります。ただし、ゼロに達すると、まだ正の速度になります。通常、この速度は重力により時間の経過とともに低下しますが、宇宙の重力は、地球上で見られる重力 (-9.8m/s または -32 ft/s) に比べて非常に小さくなります。したがって、時間で計算される速度に重力減衰を実装することもできます

また

重力を無視して、S キーを押して負の加速度 (-2) を適用し、それを速度に適用することができます。これにより、負の値で速度が低下し、船がスラスターを反対方向に向けていると考えることができます。

もちろん、ゲーム開発者のふりをして、速度がゼロ以下にならないようにすることもできます (プレーヤーを前方にのみ移動させたい場合)。負の速度を検出した場合は、速度を 0 に、加速度を 0 に設定します。

注: 加速度の「劣化」は正と負の両方で発生し、ゼロに向かって「劣化」します。これらの値をいじくり回してテストを行い、何が正しいかを確認する必要があります。加速度は毎秒 1 低下する必要がありますか? 前述の加速度値として 2 と -2 の値を使用する必要がありますか? 2 と -2 は機能するかもしれませんが、3 と -3 の方が良いでしょうか? これらはすべて、テストすることで自分自身で答えられる質問です。

これがあなたにいくつかのアイデアを与え、あなたの質問を完全に解決するのに役立つことを願っています! それがどうなるか教えてください。

于 2013-06-15T16:05:19.270 に答える