Is there a way to summarize all these else if?

2

Good, I'm with a project where a function checks if a ball touches a wall, which is an array of 15 "portions" with each 50u of size. I need to know what part of the wall it touches and for that I have done the following, but it is exaggeratedly spectacular:

if(bolaY == INIPANTALLAY + ALCADAMAO)//Comprueba que llegue hasta la altura del maon
            {   
                if (bolaX > 30 && bolaX < 80)
                {
                    if (Mao[0].maotrencat == false)//Si el maon tocado no esta roto continua
                    {
                        Mao[0].maotrencat = true;//Cambia el estado del maon
                        punts += 1;//Suma 1 punto
                        dirX *= -1;// cambio de direccion
                        dirY *= -1;// cambio de direccion
                    }
                }
                else if (bolaX > 80 && bolaX < 140)
                {

                    if (Mao[1].maotrencat == false)//Si el maon tocado no esta roto continua
                    {
                        Mao[1].maotrencat = true;//Cambia el estado del maon
                        punts += 1;//Suma 1 punto
                        dirX *= -1;// cambio de direccion
                        dirY *= -1;// cambio de direccion
                    }
                }
                else if (bolaX > 140 && bolaX <200)
                {

                    if (Mao[2].maotrencat == false)//Si el maon tocado no esta roto continua
                    {
                        Mao[2].maotrencat = true;//Cambia el estado del maon
                        punts += 1;//Suma 1 punto
                        dirX *= -1;// cambio de direccion
                        dirY *= -1;// cambio de direccion
                    }
                }
                else if (bolaX > 200 && bolaX <260)
                {

                    if (Mao[3].maotrencat == false)//Si el maon tocado no esta roto continua
                    {
                        Mao[3].maotrencat = true;//Cambia el estado del maon
                        punts += 1;//Suma 1 punto
                        dirX *= -1;// cambio de direccion
                        dirY *= -1;// cambio de direccion
                    }
                }
                else if (bolaX > 260 && bolaX <320)
                {

                    if (Mao[4].maotrencat == false)//Si el maon tocado no esta roto continua
                    {
                        Mao[4].maotrencat = true;//Cambia el estado del maon
                        punts += 1;//Suma 1 punto
                        dirX *= -1;// cambio de direccion
                        dirY *= -1;// cambio de direccion
                    }
                }
                else if (bolaX > 320 && bolaX <380)
                {

                    if (Mao[5].maotrencat == false)//Si el maon tocado no esta roto continua
                    {
                        Mao[5].maotrencat = true;//Cambia el estado del maon
                        punts += 1;//Suma 1 punto
                        dirX *= -1;// cambio de direccion
                        dirY *= -1;// cambio de direccion
                    }
                }
                else if (bolaX > 380 && bolaX <440)
                {

                    if (Mao[6].maotrencat == false)//Si el maon tocado no esta roto continua
                    {
                        Mao[6].maotrencat = true;//Cambia el estado del maon
                        punts += 1;//Suma 1 punto
                        dirX *= -1;// cambio de direccion
                        dirY *= -1;// cambio de direccion
                    }
                }
                else if (bolaX > 440 && bolaX <500)
                {

                    if (Mao[7].maotrencat == false)//Si el maon tocado no esta roto continua
                    {
                        Mao[7].maotrencat = true;//Cambia el estado del maon
                        punts += 1;//Suma 1 punto
                        dirX *= -1;// cambio de direccion
                        dirY *= -1;// cambio de direccion
                    }
                }
                else if (bolaX > 500 && bolaX <560)
                {

                    if (Mao[8].maotrencat == false)//Si el maon tocado no esta roto continua
                    {
                        Mao[8].maotrencat = true;//Cambia el estado del maon
                        punts += 1;//Suma 1 punto
                        dirX *= -1;// cambio de direccion
                        dirY *= -1;// cambio de direccion
                    }
                }
                else if (bolaX > 560 && bolaX <620)
                {

                    if (Mao[9].maotrencat == false)//Si el maon tocado no esta roto continua
                    {
                        Mao[9].maotrencat = true;//Cambia el estado del maon
                        punts += 1;//Suma 1 punto
                        dirX *= -1;// cambio de direccion
                        dirY *= -1;// cambio de direccion
                    }
                }

I tried to improve it with a switch, but I'm not sure if it's possible considering the comparison and the & & amp; in each case.

    
asked by ElPatrón 14.04.2017 в 19:42
source

4 answers

5

You should take advantage of the fact that each portion has the same size, that is the key . Then you could use a for cycle like this:

for (int i = 0; i < 15; i++)
{
    if (bolax > 20 + 60*i && bolax < 80 + 60*i)
    {
        if (Mao[i].maotrencat == false)//Si no esta roto continua
        {
            Mao[i].maotrencat = true;//Cambia el estado del maon
            punts += 1;//Suma 1 punto
            dirX *= -1;// cambio de direccion
            dirY *= -1;// cambio de direccion
        }
    break; // este break evita que se siga evaluando todos los otros casos
    // tambien puede servir 
    // i = 15;
    }

}

This way your code is reduced.

    
answered by 14.04.2017 / 20:33
source
1

Try the following if it gives the same result; I see that the common thing is always to realize:

Mao[INDICEAMODIFICAR].maotrencat = true;
// Las siguientes 3 son simprelas mismas
punts += 1;//Suma 1 punto
dirX *= -1;// cambio de direccion
dirY *= -1;// cambio de direccion

The if internal to if(bolaY == INIPANTALLAY + ALCADAMAO) in the following way:

int indice=-1; // Iniciado el negativo para indicar ninguno a modificar.

if (bolaX > 30 && bolaX < 80 && (!Mao[0].maotrencat))
{
    indice=0;
}
else if (bolaX > 80 && bolaX < 140 && (!Mao[1].maotrencat))
{

    indice=1;
}
else if (bolaX > 140 && bolaX <200 && (!Mao[2].maotrencat))
{
    indice=2;
}
else if (bolaX > 200 && bolaX <260 && (Mao[3].maotrencat))
{
    indice=3;
}
else if (bolaX > 260 && bolaX <320 && (!Mao[4].maotrencat))
{
    indice=4;
}
else if (bolaX > 320 && bolaX <380 && if (!Mao[5].maotrencat))
{
    indice=5;
}
else if (bolaX > 380 && bolaX <440 && (!Mao[6].maotrencat))
{
    indice=6;
}
else if (bolaX > 440 && bolaX <500 && (!Mao[7].maotrencat))
{
    indice=7;
}
else if (bolaX > 500 && bolaX <560 && (!Mao[8].maotrencat))
{
    indice=8;
}
else if (bolaX > 560 && bolaX <620 && (!Mao[9].maotrencat))
{
    indice=9;
}

if (indice>=0) {
   Mao[indice].maotrencat = true;
   punts += 1;//Suma 1 punto
   dirX *= -1;// cambio de direccion
   dirY *= -1;// cambio de direccion
}

Another way is that instead of evaluating if ([...] && (!Mao[INDICE].maotrencat)) you only evaluate bolaX (it is the only one that I see you evaluate) and the if that I put where index is evaluated:

if (indice>=0) {
   if (!Mao[indice].maotrencat) {
      Mao[indice].maotrencat = true;
      punts += 1;//Suma 1 punto
      dirX *= -1;// cambio de direccion
      dirY *= -1;// cambio de direccion
   }
}
    
answered by 14.04.2017 в 20:37
1

You can use an array to get the result directly.

I do not understand exactly how your wall is organized; from what I see in your code, they are pieces of different sizes. But, in any case, all the pieces are multiples of 10, so you can use something like this:

struct accion_s {
  int Mao;
  int punts;
  int dirX;
  int dirY;
}; 

struct accion_s acciones[620/10] = {
  { W, X, Y, Z },
  { W2, X2, Y2, Z2 },
  { W3, X3, Y3, Z3 },
  ...
};

Now, you only have to check once:

if( bolaY == INIPANTALLAY + ALCADAMAO ) {
  struct accion_s accion = acciones[bolax / 10];

  // Es SEGURO que estamos en el muro.
  Mao[accion.Mao].maotrencat = true;//Cambia el estado del maon.
  punts += accion.punts; //Suma 1 punto
  dirX *= accion.dirX;// cambio de direccion
  dirY *= accion.dirY;// cambio de direccion
}

This is a basic technique in game development: precalculate as much as you can .

    
answered by 14.04.2017 в 20:52
1

After reading all the comments, I understand that what you want to do is this:

You have a wall, divided into several pieces, and a ball:

------
  o

The pieces with contiguous , without separation. The coordinate X of the first piece of wall is 20 . The width of all the pieces is the same, 60 pixels .

And you know the position X of the ball at all times.

To know the piece of wall you hit, you do not have to do any if . You just have a simple division .

muro = ( pelota.X - 20 ) / 60;

We subtract from the current position of the ball the beginning of the first wall, and divide it by the width of the walls; with that, we already have an index for your Mao[] directly.

Since, in all cases, you do the same thing, it would be enough for you to do

if( bolaY == INIPANTALLAY + ALCADAMAO ) {
  int idx = ( bolaX - 20 ) / 60;

  if( Mao[idx].maotrencat == false ) {
    Mao[idx].maotrencat = true;
    punts += 1;
    dirX *= -1;
    dirY *= -1;
  }
}

In the event that you had to perform different operations depending on the wall, it is when you would use the solution proposed by @Trauma: add the concrete data of each wall in an array In your case, from what I see, you would add that extra data to your Mao[] .

    
answered by 15.04.2017 в 09:09