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

Author Topic: Weird movement in my program[SOLVED]  (Read 8024 times)

0 Members and 1 Guest are viewing this topic.

Sanction

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Weird movement in my program[SOLVED]
« on: August 11, 2015, 04:00:32 pm »
I'm getting back into C++ before I forget it all.. I'm vary rusty. I'm following all the SFML books and tutorials.

The question I have is Why is my _Player movement is radical?
Is this because of the _Window.setFramerateLimit(FPS) ?

Main.cpp
(click to show/hide)
Game.cpp
(click to show/hide)
Game.h
(click to show/hide)
« Last Edit: August 12, 2015, 01:56:49 pm by Sanction »
Knowledge comes, but wisdom lingers. It may not be difficult to store up in the mind a vast quantity of facts within a comparatively short time, but the ability to form judgments requires the severe discipline of hard work and the tempering heat of experience and maturity.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Weird movement in my program
« Reply #1 on: August 11, 2015, 04:22:17 pm »
Your update function always moves by a fixed amount. It doesn't take the time between frames into account.

I'd suggest reading these links:

http://gafferongames.com/game-physics/fix-your-timestep/
http://www.koonsolo.com/news/dewitters-gameloop/
http://gameprogrammingpatterns.com/game-loop.html
http://gameprogrammingpatterns.com/update-method.html

Sanction

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Weird movement in my program
« Reply #2 on: August 11, 2015, 04:29:17 pm »
Thankyou.. I had a feeling something weird was going on I just could not put my finger on it.
Knowledge comes, but wisdom lingers. It may not be difficult to store up in the mind a vast quantity of facts within a comparatively short time, but the ability to form judgments requires the severe discipline of hard work and the tempering heat of experience and maturity.

Sanction

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Weird movement in my program
« Reply #3 on: August 11, 2015, 05:31:38 pm »
So I read http://gameprogrammingpatterns.com/game-loop.html it was the most helpful to explaining what is going on..

I'm also trying to follow the book and compare something is not right here. same movement issues and the numbers don't seem right.

Game.cpp
(click to show/hide)
Knowledge comes, but wisdom lingers. It may not be difficult to store up in the mind a vast quantity of facts within a comparatively short time, but the ability to form judgments requires the severe discipline of hard work and the tempering heat of experience and maturity.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Weird movement in my program
« Reply #4 on: August 11, 2015, 05:33:15 pm »
I'd personally recommend the first link "Fix your timestep" as the best by far (try reading it again) :)

Sanction

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Weird movement in my program
« Reply #5 on: August 11, 2015, 06:18:36 pm »
that just confusing me even more.

This should work, but I'm still running into the same problem..
void Game::run()
{      
        sf::Clock clock;
        sf::Time timeSinceLastUpdate = sf::Time::Zero;

        while (_Window.isOpen())
        {
                sf::Time elapsedTime = clock.restart();
                timeSinceLastUpdate += elapsedTime;
                while (timeSinceLastUpdate > TimesPerFrame)// sf::Time TimesPerFrame = sf::seconds(1.f / 60.f);
                {
                        timeSinceLastUpdate -= TimesPerFrame;

                        //Handle Events
                        processEvents();
                        //Game Logic
                        update();
                }

                //Draw to Screen
                render();
        }
}
 
« Last Edit: August 11, 2015, 06:48:11 pm by Sanction »
Knowledge comes, but wisdom lingers. It may not be difficult to store up in the mind a vast quantity of facts within a comparatively short time, but the ability to form judgments requires the severe discipline of hard work and the tempering heat of experience and maturity.

Sanction

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Weird movement in my program
« Reply #6 on: August 11, 2015, 07:48:16 pm »
I added in a function that shows my FramesPerSec and I'm getting like 340ish.. and it should be set at 60 :'( something isn't working correctly
« Last Edit: August 11, 2015, 08:01:54 pm by Sanction »
Knowledge comes, but wisdom lingers. It may not be difficult to store up in the mind a vast quantity of facts within a comparatively short time, but the ability to form judgments requires the severe discipline of hard work and the tempering heat of experience and maturity.

Hapax

  • Hero Member
  • *****
  • Posts: 3378
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Weird movement in my program
« Reply #7 on: August 11, 2015, 08:03:14 pm »
TimesPerFrame is a confusing name for that particular variable since it's actually how much time each loop should process (aka timestep), not how many times it does so.
e.g. 1/60 would mean it would do something once every sixty seconds, not sixty times every one second. (when it's named "times per frame")

I added in a function that shows my FramesPerSec and I'm getting like 340ish.. and it should be set at 60 :'(
Your setFramerateLimit() is commented out.
If it's not, your calculations could be erred.

This should work
Although technically, I can't think right now of any logical reason other than overkill to avoid putting events in the inner (update) loop, I don't understand why you actually placed input and events inside that loop as even in the article you said helped you, they quite clearly don't do that:
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Sanction

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Weird movement in my program
« Reply #8 on: August 11, 2015, 08:44:50 pm »
setFramerateLimit() was commented out because it would sleep my whole game loop and it was causing problems with eventpoll. That's how we got to creating fixed time step. (from my understanding and research is sleeps from the window.display() but don't take my word for it I've read so many forms about time step)

The reason the events were in the inner loop is because its straight out of the SFML book. What I have its identical to the source code. probably why I'm really confused on why this isn't working right. The book must be wrong.
Knowledge comes, but wisdom lingers. It may not be difficult to store up in the mind a vast quantity of facts within a comparatively short time, but the ability to form judgments requires the severe discipline of hard work and the tempering heat of experience and maturity.

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: Weird movement in my program
« Reply #9 on: August 11, 2015, 09:07:43 pm »
Quote
setFramerateLimit() was commented out because it would sleep my whole game loop
I think Hapax pointed out that setFramerateLimit() is commented out because it could explain why your measured FPS is so high. You didn't show how you are measuring frame rate, but if you are just doing it from your main loop in Game::run(), then it would make sense for it to be high. There is nothing to slow it down. Your game logic (update) is running at roughly 60 FPS due to your fixed time step, but your game loop itself (with the render() call) is not being limited in any way.

Having said that, after reading this thread I'm not exactly sure what the problem is that we're trying to solve (probably because I don't have a way to test the code you posted right now). You said the player movement is radical, but I don't really know what that means. Is the player movement just not smooth looking or is it faster/slower than expected?
« Last Edit: August 11, 2015, 09:10:24 pm by Arcade »

Sanction

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Weird movement in my program
« Reply #10 on: August 11, 2015, 09:22:07 pm »
Its got to be something simple or something I'm over looking. but what happens is the movement isn't smooth.. and feel sticky.. press 'W' key and release keeps moving up for a few seconds and always moves to the right if you pressed 'D' key once.

With setFramerateLimit() uncommented it does keep a steady FPS.. however its still had that sticky movement. I'm bewildered..


My current code..
Main.cpp
(click to show/hide)
Game.cpp
(click to show/hide)
Game.h
(click to show/hide)
Knowledge comes, but wisdom lingers. It may not be difficult to store up in the mind a vast quantity of facts within a comparatively short time, but the ability to form judgments requires the severe discipline of hard work and the tempering heat of experience and maturity.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Weird movement in my program
« Reply #11 on: August 11, 2015, 09:26:17 pm »
Try something along the lines of this:

void update(sf::Time delta_time) {
  // advance the simulation - taking delta_time into account. For example:
  auto distance_to_move_this_frame = velocity * delta_time.asSeconds();
  stuff.move(distance_to_move_this_frame);
}

const sf::Time timestep = sf::seconds(1.f) / 40.f;  // take one physics step / simulation step every 1 fourtieth of a second
sf::Time remainder_time = sf::seconds(0.f);  // left over time from previous frame(s)
sf::Time elapsed_time = sf::seconds(0.f);
sf::Clock clock;
window.setFramerateLimit(60);  // render at aproximately 60 fps

while (whindow.isOpen()) {  // our main game loop
  // ... event handling goes here ...
  elapsed_time = clock.restart();  // figure out how much time passed since last frame
  elapsed_time += remainder_time;  // add the time we have left over and not yet accounted for
  while (elapsed_time >= timestep) {  // as long as enough time has passed that we need to take a step to keep up ..
    update(timestep);  // update simulation; pass in timestep so it can scale based on passed time
    elapsed_time -= timestep;  // we just took a step so subtract the time one represents
  }
  remainder_time = elapsed_time;  // whatever is left in elapsed_time is our remainder for the next frame
  window.clear();  // clear the screen in preparation for rendering the current frame
  window.draw(stuff); // render the current state of the simulation
  window.display();  // put it on the screen
}
 

The above example code has a number of advantages over what you posted above:

1) Every update advances the simulation by the exact same amount of time. This gives you reproducibility; if you replay a simulation from time T to T + N you'll always take the exact number of steps and the result after each step is deterministic (and since the update() function takes the actual value of delta_time into account it's easy to experiment with changing the timestep).

2) Updating by a fixed amount of time each step let's you guarantee such things as "my player cannot ever move entirely through a wall in a single update without me detecting it" and "I'll never overflow this calculation since I know the time/distance/whatever is always within this bound for each discreet step" etc.

3) The loop above takes as many steps as needed (or none) to catch the simulation up to real time and (crucially) it remembers the time-not-simulated-this-frame for the next one so that the simulation does not leak time and does always eventually catch up with (or at least stays close to) real-time and does not fall more and more behind.

4) it completely decouples simulation update from rendering - the two can happen at completely different intervals (as long as the simulation can keep up) and you don't depend on the actual frame rate to achieve smooth movement/simulation progress.

How you choose to step your simulation forward based on the time passed (the timestep) is up to you and how precise you want it to be of course. You can do simple Euler integration (which is not great but simple and perfectly fine for a lot of simple stuff) or you can go with Verlet or RK4 if you need more accuracy. But that's a completely different thing from keeping the timestep fixed and updating frame-rate independent and and not "leaking" time.
Also; what I present above is not perfect. It can be improved in various ways; like using the remainder_time to interpolate between the current and next frame and other tricks. But it's usually good enough for most simple (and not so simple) use cases in my experience.

I hope that made sense and was useful/helpful. If not; feel free to ask.
And if someone on the forum can find faults with the above; please do correct me.
« Last Edit: August 11, 2015, 09:29:21 pm by Jesper Juhl »

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: Weird movement in my program
« Reply #12 on: August 11, 2015, 10:38:49 pm »
and always moves to the right if you pressed 'D' key once.

Sorry if this is a dumb question, but are you sure the code you posted is the same that you are testing? I ask because looking at what you posted, it doesn't look like your player should be able to move right at all. The code makes it look like pressing D makes it move down.

if (key == sf::Keyboard::D)
    {
        _IsMovingDown = isPressed;
        ...
 

By the way, you have a several uninitialized member variables in your game class. You should initialize everything in an initialization list in your constructor (or do the C++11 equivalent if you are familiar with it). Perhaps this is the reason your player moves right.

Sanction

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Weird movement in my program
« Reply #13 on: August 11, 2015, 11:14:48 pm »
Okay so Thanks to Arcade I got this sticky movement fixed. I initialize some variables and 'D' key fixed..
Arcade how would you initialize everything in an initialization list in your constructor ?

Jesper, That really help explain a lot thankyou. The FPS seems to be working correctly however it seems to gallop.. I added a sf::shape called test that just moves across the screen and he seems to gallop.. I don't know how to explain it. same with player movement.

Game.cpp
(click to show/hide)

Game.h
(click to show/hide)
« Last Edit: August 11, 2015, 11:17:10 pm by Sanction »
Knowledge comes, but wisdom lingers. It may not be difficult to store up in the mind a vast quantity of facts within a comparatively short time, but the ability to form judgments requires the severe discipline of hard work and the tempering heat of experience and maturity.

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: Weird movement in my program
« Reply #14 on: August 11, 2015, 11:33:20 pm »
Quote
Arcade how would you initialize everything in an initialization list in your constructor
How you have done it in the header file is the more modern (C++11) way to initialize things and is generally fine (except you forgot _StatisticsNumFrames).

Alternatively, you could have used an initialization list in the constructor. You are actually already using the initialization list for a few things, but if you wanted to initialize all variables this way it would look like this (I did not try compiling this so there may be typos):

Game::Game()
   : _Window(sf::VideoMode(640, 480), "Window"),
      _Player(),
      timestep(sf::seconds(1.f) / 40.f),
      remainder_time(sf::seconds(0.f)),
      elapsed_time(sf::seconds(0.f)),
      _StatisticsUpdateTime(),
      _StatisticsNumFrames(0),
     isPressed(false),
    _IsMovingUp(false),
    _IsMovingDown(false),
    _IsMovingLeft(false),
    _IsMovingRight(false),
    velocity(100.f)
{
   ...
}
 

Anyway, you probably get the idea. Another thing to keep in mind is that you should order the initialization list in the same order you have the variables in the header file. You can also omit things from the initialization list that have default constructors, such as _Player, though some people argue that this is bad practice.
« Last Edit: August 11, 2015, 11:36:09 pm by Arcade »