Temporarily Deactivating Collisions

T

Toxicosis

Guest
I'm still working on a prototype to gain experience.

In this prototype, the player can GRAB things during a collision event with their hands, and then throw them away. I have a problem, though- I made the player able to grab wall segments. However, rather than make them disappear, I placed them on the player's hand.

And that's a problem, because the wall segments prevent the player from moving in the wall's direction very quickly, or in the other direction at all- turning around forces the segment to overlap the player, and thus, no movement in any direction is possible.

I tried to disable the mask for that instance alone while the player is grabbing, but that caused a problem of its own: the objects the player grabs no longer have a sprite while grabbed, and while that did nothing to the walls, the enemies have a draw event that fails if they have no sprite. Can anyone spot the mistake? I've spent the whole Sunday on this, I no longer really know what's what.

I tried saving the sprite index to a control object, then duplicating it with an inexistent mask, which gets assigned to the particular instance the player has in hand. After the player releases the object, the control object restores the grabbed instance's initial sprite. A lot of it was trial, error... flailing, really. I've got no clue what's wrong in this code anymore.

Code for grabbing:
Code:
//When the pinch grabs an enemy, the enemy must resort to behaviour 101. Then we must make the pinch change behaviour itself.
//Change: when the pinch grabs an instance, their ID is stored in a control object that we create. Hold becomes true, too.
//if hold == true exit;

var grab;
grab = noone;
if hold == true exit;

if place_meeting(x,y,obj_enemy) //If it touches an enemy
{
  with obj_enemy
  {
  if sticking == 1 //Check that the enemy's not sticking to the player.
  exit;
  }
  with other  //Back to the player,
  hold=true;  //start holding.
  with obj_enemy  //Back to the enemy,
  {
  if place_meeting(x,y,obj_pinch)  //If there's one hitting the player's hand
  {
  abnormal_behaviour = 101;  //abnormal behaviour 101.
  grab = id;  //Mark it under grab.
  }
  }
}

if place_meeting(x,y,obj_wallz_pick_up)  //If it touches a pickuppable wall,
{
  hold=true;  //also held. Check the walls for one that's in position.
  with obj_wallz_pick_up
  {
  if place_meeting(x,y,obj_pinch)
  grab = id;  //Mark it as grabbed.
  }
}
if grab != noone  //Did we grab something? Create a grab instance of control_throw, and tell it to file them.
  {
  grabb = instance_create(x,y,obj_control_throw); //Create the control object.
  grabb.inst = grab; //Make it point to the object we're grabbing.
  grabb.grabbing = true; //Tell it we're grabbing that thing right now.
   
  grabb.spr_store = grabb.inst.sprite_index; ///Store the current index.
  if sprite_exists(spr_throw) sprite_delete(spr_throw); //Clears spr_throw.
  grabb.spr_throw = sprite_duplicate(grabb.inst.sprite_index); //Assigns spr_throw the current sprite of the grabbed instance.
  sprite_collision_mask(spr_throw, false, 1,  sprite_width/2, sprite_height/2, sprite_width/2, sprite_height/2,  1, 0); //Assigns that same sprite a pretty empty collision mask.

  var sprite_throw; //Readies a variable to pass things to inst.
  sprite_throw = spr_throw; //Assigns the variable to spr_throw.
  with grabb.inst
  {   
  sprite_index = sprite_throw; //Assigns the sprite to the object.
  }
  }
Code for releasing:
Code:
//So long as there's a pinch, inst must remain in that position.

var fall = 5;

if grabbing == true
{
fling_direction = obj_player.facing;
fling_speed = sprite_get_width(spr_punch)/2;
}

if instance_exists(inst) && instance_number(obj_pinch) == 1 && grabbing == true
{
  with inst
  prep_hurl()
  exit;
}

//Once the pinch is out, we're no longer grabbing.
if instance_number(obj_pinch) == 0
  {
  var sprite_store; //Creates the variable.
  sprite_store = spr_store; //Stores the variable.
  with inst sprite_index = sprite_store; // restores the sprite to the value that had been stored before.
  grabbing = false; //Grabbing is no longer its initial value.
  }
//Which means we're flying.   
if instance_exists(inst) && grabbing == false
{
  grabbing = false;
//  if !be_flung(fall,fling_speed/4,fling_direction,inst) //I made a script because I was getting tired of typing the whole thing all the time. It returns false if it can't move.
  if !be_flung(fall,fling_speed,fling_direction,inst)
  instance_destroy(); //If the thing we want to throw cannot fly anymore, no need for this.
}
 
G

GewoonNiels

Guest
Why not only draw the instance, when grabbing it:
Code:
///draw event
if hold{
   draw_sprite(grab.sprite_index,*at hand position)
}
After grabbing this segment delete it, and create it when you release it again.
 
T

Toxicosis

Guest
I almost went for your solution, but the problem is that I want the items' values to be mostly preserved, so enemies don't get their HP resetted after being thrown, and any item's destroy events are not executed every time I grab them.

I guess I could make them get transported elsewhere, like at x -10000 y -10000 and then just get drawn in place, but I'm sure that's gonna cause problems down the line. The other, final alternative is to rotate them so they stay out of the player's way, but that's a last resort, because I'm sure it's gonna cause problems down the line too.
 
B

bojack29

Guest
Why not when you pick up an object that you absorb its properties for being held? Then when it is put down it simply creates the object again and returns those properties to it?
Code:
with(instance_create(x, y, object)){
     info0 = other.info0;
     info1 = other.info1;//etc
}
 
T

Toxicosis

Guest
That's an idea, bojack, and a good one- but to do that, I'd have to preface every pickuppable object's properties with enemy_ or wall_ something, or the player's with player_ in order to avoid an embarassing duplicate that somehow altered the player's properties (or forced some of them into the object grabbed). Besides, the destroy event would probably give me trouble if I did that.

My last attempt was showing me that if I grab an enemy, since they have a draw event, once I assign them an inexistent sprite, the game crashes on the draw event. It's rather frustrating, but manageable. I'll just reread the instructions for these functions, I guess, until I get them right, I'll keep struggling with sprite_duplicate and sprite_index in the meantime. If everything else fails, I'll have to try one or more of those things.
 
B

bojack29

Guest
I bring this up because I built a turn based strategy game in another life that required soldier units to "get in" to another unit. Mainly a transport helicopter or some land transportation vehicle. The trick was that the transportation vehicle had an array within it that kept track of all the properties each soldier had when they entered the vehicle. The transportation vehicle would snag real values like health, ammo, object_index (for the difference between mechs and soldiers) and so on. It would then proceed to delete each unit that came aboard.

When a unit was to 'leave' the vehicle it simply created new objects with designated properties stored in the appropriate array.

This worked really well and kept everything organized. I didnt have to 'move' units off the map. That could cause all sorts of problems. Good luck!
 
T

Toxicosis

Guest
I figured out a simpler way. I was doing it the wrong way.

Simply creating an empty spr_throw and assigning it an empty sprite, then assigning the grabbed instance that mask while it's grabbed and returning it to normal after it was done was much simpler and less buggy. The lines of command involved were

mask_index = spr_throw;
to clear the mask,

mask_index = sprite_index;
to reset it.
 
Last edited by a moderator:
Top