For example, I have a Game class and it keeps an int
that tracks the player's lives. I have a conditional
if ( mLives < 1 ) {
// Do some work.
}
However this condition keeps firing and the work is done repeatedly. For example, I want to set a timer to exit the game in 5 seconds. Currently, it will keep setting it to 5 seconds every frame and the game never ends.
This is just one example, and I have the same problem in several areas of my game. I want to check for some condition and then do something once and only once, and then not check or do the code in the if-statement again. Some possible solutions that come to mind are having a bool
for each condition and set the bool
when the condition fires. However in practice this gets very messy handling lots of bools
, since they have to be stored as class fields, or statically within the method itself.
What is the proper solution to this (not for my example, but for the problem domain)? How would you do this in a game?
Answer
I think that you can solve this problem simply by exerting more careful control over your possible code paths. For example, in the case where you're checking if the number of the player's lives has dropped below one, why not check only when the player loses a life, instead of every frame?
void subtractPlayerLife() {
// Generic life losing stuff, such as mLives -= 1
if (mLives < 1) {
// Do specific stuff.
}
}
This, in turn, assumes that subtractPlayerLife
would only be called on specific occasions, which would perhaps result from conditions that you must check every frame (collisions, perhaps).
By carefully controlling how your code executes, you can avoid messy solutions like static booleans and also cut down bit-by-bit on how much code is executed in a single frame.
If there's something that just seems impossible to refactor, and you really need to only check once, then state (like an enum
) or static booleans are the way to go. To avoid declaring the statics yourself, you can use the following trick:
#define ONE_TIME_IF(condition, statement) \
static bool once##__LINE__##__FILE__; \
if(!once##__LINE__##__FILE__ && condition) \
{ \
once##__LINE__##__FILE__ = true; \
statement \
}
which would make the following code:
while (true) {
ONE_TIME_IF(1 > 0,
printf("something\n");
printf("something else\n");
)
}
print something
and something else
only once. It doesn't yield the best looking code, but it works. I'm also pretty sure there are ways to improve it, perhaps by better ensuring unique variable names. This #define
will only work once during the runtime though. There is no way to reset it, and there is no way to save it.
Despite the trick, I strongly recommend better controlling your code flow first, and using this #define
as a last resort, or for debug purposes only.
No comments:
Post a Comment