Jump to content


Multiple instances of objects as switches


  • Please log in to reply
13 replies to this topic

#1 Guest_deepseaengine_*

Guest_deepseaengine_*
  • Guests

Posted 09 February 2012 - 12:23 PM

Forgive a super-beginner question, but I'm a bit stumped for the simplest way to do this.

I'm trying to add multiple switches to a map which, once all have been activated, will open the room exit. Simple enough, but object placement from the drag-n-drop room creator means each instance of the switch is identical - one activation flips all of the switches. I imagine I could add multiple objects (switch ID1, switch ID2, etc) but was hoping there was a simpler way?

This dynamic will be repeated for each room - would I need to assign IDs and 'create' the switch objects at specific co-ordinates for each switch in each room, can I simply auto-assign an ID to each switch placed by drag-n-dropping and code the game to recognise 'switch ID x has been activated'?

Many thanks in advance.

#2 thegame

thegame

    Flying Penguin

  • GMC Member
  • 1405 posts
  • Version:GM:Studio

Posted 09 February 2012 - 01:06 PM

All objects have a unique instance ID, starting at 100000 or something and going up one every time an object is placed in the room editor, or created with instance_create, but not going back down and filling in holes where objects were deleted.
In the event where you switch the instance (a key press event?), do this
var otherSwitch = collision_rectangle(x,y,bbox_right, bbox_bottom, obj_switch, true, true);
if(otherSwitch)
  otherSwitch.activated = !otherSwitch.activated;
collision_rectangle returns the collided instance's ID, and an ID can be used just the same way as an object's index but only affecting the specific instance rather than all of them.
I believe if its in a collision event, you can just use the keyword other for the same effect, but won't be toggle-able without checking for a keypress:
other.activated = true;
/*OR DO THIS*/
if(keyboard_check_pressed(vk_space))
  other.activated = !other.activated;

  • 0

#3 Mr Game

Mr Game

    GMC Member

  • New Member
  • 177 posts
  • Version:GM8

Posted 09 February 2012 - 01:09 PM

Do you want a precise code, or just an idea how to do?
  • 0

#4 Guest_deepseaengine_*

Guest_deepseaengine_*
  • Guests

Posted 09 February 2012 - 01:27 PM

Brilliant, thanks, thegame! I'll have to test that to get a better grip on it. My GML knowledge is very basic at the moment so this'll be a good exercise.

Mr Game, thank you, but I'll do some trial-and-error first and post my results for dissection. I find problems help me learn better.

Edited by deepseaengine, 09 February 2012 - 01:28 PM.


#5 Caracol

Caracol

    GMC Member

  • GMC Member
  • 153 posts
  • Version:GM8.1

Posted 09 February 2012 - 06:26 PM

Here's an option you can do with just drag-and-drop:

Every time a switch is flipped, add +1 to a variable in the DOOR object (the one that opens when all the switches are flipped). Call it num_switches_flipped or something.

In the door object, use the "Test Instance Count" on the switch object (to see how many switches are in the room) and compare it to num_switches_flipped. If they are equal, the door opens.

This way is a little simpler and a one-size-fits-all for every room.
  • 0

#6 thegame

thegame

    Flying Penguin

  • GMC Member
  • 1405 posts
  • Version:GM:Studio

Posted 09 February 2012 - 09:35 PM

@Caracol - It is no more one-size-fits all than any other method...

You can check the same thing like this with code
var i;
with(obj_switch) {
  if(activated)
    other.i += 1;
}
if(i == instance_count(obj_switch)) {
  //Open door
}

  • 0

#7 iam1me

iam1me

    GMC Member

  • GMC Member
  • 380 posts
  • Version:GM8

Posted 09 February 2012 - 09:51 PM

Here's an alternate, generic, solution:

define_Switch():
{
   if(!variable_global_exists("Switch"))
   {
      globalvar Switch;
      Switch = object_add();
      object_event_add(Switch,ev_create,0,"create_Switch();");
   }
}

create_Switch():
{
   state = 0; 
   action_script = -1; //id of script to execute when switch is toggled
}

toggle_Switch():
{
   if(action_script != -1) script_execute(action_script); 
}

Then create several instances and set their action_script = room0_OnToggle; *NOTE: do not put () at the end - you aren't calling the script here but giving a ref to it. Then write the room0_OnToggle script...

room0_OnToggle():
{
   if(switch_0.state == 0) exit;
   if(switch_1.state == 0) exit;
  ...

   //if it reaches this point, all switches have been flipped.
   open_door(); //replace with relevant code
}

This is a more generic solution, so you should be able to apply it to many different situations with ease.
  • 0

#8 Caracol

Caracol

    GMC Member

  • GMC Member
  • 153 posts
  • Version:GM8.1

Posted 09 February 2012 - 10:03 PM

@Caracol - It is no more one-size-fits all than any other method...


Yeah, I was assuming he wanted a drag-and-drop method, my comment was meant to say "it's still one-size-fits-all even though it doesn't use GML".

Anyway, if you want to use GML, it'll be slicker and better in the long run. More power to you!
  • 0

#9 Guest_deepseaengine_*

Guest_deepseaengine_*
  • Guests

Posted 09 February 2012 - 10:27 PM

Thank you all! Some of this is a bit over my head at the moment, so I'll have to sit down and test different methods.

Caracol - thank you for your non-GML solution. I'll try that, but I'm hoping to learn GML through this project, so I'll probably go for the coding instead.

#10 Guest_deepseaengine_*

Guest_deepseaengine_*
  • Guests

Posted 11 February 2012 - 12:43 PM

Apologies for the 'legal' bump - but I'm still finding my all switches being activated at once rather than just one instance. I've tried a few different methods / suggestions but some I don't fully understand and others don't really apply. If I can get this (basic) version down, I'd like to dabble with the other methods suggested, but I can't see any flaws in my DND / code:

In obj_CHAR:

IF obj_CHAR collides with obj_SWITCH
swACTIVATE=1;

In obj_SWITCH:
On keypress 'F'
if(obj_CHAR.swACTIVATE=1)
{
    swON=1;
    obj_SWITCH.image_index=1;
    obj_SWITCH.image_speed=0;
}

I just want the collided instance of obj_SWITCH to change its variable 'swON' from 0 to 1 and for the sprite to change from image 0 to image 1. Both of these things do happen, but to all instances of the obj_SWITCH rather than the one obj_CHAR is colliding with. I don't want to reference specific instance IDs - I'd rather just do a 'the-currently-collided-with-instance' reference. I bet it's a really obvious solution... any ideas?

#11 thegame

thegame

    Flying Penguin

  • GMC Member
  • 1405 posts
  • Version:GM:Studio

Posted 11 February 2012 - 01:49 PM

if(obj_CHAR.swACTIVATE && place_meeting(x,y,obj_CHAR)) {

    swON=1;

    obj_SWITCH.image_index=1;

    obj_SWITCH.image_speed=0;

}

  • 0

#12 Guest_deepseaengine_*

Guest_deepseaengine_*
  • Guests

Posted 11 February 2012 - 02:37 PM

if(obj_CHAR.swACTIVATE && place_meeting(x,y,obj_CHAR)) {
    swON=1;
    obj_SWITCH.image_index=1;
    obj_SWITCH.image_speed=0;
}

I'd tried an instance_position variant of that which didn't work. Unfortunately, this doesn't either. Any other suggestions?

#13 thegame

thegame

    Flying Penguin

  • GMC Member
  • 1405 posts
  • Version:GM:Studio

Posted 11 February 2012 - 04:33 PM

if(obj_CHAR.swACTIVATE && place_meeting(x,y,obj_CHAR)) {
    swON=1;
    image_index=1;
    image_speed=0;
}
You were setting it for all of the switches... that's what was wrong
Putting obj_name.var_name will change var_name's value in all instances obj_name

Edited by thegame, 11 February 2012 - 04:34 PM.

  • 0

#14 Guest_deepseaengine_*

Guest_deepseaengine_*
  • Guests

Posted 11 February 2012 - 04:46 PM

Oh boy, I knew it'd be something simple. Thank you so much - now to start experimenting with other techniques.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users