SFML community forums

Help => General => Topic started by: ikarah on March 12, 2016, 12:02:01 am

Title: I want to make sprites appear with a random time delay
Post by: ikarah on March 12, 2016, 12:02:01 am
I want to make certain sprites appear with a random time delay. For some reason just putting in this code in the beginning of main to begin with.


   sf::Clock clock;
      Time time1 = clock.getElapsedTime();
      Time time2 = clock.restart();

It gives me an error that time is an undeclared identifier? How can I go about doing this.  :(
Title: Re: I want to make sprites appear with a random time delay
Post by: eXpl0it3r on March 12, 2016, 12:07:17 am
Probably because it's missing the sf:: namespace?
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 12, 2016, 12:08:00 am
Yes I figured it out by doing this

sf::Clock Clock;
   sf::Time time;
      time = Clock.getElapsedTime();
      Clock.restart();

But how can I make sprites appear at random times within a certain time range somehow?

Also when I do something like this

if (time.asSeconds() >= 10.0f) {
            Window.draw(Player1);
         }

It just doesn't work. The code runs fine but nothing is drawn after the 10 seconds pass
Title: Re: I want to make sprites appear with a random time delay
Post by: Arcade on March 12, 2016, 12:50:14 am
You don't really give enough information about your code to tell what is going wrong. I'll try to take some guesses though.

Quote
sf::Clock Clock;
sf::Time time;
time = Clock.getElapsedTime();
Clock.restart();
 

Clock.getElapsedTime() returns the amount of time since the clock was constructed or last restarted. You are constructing the clock right before this call, so not much time will have passed at all. If you aren't reading from the clock again later in your code in a loop or something then your time variable certainly won't be 10 seconds.

Also, make sure you are displaying your window after you draw to it.
Title: AW: I want to make sprites appear with a random time delay
Post by: eXpl0it3r on March 12, 2016, 12:50:21 am
Time only holds a certain duration, e.g. like 2s or 500ms, it doesn't change unless you assign it a new value.

You can use the clock and generate random numbers with the functions found in the C++ header <random>.
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 12, 2016, 03:55:00 am
Ok I will clarify,

As a test I first created the following:

sf::Clock clock;
   sf::Time time;
      time = clock.getElapsedTime();
   while (Window.isOpen()) {
      sf::Event Event;
      while (Window.pollEvent(Event)) {
         sf::Time t1 = sf::seconds(10.0);
         time = clock.getElapsedTime();
         std::cout << time.asSeconds() << std::endl;
         std::cout << t1.asSeconds() << std::endl;

         if (time.asSeconds() >= t1.asSeconds()) {
            std::cout << "player 1 is drawn";

         }

With this code I do in fact get "Player 1 is drawn" on the console after 10 seconds. However when I place the following code,

Window.draw(PlayerTwo); in the if statement and i already defined the sprite image and texture before in main. Nothing gets drawn on my window. What is going on here? There are no errors too.
Title: Re: I want to make sprites appear with a random time delay
Post by: Hapax on March 12, 2016, 04:07:34 am
make sure you are displaying your window after you draw to it.
You did not answer this.
Are you using window.display()?
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 12, 2016, 04:11:23 am
Yes of course window display and window clear
Title: Re: I want to make sprites appear with a random time delay
Post by: Hapax on March 12, 2016, 06:25:20 am
Where is your clear? Is just before your display (but after your draw)?
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 12, 2016, 02:11:09 pm
It is after my window draw and window display. Is this what's causing the issue?
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 12, 2016, 07:52:03 pm
Ok so I removed the window clear and my code worked but now the sprite is flashing non stop I want it to be a stable image. What is causing this flashing if the condition of the time has been met?

I figured that this was due to me placing the code in the event poll area instead of the window open area.. Now how can I generate a random time within a certain time range for example. Generate random seconds between 5-10 seconds?

Also I realized that it will continue to draw the sprite continuously since the condition was met I only want it to draw the sprite once and thats it. How can I do that?
Title: AW: I want to make sprites appear with a random time delay
Post by: eXpl0it3r on March 12, 2016, 09:04:06 pm
So you removed all clear statements?

You should always clear(), draw(), display().
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 12, 2016, 09:17:55 pm
That advice worked perfectly. Now, how can I make random variables?
float x for example

I want x to carry random numbers in a certain range? For example from 5-9
Title: Re: AW: I want to make sprites appear with a random time delay
Post by: korczurekk on March 12, 2016, 10:09:01 pm
So you removed all clear statements?

You should always clear(), draw(), display().
clear() isn't always needed, well, it's useless in almost every bigger project which overwrites whole screen with some background.

That advice worked perfectly. Now, how can I make random variables?
float x for example

I want x to carry random numbers in a certain range? For example from 5-9
Use something like this:

rand() % (9 - 5) + 5;
or
rand() % (9 - 5 + 1) + 5;

EIDT: Or if you want floating point value like 0.01:
static_cast<float>(rand() % (900 - 500) + 500) / 100.f;
Title: AW: Re: AW: I want to make sprites appear with a random time delay
Post by: eXpl0it3r on March 12, 2016, 10:18:20 pm
clear() isn't always needed, well, it's useless in almost every bigger project which overwrites whole screen with some background
This is wrong. SFML requires you to call clear, due to double buffering.
Title: Re: AW: Re: AW: I want to make sprites appear with a random time delay
Post by: korczurekk on March 12, 2016, 10:19:45 pm
clear() isn't always needed, well, it's useless in almost every bigger project which overwrites whole screen with some background
This is wrong. SFML requires you to call clear, due to double buffering.
I don't use it for a long time and haven't noticed any problems, what can be wrong?
Title: Re: AW: I want to make sprites appear with a random time delay
Post by: Jesper Juhl on March 12, 2016, 10:22:11 pm
So you removed all clear statements?

You should always clear(), draw(), display().
clear() isn't always needed, well, it's useless in almost every bigger project which overwrites whole screen with some background.
Please, please don't say that.
Yes, if you do draw the entire screen, then clear() is pointless. But it is also harmless. It doesn't hurt performance and it doesn't screw up rendering.
When it /is/ needed it really is needed. You get strange rendering artifacts if you leave it out.
You should just always do it. It doesn't hurt when not needed and it does real needed work when needed (most of the time).
Please don't advice people to skip it.
clear(), draw(), display() - always!
Title: Re: I want to make sprites appear with a random time delay
Post by: korczurekk on March 12, 2016, 10:31:00 pm
So you removed all clear statements?

You should always clear(), draw(), display().
clear() isn't always needed, well, it's useless in almost every bigger project which overwrites whole screen with some background.
Please, please don't say that.
Yes, if you do draw the entire screen, then clear() is pointless. But it is also harmless. It doesn't hurt performance and it doesn't screw up rendering.
When it /is/ needed it really is needed. You get strange rendering artifacts if you leave it out.
You should just always do it. It doesn't hurt when not needed and it does real needed work when needed (most of the time).
Please don't advice people to skip it.
clear(), draw(), display() - always!
I don't say people should skip it.  :)

However, those "strange rendering artifacts" are very characteristic and removing clear() helped me a lot in searching for other rendering bugs. I don't see any problem in using it for debugging.
Title: Re: I want to make sprites appear with a random time delay
Post by: Laurent on March 12, 2016, 10:39:43 pm
Quote
This is wrong. SFML requires you to call clear, due to double buffering.
clear() just fills the whole buffer with a color. If the next thing you do is to fill it with something else, it is indeed not required -- it is even mentioned in the tutorials ;)
And double-buffering has nothing to do with this.
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 13, 2016, 01:58:45 am
Alright back on topic haha. The random and all worked great. I want to be able to delay with time though for example

if (bla = bla){

Dosomething;

Wait 5 seconds then start again from the top
}

How can I do that using time or clock?
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 13, 2016, 07:02:10 pm
Bump anyone?
Title: Re: I want to make sprites appear with a random time delay
Post by: OualidH38 on March 13, 2016, 08:15:01 pm
/*Use a boolean for your condition: mValue
a float that will holds the time: mCountDown
another float with a const value sf::seconds(5.f): TimeInterval

Use this inside an update function with an sf::Time dt that holds elapsedTime */


if (mValue && mCountDown <= sf::Time::Zero) {

                mValue= false;

                //Do your stuff here

                mCountDown += TimeInterval;
               
               
        }
        else if (mCountDown > sf::Time::Zero) {

                mCountDown -= dt;

}

 
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 13, 2016, 08:42:58 pm
I don't really understand the code you sent me ?
Why is mvalue which is a bool less than time zero? What are you achieving with the += and the -= Please elaborate ..
Title: AW: I want to make sprites appear with a random time delay
Post by: eXpl0it3r on March 13, 2016, 08:58:52 pm
Have you ever sat down and thought it through on your own? I mean programming shouldn't consist of waiting for people to suggest random things that one can then pretty much copy&paste.

I suggest to take a piece of paper and a pen, sit down and go step by step through the logic of how to go about it.
Make use of what you have (clock, random number generator, sprites) and figure out when you can use what where and how it will fit into your solution. ;)
Title: Re: I want to make sprites appear with a random time delay
Post by: OualidH38 on March 14, 2016, 12:13:42 am
I don't really understand the code you sent me ?
Why is mvalue which is a bool less than time zero? What are you achieving with the += and the -= Please elaborate ..

I suggest you to read carefully what I wrote, I'm not trying to compare a bool with sf::Time::Zero.
The if statement tests the boolean and the mCountDown value.

eXpl0it3r is right, you should learn a bit more before asking for a pre-made solution.
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 14, 2016, 11:30:21 am
Actually I was able to solve my problem in a completely different way on my own which is fine. But, because I want to learn more and have a thirst for knowledge I am asking since I tried to understand the logic behind the code you put here and didn't really get the Boolean part? That's why I am asking. It's fine to ask questions when you don't understand otherwise you won't learn. As for asking for code to copy paste in that's obviously not what I am asking for because that is pointless and each and every program is written in a different way.
Title: Re: I want to make sprites appear with a random time delay
Post by: OualidH38 on March 14, 2016, 01:51:31 pm
Can you please past the solution here and put your problem as "solved" if you found a solution by your own?

I was not trying to be mean when I said that you should learn a bit more. The if statement was a basic condition, and you did not understand it. No offense.

I admire the fact that you are motivated and looking for how things work, but start with the begining (c++ basis, logic, etc) before.

It's fine when you ask questions of course, but the logic that I've put before is easy to understand.

Sorry if I offended you, that was not my purpose.
Good luck
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 14, 2016, 07:02:50 pm
Well the way I did it was like so

sf::Time t1 = sf::milliseconds(500);
      sf::Time t2 = sf::milliseconds(1000);
      time = clock.getElapsedTime();
      sf::Event Event;
      if ((time.asMilliseconds() >= t1.asMilliseconds()) && (time.asMilliseconds() <= t2.asMilliseconds())) {
      clock.restart();
}

Basically that way it will meet this condition only once then the clock will restart achieving the delay effect I wanted. I understand if statements but, the way you went about it is just different.
Title: Re: I want to make sprites appear with a random time delay
Post by: Jesper Juhl on March 14, 2016, 07:30:25 pm
This is fragile and will fail if, for some reason, you are not passing through this code at least once every 0.5 seconds and you end up with time.asMilliseconds() returns 5000 for example.
This could happen if the user drags the window so events are not processed for a while or for many other reasons.
Title: Re: I want to make sprites appear with a random time delay
Post by: ikarah on March 14, 2016, 09:00:26 pm
Thank you Jesper what do you recommend then?
Title: Re: I want to make sprites appear with a random time delay
Post by: Hapax on March 15, 2016, 04:41:14 pm
A way to avoid the missing the passing of time when the application is not active (i.e. blocked during OS modification), you can simple use an accumulation time and add to it the amount of time that has passed since the last frame - as long as that frame time is shorter than a chosen boundary.

sf::Clock;
sf::Time frameTime;
sf::Time accumulatedTime = sf::Time::Zero;
sf::Time maximumFrameTime = sf::milliseconds(200);

{
    // inside main loop
    frameTime = clock.restart();
    if (frameTime > maximumFrameTime)
        frameTime = maximumFrameTime;
    accumulatedTime += frameTime;
}

Then, "accumulatedTime" is the current time passed and would never process a frame of more than 200 milli-seconds. Note that some time can be discarded in this method. Although that is the intention for this method, it may be unwanted in some cases (real-time timing, for example).

Title: Re: I want to make sprites appear with a random time delay
Post by: Jesper Juhl on March 16, 2016, 08:28:51 am
... what do you recommend then?
Well, there are many ways to do it.
If you want to stick to your current solution you could modify it slightly as
 if ((time.asMilliseconds() >= t1.asMilliseconds()) &&
    (time.asMilliseconds() <= t2.asMilliseconds()) ||
    time.asMilliseconds() > t2.asMilliseconds()) {
that would address the specific problem I pointed out, but it's not really elegant.

Another option would be to calculate the time in the future when you want the object to spawn as "now() + nr_of_ms_until_spawn" and then simply check if "now()" is greater than or equal to that value and spawn an object if it is and then calculate a new spawn time.

What I would probably do myself would be to generate a random number between 500 and 1000 using the facillities in the <random> header (like std::random_device, std::mt19937 & std::uniform_int_distribution) and then set a timer to trigger a spawn_object() callback after that many milliseconds.

See also:
 http://en.cppreference.com/w/cpp/numeric/random
 http://en.cppreference.com/w/cpp/header/random
 http://www.bromeon.ch/libraries/thor/documentation/v2.0/classthor_1_1_callback_timer.html
Title: Re: I want to make sprites appear with a random time delay
Post by: Hapax on March 16, 2016, 08:10:32 pm
 if ((time.asMilliseconds() >= t1.asMilliseconds()) &&
    (time.asMilliseconds() <= t2.asMilliseconds()) ||
    time.asMilliseconds() > t2.asMilliseconds()) {
Assuming that t1 is before t2, that code is equivalent to:
if (time.asMilliseconds() >= t1.asMilliseconds()) {
Title: Re: I want to make sprites appear with a random time delay
Post by: Jesper Juhl on March 16, 2016, 09:23:33 pm
Right you are Hapax.
I didn't think too much about that since I think the better option in any case is a timer with a random time (within the required limits) and a callback function is the better option. So I just tacked on a bit of code to his version to address the issue I noted without giving it much thought ;)
Title: Re: I want to make sprites appear with a random time delay
Post by: Hapax on March 16, 2016, 09:53:03 pm
Just as an aside, there's no real need for us to use "asMilliseconds()" here as an sf::Time can be compared to another sf::Time.
That line could just be:
if (time >= t1) {
;D
Title: Re: I want to make sprites appear with a random time delay
Post by: Jesper Juhl on March 16, 2016, 09:55:00 pm
Sure. But that's not really central to OP's problem. But you are right of course (and it is nicer that way).