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;
}
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. ;)