Billiards Style Collision Physics


Tweet blitz3d physics code-archives algorithms
(Posted 11 months ago) RonTek

This type of collision response isn't just useful for pool and billiard style games, and in fact, I didn't write it for that reason at all. I wrote it because I needed to have collision for the space ships in my game 'Unity'. When their shields are up, they use this relatively simple method. It can be used for almost anything - player character bouncing off enemies in a platform game, to space ship collision, to a game which does actually involve balls. I think that realistic physics, even if pretty simple, can make a game feel a lot more immersive and interesting. The idea is that you should read my code, see how I use the collision response section, hack it up, and use it in your own game :-)

Author: Phish

Image

;------------------------------------------
;2D COLLISION DEMO CODE
;------------------------------------------
; By Joseph 'Phish' Humfrey
; This type of collision response isn't
; just useful for pool and billiard style
; games, and in fact, I didn't write it for
; that reason at all. I wrote it because I
; needed to have collision for the space
; ships in my game 'Unity'. When their
; shields are up, they use this relatively
; simple method. It can be used for almost
; anything - player character bouncing off
; enemies in a platform game, to space
; ship collision, to a game which does
; actually involve balls. The basic
; algorithm which I used would work for
; both 2d and 3d, so if you would like to
; see it, email me at [email protected]
;------------------------------------------
; The actual code which works out what
; happens after a collision is in the
; UpdateCirclePhysics() function.
;------------------------------------------
; Enjoy!
;------------------------------------------
;------------------------------------------

Graphics 800, 600, 16, 2
SetBuffer BackBuffer()
SeedRnd MilliSecs()



;------------------------------------------
; MAIN DATA TYPE
;------------------------------------------
; This exact type isn't supposed to be used
; Instead, you should use some of the fields
; in your own type, or just use this one
; for reference, to see what each field does
Type circle
    Field x#, y#        ;position
    Field dx#, dy#      ;x and y speeds

    Field radius#       ;radius of circle
    Field mass#         ;mass of circle
End Type
;------------------------------------------
;------------------------------------------






;------------------------------------------
; SET UP BALLS INTO A POOL STYLE ARRANGEMENT
; FOR DEMO
;------------------------------------------
.Setup
ballTriangleSize=5
For xloop = ballTriangleSize To 1 Step -1
    For yloop = 1 To xloop
        c.circle = New circle
        c\x = (5-xloop)*27 + 200
        c\y = yloop*31-(xloop*31)/2.0 + 300
        c\dx=0
        c\dy=0
        c\radius = 15
        c\mass = 50
    Next
Next

;Cue ball (smaller so you know which it is :)
cue.circle = New circle
cue\x = 800
cue\y = 300 +20
cue\dx = -20
cue\dy = Rnd(4)-2
cue\radius = 14
cue\mass = 50
;------------------------------------------
;------------------------------------------







;------------------------------------------
;MAIN LOOP
;------------------------------------------
; This is the main While..Wend game loop
While Not KeyDown(1)

    Cls

    UpdateCirclePhysics()
    RenderCircles()

    ;------------
    ; Reset button
    Text 10, 10, "Press a mouse button to reset."
    Text 10, 25, "Press Esc to exit."
    If GetMouse() Then
        For c.circle = Each circle
            Delete c
        Next
        Goto setup
    End If
    ;------------

    Flip

Wend
;------------------------------------------
;------------------------------------------
End









;------------------------------------------
Function UpdateCirclePhysics()
;------------------------------------------
; This is the main physics function for the
; circles. It contains the very basic
; movement physics as well as the collision
; response code.
;------------------------------------------

    For c.circle = Each circle

        ;update positions
        c\x=c\x+c\dx
        c\y=c\y+c\dy

        ;gradually slow down
        c\dx=c\dx*0.99
        c\dy=c\dy*0.99

        ;------------------------------------------
        ;COLLISION CHECKING
        ;------------------------------------------
        ; Check each circle in the loop against
        ; every other (c against c2)
        For c2.circle = Each circle

            collisionDistance# = c\radius+c2\radius
            actualDistance# = Sqr((c2\x-c\x)^2+(c2\y-c\y)^2)

            ;Collided or not?
            If actualDistance<collisionDistance Then

                collNormalAngle#=ATan2(c2\y-c\y, c2\x-c\x)

                ;Position exactly touching, no intersection
                moveDist1#=(collisionDistance-actualDistance)*(c2\mass/Float((c\mass+c2\mass)))
                moveDist2#=(collisionDistance-actualDistance)*(c\mass/Float((c\mass+c2\mass)))
                c\x=c\x + moveDist1*Cos(collNormalAngle+180)
                c\y=c\y + moveDist1*Sin(collNormalAngle+180)
                c2\x=c2\x + moveDist2*Cos(collNormalAngle)
                c2\y=c2\y + moveDist2*Sin(collNormalAngle)


                ;------------------------------------------
                ;COLLISION RESPONSE
                ;------------------------------------------
                ;n = vector connecting the centers of the circles.
                ;we are finding the components of the normalised vector n
                nX#=Cos(collNormalAngle)
                nY#=Sin(collNormalAngle)

                ;now find the length of the components of each movement vectors
                ;along n, by using dot product.
                a1# = c\dx*nX  +  c\dy*nY
                a2# = c2\dx*nX +  c2\dy*nY

                ;optimisedP = 2(a1 - a2)
                ;             ----------
                ;              m1 + m2
                optimisedP# = (2.0 * (a1-a2)) / (c\mass + c2\mass)

                ;now find out the resultant vectors
                ;r1 = c1\v - optimisedP * mass2 * n
                c\dx = c\dx - (optimisedP*c2\mass*nX)
                c\dy = c\dy - (optimisedP*c2\mass*nY)

                ;r2 = c2\v - optimisedP * mass1 * n
                c2\dx = c2\dx + (optimisedP*c\mass*nX)
                c2\dy = c2\dy + (optimisedP*c\mass*nY)

            End If

        Next
        ;------------------------------------------
        ;------------------------------------------


        ;Simple Bouncing off walls.
        If c\x<c\radius Then
            c\x=c\radius
            c\dx=c\dx*-0.9
        End If
        If c\x>GraphicsWidth()-c\radius Then
            c\x=GraphicsWidth()-c\radius
            c\dx=c\dx*-0.9
        End If
        If c\y<c\radius Then
            c\y=c\radius
            c\dy=c\dy*-0.9
        End If
        If c\y>GraphicsHeight()-c\radius Then
            c\y=GraphicsHeight()-c\radius
            c\dy=c\dy*-0.9
        End If

    Next

End Function





;------------------------------------------
Function RenderCircles()
;------------------------------------------
; Simple function draws all the circles
; on the screen.
;------------------------------------------

    For c.circle = Each circle
        If c\radius=15 Then Color 200, 50, 50 Else Color 255, 255, 255
        Oval c\x-c\radius, c\y-c\radius, c\radius*2, c\radius*2
    Next

End Function
;------------------------------------------
;------------------------------------------
(Posted 11 months ago) rimmer commented:

The code is not complete and does not work because the html is stripping most of it out with the use of < > characters.
Any chance you can post an attachment of the code. Thanks for the code snippet.

(Posted 11 months ago) RonTek commented:

Hey rimmer, Welcome to the Forums!

Thanks for reporting this issue. I have made some updates on this code formatting so try copying again as this has been just tested and should now be fixed.

I will be adding soon a download source feature as another direct option. cheers.

(Posted 11 months ago) rimmer commented:

Hey RonTek, I was just browsing the forums after stumbling across Blitz again :)
I did notice the server is struggling a bit also, experiencing a few lost connections with the hosting provider.
Thanks for weening the source code, works great now!

(Posted 11 months ago) RonTek commented:

Awesome! yes, we're getting some server issues recently but this will be fixed soon.

Great to have you on board and cheers.

(Posted 1 month ago) hardcoal commented:

you know i use many of your blitz3d code and converting it to xors and its works fine
so this blitz3d codes are very useful though i dont use blitz3d

(Posted 1 month ago) RonTek commented:

First off, as you can see it's not my code there as most snippet here has been reposted from the old archives and other sources.

so this blitz3d codes are very useful though i dont use blitz3d

that's great

Reply To Topic (minimum 10 characters)

Please log in to reply