GML [SOLVED] Ball bouncing off of enemies but they now do not receive damage

A

Andrew R. C. Beck

Guest
Just as the title says, I'd managed to sort out the collisions of the ball from fine folks here with a place_meeting code in the ball's Step Event:

[
code]
//Collision Checks//
//----------//
//Horizontal//
//-----//
if place_meeting( x - 1, y, all)
||
place_meeting( x + 1, y, all)
{
audio_play_sound(bump, 2, false);
move_bounce_all(true);
}
//-----//
//Vertical//
//-----//
if place_meeting(x, y + 1, all)
||
place_meeting(x, y - 1, all)
{
audio_play_sound(bump, 2, false);
move_bounce_all(true);
}
//-----//
//V + H//
//-----//
if place_meeting(x, y + 1, all) && place_meeting(x + 1, y, all)
||
place_meeting(x, y + 1, all) && place_meeting(x - 1, y, all)
||
place_meeting(x, y - 1, all) && place_meeting(x + 1, y, all)
||
place_meeting(x, y - 1, all) && place_meeting(x - 1, y, all)
{
audio_play_sound(bump, 2, false);
move_bounce_all(true);
}
//-----//
[/code]

this has helped the ball to collide and bounce off of the enemies, but now it is stopping them from receiving damage. Here is code from a Collision Event with the ball in an enemy object:

Code:
//Hit//
//-----//
if (hit = 0)
   {
   if (block_dur >= 1)
      {
      block_dur -= 1;
      audio_play_sound(sky_shape_hit, 2, false);
      image_index = 1;
      image_speed = 30;
      hit = 15;
      }
      else
      {
      audio_play_sound(sky_shape_hit2, 2, false);
      instance_destroy();
      }
   }
//-----//
I would appreciate any observations or help with this and if possible, I would like to use a Step Event in the enemy objects instead to avoid event clutter :)
 
Last edited by a moderator:
T

Timothy

Guest
Just as the title says, I'd managed to sort out the collisions of the ball from fine folks here with a place_meeting code in the ball's Step Event:
[
code]
//Collision Checks//
//----------//
//Horizontal//
//-----//
if place_meeting( x - 1, y, all)
||
place_meeting( x + 1, y, all)
{
audio_play_sound(bump, 2, false);
move_bounce_all(true);
}
//-----//
//Vertical//
//-----//
if place_meeting(x, y + 1, all)
||
place_meeting(x, y - 1, all)
{
audio_play_sound(bump, 2, false);
move_bounce_all(true);
}
//-----//
//V + H//
//-----//
if place_meeting(x, y + 1, all) && place_meeting(x + 1, y, all)
||
place_meeting(x, y + 1, all) && place_meeting(x - 1, y, all)
||
place_meeting(x, y - 1, all) && place_meeting(x + 1, y, all)
||
place_meeting(x, y - 1, all) && place_meeting(x - 1, y, all)
{
audio_play_sound(bump, 2, false);
move_bounce_all(true);
}
//-----//
[/code]
this has helped the ball to collide and bounce off of the enemies, but now it is stopping them from receiving damage. Here is code from a Collision Event with the ball in an enemy object:

Code:
//Hit//
//-----//
if (hit = 0)
   {
   if (block_dur >= 1)
      {
      block_dur -= 1;
      audio_play_sound(sky_shape_hit, 2, false);
      image_index = 1;
      image_speed = 30;
      hit = 15;
      }
      else
      {
      audio_play_sound(sky_shape_hit2, 2, false);
      instance_destroy();
      }
   }
//-----//
I would appreciate any observations or help with this and if possible, I would like to use a Step Event in the enemy objects instead to avoid event clutter :)
Step event happens before the collision event happens. So there is likely never a collision event triggered since you resolve it in the step event. Move your step event code to the end step event. This might remedy your issue because the end step event happens after the collision event. Now you might run into issue where you get more damage than expected, but save that issue for another day if it comes up.
 
A

Andrew R. C. Beck

Guest
Step event happens before the collision event happens. So there is likely never a collision event triggered since you resolve it in the step event. Move your step event code to the end step event. This might remedy your issue because the end step event happens after the collision event. Now you might run into issue where you get more damage than expected, but save that issue for another day if it comes up.
I appreciate the quick response @Timothy ! I am no longer at that PC for the night but i will take this on when I come back to it in the morning :D Thanks pal!
 
A

Andrew R. C. Beck

Guest
Step event happens before the collision event happens. So there is likely never a collision event triggered since you resolve it in the step event. Move your step event code to the end step event. This might remedy your issue because the end step event happens after the collision event. Now you might run into issue where you get more damage than expected, but save that issue for another day if it comes up.
@Timothy You may be happy to know that this in fact was just the thing that helped pal! :D Only issue I have now is that the ball seems to want to mirror its previous path when bouncing instead of bouncing naturally as it were :S Always one thing after one is solved right? XD

Here's an example of the issue I am now having :) :
https://gyazo.com/26288ec55bf1fa08bf76c9e24fe2b4df
 
Last edited by a moderator:
A

Andrew R. C. Beck

Guest
Did it have this problem before you moved it to the End Step? That could be messing with it. I don't know how or when GMS calculates the bounce
Before setting the ball damage to the end step event I didn't have this issue :S
 
T

Timothy

Guest
Before setting the ball damage to the end step event I didn't have this issue :S
The issue seems to be that by moving your code to the end step, we messed with GMSs calculations. Do this instead - remove all your collision stuff that is in the end step and replace it with this:
Code:
var prev_direction = direction;
move_bounce_all(true);

if (prev_direction != direction)
{
    audio_play_sound(bump, 2, false)
}
EDIT: The idea here is to let GMS do its thing then simply check if the ball changed directions... ie, bounced. This should still be in the end step btw so that your collision events still fire.
 
A

Andrew R. C. Beck

Guest
The issue seems to be that by moving your code to the end step, we messed with GMSs calculations. Do this instead - remove all your collision stuff that is in the end step and replace it with this:
Code:
var prev_direction = direction;
move_bounce_all(true);

if (prev_direction != direction)
{
    audio_play_sound(bump, 2, false)
}
EDIT: The idea here is to let GMS do its thing then simply check if the ball changed directions... ie, bounced. This should still be in the end step btw so that your collision events still fire.
Thanks pal! Just to clarify though, do you mean the end step of the enemy entity? I ask because down this line of investigation that is the one I set to End Step :)
 
A

Andrew R. C. Beck

Guest
Just so we are on the same page, post your code that you have now... enemy and player
Shall do! :D
Ball Step Event (Overall)
Code:
//Direction//
//-----//
if (vspeed < 0 || vspeed > 0) && (hspeed == 0)
   {
   hspeed += 1;
   }
if (hspeed < 0 || hspeed > 0) && (vspeed == 0)
   {
   vspeed += 1;
   }
//----------//
//Bounce//
//----------//
//Top Boundary//
//-----//
if ((y - 15) <= 15)
   {
   audio_play_sound(bump, 2, false);
   vspeed = vspeed * -1;
   }
//-----//
//Bottom Boundary//
//-----//
if ((y + 15) >= 885)
   {
   audio_play_sound(bottom_hit, 2, false);
   lvl_1_scr.hp -= 1;
   instance_destroy();
   }
//-----//
//Left Boundary//
//-----// 
if (x - 15 <= 405)
   {
   audio_play_sound(bump, 2, false);
   hspeed = hspeed * -1;
   }
//-----//
//Right Boundary//
//-----// 
if (x + 15 >= 1585)
   {
   audio_play_sound(bump, 2, false);
   hspeed = hspeed * -1;
   }
//-----//
//Collision Checks//
//----------//
//V + H//
//-----//
if place_meeting(x + 1, y + 1, all)
   ||
   place_meeting(x - 1, y + 1, all)
   ||
   place_meeting(x + 1, y - 1, all)
   ||
   place_meeting(x - 1, y - 1, all)
      {
      audio_play_sound(bump, 2, false);
      move_bounce_all(true);
      }
//-----//
//Horizontal//
//-----//
if place_meeting( x - 1, y, all)
   ||
   place_meeting( x + 1, y, all)
      {
      audio_play_sound(bump, 2, false);
      move_bounce_all(true);
      }
//-----//
//Vertical//
//-----//
if place_meeting(x, y + 1, all)
   ||
   place_meeting(x, y - 1, all)
      {
      audio_play_sound(bump, 2, false);
      move_bounce_all(true);
      }
//-----//
Enemy End Step Event
Code:
//Hit//
//-----//
if place_meeting(x + 1, y, projectile_obj)
   ||
   place_meeting(x - 1, y, projectile_obj)
   ||
   place_meeting(x, y + 1, projectile_obj)
   ||
   place_meeting(x, y - 1, projectile_obj)
   ||
   place_meeting(x + 1, y + 1, projectile_obj)
   ||
   place_meeting(x - 1, y + 1, projectile_obj)
   ||
   place_meeting(x + 1, y - 1, projectile_obj)
   ||
   place_meeting(x - 1, y - 1, projectile_obj)
   {
   if (hit = 0)
      {
      if (block_dur >= 1)
            {
            block_dur -= 1;
            audio_play_sound(sky_shape_hit, 2, false);
            image_index = 1;
            image_speed = 30;
            hit = 15;
            }
            else
            {
            audio_play_sound(sky_shape_hit2, 2, false);
            instance_destroy();
            }
      }
   }
//-----//
 
T

Timothy

Guest
Shall do! :D
Ball Step Event (Overall)
Code:
//Direction//
//-----//
if (vspeed < 0 || vspeed > 0) && (hspeed == 0)
   {
   hspeed += 1;
   }
if (hspeed < 0 || hspeed > 0) && (vspeed == 0)
   {
   vspeed += 1;
   }
//----------//
//Bounce//
//----------//
//Top Boundary//
//-----//
if ((y - 15) <= 15)
   {
   audio_play_sound(bump, 2, false);
   vspeed = vspeed * -1;
   }
//-----//
//Bottom Boundary//
//-----//
if ((y + 15) >= 885)
   {
   audio_play_sound(bottom_hit, 2, false);
   lvl_1_scr.hp -= 1;
   instance_destroy();
   }
//-----//
//Left Boundary//
//-----//
if (x - 15 <= 405)
   {
   audio_play_sound(bump, 2, false);
   hspeed = hspeed * -1;
   }
//-----//
//Right Boundary//
//-----//
if (x + 15 >= 1585)
   {
   audio_play_sound(bump, 2, false);
   hspeed = hspeed * -1;
   }
//-----//
//Collision Checks//
//----------//
//V + H//
//-----//
if place_meeting(x + 1, y + 1, all)
   ||
   place_meeting(x - 1, y + 1, all)
   ||
   place_meeting(x + 1, y - 1, all)
   ||
   place_meeting(x - 1, y - 1, all)
      {
      audio_play_sound(bump, 2, false);
      move_bounce_all(true);
      }
//-----//
//Horizontal//
//-----//
if place_meeting( x - 1, y, all)
   ||
   place_meeting( x + 1, y, all)
      {
      audio_play_sound(bump, 2, false);
      move_bounce_all(true);
      }
//-----//
//Vertical//
//-----//
if place_meeting(x, y + 1, all)
   ||
   place_meeting(x, y - 1, all)
      {
      audio_play_sound(bump, 2, false);
      move_bounce_all(true);
      }
//-----//
Enemy End Step Event
Code:
//Hit//
//-----//
if place_meeting(x + 1, y, projectile_obj)
   ||
   place_meeting(x - 1, y, projectile_obj)
   ||
   place_meeting(x, y + 1, projectile_obj)
   ||
   place_meeting(x, y - 1, projectile_obj)
   ||
   place_meeting(x + 1, y + 1, projectile_obj)
   ||
   place_meeting(x - 1, y + 1, projectile_obj)
   ||
   place_meeting(x + 1, y - 1, projectile_obj)
   ||
   place_meeting(x - 1, y - 1, projectile_obj)
   {
   if (hit = 0)
      {
      if (block_dur >= 1)
            {
            block_dur -= 1;
            audio_play_sound(sky_shape_hit, 2, false);
            image_index = 1;
            image_speed = 30;
            hit = 15;
            }
            else
            {
            audio_play_sound(sky_shape_hit2, 2, false);
            instance_destroy();
            }
      }
   }
//-----//
Ok, I had to do some testing. The most reliable solution I came up with is this:
Ball Create Event:
Code:
// we use use the damager instance to mark a location that we know we collided with something at
// we create it in a position way put of the way to prevent unwanted collisions with it
damager = instance_create_layer(-10000, 0, "Instances", o_damager);
damager.visible = false;
Ball Step Event - Replace collision checks with:
Code:
// move the damager put of the way
damager.x = -10000;
// cache our predicated position to move the damager
var damage_x = x + hspeed + sign(hspeed);
var damage_y = y + vspeed + sign(vspeed);
var prev_direction = direction;
// let GMA do it's thing
// this can alter our direction, speed components, and position
move_bounce_all(true);

if (direction != prev_direction)
{
    // our direction was altered so we know we collided during the move_bounce_all call
   audio_play_sound(bump, 2, false);
   // move the damager where we would have been if we did not collide
   // we do this so that if there is an enemy there, it will detect the collision and take damage
   damager.x = damage_x;
   damager.y = damage_y;
}
Enemy End Step:
Code:
if (hit ==0)
{
   if (place_meeting(x, y, o_damager))
   {
       if (block_dur >= 1)
       {
           block_dur -= 1;
           audio_play_sound(sky_shape_hit, 2, false);
           image_index = 1;
           image_speed = 30;
           hit = 15;
         }
         else
         {
            audio_play_sound(sky_shape_hit2, 2, false);
            instance_destroy();
          }
       }
   }
}
IMPORTANT
Create a new object and call it o_damager. Give o_damager the same sprite and collision mask as your ball. Give this a try and let me know how it works.
 
Last edited by a moderator:
A

Andrew R. C. Beck

Guest
Ok, I had to do some testing. The most reliable solution I came up with is this:
Ball Create Event:
Code:
damager = instance_create_layer(-10000, 0, "Instances", o_damager);
damager.visible = false;
Ball Step Event - Replace collision checks with:
Code:
damager.x = -10000;
var damage_x = x + hspeed + sign(hspeed);
var damage_y = y + vspeed + sign(vspeed);
var prev_direction = direction;
move_bounce_all(true);

if (direction != prev_direction)
{
   audio_play_sound(bump, 2, false);
   damager.x = damage_x;
   damager.y = damage_y;
}
Enemy End Step:
Code:
if (hit ==0)
{
   if (place_meeting(x, y, o_damager))
   {
       if (block_dur >= 1)
       {
           block_dur -= 1;
           audio_play_sound(sky_shape_hit, 2, false);
           image_index = 1;
           image_speed = 30;
           hit = 15;
         }
         else
         {
            audio_play_sound(sky_shape_hit2, 2, false);
            instance_destroy();
          }
       }
   }
}
IMPORTANT
Create a new object and call it o_damager. Give o_damager the same sprite and collision mask as your ball. Give this a try and let me know how it works.
Thanks for the help :D I tried putting all that in where you instructed as well as making the o_damager object with the same sprite and collision mask as the ball, but it does not seem to like instance_create_layer :S

https://gyazo.com/49d8830f04958947c70f48b0de06024a
 
A

Andrew R. C. Beck

Guest
Yep, we want it put of the way.
Aaaah I see! :D Well, I have put in the code that you posted and I must say it seems to be working well! :D Would it be too much trouble if I asked you to explain what the code is doing to learn going forward? :)
 
Top