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

Author Topic: Help with nested if statements? (sf::Time)  (Read 4202 times)

0 Members and 1 Guest are viewing this topic.

Pikmeir

  • Newbie
  • *
  • Posts: 31
    • View Profile
Help with nested if statements? (sf::Time)
« on: July 30, 2012, 06:16:41 am »
Hey guys,
I'm finally adding timers into my game for using special items and spells. I'm not sure if this is a simple nested if statement problem I'm having, or if it's related to sf::Time.

When I click on the screen, it'll wait 5 seconds (it seems a bit short though) then display the message on the console.
After that, when I click again it'll immediately display the message again, instead of waiting the appropriate 5 seconds. Isn't it supposed to have reset to default, and not automatically show the message for another 5 seconds? Anyway I'm a bit stumped here.

Here's the shortest possible example of this I could replicate (this of course isn't my actual code since it's way too long, but this is set up the same way as my real program is).

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <iostream>

std::vector <sf::Time> timerArray (200); // one for each spell
sf::Time currentTime;

// Every spell gets a 5 second timer
void castSpell(unsigned int spellNumber)
{ timerArray.at(spellNumber) = currentTime + sf::seconds(5); }

int main () {
        sf::RenderWindow Screen (sf::VideoMode (800, 600, 32), "Game");

        sf::Clock clock;
        sf::Time startTime = clock.restart();
        sf::Time currentTime = clock.getElapsedTime();

        // Activate all consumable timers (set to startTime)
        for (int i = 1; i <= 199; i++)
        { timerArray.at(i) = startTime; } // default is startTime

        while (Screen.isOpen()) {
                Screen.clear();
                currentTime = clock.getElapsedTime();
       
                sf::Event Event;
                while (Screen.pollEvent (Event)) {
                        if (Event.type == sf::Event::Closed)
                        { Screen.close(); }
                        if (Event.type == sf::Event::MouseButtonPressed)
                        { castSpell(4); }
                }

                // Remove effects of spells (if any)
                for (int i = 1; i <= 199; i++)
                {
                        if (timerArray.at(i) != startTime) // if not in default setting
                        {
                                if (timerArray.at(i) <= currentTime) // if the current time surpasses the set timer
                                {
                                        timerArray.at(i) = startTime; // reset the timer to default
                                        switch (i)
                                        {
                                                case 4: // Spell # 4
                                                        std::cout << "Death spell has worn off!" << std::endl;
                                                        break;
                                                default:
                                                        break;
                                        }
                                }
                        }
                }

                Screen.display();
        }

        return 0;
}
« Last Edit: July 30, 2012, 06:20:21 am by Pikmeir »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Help with nested if statements? (sf::Time)
« Reply #1 on: July 30, 2012, 09:27:43 am »
Although you do reset it before displaying the message, it doesn't matter since you change the time value currentTime+5 at any point in time.
But it actually should indeed wait for another 5 seconds.

Btw you should never put the Screen.clear() command at the beginning of the game loop, but instead it should come directly before the first draw call.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Pikmeir

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: Help with nested if statements? (sf::Time)
« Reply #2 on: July 30, 2012, 09:39:30 am »
You're saying that what I have should work, but simply isn't?
Maybe I should figure out a new way to set/clear timers.

I'll swap the Screen.clear() command before my first draw call. I wasn't sure the best place to put it. Thanks for that advice.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Help with nested if statements? (sf::Time)
« Reply #3 on: July 30, 2012, 11:58:04 am »
You're saying that what I have should work, but simply isn't?
Maybe I should figure out a new way to set/clear timers.
No it meant I did have time to test and debug it on my own and could only stare at it. ;)

The problem is that you declare currentTime twice, once in the global scope and once in the main function:
sf::Time currentTime; // 1
int main() {
//...
sf::Time currentTime = clock.getElapsedTime(); // 2

Now calling currentTime within the main function will use the currentTime marked as 2 but from the castSpell function it will call currentTime marked as 1.
The global currentTime will always be 0 thus currentTime + sf::second(5) in the castSpell function will always result in 5s. In the beginning when the application didn't run for 5 seconds it will shown delayed (but a porbably a bit too short as you've noticed) and later on the runtime will long have exceeded those 5s. ;)
Although you said your code looks diffrent in the original, I just wanted to point out that using global varaibles isn't such a good idea.
Btw if you want to access a global variable but you have the same name used for a local variable you can use ::var to access it. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Pikmeir

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: Help with nested if statements? (sf::Time)
« Reply #4 on: July 30, 2012, 08:08:36 pm »
Thank you so much! I simply removed the "sf::Time currentTime = clock.getElapsedTime();" from the start of main() and it works now. I didn't even realize that I was declaring it twice.

I have a few other global variables that are used this way too (in my actual program), so I'll think of a way to not have to use them anymore. Perhaps they could cause more problems like this for me in the future.

Thanks again for your help.