Click here to Skip to main content
15,885,141 members
Please Sign up or sign in to vote.
4.00/5 (3 votes)
See more:
Hi everyone,
I started writing programs on VB .NET in the year of 2006, reading Jim Buyens book "Faster Smarter Beginning Programming" and that's only skill I got in programming, so I could say that I'm new in writing programs. My dream was to make my own game, I searched the net to find a simple collision detect system, but all I found was "detecting collisions between 2 or three, or maximum 10 objects" which is pretty simple because there is very small count of objects and we know exactly how much they are. There was nothing like "collision detect between various number of objects", so I've made myself one using the following logic:
   I've created a string array which size is equal to the count of the pixels that the playground is made of - if my playground is 9000 x 9000 then the array is something like this: strWorldArr(81000000) - each element in the array represents a single pixel of the playground and all objects that move on the playground fill their name in the elements of the array using their coordinates to locate the elements of the array which represents the pixels beneath them. Here is the code of the main part of my collision detect system:

<pre>REM: checking the pixels before moving the object if the values of the array elements which they present are clean then its good to go:
      Function CleanChecker(ByVal panHero As HeroBody, ByVal szeSize As Size, _
                              ByVal intStartPos As Integer, ByVal intEndPos As Integer, _
                              ByVal intCycle As Integer)
            Dim intCount As Integer = 0
            For i = 0 To intCycle
                  For e = intStartPos To intEndPos
                        If strWorldArr(e) <> panHero.Name And strWorldArr(e) <> "†" Then
                              intCount += 1
                        End If
                  Next
                  intStartPos += szeSize.Width
                  intEndPos += szeSize.Width
            Next
            Return intCount
      End Function

      REM: this subroutine cleans behind the object, or fills it's new positions:
      Sub CleanOrFill(ByVal panHero As HeroBody, ByVal strChar As String, _
                              ByVal szeSize As Size, ByVal intStartPos As Integer, _
                              ByVal intEndPos As Integer, ByVal intCycle As Integer)
            For i = 0 To intCycle
                  For e = intStartPos To intEndPos
                        strWorldArr(e) = strChar
                  Next
                  intStartPos += szeSize.Width
                  intEndPos += szeSize.Width
            Next
      End Sub

      REM: this subroutine is one of 4 which call the CleanChecker and CleanOrFill to detect a collision:
      Private Sub mUP(ByVal panHero As HeroBody, ByVal szeSize As Size, _
                              ByVal intObjSpeed As Integer, ByVal intTolerance As Integer)

            Dim intChkStart As Integer = panHero.Left + intStartNum(panHero.Top - intObjSpeed)
            Dim intChkEnd As Integer = intChkStart + panHero.Width
            Dim intCleanStart As Integer = panHero.Left + intStartNum(panHero.Bottom - intObjSpeed)
            Dim intCleanEnd As Integer = intCleanStart + panHero.Width

            If CleanChecker(panHero, szeSize, intChkStart, intChkEnd, intObjSpeed) >= intTolerance Then
               REM: the path is blocked
            Else
               REM: the path is passable
                  panHero.Top -= intObjSpeed
                  CleanOrFill(panHero, panHero.Name, szeSize, intChkStart, intChkEnd, intObjSpeed)
                  CleanOrFill(panHero, "†", szeSize, intCleanStart, intCleanEnd, intObjSpeed)
            End If
      End Sub</pre>

To pass this code through all of the objects I use For Each... Next statement.
On core2 duo CPU 2GHz 4mb l2 cache and 2GB RAM this system can support smoothly up to 100
objects, on intel Pentium4 1800 MHz 512 kb l2 cache and 1GB RAM this system works so badly that it
can't move even one object normally.
I think that this code is pretty simple, why it takes so much power to run? Is this slow calculation have
anything to do with the programming language - Visual Basic 2008 - .NET Framework 3.5? Is there anyway to
improve the collision detect performance of this system or this project is doomed?
Sorry for my bad english, and thank you in advance.

<div class="ForumMod">modified on Wednesday, March 18, 2009 10:39 AM</div>
Posted

1 solution

Member 3734843 wrote:
I think that this code is pretty simple, why it takes so much power to run?


Well, since String's under the .NET CLR are immutable (cannot change them), every time you make a change to a string you're creating a new 81 MEGABYTE string! [WTF] Each old string is dropped, by not before the new one is created. Multiply that by the number of times you're making a change to the string and you've quite possibly created the worst collision detection algorithm ever.


Member 3734843 wrote:
Is this slow calculation have
anything to do with the programming language - Visual Basic 2008 - .NET Framework 3.5?


Nope. I can assure you, the performance problem is entirely in the design of your algorithm.


Member 3734843 wrote:
Is there anyway to
improve the collision detect performance of this system or this project is doomed?


Until you completely rewrite the detection algo to use the processor more efficiently, you're project is doomed.

Using an array of integers should improve performance dramatically. Completely scraping the array and comparing the bounds of object to object would be far better since you don't have to compare against 81000000 pixels every time you more something by 1 pixel.

It comes down to representing your objects more effificently and in a manner that lends itself to better collision detection. Really, pickup a book or two on game programming. I really can't explain how to do something better in a forum post.

 
Share this answer
 


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900