How to repel objects from one object?

A

Artwark

Guest
Ok so I want it so that when the player touches the powerup, it should repel other objects for a short time.

So this is how I tried doing it but nothing happened

Code:
Create Event
global.repel = 0;
On collision with powerup
Code:
global.repel = 300;
Step event

Code:
if global.repel;

global.repel--;
Then I go for the collision even for the enemy object that collides with the player

Collision Event if obj_asteroids collides with obj_player

Code:
if (global.repel !=0)
{
direction=point_direction(obj_player.x,obj_player.y,obj_asteroids.x,obj_asteroids.y-50);
}
When I test it, it shows this error

FATAL ERROR in
action number 1
of Step Eventobj_player
for object obj_asteroids:

Unable to find any instance for object index '0' name 'obj_player'
at gml_Object_obj_asteroids_CollisionEvent_0_1 (line 40) - direction=point_direction(obj_player.x,obj_player.y,obj_asteroids.x,obj_asteroids.y-50,)

How do I fix this?

EDIT: Oh an when I mean repel, I meant the enemies are pushed away from the player like some strong force.
 

TheBroman90

Member
Code:
if (global.repel !=0) and instance_exists(obj_player)
{
direction=point_direction(obj_player.x,obj_player.y,obj_asteroids.x,obj_asteroids.y-50);
}
What happens if you try this?
 
A

Artwark

Guest
The error does not show up but it still doesn't work.

It just destroys the object and that's it. the asteroid is not being pushed away from the player.....
 

TheBroman90

Member
Code:
if (global.repel !=0) and instance_exists(obj_player)
{
direction=point_direction(obj_player.x,obj_player.y,obj_asteroids.x,obj_asteroids.y-50);
speed = 10; // Set to whatever...
friction = 0.5;
}
And I guess that you would have to disable the destroy event for the object if you want to push it instead.
 
A

Artwark

Guest
Still not working...but I'm suprised that you guessed right and that I happen to have a destroy event for the enemy!

But it doesn't do anything if you're curious about the destroy event except just creating another instance which is basically a parent:

Code:
instance_create(x, y, obj_asteroids_s);
instance_create(x, y, obj_asteroids_s);
global.points = global.points + 50;
audio_play_sound(snd_explosion1,0,0);
global.c +=1;

if global.c == 1
{
achievement_post("CgkIq97D09UPEAIQAg",100)
}
I don't mind having to write a different code if this is a bit annoying to you so long as I get that repulsion.
 

TheBroman90

Member
Oh what I meant was that you have to disable the object getting destroyed when colliding with the player, if you want to push it instead.
 
A

Artwark

Guest
I disabled the destroy upon collision but it still doesn't work......
 

TheBroman90

Member
I noticed now that you are moving away from
Code:
obj_asteroids.x,obj_asteroids.y-50
which means all asteroid objects. Remove "obj_asteroids" and do like this instead:
Code:
if (global.repel !=0) and instance_exists(obj_player)
{
direction=point_direction(obj_player.x,obj_player.y,x,y-50);
speed = 10; // Set to whatever...
friction = 0.5;
}
I tried it in a project and the object moves away on collision with the player.
 
A

Artwark

Guest
I noticed now that you are moving away from
Code:
obj_asteroids.x,obj_asteroids.y-50
which means all asteroid objects. Remove "obj_asteroids" and do like this instead:
Code:
if (global.repel !=0) and instance_exists(obj_player)
{
direction=point_direction(obj_player.x,obj_player.y,x,y-50);
speed = 10; // Set to whatever...
friction = 0.5;
}
I tried it in a project and the object moves away on collision with the player.
But how is it not working for me now that I tried doing what you just gave? I swear, its either the version difference or that I need to be clear here.

Ok so to just be clear here.

Create Event
global.repel = 0;

collision with obj_bang
global.repel = 300;

Step event

if global.repel
global.repel--;

and this is where I just applied your code when obj_asteroids collides with the player.
if (global.repel !=0) and instance_exists(obj_player)
{
direction=point_direction(obj_player.x,obj_player.y,x,y-50);
speed = 10; // Set to whatever...
friction = 0.5;
}
This is how I've done it.....but even with this, it still doesn't work.....I can't figure out the issue. It worked for the previous powerup which is the shield so why can't it work here?
 

TheBroman90

Member
But you're saying that the asteroid gets destroyed instead of pushed. There is no instance_destroy() code here, so you must have it somewhere else.
 
A

Artwark

Guest
no the asteroid does not get destroyed. Its the player that gets destroyed.
 
A

Artwark

Guest
Guys!
My code repels the astriods!
I'm getting this fatal error.....

FATAL ERROR in
action number 1
of Step Event0
for object obj_asteroids:


Variable obj_asteroids.v(100025, -2147483648) not set before reading it.
at gml_Object_obj_asteroids_StepNormalEvent_1 (line 27) - Dis = point_distance(v.x,obj_repel.y,x,y);

I'm just curious as to how you are giving a variable sightDis if you haven't created it. Of course I can be wrong here but I always have known that you need to create a variable before giving it conditions....isn't that right?

But anyways...still not working. I don't know what to do at this point.

Ok what's your collision code for the player then?
the obj_player does not have a collision for the asteroids. its only in the asteroids that its done so I put collision on player for asteroid and marked it as other instead of self.
the only collision that the player has is the powerups which will give effects to the player and the powerups get destroyed if the player touches them.
 
A

Artwark

Guest
Ooops!
Change all sightDis to just Dis, and all sightDir to just Dir.
Sorry!

Try that!

Oh! And put the code that repels in the astroids end step event, and make it where when you have the power up, it repels!
still getting this error......

FATAL ERROR in
action number 1
of Step Event0
for object obj_asteroids:


Variable obj_asteroids.v(100025, -2147483648) not set before reading it.
at gml_Object_obj_asteroids_StepNormalEvent_1 (line 27) - Dis = point_distance(v.x,obj_repel.y,x,y);

And its in the end of the step event of the obj_asteroids as you said....
 

TheBroman90

Member
It's a typo. This
Code:
Dis = point_distance(v.x,obj_Shield.y,x,y);
Should be this
Code:
Dis = point_distance(obj_Shield.x,obj_Shield.y,x,y);
 
A

Artwark

Guest
It's a typo. This
Code:
Dis = point_distance(v.x,obj_Shield.y,x,y);
Should be this
Code:
Dis = point_distance(obj_Shield.x,obj_Shield.y,x,y);
I'm getting this......

FATAL ERROR in
action number 1
of Step Event0
for object obj_asteroids:

Unable to find any instance for object index '12' name 'obj_repel'
at gml_Object_obj_asteroids_StepNormalEvent_1 (line 26) - Dir = point_direction(obj_repel.x,obj_repel.y,x,y);

EDIT: Would you guys like to get the gmz file? I don't want to sound rude but I'm not sure if this is getting any progress....I mean if its working for you guys, how can't it not work for me?
 

TheBroman90

Member
Then you have to check if the instance exists first.
Code:
if instance_exists(obj_repel)
Dir = point_direction(obj_repel.x,obj_repel.y,x,y);
 
A

Artwark

Guest
Dude! Listen carefully!
Lets say when you collide with the shield power-up, ether you have a var that says you have a shield, or you make a object thats a shield that follows the player, I would advize you to make a object shield (This works best).

If you have an object shield, then in the end step event of the astriod object, say:

Code:
Dir = point_direction(obj_shield.x,obj_shield.y,x,y);
Dis = point_distance(obj_shield.x,obj_shield.y,x,y);

if instance_exists(obj_shield)
{
   if Dis <= //Just put your players sprite width and height here, example 32
   {
      x = obj_shield.x + lengthdir_x(30,Dir);
      y = obj_shield.y + lengthdir_y(30,Dir);
   }
}
remember! Make a shield object around the player!
Try again and see if this works.
Thanks!
This is what I've done.

if instance_exists(obj_repel)
{

Dir = point_direction(obj_repel.x,obj_repel.y,x,y);

Dis = point_distance(obj_repel.x,obj_repel.y,x,y);
if Dis <= 30
{
x = obj_repel.x + lengthdir_x(80,Dir);
y = obj_repel.y + lengthdir_y(80,Dir);
}
}

It no longer shows that error......but it still doesn't work.

Thing is, the shield is created through a draw event so its a sprite.... and the variable acts as the function.
 
A

Artwark

Guest
Ok here's how the collision is done in the obj_asteroids if it hits the player.....

Code:
//if(sprite_index == spr_player)
if(sprite_index == spr_player && shield == 0 && global.repel ==0)
{
instance_create(obj_player.x,obj_player.y,obj_dead);

audio_play_sound(snd_explosion2,10,0);

if(global.life > 0)
{
instance_create(room_width/2,room_height/2,obj_playerspawn);

global.life -=1;
}
else
{   
instance_create(0,0,obj_gameover);
}
instance_destroy();
}
if(global.repel != 0) && instance_exists(obj_player)
{
direction = point_direction(obj_player.x,obj_player.y,x,y-50);
speed = 10
friction =0.5;
}
So now, something does hapen but if I collide it with the ship, the ship moves up and it stops moving instead of the asteroid being pushed up.
 
A

Artwark

Guest
Ok here's what I want since I didn't elaborate exactly on what kind of repulsion I wanted.

I want the repulsion in such a way that when you touch a powerup, you get a sprite shield. This sprite shield should push the asteroids to the mirror direction if they get close to the player while the power up is activated. I don't want its speed to change, just it should be pushed back with the same speed its going. That's it. The player should not get pushed back and it should maintain its new direction as soon as the powerup goes off.
 
A

Artwark

Guest
ok I figured out how to do it...sort of.

So I made a collision code for asteroids and clicked self and pasted the code I originally did and added this:
if(global.repel != 0) && instance_exists(obj_player)
{
x--;
y--;
}
It works but now I need to make it so that it goes a bit away from the shield sprite.
 
A

Artwark

Guest
New
Ok I got how to do it.

I added a code in the collision event for obj_asteroids and checked it self and did this code.

if(global.repel != 0) && instance_exists(obj_player)
{
y-=50;
x-=50;
//speed = -0.5;;
direction = point_direction(obj_player.x,obj_player.y,obj_player.x,obj_player.y);
//speed = 10;
//friction = -0.5;
}

By messing around with this, I managed to push the asteroidaway from the player....now I need to figure out how to make it so that when it pushes, it gets pushed back smoothly and then goes to the opposite direction it originally went.

If I can do this, then all the powerups of the game is done!
 

Aviox

Member
If you want the asteroid to "ease" away, I'd suggest something like this, if you want to do it simply:

In the step event of an asteroid:
Code:
if (global.repel > 0)
{
     if instance_exists(obj_player)
     {
          if (distance_to_object(obj_player) < 50) //adjust "50" so it starts to "repel" at the right place.
         {
               gravity_direction = point_direction(obj_player.x,obj_player.y,x,y);
               gravity = 1; //"1" would be the repelling force in speed change per step. Adjust to taste.
         }
         else gravity = 0;
     }
}
//set a max speed value. "10" is the current max.
speed = min(speed,10);
Then get rid of the collision stuff having to do with global.repel.

Hope that helps.
 
A

Artwark

Guest
If you want the asteroid to "ease" away, I'd suggest something like this, if you want to do it simply:

In the step event of an asteroid:
Code:
if (global.repel > 0)
{
     if instance_exists(obj_player)
     {
          if (distance_to_object(obj_player) < 50) //adjust "50" so it starts to "repel" at the right place.
         {
               gravity_direction = point_direction(obj_player.x,obj_player.y,x,y);
               gravity = 1; //"1" would be the repelling force in speed change per step. Adjust to taste.
         }
         else gravity = 0;
     }
}
//set a max speed value. "10" is the current max.
speed = min(speed,10);
Then get rid of the collision stuff having to do with global.repel.

Hope that helps.
Ah...sorry for the late reply here.....

I did like how you said but as soon as I touch the powerup, the asteroid gets repelled very fast and goes offscreen rapidly. It sometimes appears and it sometimes disappears.....
 
M

Maximus

Guest
I'd try something like this in the player step

Code:
if (repel_active)
{
    with (obj_astroids)  // like a 'for each' loop
    {
        var dist = point_distance(other.x, other.y, x, y);
        if (dist < repel_range)
        {
            var dir = point_direction(other.x, other.y, x, y);
            motion_add(dir, repel_acc);
        }
    }
}
 
A

Artwark

Guest
I'd try something like this in the player step

Code:
if (repel_active)
{
    with (obj_astroids)  // like a 'for each' loop
    {
        var dist = point_distance(other.x, other.y, x, y);
        if (dist < repel_range)
        {
            var dir = point_direction(other.x, other.y, x, y);
            motion_add(dir, repel_acc);
        }
    }
}
So what is repel_active? a variable? and what is repel_acc?

I have a variable called global.repel.
 
Top