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

Author Topic: sf::Seconds delay?  (Read 14994 times)

0 Members and 3 Guests are viewing this topic.

rush905

  • Newbie
  • *
  • Posts: 36
    • View Profile
sf::Seconds delay?
« on: August 23, 2012, 07:01:17 am »
I'm trying to get a delay in between events. The point of this is so that when the user tries to move the character, they can't simply hold down the arrow key and fly off into the distance. Now I looked into the documentation for handling time, but all I could find was how to measure it. Now how to delay the program.

So is there any way to do this? I'm sure it's really simple, and I'm just not seeing the obvious here.

I don't think showing source here is necessary, but if anyone needs it, let me know.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: sf::Seconds delay?
« Reply #1 on: August 23, 2012, 09:06:10 am »
I think the sf::Clock class can help you there.
« Last Edit: August 23, 2012, 09:25:34 am by Hiura »
SFML / OS X developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::Seconds delay?
« Reply #2 on: August 23, 2012, 09:24:47 am »
As Hirua said using a sf::Clock you can messure the delay time and as long as it hasn't stepped over the delay time you simply do not process the event. If you want to process the events afterwards you'll have to store them, although this might generate strange behaviour. :D
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Re: sf::Seconds delay?
« Reply #3 on: August 23, 2012, 01:29:28 pm »
For the purpose of a moving character I think that using the delta time between the frames can be used for that.

if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)==true)
  movement.y -= 1 * delta_time );

Now you'll have to change it depending on how your implementation works but this is the most common thing to do. Though the other ways proposed have it's benefits as well. But this one works with least amount of code and least amount of trouble.

If I am unclear I can give you more hints on how to do this ;)
« Last Edit: August 23, 2012, 01:31:56 pm by Groogy »
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

rush905

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: sf::Seconds delay?
« Reply #4 on: August 23, 2012, 05:38:00 pm »
For the purpose of a moving character I think that using the delta time between the frames can be used for that.

if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)==true)
  movement.y -= 1 * delta_time );

Now you'll have to change it depending on how your implementation works but this is the most common thing to do. Though the other ways proposed have it's benefits as well. But this one works with least amount of code and least amount of trouble.

If I am unclear I can give you more hints on how to do this ;)

I'm having a bit of trouble thinking of how that actually works. I was thinking that I would start a clock, then I would have an if statement like so:

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && clock.getElapsedTime > sf::Seconds(.25))
{
    sprite.move(0, -14);
}
 

But when I do that, and run the program, the sprite doesn't even move. What's wrong with that?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::Seconds delay?
« Reply #5 on: August 23, 2012, 06:08:55 pm »
Well if you want framerate depended movement then you'll have to do what Groogy proposed.

Something like:
sf::Sprite sprite;
sf::Vector2i direction(0, -1);
sf::Vector2f speed(0, 14);
sf::Clock clock;
while(window.isOpen())
{
    sf::Time dt = clock.restart();

    sf::Event event;
    while(window.pollEvent(event))
    {
        if(even.type == sf::Event::Closed)
            window.close();
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
    {
        sprite.move(0, direction.y * speed.y * dt.asSeconds());
    }
}

The sf::Clock will get restarted every frame thus, it will capture the time between two frames aka delta time or dt.
If you now take the velocity (speed) and multiply it by dt then you get the speed for that short time period and you don't apply the fully velocity for every frame. The direction variable is just a help to easily swap directions without having to change the actual velocity value.
It's adviced to use window.setFramerateLimit and use a fixed timestep (dt) to match the framerate (i.e. dt = 1/FPS).
« Last Edit: August 23, 2012, 06:17:28 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

rush905

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: sf::Seconds delay?
« Reply #6 on: August 23, 2012, 06:36:46 pm »
Well if you want framerate depended movement then you'll have to do what Groogy proposed.

Something like:
sf::Sprite sprite;
sf::Vector2i direction(0, -1);
sf::Vector2f speed(0, 14);
sf::Clock clock;
while(window.isOpen())
{
    sf::Time dt = clock.restart();

    sf::Event event;
    while(window.pollEvent(event))
    {
        if(even.type == sf::Event::Closed)
            window.close();
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
    {
        sprite.move(0, direction.y * speed.y * dt.asSeconds());
    }
}

The sf::Clock will get restarted every frame thus, it will capture the time between two frames aka delta time or dt.
If you now take the velocity (speed) and multiply it by dt then you get the speed for that short time period and you don't apply the fully velocity for every frame. The direction variable is just a help to easily swap directions without having to change the actual velocity value.
It's adviced to use window.setFramerateLimit and use a fixed timestep (dt) to match the framerate (i.e. dt = 1/FPS).

I'm not quite understanding what exactly this code is doing. For example, why are you multiplying the direction by the speed, and the time? What does that accomplish? Also, why do you have a vector "speed" , and multiplying that by -1. Why not just get rid of the vector and just have the sprite move -14 pixles. It would kill two birds with one stone.

Again, sorry if these are stupid questions, I simply want a better understanding of this.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::Seconds delay?
« Reply #7 on: August 23, 2012, 06:57:55 pm »
Well I'm not sure if you have read my explenation underneath the code, it actually explains most of what you've ask.

If you want to move your sprite by -14px the you have to ask yourself in what time period do I want to move that? Do you want it to move just once -14px? Do you want to smoothly move it from point A to point B with a speed of -14px per second?
If you do not take care of timing (i.e. sprite.move(0, -14)) then your sprite will move with a speed of -14px*FPS and with a simple application drawing one sprite you can get around 500-5000fps thus your sprite would move with a speed of -7'000px/s-70'000px/s which well isn't really usefull. Thus you have to make your movement depended of the framerate (/ fixed timestamp with fixed fps). That's where the velocity*dt comes in.

Like I already said the direction is just an easy way to change direction without having to influence the actual velocity value, but you can of course merge them together and just use positive/negative velocities to describe the direction.

The use of vectors comes from math/physics itself. An object can have a diffrent x and y velocity, e.g. you can jump with -14px/s but you don't have to move forward thus your x speed would be 0px/s. Now instead of having two variables speedx and speedy you simply merge them into one class 'vector'. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

rush905

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: sf::Seconds delay?
« Reply #8 on: August 23, 2012, 07:10:04 pm »
Ok, I'm starting to understand now. But when I use your code, the sprite is only moving 1 pixle per 1 second. Why is that?

Source:

http://pastebin.com/YgMCYtYs

EDIT: When I change the value of how much it moves to a much larger number, there's no delay at all. It moves whenever I press the key. And if I hold it down, the sprite freezes, but when I release it move really far.
« Last Edit: August 23, 2012, 07:16:45 pm by rush905 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::Seconds delay?
« Reply #9 on: August 23, 2012, 07:25:40 pm »
Well you're doing a few things wrong. ;)

First if you hardcode your speed you obviously don't need that 1/-1 for direction...
Second take again a closer look at my example, I've put the movement function outside of the while(window.pollEvent()) loop. That's what you have to do too. If your code does not depend on an event then it should never be in the event loop.
Third you're loading a new image whenever you press a key, this leads to the freezing, when keeping the key pressed, since SFML then is working very hard loading constantly a new image => very inefficient.
At best you should put all the diffrent images of your character in one image and then load this onces. You then can use sprite.setTextureRect to change the visible rectangle on the texture (i.e. you can 'cut' out the image you need). That way you'd load the texture once and then only move the rectangle on the loaded image.

I would suggest to use setFramerateLimit since one can force VSync to be off or on from the system and SFML's setVerticalSync won't be able to change anything.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

rush905

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: sf::Seconds delay?
« Reply #10 on: August 23, 2012, 11:19:53 pm »
Alright, well I did what you said, but now the Sprite isn't showing up.

Source:

http://pastebin.com/SePTHHNh

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::Seconds delay?
« Reply #11 on: August 23, 2012, 11:29:05 pm »
Well are all the rects correctly configured?
Otherwise it wouldn't make any sense that it doesn't show up.

Btw: You can also post the code here to the forum with the code=cpp tag and if you ever post code to pastebin, make sure to choose the right syntax highlighting (e.g. C++) so we don't have to stare at black text which makes it hard to understand... ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

rush905

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: sf::Seconds delay?
« Reply #12 on: August 23, 2012, 11:30:57 pm »
Sorry, I just didn't want to have it take up so much room here, so I decided to put it else where. And sorry about the not choosing C++, silly mistake. I'll take a look at it again, and see if I can fix it.

Oh, quick question. With "sprite.setTextureRect(), the first two arguments are for the cords of the top left corner of the selection, correct? Or, you could just link me to the documentation, because I have a hard time finding the write page   :-[
« Last Edit: August 23, 2012, 11:35:25 pm by rush905 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::Seconds delay?
« Reply #13 on: August 23, 2012, 11:37:34 pm »
Oh, quick question. With "sprite.setTextureRect(), the first two arguments are for the cords of the top left corner of the selection, correct? Or, you could just link me to the documentation, because I have a hard time finding the write page   :-[
Yes as described in the documentation. :D
Well you click on 'Classes' and then choose the one you want to inspect further and there you'll also find links to related classes etc. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

rush905

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: sf::Seconds delay?
« Reply #14 on: August 23, 2012, 11:52:55 pm »
   
sf::Rect< T >::Rect     (       T       rectLeft,
                T       rectTop,
                T       rectWidth,
                T       rectHeight
        )              

That's from the documentation. How do I pass in 4 cords with only 4 integers? Should I be passing in 4 vectors instead, because they store an x and a y cord? Also, I'm not understanding the first two params.
« Last Edit: August 23, 2012, 11:57:37 pm by rush905 »

 

anything