0
\$\begingroup\$

Within my game (which is Java/Android), I wish to draw a sprite only under certain conditions, so up until now, I've been using if statements to accomplish this. Something like so:

if (powerUpActive){

    draw(shieldSprite);

}

So the above, uses a simple boolean primitive (powerUpActive) and only draws the sprite (shieldSprite) when the boolean is true.

This works, however, my logic code is littered with if statements and I'm not sure this is a good thing. I keeps reading that too many if statements are a bad thing however, I can't work out how to accomplish this without using them.

Note, the above is just an example, I use many other boolean flags in my code

The only alternative that I can think of is to use a batch of sprites where I can specify the number to draw. (This is OpenGL ES 2.0 so I use a for loop to upload the vertices for the sprites I want to draw within the batch). If I simply set the number to draw to 0, it won't draw any. However, it seems a little overkill to use a batch when I know there will only ever be one sprite in it.

public void draw(){

    for (int i = 0;i < numberToDraw; i++){

        //Code here to upload vertices
    }

    //Code here to draw sprite (draws nothing if numberToDraw is set to 0)

}

So I'm really not if there is a better way do things in java on condition without using if's or switch statements.

\$\endgroup\$
  • 1
    \$\begingroup\$ This question has a faulty premise: that using if statements to determine whether to render sprites is somehow bad. Without elaborating on why you think it's bad, or what those "certain conditions" are, you're really just asking for a list of programming techniques that avoid using if, which isn't really game dev related. \$\endgroup\$ – congusbongus Feb 6 '15 at 4:07
  • \$\begingroup\$ @congusbongus I think its bad because my render method is littered with if statements. It just looks a mess and is a nightmare when trying to maintain the code. Plus the fact that this is code called from my Game loop - which I'm attempting to make as efficient as possible. I'm not sure having all these ifs in a performance critical game loop is such a good idea. However fair enough. Feel free to migrate this question to SO if u feel it isn't game dev oriented enough (not sure if that's possible now it has answers?!) Cheers \$\endgroup\$ – BungleBonce Feb 6 '15 at 14:00
1
\$\begingroup\$

Great question!

Groo posted a fantastic answer to this question in a StackOverflow thread several years ago, which you can find here, which boils down to readability and future proofing is an enemy of the if statements.

That's not to say that you should always avoid if statements though! They have their uses, in simple, one off checks.

To answer your question, I would move

if (powerUpActive){

    draw(shieldSprite);

}

inside a function, in the class PowerUp like so:

class PowerUps {
    public void Check() {
        if (powerUpActive){

            draw(shieldSprite);

        }
    }
}

and just call

powerUp.Check; 

from render.

To future proof this, I would also even change powerUpActive to something even more specific like a class Shield, inside class PowerUp and then check it's activity with shield.enable() like so:

class PowerUps {
    class Shield {
        private boolean active = false;

        public void enable() {
            active = true;
        }

        public void disable() {
            active = false;
        }
    }
    public void Check() {
        if (shield.active){

            draw(shieldSprite);

        }
    }
}

The purpose of this is two-fold -- you can enable/disable power-ups from a game event easily, by calling powerUp.shield.enable() and draw it without having to worry too much about backtracking.

This may seem like a lot of work for one shield power-up, but it's a question of future-proofing your code and saving yourself hours, upon hours of hard work later on, when you would eventually want to expand.

Just think think about how pretty your render function will look! And how easy it will be to expand your game without worrying if you've broken something! I don't know about you, but I'm excited already! :3

NB: The examples I provided are just to elaborate on a point. In the real world you would probably want to use inheritance more actively and organize things even more, like keeping a reference to the shieldSprite inside the Shield class.

\$\endgroup\$
  • \$\begingroup\$ Thanks @Sipty. I read through Groo's answer but still a little confused. OK so I already have a PowerUps class. What is 'Check' in your answer? I can call draw(shieldSprite) directly from my PowerUp class like so PowerUp.draw(shieldSprite); and simply put my condition check within that draw method. I would still have the if statement but it would look tidier. Be grateful if you could elaborate. Cheers \$\endgroup\$ – BungleBonce Feb 6 '15 at 13:54
  • \$\begingroup\$ You're on the right track! The whole idea is to write cleaner code, which explains and maintains itself. Allow me to elaborate -- if you have powerUp.Check in the render function, you're keeping everything regarding drawing in the appropriate place. Imagine one, two or even three years from now, you want to add a few more power-ups. Well, instead of having to go to render and write powerUp.draw() with 5, 10 or even 15 different sprite names, you would have the handy-dandy powerUp.Check function, which does all of that for you! I will edit the answer with a few more examples to elaborate. \$\endgroup\$ – Sipty Feb 6 '15 at 14:13
  • \$\begingroup\$ To put it simply -- if statements should be used sparingly, but that's not to say you shouldn't use them at all. \$\endgroup\$ – Sipty Feb 6 '15 at 14:48
  • \$\begingroup\$ Thanks @Sipty, this seems like a nice way of doing things, it doesn't address the fact that I'm using an if (which was one of my worries from a performance perspective, this being in my game loop), but maybe I'm getting a little ahead of myself there. As you say, using if's in the right way shouldn't really be a problem. This code does however, make things so much more readable! I'll give it a try and will return to mark your answer as accepted :-) \$\endgroup\$ – BungleBonce Feb 6 '15 at 14:55
  • \$\begingroup\$ If statements aren't computationally expensive. Their evilness comes from their tendency to multiply by the dozen, unless handled with care. \$\endgroup\$ – Sipty Feb 6 '15 at 14:59
0
\$\begingroup\$

I use C#, so I don't know the exact equivalents for your setup and you may already be well aware of these...

-Combine if's using shortcuts where appropriate:

"Orelse"  
if (Condition1 || Condition2) //Condition2 is not evaluated if Condition1 tests true  
{  
...  
}  

"Andalso"  
if (Condition1 && Condition2) //Condition2 is not evaluated if Condition1 tests false  
{  
...  
}  

-Test out-of-bounds/range first or early:

void ASDF()  
{  
if (SomethingInvalid) return; //immediately  
if (SomethingOutOfRange) return; //immediately  
... //Much to do, all of which is skipped upon return  
}  

Conditional branching is generally accepted everywhere but shaders. Other heavily-distributed processes may waste more time synchronizing thread-safe access to shared resources than was saved by threading them in the first place.

\$\endgroup\$
0
\$\begingroup\$

The logic will be easier to follow if you break it into different functions, i.e.

void update() {
   handleCollisions();
   handleShield();
   handleWeapons();
   handle...
}

void handleShield() {
   if(shieldActive) {
      // do shield stuff
   }
}

and when it comes to drawing, you're better off either building static actor graphics groups (nodes, whatever), so that they either always contain the shield, weapons, powerup and other effects sprites, and you regulate their alpha and visibility in your logic, OR you re-build the actor display groups when their state changes. That way your graphics code won't be iffing, but instead just looping unconditionally through display lists like it should.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.