• 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!

[SOLVED] Switch to toggle other object

C

catchpharse

Guest
Hi there fellow coders,

I am totally new to GameMaker but not to programming in general, so please point me to a ressource of knowledge, if my question turns out to be pointless :p

I am trying to accomplish the following:

a) define a toggle object (here called obj_dice)
b) define a background object (here called obj_dice_bg)

c) generate two instances of toggles and two of background, such that the sprite of the first backgound is toggeled (on) by the first switch and the second by the second switch.

I did this by adding the following code to a step event of obj_dice:

Code:
if (mouse_check_button_released(mb_left) && position_meeting(mouse_x,mouse_y,id)) {

    global.checked_id=instance_id;
    stateIndex+=1;

    stateIndex = stateIndex mod 2;
       
    global.key = key;
   
    if (stateIndex==0) {

           
        with(obj_dice_back)
       
        if (key==global.key)
            { sprite_index=7; }    
    } 
 
    if (stateIndex==1) {
           
        with(obj_dice_back) {
       
        if (key==global.key)  
            { sprite_index=6;}
        } 

    }
}
Additional Info:
The stateIndex is currently computed mod 2, but there may be more states later than two.

My question is now:
Is there a smarter way to pass the key for matching the nth instance of object A to the nth instance of object B than changing a global variable? How do you guys do that? Write a third class with a member function/variable that takes care of that?

Thank you for your thoughts and ideas, I am looking forward to learn from your experience!
catchphrase
 

Roderick

Member
This is pseudo-code! Do not try to use it directly!

Code:
To create the objects:

for (var i = 0; i < 20; i++)
{
 dice[i] = instance_create(obj_dice)
 dice_bg[i] = instance_create(obj_dice_bg)
 dice_bg[i].counter = i
}
Code:
In the step code of the clickable object, or drop the if and put in a mouse left click action:

if (dice_bg is clicked on)
{
 with (dice[counter])
 {do stuff}
}
Edit: I made obj_dice_bg the clickable, and obj_dice the reactive object. Switch them around to make it work the way you described.
Edit edit: So many typos and omitted info! It should be right now.
 
Last edited:
C

catchpharse

Guest
Thank you very much for your input. I tried something like that before: instancing the objects with a loop and putting them into an array. Or just instancing a few by hand.
If I use your approach, I get an error message:

Code:
trying to index a variable which is not an array
 at gml_Object_obj_dice_StepNormalEvent_1 (line 21) -         with(dice_bg[counter]) {
I think, the step event in the dice object does not know about the dice_bg instances. At the moment, they are created in a initScript, wich is called in a creation event of a simple none sprite object obj_gameInit in the room.

Where should I put the creation code?
 
Last edited by a moderator:
A

Aura

Guest
The best approach would be to use the creation code of each target instance to define an unique identifier.

Code:
my_id = 5;
Similarly, in the creation code of the switch instances, define the identifier whose corresponding instance is to be affected.

Code:
effect_on = 5;
Then you can go about checking if the identifier of the target instance is the same as yours.

Code:
if (mouse_check_button_released(mb_left) && position_meeting(mouse_x, mouse_y, id)) {
   with (obj_target) {
      if (my_id == other.effect_on) {
         //Do something
      }
   }
}
Note that inside a with construction, the other keyword refers to the instance calling the code, that is, the switch object.

http://docs.yoyogames.com/source/dadiospice/002_reference/001_gml language overview/401_18_with.html
 
C

catchpharse

Guest
Aura: Thank you very much, your information completed my ansatz :) I already assinged such an identifier (named key in my code above). I misunderstood the use of the keyword other though, something like this works now:

Code:
        with(obj_dice_back)
      
    {    if (key==other.key)
            { if (sprite_index==7) {sprite_index=6;} else {sprite_index=7} }
            else
            {sprite_index=7;}     }
Roderick: I am still interested how you would make your idea work. Where would I have to instantiate the dice array so that the dice object can access it in its step event?

Cheers!
 

Roderick

Member
Thank you very much for your input. I tried something like that before: instancing the objects with a loop and putting them into an array. Or just instancing a few by hand.
If I use your approach, I get an error message:

Code:
trying to index a variable which is not an array
 at gml_Object_obj_dice_StepNormalEvent_1 (line 21) -         with(dice_bg[counter]) {
I think, the step event in the dice object does not know about the dice_bg instances. At the moment, they are created in a initScript, wich is called in a creation event of a simple none sprite object obj_gameInit in the room.

Where should I put the creation code?
Normally, I just have a single object called obj_controller that creates all my objects, handles my inputs and pretty much runs the entire game. I don't put anything else in the room; obj_controller does everything. You'd need to have a similar object that creates your objects for you.

One mistake that I made is that those arrays would belong to whatever object created the instances. In order to make them easier to access, they should be declared as global variables; ie, global.dice_bg, etc. The counter should not be made global, as we're assigning it to one of the instances, and we want it there.

Something else you could try (especially if you're placing the objects in the room editor), is only placing one or the other, then adding some creation code to the one you place:

Code:
In the obj_dice_bg create code:

partner = instance_create(x, y, obj_bg);
partner.partner = id;
This way, each object has a variable in it named "partner" that stores the id of its pair, which can be used to manipulate the other. In fact, I'd recommend this method over my previous suggestion.

Once it's set up this way, you can simply use with(partner) or partner.sprite_index = x, whichever works best for you.
 
C

catchpharse

Guest
Roderick: Okay, great, thanks a bunch! I also figured it out, that declaring the dice array as global and accessing everything with the prefix global. works also fine!

To sum it up:
a) use some global variable, be it an array of objects or the global checked_id as i did in the beginning - or -
b) introduce a local object linking id counter and check while iterating all instances with the other.counter variable

Thanks guys, I learned a lot today :D Have a nice day :)
 
Top