GML can't figure out this if statement

Hey guys I'm a real beginner when it goes to coding,
so this is pretty difficult for me, and I do need some help.

SO the idea is: that I want to make a panel that when it's clicked that it pops open(goes to the other sprite)
and when clicked again that it becomes small again(goes back to the original sprite)
I've given it a shot in the code below but it does not do what I want it to.

Do any of you legends know how to fix this problem, that would be awesome.
Thanks in advance

GML:
state = 0;

if state == 0 and mouse_check_button_released(mb_left)
    {
    sprite_index = citybarC_spr;
    state = 1;
    }

if state == 1 and mouse_check_button_released(mb_left)
    {
    sprite_index = citybar_spr;
    state = 0;
    }
 
Last edited:

chamaeleon

Member
Why Yin-Yang if Blocks suck

Besides that, if you are actually setting state to zero before the if statements as written, and it's not set in some other event, you'll of course start of the first if statement always seeing state is zero and only the mouse button test determines whether to execute the code in it.

Your code will execute in a linear fashion, one statement at a time. The next time around the same code runs, the state assignment statement will execute again and set it to zero. There's no "let's just run this code once, and the next time I come across it I know I have already done it". If that is your idea of how it works, you need to start understand the execution of code in a much more literal fashion.
 
Last edited:

Mr Magnus

Viking King
So, this is a common issue that people forget to think trough: computers do not do what you intend them to do, they do exactly what you tell them to as written.


If you have two if statements following each other *both of them* will be tested. What your code will do is go in to the first if statement block (because state is 0), it will set state to 1, and then it will keep going. Because you set state to 1 the second if statement is *also true* and so the state will go back to 0. Rinse and repeat any time you run this event.

If you have to mutually exclusive if statements that could affect each other put an else block between them.

GML:
if(state == 0){
    state = 1;
} else if(state == 1){ //Or even just the else, skipping the second check. Presumably if the state isn't 0 it must be 1 if there are only two states
    state = 0;
}

// only one if statement will be executed, no matter what the other could do.

There are other ways to do this sort of mutually exclusive checking, but to begin with you should learn how to use the else statement and how one piece of code can affect what comes below it.
 
Last edited:

Vusur

Member
Go through it, line by line, in your head. Not only once, multiple times. Read it out loud. Sounds silly, but it makes clear what happens. This is also something, that GML does.

I'll help you a little (we ignore the mouse click):

You set state = 0. This will now always be zero, before you read the first condition. If the first condition becomes true, you set stuff and set state = 1. Now you have to read the second condition, because in your setup, it will check it. Well, you set state to 1, so this also becomes true. Because of that, you change stuff back, that you have set previously.

We reached end of the code. Now do it again. You set state = 0.... and so on.

Important, don't stop midway with reading out loud.
 
thanks for the people who have answered already,

What I think I understand now from the replies is:
- that the whole piece of code will be looped until stopped.
- that the 'state = 0' in the beginning will set the statement no matter what the following statements tell it to.

I however still not now how to implement the mouse input and sprite output in the code.
Can anyone perhaps help me with that ?
 
I have found a way to make it work!

in the Create Event Iput this code:
GML:
sprite_index = citybar_spr
state = 1
and in the Left Released Event I put this code:
GML:
if state == 0 and mouse_check_button_released(mb_left)
    {
    sprite_index = citybar_spr;
    state = 1;
    }
   
else if state == 1 and mouse_check_button_released(mb_left)
    {
    sprite_index = citybarC_spr;
    state = 0;
    }
Feel free to comment on it and correct if you feel needed, thanks anyway
 

chamaeleon

Member
Good job making progress on your own!

Since you use the mouse button event you shouldn't really need to also check it explicitly in your code (it is more commonly used if one handles button checks in the step events).
 
Good job making progress on your own!

Since you use the mouse button event you shouldn't really need to also check it explicitly in your code (it is more commonly used if one handles button checks in the step events).
ah yeah, i noticed it afterwards, but good to know for next time. thanks!
 

DeScruff

Member
thanks for the people who have answered already,

What I think I understand now from the replies is:
- that the whole piece of code will be looped until stopped.
- that the 'state = 0' in the beginning will set the statement no matter what the following statements tell it to.

I however still not now how to implement the mouse input and sprite output in the code.
Can anyone perhaps help me with that ?
Nothing is technically wrong with your mouse input and sprite output. (Assuming what you want is to change the variable state, and the sprite_index)
The problem is simply that your code negates its self by giving two consecutive if statements where the second one will activate because of the actions of the first.

The easiest way to fix this: 'else' - to make sure the second if statement only gets checked if the first one didn't go through.
Oh! looks like you got this on your own! Awesome!

A more advanced way would be to learn about Switch statements:
Do open up the manual and read up on them, they might come in very handy, specially if you start adding more and more values that variable 'state' can be, since it can help with readability

GML:
mouse_check_button_released(mb_left)
    {
    switch (state)
        {
        case 0:  // When sprite should be citybar_spr!
            sprite_index = citybar_spr;
            state = 1;
            break;
        case 1: // When sprite should be citybarC_spr! - I like commenting here to help give an overview of whats to happen
            sprite_index = citybarC_spr;
            state = 0;
            break;
        }
    }

They sort of work like nested 'else if' statements in that it stops once it hits a match. Basically if case 0 executes, no matter what you do in case 0, case 1 will not execute.
But they do have a limitation in that they are testing for an exact '=' answer. Like: if something = 0 or if something = 1.
They can't test if something is > 5 or if something is < 4.

I'm probably not doing the best at explaining them, and there is more, so again, highly recommend reading the manual, or watching a tutorial, however you like to learn coding!
 
Last edited:
Nothing is technically wrong with your mouse input and sprite output. (Assuming what you want is to change the variable state, and the sprite_index)
The problem is simply that your code negates its self by giving two consecutive if statements where the second one will activate because of the actions of the first.

The easiest way to fix this: 'else' - to make sure the second if statement only gets checked if the first one didn't go through.
Oh! looks like you got this on your own! Awesome!

A more advanced way would be to learn about Switch statements:
Do open up the manual and read up on them, they might come in very handy, specially if you start adding more and more values that variable 'state' can be, since it can help with readability

GML:
mouse_check_button_released(mb_left)
    {
    switch (state)
        {
        case 0:  // When sprite should be citybar_spr!
            sprite_index = citybar_spr;
            state = 1;
            break;
        case 1: // When sprite should be citybarC_spr! - I like commenting here to help give an overview of whats to happen
            sprite_index = citybarC_spr;
            state = 0;
            break;
        }
    }

They sort of work like nested 'else if' statements in that it stops once it hits a match. Basically if case 0 executes, no matter what you do in case 0, case 1 will not execute.
But they do have a limitation in that they are testing for an exact = answer, they can't test if something is > 5 or < 4.

I'm probably not doing the best at explaining them, and there is more, so again, highly recommend reading the manual, or watching a tutorial.
Thanks anyway for the help.
I think it'll be very useful for similar situations in the future.
 
Top