Collision Detection - Asteroids

sterlingy

Active Member
Licensed User
Longtime User
I am using the CollisionDetector module from the Asteroids example,

but I have different types of objects, and I initialize the detector like this:

B4X:
collision.Initialize(leroyBd.DestRect, game.Dogs, 10, 10 * GameUtils.scale)
collision.Initialize(leroyBd.DestRect, game.Cars, 10, 10 * GameUtils.scale)

The problem with this is that when I check for a collision later, it doesn't know if it is comparing MyRect against the Dogs or the Cars. Short of setting up a different CollisionDetector Module for each type of object, is there a way for the Detector to return the specific object (or at least which LIST the object comes from) that MyRect has collided with?

This is important, because the result of the collision is determined by the type of object that MyRect has collided with.

-Sterling
 

sterlingy

Active Member
Licensed User
Longtime User
You can add a public field to this class and save whichever information you need to that specific instance.

I was thinking around the same lines, that might actually allow me to put every object into the same List, which would significantly reduce duplication of code, not that it would really speed things up, but it easier to make a change in one place instead of ten.

-Sterling
 
Upvote 0

sterlingy

Active Member
Licensed User
Longtime User
Well, I'm still stumped.

I added the Public Variable, as you suggested:

B4X:
'Class module
Sub Class_Globals
   Private MyRect As Rect
   Private Others As List
   Private checkInterval, interval As Int
   Private outRect(1) As Rect
   Private safeZone As Int
---->>   Public objectType As String    <<----
End Sub

Public Sub Initialize (vMyRect As Rect, vOthers As List, vCheckInterval As Int, vSafeZone As Int, vType As String)
   MyRect = vMyRect
   'Others is a list of objects. Each object should have a GetRect sub such as: 
   'Public Sub GetRect(outRect() As Rect)
   '   outRect(0) = bd.DestRect
   'End Sub
   'Note that this class holds a reference to the list. This means that if later an object is added or removed
   'then it will automatically affect this class as well.
   Others = vOthers
   'Check for collision every x ticks. If the objects do not move too fast there is no point
   'in checking for collision every tick.
   checkInterval = vCheckInterval
   'As each sprite is treated as a rectangle you may want to decrease the rectangle size to avoid cases
   'where the collision is in two corners for example.
   safeZone = vSafeZone
   'Define Object Type (car, dog, poop, etc.)
   objectType = vType
End Sub

'Checks for collisions. Returns the collided object if there was a collision
Public Sub Tick As Object
   interval = interval + 1
   If interval = checkInterval Then
      interval = 0
      Dim r As Rect
      For i = 0 To Others.Size - 1
         CallSub2(Others.Get(i), "GetRect", outRect)
         If MyRect.Left < outRect(0).Right - safeZone AND MyRect.Right > outRect(0).Left + safeZone _
            AND MyRect.Top < outRect(0).Bottom - safeZone AND MyRect.Bottom > outRect(0).Top + safeZone Then
            Return Others.Get(i)
         End If
      Next
      Return Null
   End If
End Sub

I have two LISTs Dogs and Cars THeir Collisions are set up like this:

B4X:
   Dim objType As String
   objType = "dog"
   collision.Initialize(leroyBd.DestRect, game.Dogs, 10, 10 * GameUtils.scale, objType)
   objType = "car"
   collision.Initialize(leroyBd.DestRect, game.Cars, 10, 10 * GameUtils.scale, objType)

The problem occurs when I try to resolve what to do when a collision is detected. I don't have an opportunity to check the Object Type.

B4X:
      Dim catchDog As Dog
      catchDog = collision.Tick
      If catchDog <> Null Then
         game.PlaySound(game.barkSFX, 1)
         game.score = game.score + 100
         game.myScoreBoard.AddScore(game.score)
         game.dogRemain = game.dogRemain - 1
         game.myScoreBoard.dogUpdate(game.dogRemain)
         catchDog.Explode
      End If
      
      Dim killLeroy As Car
      killLeroy = collision.Tick
      If killLeroy <> Null Then
         Crash
      End If

checking collision.objectType always returns "car" since that was the last LIST that was initialized with the collision Module.
 
Upvote 0

sterlingy

Active Member
Licensed User
Longtime User
There's something about this forum that helps me solve problems on my own. I pull my hair out for hours, then I post something, then the solution pops into my head. Either that, or Erel and others see the light of day before I do.

I guess what I'm saying is that I fixed this issue.

-Sterling
 
Upvote 0
Top