My SFML sprite Move() function: FeedBack?

Griffin
  • My SFML sprite Move() function: FeedBack? Griffin

    Hey so I'm making a pong game with SFML and in the process made a function that takes a Time, Speed, Angle of movement, buffer for the movement on the X axis, and buffer for the movement on the Y axis.

    I then implemented this function into my custom mySprite class, more specifically into it's update() function which updates its Position using the above function to calculate its new position.

    However I'm worried that giving the function the FrameTime() of the Window (the time since the frame was last updated) is not the best choice as the sprites might start jumping around if there's lag between frame updates or other problems.....

    Finally I would like to know how my organization, planning, etc is.. Thanks!

    my UPDATED, WORKING Code:

       #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)
    {   //Make the degrees positive
        if(Angle<0) Angle= 360+Angle;
        //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
        if((int)Angle!=0){
            if(Quadrant==2 || Quadrant==4) Angle=90-Angle; //The unit circle triangle is flipped otherwise, causing x and y to be switched
            buffY= sin(Angle / 180 * M_PI)/ (1.f/(Speed*Time));  
            buffX= 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=(float)(newAngle-(int)newAngle)+(float)((int)newAngle%360);};
    
        void Update(){ 
            float frameTime= Window.GetFrameTime();
            float X=0,Y=0;
            SetRotation(angle);
            CalculateMove(frameTime,velocity,angle,X,Y);
            Move(X,-Y);
        };
    
        void Accelerate(float PPS){velocity+=PPS;};
        void Turn(float degrees){
            angle=(float)((angle+degrees)-(int)(angle+degrees))+(float)((int)(angle+degrees)%360);};
    
        void Reflect(float CollAngle){
            SetRotation(-GetRotation());
            angle=360-angle;
            //TODO: factor in the collision angle
        };
    };
    

  • For the question about how to stop jittery movement because of frame length, what you might consider doing is rather than feed the time step directly to the update function choose a fixed time step, like this:

    void Update(){ 
        static float frameTime += Window.GetFrameTime();
        float X=0,Y=0;
        while (frameTime >= TIME_STEP)
        {
            CalculateMove(TIME_STEP,velocity,angle,X,Y);
            Move(X,-Y);
            frametime -= TIME_STEP;
        }
    };
    

    (I wouldn't localize this to just the sprite though, I would do this in the main game update loop and have it apply to everything that updates)

  • All of your calculations must be implemented independently of time, the frameTime is the correct form to do this. There are different forms to calculate this elapsed time, but you don't worry about this now. With the frameTime you calculates the desired next position of the ball and then you need to calculate collisions and adjust the position if it's necessary.

    About the code:

    1.- Decide a convention to the variable names and follow it.

    "Time" has the first letter uppercase unlike buffX

    in c++ usually the first letter of variables is lowercase

    2.- Do you think that the function CalculateMove needs to be a template?

    I don't think that the type of the parameters will be different to float in the game. If it don't needed, don't use it.

    3.- For the cast conversions is better use static_cast( variable ) form.

    Because it's more clear and it can be searched easily.

    4.- In c++ the class names usually begins with uppercase.

    5.- The constructor has a lot of parameters.

    It's better declare a structure with these parameters and pass it by const reference to the constructor. In addition, the constructor of the structure can have the default parameters.

    Like:

    struct SpriteParams
    {
          float          m_rotation;
          float          m_angle;
    
          SpriteParams()
              : m_rotation( 0.f )
              , m_angle( 0.f )
          {}
     };
    
     // The mySprite constructor
     MySprite::MySprite( const SpriteParams& params );
    

    6.- Are you sure that mySprite must inherit from Sprite?

    If this class is modelling a paddle, the class must be a paddle and contains a graphics representation ( the sprite )

    class Paddle
    {
         public:
             void update();
    
         private:
             sf::Sprite  m_sprite;
    };
    

Tags
c++ graphics mathematics sfml
Related questions and answers
  • set_location(int X, int Y) { location[0] = X; location[1] = Y;}; bool Alive() {return alive;}; void SetLife(bool f) {alive= f;}; //////////////////////////////// Move //////////// bool move(int X, int Y) { location[0] += X; location[1] += Y; return true;}; };// end of sprite... /////////////////////////////////////////////////////////////////////////////////////////////////////////// class Player : public Sprite { public: Player(string name,int X, int Y, float health){ set_symbol('8

  • = (WIDTH / 2) - 64; allegro_message("Initialzing ship class"); s-&gt;Init(x); int frame = 0; BITMAP* buffer = NULL; BITMAP* background = NULL; BITMAP* ship = NULL; SceCtrlData... Missile { private: static const double angle = (3.14159265358979323846 / 2); public: bool Alive; static const int V = 5; double X; double Y...(); missile-&gt;Init(true, s-&gt;X, s-&gt;Y); bullets-&gt;push_back(missile); } } void CleanUp() { for(unsigned int index = 0; index < bullets-&gt;size(); index

  • ; float current_time, old_time, interpol; int type, current_frame, next_frame; }; struct md2_glcmd_t { float s; float t; int index; }; #define MD2_IDENT (('2'<<24) + ('P'<<16) + ('D'<<8) + 'I') #define MD2_VERSION 8 class MD2 : public VertexModel { public: MD2(const std::string& Path); ~MD2(); void Draw(timestep_t Time); private... char index_normal; }; typedef short md2_textcoord_t[2]; struct md2_frame_t { float scale[3]; vec3_t translate; char name[16]; md2_vertex_t vertices[1]; // First vertex of this frame

  • < numTriangles; i++) { MD2Triangle* triangle = triangles + i; for(int j = 0; j < 3; j++) { MD2Vertex* v1 = frame1-&gt;vertices + triangle-&gt;vertices[j... = triangles + i; for(int j = 0; j < 3; j++) { MD2Vertex* v1 = frame1-&gt;vertices + triangle-&gt;vertices[j]; MD2Vertex* v2 = frame2-&gt;vertices + triangle-&gt;vertices[j..., In); // Get The Current Line ( NEW ) shaderData[i][0] = shaderData[i][1] = shaderData[i][2] = float(atof (Line)); // Copy Over The Value ( NEW ) } fclose

  • every frame to handle input and render etc I call an UpdatePhysics method to update the physics simulation. void GameState::UpdatePhysics(unsigned int TDeltaTime) { World-&gt;stepSimulation(TDeltaTime...)Point[0], (float)Point[1], (float)Point[2])); // set rotation btVector3 EulerRotation; QuaternionToEuler(TObject-&gt;getOrientation(), EulerRotation); node-&gt;setOrientation(1,(Ogre::Real)EulerRotation[0], (Ogre::Real)EulerRotation[1], (Ogre::Real)EulerRotation[2]); //node-&gt;rotate(Ogre::Vector3(EulerRotation[0], EulerRotation[1], EulerRotation[2])); } } void GameState

  • } // this is the function used to render a single frame void render_frame() { // clear the window to a deep blue and clear the depth buffer to 1.0f device-&gt;ClearRenderTargetView(rtv, D3DXCOLOR(0.0f, 0.2f, 0.4f...(); // create the index buffer out of DWORDs DWORD OurIndices[] = { 0, 1, 2, // side 1 2, 1, 3, 4, 0, 6, // side 2 6, 0, 2, 7, 5, 6, // side 3 6, 5, 4, 3, 1, 7, // side 4 7, 1, 5, 4, 5, 0, // side 5 0, 5, 1, 3, 7, 2, // side 6 2, 7, 6, }; // create the index buffer // D3D10_BUFFER_DESC bd; // redefinition bd.Usage = D3D10_USAGE_DYNAMIC

  • wrong in my frame buffer set up code, or elsewhere. But I can't see what. The FBO is set up through the following function: unsigned int fbo_id; unsigned int depth_buffer; int m_FBOWidth, m_FBOHeight; unsigned int m_TextureID; void initFBO() { m_FBOWidth = screen_width; m_FBOHeight = screen_height; glGenRenderbuffers(1, &amp;depth_buffer); glBindRenderbuffer(GL_RENDERBUFFER...); translate(M, Vector3(0,0,-50)); drawBox(M); } void drawRotatingBox() { Matrix4 M(1); rotate(M, rotation(Vector3(1, 0, 0), rotation_x)); rotate(M, rotation(Vector3(0, 1, 0), rotation_y

  • into a shader program, for use with glDrawArrays. My vertex data already exists in a VertexBufferObject that uses the following data structure to create a vertex buffer: class CustomVertex { public: float m_Position[3]; // x, y, z // offset 0, size = 3*sizeof(float) float m_TexCoords[2]; // u, v // offset 3*sizeof(float), size = 2*sizeof(float) float m_Normal[3]; // nx, ny, nz; float colour[4]; // r, g, b, a float padding[20]; // padded for performance }; I've already written a working VertexBufferObject class that creates a vertex buffer

  • i think i just found the solution. 1) the problem is that backbuffer surface and source surface are of different formats - that is why exception was thrown. 2) the image path needed double slash "C...; pd3dDevice -&gt; Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0); // clear the back buffer to a blue color if (SUCCEEDED(pd3dDevice -&gt; BeginScene...); //================================================================================================================================// code starts here //================// int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { if (!initWindow(hInstance)) return

Data information