GM:S 1.4 Change one instance of an object into other object

Discussion in 'Programming' started by Kuzyn, Oct 9, 2017.

  1. Kuzyn

    Kuzyn Member

    Joined:
    Oct 9, 2017
    Posts:
    7
    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);
                        }
    }
     
  2. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    1,106
    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
     
  3. Kuzyn

    Kuzyn Member

    Joined:
    Oct 9, 2017
    Posts:
    7
    I dont get it. I have many instances of obj_place so how would I know which one is selected?
     
  4. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    1,106
    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.
     
  5. Kuzyn

    Kuzyn Member

    Joined:
    Oct 9, 2017
    Posts:
    7
    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).

    [​IMG]
    [​IMG]

    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.
     
  6. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    1,106
    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.
     
  7. Kuzyn

    Kuzyn Member

    Joined:
    Oct 9, 2017
    Posts:
    7
    @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.

     
  8. Kuzyn

    Kuzyn Member

    Joined:
    Oct 9, 2017
    Posts:
    7
    Anyone got other method or can explain me how to do this? :(
     
  9. Kuzyn

    Kuzyn Member

    Joined:
    Oct 9, 2017
    Posts:
    7
    @Refresh
    Can someone explain me that step by step? I dont know what Im doing wrong.
     
  10. Kuzyn

    Kuzyn Member

    Joined:
    Oct 9, 2017
    Posts:
    7
    #Refresh anyone?
     
  11. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    1,106
    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.
     
  12. RefresherTowel

    RefresherTowel Member

    Joined:
    Jul 13, 2016
    Posts:
    379
    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.
     
  13. NeonBits

    NeonBits Member

    Joined:
    Sep 22, 2017
    Posts:
    146
    there's this in the manual:
    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.
     
  14. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    1,106
    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:
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice