Accesing a switch statement from another object

S

Stratos.la

Guest
I have an object that handles a switch statement of 3 instances. and i want it to link to another object so i can draw on the screen certain values.
so far i have the controller that each instance on the room links to a case.
create event:

GML:
if instance_exists(ospellBook)
{
switch(menus)
{
case 0: page = 1;
    break;
case 1: page = 2;
    break;
case 2: page = 3;
    break;
}
}
and here i have the object that spawns with another button and am hoping to link to the object above to display stats.

draw_gui event:

GML:
with (oMenuSelect)
{
switch(page)
{
    case 1:
        draw_text(ospellBook.x-568,ospellBook.y-340,"XP:" + string(global.p_exp))
        draw_text(ospellBook.x-568,ospellBook.y-320,"XP NEXT:" + string(global.p_exptolevel))
        draw_text(ospellBook.x-568,ospellBook.y-300,"LEVEL:" + string(global.p_level))
        draw_text(ospellBook.x-568,ospellBook.y-280,"SKILL POINTS:" + string(global.skp))
        draw_text(ospellBook.x-568,ospellBook.y-260,"HEALTH:" + string(global.hp_max))
        draw_text(ospellBook.x-568,ospellBook.y-240,"MANA:" + string(global.mp_max))
    break;
    case 2:
        draw_text(ospellBook.x-568,ospellBook.y-340,"second page")
    break;
    case 3:
        draw_text(ospellBook.x-568,ospellBook.y-340,"third page")
    break;

}
}
buuut yeah it doenst work like it is! can anyone help or spot my mistake??
 

chamaeleon

Member
Have you tried debugging to determine what code paths are/are not taken depending on the values used in control statements, and what the values are?
 
S

Stratos.la

Guest
Have you tried debugging to determine what code paths are/are not taken depending on the values used in control statements, and what the values are?
no i havent it seems with the error i get that it cant access the case 1: of the object but i think that since im calling the object it should do the switch to find page 1 which in that case is case 1 of the other object

Code:
ERROR in
action number 1
of Draw Event
for object ospellBook:

Variable oMenuSelect.page(100739, -2147483648) not set before reading it.
 at gml_Object_ospellBook_Draw_64 (line 7) -        case 1:
##########################################################################
gml_Object_ospellBook_Draw_64 (line 7)
 

chamaeleon

Member
no i havent it seems with the error i get that it cant access the case 1: of the object but i think that since im calling the object it should do the switch to find page 1 which in that case is case 1 of the other object

Code:
ERROR in
action number 1
of Draw Event
for object ospellBook:

Variable oMenuSelect.page(100739, -2147483648) not set before reading it.
at gml_Object_ospellBook_Draw_64 (line 7) -        case 1:
##########################################################################
gml_Object_ospellBook_Draw_64 (line 7)
Do you initialize page to a value in oMenuSelect create event for sure (error indicates no...)? Debugging will tell you if you skip over code.
 
S

Stratos.la

Guest
no page is set inside the first switch statement. the menu variables are set in the instances creation codes in the room. im not really that knowledgeable of switch statements and it shows!!
 

chamaeleon

Member
no page is set inside the first switch statement. the menu variables are set in the instances creation codes in the room. im not really that knowledgeable of switch statements and it shows!!
Can you prove it to yourself in the form of show_debug_message() output after the switch statement? I am hesitant to take "page is set inside the first switch statement" as definite proof, rather than "as I'm looking at this code surely the variable must be set".
 

Nidoking

Member
the menu variables are set in the instances creation codes in the room.
This isn't entirely related to your lack of knowledge of switch statements. How certain are you that the ospellBook has been initialized before the Create event you posted here runs? If there's no instance of ospellBook, then that switch doesn't even happen.
 
S

Stratos.la

Guest
well you are right but i tried create it first in the room creation order, tried setting an alarm for it but nothing. through the debugger the problem is
GML:
with (oMenuSelect)
{
switch(page)
{
    case 0:
it stops there. i can run the game and when i try to "open" the book through an object that instantiates it then i get the error.

the button to open said spell book is this
GML:
if (MENU == true)
{
        MENU = false;
        instance_destroy(ospellBook);
        instance_deactivate_layer("Book_Menu")
}
else
if (MENU == false)
{
        MENU = true;
        instance_create_layer(room_width/2,room_height/2,"Level_Info",ospellBook)
        instance_activate_layer("Book_Menu")
}
also the objects that call the switch statement are on the book_menu Layer
 
S

Stratos.la

Guest
well this happened and now it opens althought it doesnt draw .i dont know if its because its not working properly or it draws behind the book (it takes up the whole screen)
GML:
with (oMenuSelect)
{
if instance_exists(instance_id)
switch(page)
{
i checked to see if the object exists which is strange since its the same object
 

Nidoking

Member
Which object? You're checking to see whether an instance exists with the instance ID or object ID instance_id. That makes no sense at all. You need to think through the steps that you want to happen and the order in which they need to happen. Get that written down without touching your game. Once you've done that, then you can make the game.
 

FrostyCat

Redemption Seeker
instance_id is NOT the current instance ID, id is.

Also, you are hiding the initialization of page behind a condition, which is an awful idea in general. The instance_exists(ospellBook) there can return false if there is no instance of ospellBook in the room, or if the instance of ospellBook comes after the oMenuSelect in the room instance order. When that happens, page won't get a value, and you get an error when you try to reach for it later.
 

chamaeleon

Member
It almost feels like the code was written with the idea that the code within the if statement gets executed "at some point" when an instance comes into existence, versus as part of the linear execution model of a single-threaded process.
 
S

Stratos.la

Guest
well the idea was as i have done before with my level selection objects. to have a button that spawn a book covering the screen and having one object with many instances in the room act as buttons for the book pages. thus i thought i could do as i have done with the levels where i have a level_select object places many times in the room and in its creation code placed level = 1 etc that gets called in the switch statement left pressed and accordingly opens a new level each time. as i have it now it works in the way that the book opens but since i want to draw text this time it doesnt. im currently searching as to how to do a switch in the draw gui event. i could of cource create virtual buttons for each text i want to show but i thought i could do it with the switch statement. And i did make it stop giving errors by placing every call in the same object but still its not working as i would like it to
 
S

Stratos.la

Guest
i mean how would you go about doing that with the least amount of objects??
 

Pixel-Team

Master of Pixel-Fu
your page variable should be initialized BEFORE your switch statement in the create event of oMenuObject.
GML:
page = 1;
menus = 0;

if instance_exists(ospellBook) {

    switch(menus) {
        case 0: page = 1;
            break;
        case 1: page = 2;
            break;
        case 2: page = 3;
            break;
        }
}
 
S

Stratos.la

Guest
wow that actually helped a lot! i didnt know i should have written starting points in the create menu, but now it seems that the text gets overwriten and not changed when pressing on the instances.

oMenuSelect Create
GML:
page = 1;
menus = 0;

this is oMenuSelect left pressed event
GML:
if instance_exists(ospellBook) {

    switch(menus) {
        case 0: page = 1;
            break;
        case 1: page = 2;
            break;
        case 2: page = 3;
            break;
        }
}
and this is oBook draw gui event
GML:
with (oMenuSelect)
{
switch(page)
{
    case 1:
        draw_text(ospellBook.x-568,ospellBook.y-340,"XP:" + string(global.p_exp))
        draw_text(ospellBook.x-568,ospellBook.y-320,"XP NEXT:" + string(global.p_exptolevel))
        draw_text(ospellBook.x-568,ospellBook.y-300,"LEVEL:" + string(global.p_level))
        draw_text(ospellBook.x-568,ospellBook.y-280,"SKILL POINTS:" + string(global.skp))
        draw_text(ospellBook.x-568,ospellBook.y-260,"HEALTH:" + string(global.hp_max))
        draw_text(ospellBook.x-568,ospellBook.y-240,"MANA:" + string(global.mp_max))
    break;
    case 2:
        draw_text(ospellBook.x-568,ospellBook.y-340,"second page")
    break;
    case 3:
        draw_text(ospellBook.x-568,ospellBook.y-340,"third page")
    break;

}
}
 

chamaeleon

Member
Well, you'll have to have some code that sets the instance variable menus to an appropriate value depending on user interaction. Do you have that, and importantly, does it run as expected (no more and no less than required to get the appropriate value set)? It is another case of using the available debugging means to determine what code runs when, and if it does, whether you get the expected result. Have the program display variable values for you, or use debugger breakpoints to check what the state of the program is at critical points, etc.
 
S

Stratos.la

Guest
well, the debugger doesn't show anything in particular. it reaches case 1 displays the variables i want and when it moves to case 2 it draws that one on top of the other. shouldn't it clear the previous case before moving on to the new one?
 

chamaeleon

Member
well, the debugger doesn't show anything in particular. it reaches case 1 displays the variables i want and when it moves to case 2 it draws that one on top of the other. shouldn't it clear the previous case before moving on to the new one?
The only thing drawn in a given frame is the code that executes for the given draw event. If you see text while the code for it was not executed, it is an indication you do not have a background that clears the frame.
 
S

Stratos.la

Guest
that would be the clear display buffer option in the room editor? because that is turned on. and you might be right because i have set the toggle switch to destroy the book every time it closes and then respawn it but it keeps everything open as it was before. it doesn't reset. Hoping im not troubling you but you wouldn't happen to have any ideas as to why or how? its already past midnight here so i dont have enough strength to keep on for today!

and just for the sake of the thread and in case im missing something here is the toggle button for the book. in case this messes things up?
GML:
if (MENU == true)
{
        MENU = false;
        instance_destroy(ospellBook);
        instance_deactivate_layer("Book_Menu")
        layer_set_visible("Book_Menu",false)
}
else
if (MENU == false)
{
        MENU = true;
        instance_create_layer(room_width/2,room_height/2,"Book_Menu",ospellBook)
        instance_activate_layer("Book_Menu")
        layer_set_visible("Book_Menu",true)
}
 

chamaeleon

Member
I guess you could check and see if you have more than one instance of oMenuSelect using show_debug_message("Count of oMenuSelect = " + string(instance_number(oMenuSelect))); just before the with() statement in the draw event.
 

Yal

🐧 *penguin noises*
GMC Elder
This sounds like the perfect place for a global variable, to cut down on all the weird references between different instances - since you're only going to have a single page active at once anyway, you might as well just make that index a global variable and save yourself the hassle.
 
S

Stratos.la

Guest
This sounds like the perfect place for a global variable, to cut down on all the weird references between different instances - since you're only going to have a single page active at once anyway, you might as well just make that index a global variable and save yourself the hassle.
i m still not sure if this is the right way to go since in my head i want to have one page for player information , one page for leveling up skills , one page for the storyline and a final page for a list of known spells. i just thought about it that i dont know if i can make this happen like this. i mean the easy way would be to just spawn different objects everytime a button is pressed but i really dont know. i havent made a game like this before so its a challenge
 

Yal

🐧 *penguin noises*
GMC Elder
There's no shame in picking the easy way... something that works is always going to be better than something that is cool in theory but doesn't work 🦈
 
S

Stratos.la

Guest
yeah im just trying my options here and to be honest i usually try to not have many objects in the scene and to keep things relatively light. i thought it could be cool like that but now that i keep thinking about the possibilities maybe this way won't work. i'll have to try it a bit more and maybe search about player stat menus to see how people do them
 

Roderick

Member
Not directly related to your problem, but some advice that will help with debugging.

Get rid of this:

GML:
if instance_exists(ospellBook)
{
switch(menus)
{
case 0: page = 1;
    break;
case 1: page = 2;
    break;
case 2: page = 3;
    break;
}
}
Your code should be as simple as possible. What you have here can simply be written as:

GML:
if instance_exists(ospellBook)
{
page = menus + 1;
}
And really, there's no good reason to even have the page variable. Anywhere you use it, you can just use menus + 1 instead. Or just menus, and write the code that references the old page variable to be zero-indexed instead.

Complex code slows down the computer when it runs, can increase memory and CPU usage, and - most importantly - is really hard to debug. Always try to find the simplest way to do anything you code.
 
  • Like
Reactions: Yal
Top