• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM Change one instance of an object into other object

K

Kuzyn

Guest
Hey! I'm searching the web for few days now and I can't find proper solution to my problem.
I will post a video with my problem:


I've got an obj_place. I need to enter it and then when I click on obj_sawmill I want to change that one specific obj_place into obj_construction_site. But all of obj_place's changes into obj_construction_site.

My code for obj_sawmill:
Code:
if (instance_exists(obj_text_noresources)) //prevent creating many messages at once
    {
        //nothing
    }
    else
        {
            if (obj_game.sawmill == 1 && obj_game.wood_amount >= obj_game.sawmill_wood && obj_game.stone_amount >= obj_game.sawmill_stone) //build if got resources
                {
                    obj_game.sawmill = 0;
                    obj_game.wood_amount = obj_game.wood_amount - 3;
                    obj_game.stone_amount = obj_game.stone_amount - 3;
                    obj_game.place_view = false;
                   
                    with (obj_place)
                        {
                            instance_change(obj_construction_site, true);
                        }
                   
                    view_xview = 0;
                    instance_destroy(obj_place_exit);
                    instance_destroy();
                }
                else //if no resources, send msg
                    {
                        instance_create(1450, 800, obj_text_noresources);
                    }
}
 

samspade

Member
Hey! I'm searching the web for few days now and I can't find proper solution to my problem.
I will post a video with my problem:


I've got an obj_place. I need to enter it and then when I click on obj_sawmill I want to change that one specific obj_place into obj_construction_site. But all of obj_place's changes into obj_construction_site.

My code for obj_sawmill:
Code:
if (instance_exists(obj_text_noresources)) //prevent creating many messages at once
    {
        //nothing
    }
    else
        {
            if (obj_game.sawmill == 1 && obj_game.wood_amount >= obj_game.sawmill_wood && obj_game.stone_amount >= obj_game.sawmill_stone) //build if got resources
                {
                    obj_game.sawmill = 0;
                    obj_game.wood_amount = obj_game.wood_amount - 3;
                    obj_game.stone_amount = obj_game.stone_amount - 3;
                    obj_game.place_view = false;
                  
                    with (obj_place)
                        {
                            instance_change(obj_construction_site, true);
                        }
                  
                    view_xview = 0;
                    instance_destroy(obj_place_exit);
                    instance_destroy();
                }
                else //if no resources, send msg
                    {
                        instance_create(1450, 800, obj_text_noresources);
                    }
}
Using an object's name like that will reference all instances of that object. You need to reference the specific instance id of an object. See the following help page: https://docs.yoyogames.com/source/d..._gml language overview/401_05_addressing.html
 
K

Kuzyn

Guest
Using an object's name like that will reference all instances of that object. You need to reference the specific instance id of an object. See the following help page:
I dont get it. I have many instances of obj_place so how would I know which one is selected?
 

samspade

Member
I dont get it. I have many instances of obj_place so how would I know which one is selected?
There are a variety of ways to do it depending upon how you've set things up. For example, you could use point_distance, point_in_circle, distance_to_point with the instance, instance's x/y, and the mouse's x/y.

Code:
///step event of object
if (point_distance(x, y, mouse_x, mouse_y) < 50) {
    if (mouse_check_button_pressed(mb_left) {
        instance_destroy();}}


///destroy event of object
instance_create(x, y, new_object);
If your object's have masks, you could use instance_place to get the specific id such as

Code:
///step event of some controller object
inst = instance_place(mouse_x, mouse_y, object);
with (inst) {
    instance_destroy();}
And so on. I would look into the various ways of doing it as the ability to identifying a specific instance's id is virtually necessary in almost anything you do so you want to find know the various possibilities so that you can choose the one that makes the most sense for what you're working on.
 
K

Kuzyn

Guest
There are a variety of ways to do it depending upon how you've set things up. For example, you could use point_distance, point_in_circle, distance_to_point with the instance, instance's x/y, and the mouse's x/y.

Code:
///step event of object
if (point_distance(x, y, mouse_x, mouse_y) < 50) {
    if (mouse_check_button_pressed(mb_left) {
        instance_destroy();}}


///destroy event of object
instance_create(x, y, new_object);
If your object's have masks, you could use instance_place to get the specific id such as

Code:
///step event of some controller object
inst = instance_place(mouse_x, mouse_y, object);
with (inst) {
    instance_destroy();}
And so on. I would look into the various ways of doing it as the ability to identifying a specific instance's id is virtually necessary in almost anything you do so you want to find know the various possibilities so that you can choose the one that makes the most sense for what you're working on.
Sorry but I still dont understand how this instructions can help me with changing one instance of an object (one specific that I want to, not random or the closest to my mouse position).




When I click on these 4 objects it goes from screen 1 to the screen 2. Then I've got specific menus etc.
And I just want to do this: when I click on e.g. "left" obj_place it saves it name/id/number whatever, then I click obj_sawmill and he turns that "left" obj_place into obj_construction (not all instances).

I'm noob and I don't understand how can I achieve this with your tips.
 

samspade

Member
When I click on these 4 objects it goes from screen 1 to the screen 2. Then I've got specific menus etc.
And I just want to do this: when I click on e.g. "left" obj_place it saves it name/id/number whatever, then I click obj_sawmill and he turns that "left" obj_place into obj_construction (not all instances).
That's exactly what my example code is intended to do, admittedly skipping some of the steps you want. Are your screens different rooms or just different screens? If different rooms you'll either have to make objects persistent or global so that they carry over. Otherwise, using "inst = instance_place(mouse_x, mouse_y, object);" you get and save the specific id of an instance, in this case it could be "left" obj_place. Then you simply need to add a few more steps. The next step would be something that registers a click on obj_sawmill. It sounds like you already have this. Then instead of using your original code, you can modify it to something like this:

Code:
with (inst)
{
    instance_change(obj_construction_site, true);
}
However, I would recommend against instance_change and instead destroy inst and create obj_construction_site at that location. I think this is close to what instance_change already does, but conceptually I think it's better as it forces you to take the objects destroy and create events into account. But you don't need to.
 
K

Kuzyn

Guest
@samspade
I thought that I already understand this but... eh.
I've tried 2 ways and still doesn't work (the:

First try:
in obj_sawmill (left released):
Code:
with (obj_place.inst)
{
    instance_change(obj_construction_site, true);
}
in obj_place (left_released):
Code:
inst = instance_place(mouse_x, mouse_y, obj_place);
Also I've added inst = 0; in obj_place (create) and tried without it.
In this attempt inst equals 0 all the time.

Second try:
in obj_sawmill(left released):
Code:
with (obj_game.inst)
{
    instance_change(obj_construction_site, true);
}
in obj_game (step event):
Code:
inst = instance_place(mouse_x, mouse_y, obj_place);
I did the same with create event, but both ways does't work.
And inst equals -4 here.

 
K

Kuzyn

Guest
@Refresh
Can someone explain me that step by step? I dont know what Im doing wrong.
 

samspade

Member
#Refresh anyone?
My earlier code had a typo. Should have been instance position not place but that's still how you do it. Select an instance of an object with some form of collision check and use the instance I'd. Which form is up to you and depends on your code.
 
To further buttress samspades point, instance_place simply tells you whether an instance exists at that position or not (a simple boolean true or false is returned) whereas instance_position returns the instance ID of the instance at the position, or false if there is no instance there.
 
N

NeonBits

Guest
there's this in the manual:
Code:
position_change
Changes all instances at a given position to a different object.
Syntax:

position_change(x, y, obj, perf);


Argument 	Description
x 	The x coordinate of where to change colliding instances.
y 	The y coordinate of where to change colliding instances.
obj 	The new object the calling object will change into.
perf 	Whether to perform that new object's Create event (true) or not (false).


Returns: N/A


Description

This function will check a position for a collision with any instances at the given point, and if there is one, it will change all instances in collision to be instances of the chosen object. You can set the "perf" argument to true which will force GameMaker: Studio to perform the destroy event of the found instance and the create event of the new instance, or false to not perform either of these events. Please note, that if you choose not to perform the destroy and create events, any instance created that uses a variable normally defined in the create event will crash the game as that variable will no longer exist.


Example:

position_change(200, 200, obj_Bird, true);

This will change all instances colliding at point (200,200) into an instance of "obj_Bird", performing "obj_Bird"s Create event for each of them in the process.
Or you can make a variable in the create event of the object you want to change and set it to false. Once the specefic condition that you want to happen follows [ex: if keyboard_pressed(vk_ctrl)] write "{variable = true;}". In the step event of the object, write "if ('variable' == true){do this}. Do you realy want to change object and not only its sprite? It's easier sometimes to just change sprite and make conditions based on the new sprite than switching object. But that depends of the project.
 

samspade

Member
Since I gave (at least conditionally) bad advice earlier I'll try for a more thorough answer or at least a full code example based upon what I think you're trying for:

Code:
///step event of object you want to be able to select select (so I think reading your code, obj_place)
if (mouse_check_button_pressed(mb_left)) {
    if (instance_position(mouse_x, mouse_y, id) {
        ///object is selected, put code here for example
        global.selected_obj = id;
    }
}

///use - step event of sawmill
if (mouse_check_button_pressed(mb_left)) {
    if (instance_position(mouse_x, mouse_y, id) {    
        with (global.selected_obj) {
            instance_change(obj_construction_site, true);
        }
    }
}
Reviewing the code you tried, the first version is essentially a different way of implementing the above idea and might work if you just changed instance_place to instance_position. The second version won't because it is checking every step which means it will only be an instance id if the mouse is currently over it, and it won't be when clicking on some other object (unless sawmill is a child of obj_place in which case you would be changing sawmill, which I don't think is what you want).

It may also be helpful to review the various collision functions and what each one does:
 
Top