Как мой СФМЛ переместить спрайт (функция)?


Я делаю понг игры с СФМЛ и в процессе сделал функцию, которая принимает время, скорость, угол движения, буфер для перемещения по оси X, и буфер для движения по оси Y.

Затем я реализовал эту функцию в мой пользовательский класс mysprite класса, точнее в его обновлении() функция, которая обновляет свое местоположение, используя приведенные выше функции, чтобы вычислить новое положение.

Однако, я боюсь, что отдав функции FrameTime() окна (время, прошедшее с момента последнего обновления кадров) - не лучший выбор в качестве спрайтов может начать прыгать вокруг, если есть разрыв между рамкой обновления или другие проблемы.

Наконец, я хотел бы знать о моей организации, планирования и др.

#include<SFML/Graphics.hpp>
#include<SFML/System.hpp>
#include<cmath>
#include<vector>
#    define M_PI 3.14159265358979323846 

sf::RenderWindow Window;

template<typename T> 
void CalculateMove(T Time, T Speed, T Angle, T& buffX, T& buffY)
{   //determine what quadrant of circle we're in
    unsigned int  Quadrant= 1;
    if(Angle>90)  Quadrant= 2;
    if(Angle>180) Quadrant= 3;
    if(Angle>270) Quadrant= 4;

    //anything above 90 would be impossible triangle
    Angle= (float)(Angle-(int)Angle)+(float)((int)Angle%90); 

    // calculates x and y based on angle and Hypotenuse.02433
    if((int)Angle!=0){
        buffX= sin(Angle / 180 * M_PI)/ (1.f/(Speed*Time));
        buffY= sin((180-Angle-90)/ 180 * M_PI)/ (1.f/(Speed*Time));}

    else{// Movement is a straight line on X or Y axis
        if(Quadrant==0 || Quadrant==2) buffX= Speed*Time;
        if(Quadrant==1 || Quadrant==4) buffY= Speed*Time;}

    //Quadrant Factor (positive or negative movement on the axis)
    switch(Quadrant){
    case 1: break;
    case 2: buffX=-buffX; break;
    case 3: buffX=-buffX; buffY=-buffY; break;
    case 4: buffY=-buffY; break;}
};

/////////////////////////////////////////   Mysprite    ////////////////////////////////
class mySprite : public sf::Sprite
{
private:
    float velocity;
    float angle;

public:
    // all the values needed by the base class sprite();
    mySprite(
        const sf::Image& Img, 
        const sf::Vector2f& Position = sf::Vector2f(0, 0), 
        const sf::Vector2f& Scale = sf::Vector2f(1, 1), 
        float Rotation = 0.f, 
        const float Angle= 0.f, 
        const float Velocity= 0.f, 
        const sf::Color& Col = sf::Color(255, 255, 255, 255)):
      Sprite(Img, Position, Scale, Rotation, Col){
        angle= Angle;
        velocity= Velocity;};

    float Velocity(){return velocity;};
    void SetVelocity(float newVelocity){velocity=newVelocity;};
    float Angle(){return angle;};
    void SetAngle(float newAngle){angle=newAngle;};

    void Update(){ 
        float frameTime= Window.GetFrameTime();
        float X=0,Y=0;
        CalculateMove(frameTime,velocity,angle,X,Y);
        Move(X,-Y);
    };

    void Reflect(float CollAngle){
        SetRotation(-GetRotation());
        angle=-angle;
        //TODO: factor in the collision angle
    };
};


2384
2
задан 17 июня 2011 в 01:06 Источник Поделиться
Комментарии
1 ответ

Это часто проще иметь фиксированную частоту кадров в игре. Тогда вам не придется умножить все на коэффициент времени. В этом случае, вам не придется снизить частоту кадров до минимального значения, что все компьютеры способны обрабатывать. Вы можете, например, давайте обновления положении Run на 200Гц и обновление графики на максимум скорость может обработать компьютер (который может быть ниже 200 Гц).

Если обновления может легко работать на фиксированной скорости, на все оборудование вы хотите запустить, это может хорошо работать. Это хороший способ, чтобы получить последовательное поведение в симуляции физики, и для простых игр, обновление ПО значительно более высокой скоростью, чем требуется для графика это не проблема.

С другой стороны, если обновления установки являются сложными, вы не можете быть в состоянии выполнять их на предельной скорости, и вы будете иметь, чтобы справиться с различной интервалов (как в коде). Это часто сложнее. В "прыгающих вокруг в случае запаздывания" проблемы есть простой (но не идеальное) решение: просто поставить ограничение на время дельты, так что вы никогда не будете делать расчеты по времени Дельта больше, чем скажем 50 мс.

Я думаю, эту часть вопроса лучше было бы поместить в gamedev.stackexchange.com там, где, наверное, уже обсуждали это.

Редактировать: конечно, взгляните на https://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step

2
ответ дан 21 июня 2011 в 07:06 Источник Поделиться