Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: SFML and Game time  (Read 15635 times)

0 Members and 2 Guests are viewing this topic.

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: SFML and Game time
« Reply #15 on: May 29, 2016, 03:58:39 am »
   Private Structure State
        Dim pos As Single
        Dim vel As Single
    End Structure
 

The original C++ code for this structure is:

struct State
{
        float x;
        float v;
};
 

From my understanding of the syntax a float is the smallest variable that can be used and should translate to single in vb.net.

I replaced State(x, v,) with State(pos, vel) so I understand it better (position, velocity).  In a 2d environment there's coordinates for Object.Position(x, y) and Object.Velocity(x, y).  Since I cannot store a vector value in a single, and I have no idea what I am doing, I tried this:

   Private Structure State
        Dim posX As Single
        Dim posY As Single
        Dim velX As Single
        Dim velY As Single
    End Structure
 

And modified the rest of the methods and functions to support that.  But since it is not used in the original C++ code, and none of the simple methods for RK4 used anything like that I felt it was best to try something more realistic, instead of my redneck-math-foo I tried to develop, LOL

I also realized that this was not intended to find the (x) horizontal values for velocity, only the vertical values.  I have found only 1 other source specific to vb for resolving all the physics for a falling ball.  However the maths used for it were very flawed, and were not easily compatible with anything else, such as the trig functions used for multiple object collisions.

Regardless of all that, I have had the gravity partially working before I actually had a fixed time step.  The whole point of starting this was to make sure the maths were correct so I could extend my 2d top down engine to support side scrolling platform.  Since just about all the math involved relies on a fixed time step, I have to sit down again and go over pretty much everything.  I honestly did not know it was going to be this much work, time, and confusion just trying to get not only something that works, but something that works like it is supposed to so that all they other systems work better.

***Note:  I believe my maths are completely wrong on the slimmed down RK4, and I have the positions and velocities backwards.
« Last Edit: May 29, 2016, 05:44:16 pm by Recoil »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: SFML and Game time
« Reply #16 on: June 02, 2016, 12:17:45 am »
SFML provides "vectors" that can be used to store both x and y fields together and perform calculations on them together as a vector. I can only assume that the VB binding has them too.

You could then pass the two Vector2 variables around the physics maths; you'd simply pass position and velocity (each would be [x,y]).

If you can't get that to work, though, simply passing position.x with velocity.x and position.y with velocity.y is possible by performing the calculation twice.

Note: float in c++ simply means a single floating-point value. I would presume that "single" would match "float" since c++ also has "double" after float  ;D
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: SFML and Game time
« Reply #17 on: June 02, 2016, 03:32:11 pm »
Yes, I have recently tried using vectors to try to work through this, Vector2f to be precise.  Even when I use 2 vectors in the Enum State, one for the [position(x,y) As Vector2f] and one for the [velocity(x,y) As Vector2f], I still have to access them like this:

Obj.State.Position.Y += Obj.State.Velocity.Y * DT
 

Several examples I have come across (in C++) actually use the entire Vector in the calculations.  Those are mostly in particle simulators that change both the (x,y) values at the same time so an object will go in an ellipse around a central object.

After a brief break to brush up on calculus, using the original code from the integration example, I do not understand this:

Private Function acceleration(ByVal state As State, ByVal t As Single) As Single
        Const k As Single = 10                      '//-------gravity
        Const b As Single = 1                        '//-------randomly obscure value
        Return -k * state.pos - b * state.vel  '//------this line, right here...
    End Function
 

I can partially get the slimmed down equations work though, but struggling to understand why so I can finish adding stuff to it.  For the most part every RK2-4 example uses the same math equations regardless of language:

Runge-Kutta_method
double rk4(double(*f)(double, double), double dx, double x, double y)
{
        double  k1 = dx * f(x, y),
                k2 = dx * f(x + dx / 2, y + k1 / 2),
                k3 = dx * f(x + dx / 2, y + k2 / 2),
                k4 = dx * f(x + dx, y + k3);
        return y + (k1 + 2 * k2 + 2 * k3 + k4) / 6;
}
 
double rate(double x, double y)
{
        return x * sqrt(y);
}
 
int main(void)
{
        double *y, x, y2;
        double x0 = 0, x1 = 10, dx = .1;
        int i, n = 1 + (x1 - x0)/dx;
        y = malloc(sizeof(double) * n);
 
        for (y[0] = 1, i = 1; i < n; i++)
                y[i] = rk4(rate, dx, x0 + dx * (i - 1), y[i-1]);
 
        printf("x\ty\trel. err.\n------------\n");
        for (i = 0; i < n; i += 10) {
                x = x0 + dx * i;
                y2 = pow(x * x / 4 + 1, 2);
                printf("%g\t%g\t%g\n", x, y[i], y[i]/y2 - 1);
        }
 
        return 0;
}
 

Unless I am reading that wrong, it and nearly every other code example using RK4 use [pos * Sqrt(vel)] to work out the f functions, which works if I swap the positions and velocities in the function.  However, buried way off in a power point file I alternatively found [dy/dx = y-x^2] to work out the functions.  That does not return proper results though (but I cannot remember what it does right now).

Eh, wall-o-text again :/ .  The reason I need to understand this is because there are several things I am not able to calculate, like Drag & Friction.  Acceleration seems to be calculated somewhere in there, and depending on which method I try to calculate the function will appear to speed up as an object is falling...I just don't know where.

Gonna go back and reevaluate the needs of this method, or needing a physics engine altogether...

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: SFML and Game time
« Reply #18 on: June 03, 2016, 12:07:15 am »
I think I may at least partially understand your issue.

You're trying to smush 2 dimensions (x and y) into 1 dimension for rk4. ("State" in gaffer's article.)
Remember that dimensions are completely separate from one another!

Gaffer's article shows rk4 in only 1 dimension. Be careful with x and y in some articles. x and y may be used as variable names without much meaning, whereas they represent different spatial dimensions in physics. :)

Are you familiar with Taylor Series? The RK4 is similar-ish.

Constant position (1st order): p(t) = c.
Constant velocity (2nd order): p(t) = v * t + c.
Constant acceleration (3rd order): p(t) = a * t^2 + v * t + c.
Constant jerk (4th order): p(t) = j * t^3 + a * t^2 + v * t + c.
(Yes, "jerk" is the correct name for "change in acceleration". However, I guess it's sometimes called a "jolt". Yes, it exists. Real-life example: you pressing the gas pedal in a vehicle is jerk, as you are changing the acceleration of the vehicle.)

You can keep going, but, there's a point where it's just inane (jerk is usually that point).

Euler's method is inaccurate when any of the above values are not constant over a timestep, 't' (realistically true). Gaffer explains this in the beginning of his article you linked.
And since computers are finite, we can't be as accurate as the real world, hence the concept of a timestep.

RK4 takes this into account, and takes 4 samples ahead, where each following sample uses the previous sample to calculate itself, to more accurately estimate changes in velocity, acceleration, and jerk.

I hope this helps RK4 make more sense.

As for your acceleration function you have there, that's not acceleration due to gravity. That's acceleration due to a spring, Hooke's Law.

What you should do in that function, is add together all sources of acceleration on an object. Gravity, collisions, friction, drag.... springs. :) Then return that total.

Also, since you're using VB.NET, C# DLLs should *just work*, since they both are just compiled to CLR IR.

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: SFML and Game time
« Reply #19 on: June 03, 2016, 03:18:49 am »
Quote
You're trying to smush 2 dimensions (x and y) into 1 dimension for rk4.

Yes and no.  Initially I was, but then realized with several examples that the (x, v) referred to position and velocity.  C++ programming examples provided enough info for calculating the position of a particle, but not as a 1 dimensional point, which confused me even more.  Some examples were using single values for their states and not vector values, while others did use vectors, but the same equations as the single value states.

I honestly felt a bit better that no one else had a definitive idea of what they were doing since everyone was doing something different o achieve the same results :)

I had not heard of the Taylor Series, but have the wiki page pulled up to read over in a bit.  I believe "jerk" and "jolt" are possibly "impulse" or "thrust" as well, as I have ran into those references many times over the past few weeks.

I have also ran into RK4 equations that calculate not only (k1, k2, k3, k4) but (l1, l2, l3, l4) which refer to a coupled equation, which I had to read even more info on that made much less sense.  (a1, a2, a3, a4) are in a few as well, but they calculate what I believe is acceleration from (kn, ln).  Honestly the more that is added the more sense it makes, yet confuses the heck out of me even more, LOL

Quote
What you should do in that function, is add together all sources of acceleration on an object. Gravity, collisions, friction, drag.... springs. :) Then return that total.
That is the simplest explanation of what-to-do I have ran into regarding all of this.  It gives me a much better idea of what all needs to be calculated in that function so it will calculate accordingly.

My original goal of extending my engine has been drastically changed to me reinventing the wheel for a lot of things that just do not publicly exist for vb.net apps.  And while there are some C# libraries that I could use, this is proving to be a very eye-opening experience of what little I really understand about what I need to do to accomplish a simple 2d platformer engine, correctly at least.  I am literally 1 month in and essentially have not 1 line of working code that is going to be able to be used in my final project outline (aside from the time step).  That's 6 month's in total on my entire engine that I am putting on the back burner to brush up on more logical and applicable math concepts ;)


Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: SFML and Game time
« Reply #20 on: June 04, 2016, 03:35:11 pm »
Yes, I have recently tried using vectors to try to work through this, Vector2f to be precise.  Even when I use 2 vectors in the Enum State, one for the [position(x,y) As Vector2f] and one for the [velocity(x,y) As Vector2f], I still have to access them like this:

Obj.State.Position.Y += Obj.State.Velocity.Y * DT
 

Several examples I have come across (in C++) actually use the entire Vector in the calculations.
Vector2fs have the ability to be multiplied with a scalar so, with your code example here, this code be simply replaced with:
Obj.State.Position += Obj.State.Velocity * DT
instead of:
Obj.State.Position.x += Obj.State.Velocity.x * DT
Obj.State.Position.y += Obj.State.Velocity.y * DT

After a brief break to brush up on calculus, using the original code from the integration example, I do not understand this:

Private Function acceleration(ByVal state As State, ByVal t As Single) As Single
        Const k As Single = 10                      '//-------gravity
        Const b As Single = 1                        '//-------randomly obscure value
        Return -k * state.pos - b * state.vel  '//------this line, right here...
    End Function
 
I can't say that I fully understand this.
k represents the force and b is (as far as I can tell) is multiplying the velocity by 1 (so, in this case, doing nothing). From reading some of the comments, b looks like it is damping.
It's likely that this is all negative because the axis is based on increased y being upwards so you may need to change this for use with SFML.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: SFML and Game time
« Reply #21 on: June 04, 2016, 04:57:04 pm »
Yes, I can multiply by scalar values.  What I don't understand is why I would want to multiply the entire position, including horizontal (x) coordinate as well.  This likely has more to do with the type of game you are designing for.  What works for making one planet rotate around a sun (particle A in middle, particle B circling) in an example, is not going to work similarly to a character jumping.  So a normal physics engine is going to use functionA when gravity is pulling in the center, and functionB when gravity is pulling down...probably not likely.

This is the original code from the Gaffer TimeStep and Integration sources:
float acceleration(const State &state, float t)
{
        const float k = 10;
        const float b = 1;
        return - k*state.x - b*state.v;
}
 

I believe it is the same thing as what I am doing, and the b = 1 just makes no sense, because before subtraction, multiplication is going to happen without parenthesis defining which come first.  And why is he passing t (time step?) through, yet doing nothing with it?  However, in Timestep when converted to VB code, the ball in the center just springs left to right, so maybe that is why he is calculating things the way he is?

I am going to have to let this be for now because I am not making any progress understanding how to mush everything else in there, not to mention what all I have to mush in there for it to calculate correctly.  It seems a physics engine is going to be out of the scope of my understanding.  Don't get me wrong, everything you guys have had to say make 100% sense, but I believe trying to properly take into account all the variables that I am supposed to be calculating is just too overwhelming.

All that being said, I have not even touched code in the last few days because I have been reading this: http://gameprogrammingpatterns.com.  Just in case no one has come across it I thought I would pass it along.  It's great and has given me a better insight on how I need to develop my engine.

No joke, I have been so stubborn about changing languages in the last 8 years because of how much I like VB, but now with all this I feel I might make better progress if I just moved to C++ because there is so much more support for doing really complicated stuff...not to mention much smarter people already have working physics engines working for C++  ;D

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: SFML and Game time
« Reply #22 on: June 07, 2016, 04:38:32 am »
Yes, I can multiply by scalar values.  What I don't understand is why I would want to multiply the entire position, including horizontal (x) coordinate as well.
The position is two-dimensional so all forces act on both dimensions. In this case, k would probably also be two-dimensional; that's the direction of the force. If that force is gravity, the x value of velocity would be zero.

This is the original code from the Gaffer TimeStep and Integration sources:
[...]
I believe it is the same thing as what I am doing, and the b = 1 just makes no sense, because before subtraction, multiplication is going to happen without parenthesis defining which come first.  And why is he passing t (time step?) through, yet doing nothing with it?  However, in Timestep when converted to VB code, the ball in the center just springs left to right, so maybe that is why he is calculating things the way he is?
That's right. b being 1 and used as multiplication has no effect. b is "damping" and, in this case, is not used. b would be changed to allow damping.
t is passed, I believe, because some calculations require the current time (t = current time). His implementation here has been stripped of requiring those calculations so does not use t. If you read the comments (you really should; there are a lot of questions answered there), you can see that someone has pointed out this already.

However, in Timestep when converted to VB code, the ball in the center just springs left to right, so maybe that is why he is calculating things the way he is?
Is it possible that you're applying it to the x co-ordinate instead of the y and maybe the view's centre is (0, 0)?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: SFML and Game time
« Reply #23 on: June 07, 2016, 04:54:35 pm »
OMG, the comments...how did I not notice them before?!?  You're right, they do provide much clearer explanations of what all is going on in the equations.

No joke, I thought this area would be a general 1-type of equation is going to work, but that is not the case.  He's leaving out friction, and drag is set to 1.  He even further explains that his example IS for 1D, and that t can be used for other things that he isn't covering.

However, after reevaluating everything (the pm I sent) I am going to take a different approach on how to implement the 2d physics class, because not every game is going to use the same class :)

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: SFML and Game time
« Reply #24 on: June 07, 2016, 05:16:16 pm »
There are further articles on that site that progress onto applying physics in three dimensions so there should be plenty of information for working with just two dimensions ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Paul

  • Jr. Member
  • **
  • Posts: 78
    • View Profile
Re: SFML and Game time
« Reply #25 on: November 19, 2018, 05:51:48 pm »
Some pseudo code for an implementation of fixed timestep:
deltaTime = 0.1 seconds
while (windowIsOpen)
{
    currentTime = clock.currentTime
    timeToProcess = timeToProcess + currentTime - previousTime
    previousTime = currentTime

    while (timeToProcess >= deltaTime)
    {
        applyLogicAndPhysics()
        timeToProcess = timeToProcess - deltaTime
    }

    prepareDisplay()
    drawDisplay()
}

One question here.

In RTS games like SimCity or Age of Empires player can change game speed by changing deltaTime. World simulation can run 0.5x slower (1/15), 1x - normal speed (1/30) or 10x times faster (1/300). Thats right approach if I'm not wrong.

But what with rest of logic - some GUI updates, smooth camera movement (1/60), determine which object is under cursor (1/10). They should be outside world simulation but also they need some limitation - not to burden the CPU, not move too fast (camera). Can I just use more fixed updates (in row) like the one above or what is propper way?

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: SFML and Game time
« Reply #26 on: November 20, 2018, 01:08:39 am »
One important thing to remember is that changing the delta time doesn't really change how fast the application runs/updates; it only changes the size of the chunk of time that is processed.
One way to "slow down time" is to scale the delta time that is multiplied in the updates differently from the delta time that is processed in the time loops.

In that pseudo code you just quoted, I might put it here:
applyLogicAndPhysics(deltaTime * 0.5);
instead of passing the deltaTime unaltered (it should probably have passed the deltaTime in the original pseudo code).
Again, leaving the actual time processed being the same but the updates think that a different amount of time has passed.

Another way is to use a clock in which the speed of time can be changed. I'll mention Kairos' Timestep because I use it myself for time step stuff including time bending stuff. Timestep uses Kairos' Continuum clock, which can change time's speed so you can change the speed of Timestep.
You could change only the speed of the clock, which means that the same delta time takes longer so might update more jerkily at slower speeds but updates logically identically, or change the speed of the clock and scale the delta time used to match, which means that the updates takes the same amount of actual time and can be more smooth at slower speeds but updates are logically different since the timestep has now changed.
One thing to be aware of if you do use a time-bending clock is that a speed of zero could cause an infinite loop. Also, a time-bending clock running in reverse (negative speed) means that the delta time needs to be able to deal with that.

It's been a little while since I did time-bending timesteps so my memory on the subject might be a little rusty.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Paul

  • Jr. Member
  • **
  • Posts: 78
    • View Profile
Re: SFML and Game time
« Reply #27 on: November 21, 2018, 12:38:55 pm »
applyLogicAndPhysics(deltaTime * 0.5);

This seems working fine. I found one thing, sf::Texture::setSmooth = false (GL_NEAREST) causes some rounding and it also affects sprite movement, "it's jumping by integers". With GL_LINEAR it's smooth even on low update rates / lower multiplier.

Quote from: Hapax
Another way is to use a clock in which the speed of time can be changed. I'll mention Kairos' Timestep
..

You could change only the speed of the clock, which means that the same delta time takes longer so might update more jerkily at slower speeds but updates logically identically, or change the speed of the clock and scale the delta time used to match, which means that the updates takes the same amount of actual time and can be more smooth at slower speeds but updates are logically different since the timestep has now changed.

In both cases it's still tied with system time (lockstep, amount of game time elapsed per tick is constant)? Anyway I will test it.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: SFML and Game time
« Reply #28 on: November 22, 2018, 01:25:40 am »
One more simple way to approach some of the more common speeds is to simply process updates multiple times.
So, for 1x speed, update once whereas for 2x speed, update twice. For 3x speed, update thrice and so on.

Basically:
speedMultiplier = 3 // for 3x speed
while (timeToProcess >= deltaTime)
{
    loop speedMultiplier times:
    {
        applyLogicAndPhysics()
    }
    timeToProcess = timeToProcess - deltaTime
}

Of course, if you wanted slower speeds, you could start slower and multiply to get the normal speed but this seems to be a less efficient approach for that case.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

 

anything