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

Author Topic: Propes use of Clock and Time for smooth movement  (Read 8386 times)

0 Members and 1 Guest are viewing this topic.

mentor

  • Newbie
  • *
  • Posts: 31
    • View Profile
Propes use of Clock and Time for smooth movement
« on: August 12, 2013, 02:54:28 pm »
 Hi!

I started writing a simple game in C++ using SFML 2.1. But I have a problem with smooth movement. I create a new clock, then get elapsed time and convert it to microseconds:

Clock clock;
Time time = clock.getElapsedTime();
float elapsed = time.asMicroseconds();

Next, in game loop I move the paddle:

while (window.isOpen()) {
        Event evt;
        while (window.pollEvent(evt)) {
                pad.move(elapsed);
                clock.restart();
        }

The method move:

void Paddle::move(float elapsed)
{
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) get().move(speed * elapsed * -1, 0);
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) get().move(speed * elapsed, 0);
}

Paddle moves, but it's not a smooth movement I'd like to have here. I've read about Clock and Time classes, but still I don't know how to solve this problem. Can anyone help?
« Last Edit: August 12, 2013, 02:58:22 pm by Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Propes use of Clock and Time for smooth movement
« Reply #1 on: August 12, 2013, 03:00:40 pm »
Quote
float elapsed = time.asMicroseconds();
You should store the elapsed time as seconds, not microseconds. Currently it makes you choose speeds in pixels / microsecond instead of pixels / second.

I'm not sure it would solve your problem though. If it doesn't, please show a complete and minimal code that reproduces the problem.
Laurent Gomila - SFML developer

mentor

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: Propes use of Clock and Time for smooth movement
« Reply #2 on: August 12, 2013, 03:08:26 pm »
Unfortunately, it doesn't solve the problem. I used Seconds, but I couldn't even move the paddle with it, that's why I used Microseconds.

Entire code? Here it is.

shapes.h
Code: [Select]
#ifndef shapes_h
#define shapes_h

#include <SFML/Graphics.hpp>

class Paddle
{
private:
int x, y;
int width, height;
float speed;
sf::RectangleShape rect;

protected:
sf::RectangleShape& get();

public:
Paddle(int nx, int ny, int nwidth, int nheight, float nspeed);
~Paddle();
void init();
void draw(sf::RenderWindow& win);
void move(float);
};

#endif

shapes.cpp
Code: [Select]
#include "shapes.h"

Paddle::Paddle(int nx, int ny, int nwidth, int nheight, float nspeed) { x=nx; y=ny; width=nwidth; height=nheight, speed=nspeed; }

Paddle::~Paddle() { }

sf::RectangleShape& Paddle::get()
{
return rect;
}

void Paddle::init()
{
rect.setPosition(x, y);
rect.setSize(sf::Vector2f(width,height));
rect.setFillColor(sf::Color(255,255,255));
}

void Paddle::draw(sf::RenderWindow& win)
{
win.draw(rect);
}

void Paddle::move(float elapsed)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) get().move(speed * elapsed * -1, 0);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) get().move(speed * elapsed, 0);
}

main.cpp
Code: [Select]
#include <SFML\Graphics.hpp>
#include "shapes.h"

using namespace sf;

int main()
{
int w=800, h=600;
RenderWindow window(VideoMode(w,h), "Breakout");
window.setVerticalSyncEnabled(true);

Clock clock;
Time time = clock.getElapsedTime();
float elapsed = time.asMicroseconds();

Paddle pad((w-100)/2,(h-20-5),100,20,5);
pad.init();

while (window.isOpen()) {
Event evt;
while (window.pollEvent(evt)) {
if ((Keyboard::isKeyPressed(Keyboard::Escape)) || (evt.type == Event::Closed)) { window.close(); }
pad.move(elapsed);
clock.restart();
}

window.clear(Color::Black);
pad.draw(window);
window.display();
}

return 0;
}
« Last Edit: August 12, 2013, 03:10:09 pm by mentor »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Propes use of Clock and Time for smooth movement
« Reply #3 on: August 12, 2013, 03:10:17 pm »
Just change the speed value accordingly (in pixels / second).
Laurent Gomila - SFML developer

mentor

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: Propes use of Clock and Time for smooth movement
« Reply #4 on: August 12, 2013, 03:45:50 pm »
You mean something like this?

In the move method:
Code: [Select]
speed += 2.0

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Propes use of Clock and Time for smooth movement
« Reply #5 on: August 12, 2013, 03:49:43 pm »
I mean, if your speed was 0.001 (pixel / microsecond), then it should be changed to 1000 (pixels / second) if you work with seconds
Laurent Gomila - SFML developer

mentor

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: Propes use of Clock and Time for smooth movement
« Reply #6 on: August 12, 2013, 04:01:36 pm »
I get it...

Code: [Select]
float elapsed = time.asSeconds();
Paddle pad((w-100)/2,(h-20-5),100,20,1000);

Instead of:

Code: [Select]
float elapsed = time.asMicroseconds();
Paddle pad((w-100)/2,(h-20-5),100,20,1);

Right? But that doesn't solve the problem...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Propes use of Clock and Time for smooth movement
« Reply #7 on: August 12, 2013, 04:05:44 pm »
You measure some meaningless elapsed time at startup, and then always use this value. This doesn't make sense, you must update the elapsed time at every iteration of your game loop.
Laurent Gomila - SFML developer

mentor

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: Propes use of Clock and Time for smooth movement
« Reply #8 on: August 12, 2013, 04:17:51 pm »
OK, I added clock.restart() right after the game loop start. Now the movement is much more smooth. Thanks!