GML Why is this switch statement not working correctly?

Enlapse

Member
Hello there!

First of all, sorry for this vague title, but making a proper title might take quite a lot of space, and second, this might be a little hard to explain and understand, so please, ask whatever you may need.

Summarizing, my problem is that I have a switch statement with two cases with no code and one with code, and when any of those two cases happen, the code from the other case that HAS code, triggers. And the second problem is that the code that triggers is actually wrong because its calling an event of the object obj_ts_close that doesn't have, but still triggers and 'works' as intended.

Well, first of everything, I will explain what I am trying to accomplish:
I have a simple title screen system with three posible selectable options:
- New game
- Options
- Close

At the moment, the "New game" and "Options" option, should not be doing nothing because I haven't coded anyting for them yet, but when the "Close" option is selected, and the user press ENTER, a window is drawn asking for confirmation to close the game, or to press ESCAPE to close that window. The problem is, even when "New game" and "Options" don't have anything coded, when I press ENTER when in any of those two options, the "Close" events trigger, and I am not sure why, because I have a problem with my switch statement, and is that as I said both options don't have anything coded but "Close" does, and the "Close" otpion is calling an event_perform_object() of an event that doesn't exist in that object, yet it works as intended with the excption that it also triggers in "New game" and "Options" option, and it shouldn't.

So my problem is: Why is this happening (the switch statement problem), and even if its 'working', why is it working if my code is wrong?

Here is all the code of each object:

obj_ts_menu (the main object of the system is coded here):
GML:
/// CREATE EVENT

window_prompted = false;
current_select = "newgame";
GML:
/// STEP EVENT

switch ( current_select ) {
    case "newgame":
        inst_ts_newgame.image_index =    1;
        inst_ts_options.image_index =    0;
        inst_ts_close.image_index =        0;
        break;
    case "options":
        inst_ts_newgame.image_index =    0;
        inst_ts_options.image_index =    1;
        inst_ts_close.image_index =        0;
        break;
    case "close":
        inst_ts_newgame.image_index =    0;
        inst_ts_options.image_index =    0;
        inst_ts_close.image_index =        1;
        break;
}
GML:
/// KEY UP - ENTER EVENT

switch ( current_select ) {
    case "newgame":
        
        break;
    case "options":
        
        break;
    case "close":
        event_perform_object( obj_ts_close, ev_keyrelease, vk_enter );
        break;
}
GML:
/// KEY UP - UP EVENT

if ( !window_prompted ) {
    switch ( current_select ) {
        case "newgame":
            current_select = "close";
            break;
        case "options":
            current_select = "newgame";
            break;
        case "close":
            current_select = "options";
            break;
    }
}
GML:
/// KEY UP - DOWN EVENT

if ( !window_prompted ) {
    switch ( current_select ) {
        case "newgame":
            current_select = "options";
            break;
        case "options":
            current_select = "close";
            break;
        case "close":
            current_select = "newgame";
            break;
    }
}
obj_ts_close (the object which the code of what the close option needs to do):

GML:
/// CREATE EVENT

image_speed = 0;
confirmation_prompted = false;
GML:
/// @description

draw_self();

if ( confirmation_prompted ) {
        
    draw_sprite_ext( spr_ts_confirm_exit, 0, room_width / 2 - 192, room_height / 2 - 168, 2, 2, 0, c_white, 1 );
    if ( keyboard_check_pressed( vk_enter ) ) {
        game_end();
    } else if ( keyboard_check_pressed( vk_escape ) ) {
        inst_ts_menu.window_prompted = false;
        confirmation_prompted = false;
    }
    
}

if ( !confirmation_prompted && keyboard_check_pressed( vk_enter ) ) {
    inst_ts_menu.window_prompted = true;
    confirmation_prompted = true;
}
And a gif of the problem replicated.


Sorry for any trouble these explanations may cause, I find a little hard to explain without a proper visual explanation.
 

Enlapse

Member
You are sending 'ev_keyrelease' but checking for 'keyboard_check_pressed'
The problem and doubt is that even with that error, it still 'works' and I am not sure why.

Im pretty sure switch statements need to use integers as case arguments. You are using strings.
I have made a research on the YoYo's documentation and it doesn't say anything that it needs to be an int, they use const and other switch statements I made had strings as cases and worked perfectly. :/
 

FrostyCat

Redemption Seeker
Your problem has nothing to do with switch blocks. There is simply nothing in obj_ts_menu that stops this part of obj_ts_close's Draw event from running:
GML:
if ( !confirmation_prompted && keyboard_check_pressed( vk_enter ) ) {
    inst_ts_menu.window_prompted = true;
    confirmation_prompted = true;
}
Also, a keyboard_check_pressed() condition in a Draw event is NOT an event.
 

Enlapse

Member
Your problem has nothing to do with switch blocks. There is simply nothing in obj_ts_menu that stops this part of obj_ts_close's Draw event from running:
GML:
if ( !confirmation_prompted && keyboard_check_pressed( vk_enter ) ) {
    inst_ts_menu.window_prompted = true;
    confirmation_prompted = true;
}
Also, a keyboard_check_pressed() condition in a Draw event is NOT an event.
So, how could I make it to only do an event when its being called? Is there a function to check if that event has been called in the draw event? Because as far as I know, I can't pass a parameter to the event_perform_object() function nor anything similar to make an if or something.

And yeah, I think you say that keyboard_check_pressed() is not an event because of my code, but my first try was with an key up - enter instead of using that function, so the code in event_perform_object() should have worked before, isnt''t it? Since it was calling a Key up - enter (key released) event. The reason why I am asking is because I didn't try it.

Thank you very much!
 

FrostyCat

Redemption Seeker
What you asked for does not exist. You have been architecting your system around an imaginary framework that is incongruent with what GMS 2 actually does.

With GMS 2.2, the closest functionality is the User Defined event (Other > User Defined). For example, use User Defined 0 to store the action, then call it like this:
GML:
switch (current_select) {
    case "newgame":
        with (obj_ts_newgame) event_user(0);
        break;
    case "options":
        with (obj_ts_options) event_user(0);        
        break;
    case "close":
        with (obj_ts_close) event_user(0);
        break;
}
In the future, DO NOT start designing systems by assembling imaginary components and then checking to see if all of them are real. Start by learning what actual components are available, and express your needs in terms of them.
 
Top