[SOLVED]Referencing variables from deactivated instances

Stranger

Member
Hello everyone. I'm having trouble pulling variables from deactivated objects. It could simply be a matter of order placement. I'm new to the community but have been working with GameMaker for a few years now. This is my very first post! I'm still rather unskilled with the coding. I'm making a game where the player walks around the map and interacts with certain objects. When you do, it pauses the game by deactivating all instances(other than the controller object) and creates an "Event object" complete with a picture and text boxes. Eventually there will be choices to make in the text box. But right now I'm having trouble drawing the different "Event sprites" based on what object the player interacted with. I don't know if GameMaker can see variables from deactivated objects, or if I just don't know the correct function to reference the object that the player is interacting with. Your help is greatly appreciated.
 

Simon Gust

Member
As long as you have the identifier (id) of the object, you can pull and push variables to it beyond deactivaion.
You will have to save the id to a variable before deactivation though.

You may show your code.
 

Stranger

Member
This is in the draw event of the object spawned from the game controller upon pause while the player interacts with an object

if(global.paused_event) {
draw_sprite_ext(spr_event_box, 0, 320, 128, 2, 2, 0, c_white, 1);
draw_sprite_ext(spr_event_machine_attack, 0, 320, 128, 2, 2, 0, c_white, 1);
draw_set_halign(fa_left);
draw_text_ext_transformed(364, 512, string(hostile_machines3), 12, 290, 2, 2, 0);
}

I would like to change the "spr_event_machine_attack" to a variable set in the create code of each object placed around the map. I've tried a few different approaches but fatal errors almost always arise.
 

Stranger

Member
To clarify, my player walks around the map picking up collectibles and interacts with "landmarks". When you are within range of a "landmark" and interact with it, the game controller pauses the game by deactivating all instances. The controller then creates a "pause object" that draws a box complete with an "event image", text and selection options. I'm trying to draw the "event image" based on an image specified by the type of "landmark" that is being interacted with(not the landmark's sprite, that is a different image that is displayed on the map). I'll repost my code in the correct way now that I know how to properly post code. This is in the draw event of the "pause object".
Code:
/// Create the event screen

if(global.paused_event) {
    draw_sprite_ext(spr_event_box, 0, 320, 128, 2, 2, 0, c_white, 1);
    draw_sprite_ext(spr_event_machine_attack, 0, 320, 128, 2, 2, 0, c_white, 1);
    draw_set_halign(fa_left);
    draw_text_ext_transformed(364, 512, string(hostile_machines), 12, 290, 2, 2, 0);
}
I would like to change the "spr_event_machine_attack" to a variable set in the create code of each type of "landmark" placed around the map. I've tried a few different approaches but fatal errors almost always arise.
 

FrostyCat

Member
You posted a paraphrase of code without actual code plus the event/script where it comes from. It's still the wrong way. One of the reasons why code-free paraphrases are next to useless in troubleshooting is because one idea can have many different executions. Another is that if your paraphrase was correct, the code would have worked the way you expected and you wouldn't have needed help with it, so the fact that you need help means any paraphrase you make of it is likely false and misleading.

First, make sure you know the difference between objects and instances and how to reference variables from a colliding instance. Then when you create the pause controller, use the return value of instance_create_layer() or instance_create_depth() to pass in the appropriate sprite. Then draw that passed in sprite.
Code:
// Interaction with a landmark
...
var inst_pause_controller = instance_create_depth(0, 0, 0, obj_pause);
inst_pause_controller.spr_thumbnail = colliding_landmark.spr_thumbnail; // Replace this with the actual instance ID and the variable name
Code:
// Draw event of obj_pause
...
draw_sprite_ext(spr_thumbnail, 0, 320, 128, 2, 2, 0, c_white, 1);
...
 
Last edited:

Stranger

Member
As long as you have the identifier (id) of the object, you can pull and push variables to it beyond deactivaion.
You will have to save the id to a variable before deactivation though.

You may show your code.
This is exactly what I'm having trouble determining. I am rather unfamiliar with instance_id() functions and how to use the with() function. I have made attempts at them and after many unsuccessful attempts have decided to skirt around it. But now I must confront them I haven't been able to properly identify to my drawing script how to get a simple variable from another object. I'll try and properly post ALL related code. I apologize in advance if I am being difficult or am not understanding what is probably a simple function. I'll list the steps in sequential order.

First is the step event of the obj_player coming within range of the obj_landmark. I have many specific child objects that have obj_landmark as their parent.
Code:
///control the Players States
scr_get_input();
depth = -y;

//execute the state
script_execute(state);

//set up the event

if distance_to_object(obj_landmark) = 0  {
    global.event_ini = true;
}else{
    global.event_ini = false;
}
Next I have the step event of the obj_game_controller.
Code:
///pause the game with the space bar

if(keyboard_check_pressed(vk_space)) && (!global.paused_event) {
    global.paused = !global.paused;
  
        if(global.paused) && (!global.paused_event) {
            global.screenshot = sprite_create_from_surface(application_surface,0,0,view_wport,view_hport,0,0,0,0);
            instance_deactivate_all(true);
            instance_create(view_wport[0] / 2, view_hport[0] / 2 + 32, obj_pause);

        }
}

//pause the game with an event

if(global.event_ini = true) && mouse_check_button_pressed(mb_left) && (!global.paused) {
    global.paused_event = !global.paused_event;
  
        if(global.paused_event) && (!global.paused) {
            global.screenshot = sprite_create_from_surface(application_surface,0,0,view_wport,view_hport,0,0,0,0);
            instance_deactivate_all(true);
            instance_create(view_wport[0] / 2, view_hport[0] / 2 + 32, obj_pause_event);

        }
}

if(global.paused_event = false) && (global.paused = false) {
    instance_activate_all();
    sprite_delete(global.screenshot);
}

// End the game
if (keyboard_check_pressed(vk_escape)) {
    game_end();  
}
Note: I have a separate global.paused function solely to pause and unpause the game with the space bar. I have made this work alongside the paused_event function.
Once the obj_game controller creates the obj_pause_event, the obj_pause_event runs this in the draw event.
Code:
///draw screenshot
if(global.paused_event) {
    draw_sprite_ext(global.screenshot, 0, 0, 0, 1, 1, 0, c_white, 1);
}
/// Create the event screen

if(global.paused_event) {
    draw_sprite_ext(spr_event_box, 0, 320, 128, 2, 2, 0, c_white, 1);
    draw_sprite_ext(spr_event_machine_attack, 0, 320, 128, 2, 2, 0, c_white, 1);
    draw_set_halign(fa_left);
    draw_text_ext_transformed(364, 512, string(hostile_machines3), 12, 290, 2, 2, 0);
}
Now all this works fine. Except that where it draws spr_event_machine_attack, I want it to draw a sprite specific to the child object of obj_landmark that was originally interacted with in the beginning of this chain. For example, some of the child objects of obj_landmark are obj_cemetery, obj_farm, obj_town etc. Each one has a sprite for the map, and one that I'm trying to reference for this pause event. I'm just having trouble telling the obj_pause_event which obj_landmark was interacted with and how to draw the corresponding sprite. Sorry again for not being specific earlier. I'm new to the forums and appreciate any and all help. Thanks again!
 

FrostyCat

Member
First you must remember this: You are dealing with instances now, not objects. Objects are types. Instances are individuals.

If at this point you still have not read my article on the difference between objects and instances, read it now. "The cat" may be specific enough at your friend's house if he/she has only one cat, but it's not specific enough at an animal shelter during kitten season. And you don't need to completely relearn how to reference things with instance IDs either. Except for operations that deal specifically with object types such as object_*() functions or the last argument to instance_create(), instance IDs can be used virtually anywhere object IDs are legal. Whenever you can use "the cat" in a phrase at your friend's house, you can use the same phrase at the animal shelter but with "the cat" replaced by a specific cat's name.

In your player's Step event, modify the landmark-handling line to also capture the instance ID, which in your case is given by instance_nearest().
Code:
if (distance_to_object(obj_landmark) < 0)  {
  global.event_ini = true;
  global.event_subject = instance_nearest(x, y, obj_landmark);
} else{
  global.event_ini = false;
  global.event_subject = noone;
}
Now assuming that your landmarks assign their own thumbnails like this (no quotes allowed):
Code:
thumbnail = spr_example;
Then obj_pause_event can simply draw the thumbnail like this:
Code:
draw_sprite_ext(global.event_subject.thumbnail, 0, 320, 128, 2, 2, 0, c_white, 1);
 

Stranger

Member
First you must remember this: You are dealing with instances now, not objects. Objects are types. Instances are individuals.

If at this point you still have not read my article on the difference between objects and instances, read it now. "The cat" may be specific enough at your friend's house if he/she has only one cat, but it's not specific enough at an animal shelter during kitten season. And you don't need to completely relearn how to reference things with instance IDs either. Except for operations that deal specifically with object types such as object_*() functions or the last argument to instance_create(), instance IDs can be used virtually anywhere object IDs are legal. Whenever you can use "the cat" in a phrase at your friend's house, you can use the same phrase at the animal shelter but with "the cat" replaced by a specific cat's name.

In your player's Step event, modify the landmark-handling line to also capture the instance ID, which in your case is given by instance_nearest().
Code:
if (distance_to_object(obj_landmark) < 0)  {
  global.event_ini = true;
  global.event_subject = instance_nearest(x, y, obj_landmark);
} else{
  global.event_ini = false;
  global.event_subject = noone;
}
Now assuming that your landmarks assign their own thumbnails like this (no quotes allowed):
Code:
thumbnail = spr_example;
Then obj_pause_event can simply draw the thumbnail like this:
Code:
draw_sprite_ext(global.event_subject.thumbnail, 0, 320, 128, 2, 2, 0, c_white, 1);
Hot-diggity-daffodil this worked perfectly. Thank you a ton. I know the difference between instances and objects I just couldn't figure out the command to get the info for the drawing. Thanks again for all the help. We can throw this sucka in the [SOLVED] category now. Onwards and upwards!
 
Last edited:
Top