Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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
    };
};
share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

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;
};
share|improve this answer
    
Thanks for all the organization/ readability tips, i just got the book "Clean Code" and have started reading it! Also do you have any comments on how i could improve performance specifically? This is what i'm most worried about right now. –  Griffin Jun 17 '11 at 6:35
    
@Griffin: Game optimizations mustn't be done in early phases. The game specifications are changing constantly. It's a lost of time do a optimization and then the code will be not necessary. Also, when you are designing the high level of your classes the programmer must have a global vision of the relation between classes, optimization is very implementation dependent. Usually the performance problems are in graphics and AI algorithms. –  momboco Jun 17 '11 at 12:47
    
You don't have to try to optimize something if it's not a bottleneck of your game. There are tools to find the bottlenecks. It's a lost of time optimize code that doesn't have much impact in the performance. It's better program with clear code and once the game is running, with lots of resources ( sprites, sounds, ... ) included, if there are a performance problem, search the bottleneck and try to optimize it. How? If there are some cores, with parallel programming. –  momboco Jun 17 '11 at 12:48
    
Use of SIMD ( single instruction multiple data ) instructions. Organizing the memory to have less memory penalty hits. Precaching resources before and not create and destroy dinamic memory in gameplay. However, there are c++ details that must be done always. For example, prefer pass a argument of a non c++ default type by const reference or reference instead of copy ( because avoid to call the copy constructor ). –  momboco Jun 17 '11 at 12:48
add comment

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)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.