GML Make a not clickable Object

P

PopatoChisp

Guest
Hi, I'm making a mouse-click controlled game, and I want the player to not be able to click on certaine spots because they are not walkable.

I think I may have an idea how to start that in the Mouseclick object (it creates a little arrow that shows where the player goes when pressing the LMB, and the player object moves towards it after it is createt and then the sprite goes transparent on meeting)
Code:
if (place_meeting(x,y,obj_NoWalk))
but I'm not really sure how to continue.
I don't want to deactivate the object completly because the player should still be able to click on the
walkable parts of the room, but I don't really know what else to do.
 

Perseus

Not Medusa
Forum Staff
Moderator
Like this?

Code:
if (mouse_check_button_pressed(mb_left)) {
   if (!position_meeting(mouse_x, mouse_y, obj_NotWalkable)) {
      if (!instance_exists(obj_Mouseclick)) {
         instance_create(mouse_x, mouse_y, obj_Mouseclick);
      }
   }
}
You might want to look into collision_line as well which can be used to stop a "mouseclick" instance from getting created in areas not accessible to the player -- such as on the other side of a wall of obj_NotWalkable instances.
 
P

PopatoChisp

Guest
Like this?

Code:
if (mouse_check_button_pressed(mb_left)) {
   if (!position_meeting(mouse_x, mouse_y, obj_NotWalkable)) {
      if (!instance_exists(obj_Mouseclick)) {
         instance_create(mouse_x, mouse_y, obj_Mouseclick);
      }
   }
}
You might want to look into collision_line as well which can be used to stop a "mouseclick" instance from getting created in areas not accessible to the player -- such as on the other side of a wall of obj_NotWalkable instances.
I'm not sure if colision line will work, since I have one whole background, where I want to make a nonwalkable and non-clickable place on trough an transparent object maybe.

And I have a little question to the code if that's alright, isn't it just creating the mouseclick (because I already managed to make it create the little arrow in the clicked place to which the player object moves towards) instead
of not creating in in this place? Sorry if I understood it wrong

Also I was trying to fix my problem by myself while waitting for some tips here ( I hope that's alright to do) , and
I have a "Global Left pressed" event in the Mousclick object with the code
Code:
x = mouse_x
y = mouse_y
which (I think) creates the object on the place I click and I put an object called obj_walk on the areas I can walk on and tried changing that code to
Code:
if(place_meeting(x,y,obj_Walk)){
x = mouse_x
y = mouse_y
}
But that just still created the mouseclick object on the area that isn't covered by the obj_walk, but made me unable to creat a new mousecklick object again by clicking somewhere else, no matter if on the obj_walk or not.

I'm not sure if this is a completly wrong aproach maybe?
 

Perseus

Not Medusa
Forum Staff
Moderator
What my code does is that it creates an instance only if the mouse is NOT over an instance of obj_NotWalkable -- practically the same as not creating it when the mouse is over one. I'm using the not operator there.

As for the inability to create more than one instance, I read another topic of yours and it appears you're simply setting its image_alpha to 0 instead of destroying it upon collision. The instance will still exist and since !instance_exists(obj_Mouseclick) will continue to return false (as an instance does exist), you won't be able to create any new instances.

Instead of doing that, keep a variable that is set to true when the instance collides with the player. The following code could make it look better.

Code:
if (collided) {
   image_alpha -= 0.1;
}
if (image_alpha <= 0) {
   instance_destroy();
}
The instance will slowly fade away and will get destroyed once fully invisible, so that you can create another instance.
 
P

PopatoChisp

Guest
What my code does is that it creates an instance only if the mouse is NOT over an instance of obj_NotWalkable -- practically the same as not creating it when the mouse is over one. I'm using the not operator there.

As for the inability to create more than one instance, I read another topic of yours and it appears you're simply setting its image_alpha to 0 instead of destroying it upon collision. The instance will still exist and since !instance_exists(obj_Mouseclick) will continue to return false (as an instance does exist), you won't be able to create any new instances.

Instead of doing that, keep a variable that is set to true when the instance collides with the player. The following code could make it look better.

Code:
if (collided) {
   image_alpha -= 0.1;
}
if (image_alpha <= 0) {
   instance_destroy();
}
The instance will slowly fade away and will get destroyed once fully invisible, so that you can create another instance.
Oh, thank you, I didn't know about the not operator (I Only started actually using game maker a bit ago).
I think I now understand the what your code does, thank you, but it sadly doesn't seem to work.
I tried using it in a step event and a left pressed event in the mouseclick object but it still creates it everywhere, even on the notwalkable object, I think I may be using it wrong.

But your other code helped a lot, thank you for that a lot, it looks nicer with the fade out and the sprite stopped changing back to walking for a moment when my player character reached it's destination (which was
the problem I decribed in the other topic, so thank you for also helping me with that) and I could create another mouseclick after creating one again.
 

Perseus

Not Medusa
Forum Staff
Moderator
I tried using it in a step event and a left pressed event in the mouseclick object but it still creates it everywhere, even on the notwalkable object, I think I may be using it wrong.
Why are you using the mouseclick object to create its own instances? Use a controller object instead and make sure this is the only code that can create a mouseclick instance. Also make sure that obj_NotWalkable has a collision mask (hint: assign the object a sprite, so that it gets a collision mask, untick the "Visible" checkbox) as position_meeting() will require that.

If that doesn't help, please post the exact code that you're using along with every relevant information.
 
P

PopatoChisp

Guest
Why are you using the mouseclick object to create its own instances? Use a controller object instead and make sure this is the only code that can create a mouseclick instance. Also make sure that obj_NotWalkable has a collision mask (hint: assign the object a sprite, so that it gets a collision mask, untick the "Visible" checkbox) as position_meeting() will require that.

If that doesn't help, please post the exact code that you're using along with every relevant information.
I forgott I put the code to creat the mouseclick into the player object, I'm sorry.
It wasn't working at first there too, but I added a sprite to the not walkable object, made it invisible like you said and it worked perfectly, thank you so much!
 
P

PopatoChisp

Guest
Why are you using the mouseclick object to create its own instances? Use a controller object instead and make sure this is the only code that can create a mouseclick instance. Also make sure that obj_NotWalkable has a collision mask (hint: assign the object a sprite, so that it gets a collision mask, untick the "Visible" checkbox) as position_meeting() will require that.

If that doesn't help, please post the exact code that you're using along with every relevant information.
I hope it's alrigth to ask another small thing to this,
but if I want to add more not walkable things ( for example if I have another object that the player can interact with but not walk on, like a character you can talk to etc.) to it should I just add another

"if (!position_meeting(mouse_x, mouse_y, obj_NextNotWalkableObject)) {}"

to the code? Or would that be wrong?
 

Perseus

Not Medusa
Forum Staff
Moderator
That's where parenting comes into use. Set obj_NotWalkable as the parent of all those objects that you want to take into consideration. This will do what you want without having to make changes to the code.

But if there's a case in which you can't assign an object a parent or it already has a parent, you could use the and (&&) operator.

Code:
if (!position_meeting(mouse_x, mouse_y, obj_NotWalkable) && !position_meeting(mouse_x, mouse_y, obj_NextNotWalkableObject)) {
   // ...
}
The && operator allows you to chain together as many expressions as you want, but as you can see, the code will get messy, so parenting is still a recommended way to go.

See: How NOT to use && and ||
 

Gamebot

Member
Is this like a maze game, without seeing the maze?

If so I would use paths, or a grid structure of some sort.

At very least some type of script that gets the only direction (s) available, then check where the mouse is reletive to the player.
If mouse is in one of those directions the player can move...
If mouse is not in one of those directions....player stands still, loses life...

All in a controller object.
 
P

PopatoChisp

Guest
That's where parenting comes into use. Set obj_NotWalkable as the parent of all those objects that you want to take into consideration. This will do what you want without having to make changes to the code.

But if there's a case in which you can't assign an object a parent or it already has a parent, you could use the and (&&) operator.

Code:
if (!position_meeting(mouse_x, mouse_y, obj_NotWalkable) && !position_meeting(mouse_x, mouse_y, obj_NextNotWalkableObject)) {
   // ...
}
The && operator allows you to chain together as many expressions as you want, but as you can see, the code will get messy, so parenting is still a recommended way to go.

See: How NOT to use && and ||
That seems way easier then I expected thank you!
 
Top