Object Collision, strange semantic bug

Started by suicidal pencil, Tue 26/01/2010 02:23:39

Previous topic - Next topic

suicidal pencil

For one of my games, I needed to hack together an object collision system..and I did. It works, but with the exception of one case.

Working along side the normal object array, I have a second one, which tracks what type of object it is (player, turret, bullet, etc.). It works fine with the turrets and the bullets...but not the player. The element positions in both arrays are one in the same, (array1[element] == array2[element]), to make it easy to track objects. The player object is element 0 in the object array and the settings array, and the value in the settings array is 6, for the player. A setting of 1 is a turret, 3 is a bullet fired from the player, etc.). Any case involving the player object fails, and every other works.

Here's the code:
Code: ags

function ObjectCollisions()
{
  int object1 = 0;
  int object2 = 0;
  while(object1 <= 39)
  {
    object2 = object1+1; //so I'm not checking collisions twice
    while(object2 <= 39)
    {
      if(object[object1].IsCollidingWithObject(object[object2])) //collision detected
      {
        if(ObjectSettings[object1] == 6) //player
        {
          if(ObjectSettings[object2] == 4) //enemy bullet
          {
            DoDamage(object1, 1);
            ReleaseObject(object2);
          }
        }
        else if(ObjectSettings[object1] == 3) //player bullet
        {
          if(ObjectSettings[object2] == 1) //turret
          {
            DoDamage(object2, 1);
            ReleaseObject(object1);
          }
        }
        else if(ObjectSettings[object1] == 1) //turret
        {
          if(ObjectSettings[object2] == 3) //player bullet
          {
            DoDamage(object1, 1);
            ReleaseObject(object2);
          }
        }
        else if(ObjectSettings[object1] == 4) //enemy bullet
        {
          if(ObjectSettings[object2] == 6) //player
          {
            DoDamage(object2, 1);
            ReleaseObject(object1);
          }
        }
      }
      object2++;
    }
  object1++;
  }
  return 0;
}


The code for collisions for the player, the turrets, and the bullets are identical, yet it fails on one very specific case.

Any thoughts?

Shane 'ProgZmax' Stevens

Have you tried it without this line:

Code: ags
 object2 = object1+1; //so I'm not checking collisions twice


Because it's effectively making the second while loop go from 1-39 instead of 0-39 as the first loop does.

suicidal pencil

#2
Quote from: ProgZmax on Tue 26/01/2010 02:52:24
Have you tried it without this line:

Code: ags
 object2 = object1+1; //so I'm not checking collisions twice


Because it's effectively making the second while loop go from 1-39 instead of 0-39 as the first loop does.

That's supposed to be there, and I have tried it without. When it's gone, the entire function stops working.

Basically, that's there so that I'm not checking if an object is colliding with itself, and to make sure I don't check collisions twice. I'm fairly certain that this is not the issue, seeing as object1 begins pointing at the player anyways when the function is first called

edit: Plus, it takes out a large amount of processing. If it was not there, the function would loop 1640 times, but with it, it only loops 840 :P (object1 increments 1 for every 40th increment of object2, and the second loop would run 1600 times without that one line, and only 800 times with. That's half the steps. (including the first loop, add 40))

Khris

First of all, object 1 should only increment up to 38. That's just a cosmetic error, since the inner while loop is skipped when object1 is 39 anyway though.
Secondly, the last check will never be true since object2 starts at 1 and the player is 0.

Regarding the problem: I've never used .IsCollidingWithObject myself, but maybe the check requires both objects to be solid and/or clickable?

Use Display lines to find out whether
  if(object[object1].IsCollidingWithObject(object[object2]))
or
  if(ObjectSettings[object1] == 6)
doesn't return true for object1 == 0.

suicidal pencil

Quote from: Khris on Tue 26/01/2010 13:15:15

Regarding the problem: I've never used .IsCollidingWithObject myself, but maybe the check requires both objects to be solid and/or clickable?

Use Display lines to find out whether
  if(object[object1].IsCollidingWithObject(object[object2]))
or
  if(ObjectSettings[object1] == 6)
doesn't return true for object1 == 0.

Both are solid/clickable, I've even tried messing with blocking heights and width.

I have used Display to figure out what the code is actually doing, and I've found that the collision script is working for the player (collision detected between object 0, and whatever the bullet was (in this case, 3))...but if(ObjectSettings[object1] == 6) //player is returning false. After more testing, it turns out that the player object as represented in the ObjectSettings array is not 6, but 0. In the function Game_Start(), I have this line: ObjectSettings[0] = 6;, but it did not work. Only putting that line in the repeatedly_execute_always() function did it start working again

Thanks for the help :)

Khris

That shouldn't be necessary.
Where are you defining the arrays?
Are the other lines in game_start() called?

It's not good to fix an error with another error ;)

suicidal pencil

Quote from: Khris on Tue 26/01/2010 14:04:36
Where are you defining the arrays?
Are the other lines in game_start() called?

Everything is in a separate module, with only one function being called from the global script, everything else is handled by the module. There is only one other line in the game_start(), it's PlayMusic(). It works fine.

And it was only a quick fix :P

Khris

Well, my guess is that you've declared the arrays in the header, thus creating a separate array for every script.
Is the game_start function containing the line the module's or the global script's?

I know it was a quick fix, but putting that in rep_ex_always is like... never mind. ;)

suicidal pencil

#8
Quote from: Khris on Wed 27/01/2010 18:16:27
Well, my guess is that you've declared the arrays in the header, thus creating a separate array for every script.
Is the game_start function containing the line the module's or the global script's?

The arrays are defined in the script as well with game_start(), not header. I may be wrong, but doesn't ags get annoyed by that? nvm, forgot about export :P

SMF spam blocked by CleanTalk