3
« on: December 14, 2012, 08:10:59 am »
I see what you're doing now. what you basically need to do is separate your event-handling code from your update code. There are two ways you could do this:
The first (and probably best) way to do this is to have separate Update() and HandleEvent() functions. The Update() function is what is called outside the event loop and would take the time and advance the game objects' states by the appropriate time. The HandleEvent() function would be what is called within the event loop, and instead of advancing object state it sets flags (i.e. isFading) based on what the events signal.
Alternately, you could keep the single update() method and create some way to signal to it that you are advancing time instead of handling a received event. There are a couple of ways to do this; for example, you could pass a pointer to the event object and have the pointer be NULL on non-event updates or you could have a separate isEvent parameter to the function.
In both cases, you are distinguishing the logic of advancing time versus handling an event. That way, you aren't advancing the time more than once per frame, and all events only get handled once (if you look, you'll see that your code will handle the last event received in a frame twice: in the event loop and then immediately afterward, and even more if the next frame has no events.)
The way this works is that when in the "handling events" stage of your frame, you modify the state of your object. For example, when the event means for you to start fading, all it would do is set an isFading flag to true. This is all the event handling needs to do. Then, in the Update stage, your object checks the isFading flag and if it is true fades the screen by the appropriate amount.
Here's a bit of pseudocode to explain:
//object
class Object : public sf::Sprite {
public:
void HandleEvent(sf::Event e) {
if(e.type == [whatever triggers your fade])
isFading = true;
};
void Update(float time) {
fadeBy(fadePerSec * time); // or however you fade
};
private:
bool isFading;
};
// run loop
Object obj;
sf::Event event;
while (win.isRunning()) {
while(win.pollEvent(event)) {
obj.handleEvent(event);
}
obj.Update(clock.restart()); // I pass the time in my update function; you set it as an attribute of your ScreenManager, which works too.
win.draw(obj);
}