Contact

 
Google
Web www.alanphipps.com

 
   
 
   
www.alanphipps.com

.: Defining Ball Collision

 
 

 

 

Using the source code from the last tutorial we will now implement a ball collision detection function. So, copy the code folder form the last tutorial and name this folder ballcollision. open the project and as usual we will start adding code in the GraphicsModule. Add the following declarations:

 

'Variables used in Ball Collision Detection
Public IndexOfMovingBall As UShort = 0
Public IndexOfMovingBallFound As Boolean = False

These variables will help us locate which ball is moving when we cycle through the ball array. Next, add the collision detection function:

'Check for Ball Collision
Public Sub CheckForCollision()
If IndexOfMovingBallFound = False Then ' If the moving ball is unknown
For m As UShort = 0 To UBound(BallArray) ' Search array for the ball that is moving
If BallArray(m).IsMoving = True Then ' When the moving ball is found
IndexOfMovingBall = m ' store the ball index in a variable and exit the for loop
IndexOfMovingBallFound = True
Exit For
End If
Next
End If

'Each ball will be enclosed in a bounding sphere. The BoundingSphere.Intersects method allows us to tell when
' two balls collide. The following objects are part of this process. The objects are declared here so that they are
' not declared in every loop, which would cause more work for the program

Dim VectorMovingBall As Vector3 = New Vector3(BallArray(IndexOfMovingBall).BallRect.X, BallArray(IndexOfMovingBall).BallRect.Y, 0)
Dim VectorOtherBall As Vector3
'One BoundingSphere for the Moving Ball
Dim TempBoundingSphereMovingBall As BoundingSphere = New BoundingSphere(VectorMovingBall, 20)
Dim TempBoundingSphereOtherBall As BoundingSphere ' One BoundingSphere for the Other ball in the collision.

For Each Singleball As Ball In BallArray ' check each ball for a collision
If Singleball.IsMoving = True Then ' If the current ball is the ball that has just been launched then
GoTo NextBall ' goto to the next ball
End If
If Singleball.BallRect.Bottom >= BallLauncherRect7.Y Then ' If the current ball is lower than the ball launcher, ie, not launched into the game yet
GoTo NextBall ' goto the next ball
End If

VectorOtherBall = New Vector3(Singleball.BallRect.X, Singleball.BallRect.Y, 0) ' Set the boundingsphere to the boundaries of the current ball
TempBoundingSphereOtherBall = New BoundingSphere(VectorOtherBall, 20)

If TempBoundingSphereMovingBall.Intersects(TempBoundingSphereOtherBall) Then 'Check for a collision between moving ball and current ball and if a collision is detected

BallArray(IndexOfMovingBall).BallXVel = 0 ' Stop the Ball in the X direction
BallArray(IndexOfMovingBall).BallYVel = 0 ' Stop the ball in the Y direction
BallArray(IndexOfMovingBall).IsMoving = False ' Set the ball's IsMoving variable to False
IndexOfMovingBallFound = False ' Tell the program to find the next moving ball
ABallHasBeenLaunched = False ' Set the Ball Moving Global variable to false
TempBoundingSphereMovingBall = Nothing ' Empty the variables
TempBoundingSphereOtherBall = Nothing
VectorOtherBall = Nothing
VectorMovingBall = Nothing
Exit Sub

End If
NextBall:
Next

' The loop is finished and the variables are disposed
TempBoundingSphereMovingBall = Nothing
TempBoundingSphereOtherBall = Nothing
VectorOtherBall = Nothing
VectorMovingBall = Nothing

End Sub

This sub might look complicated but it actually does a few simple tasks, first, it searches the ball array to find which ball is moving, remember that only one ball moves at any one time in this game. Once found that ball's array index is stored in the variable IndexOfMovingBall, which will be then used as one of the balls in the collision. Next 2 BoundingSphere's are declared, one for the moving ball and one for the other ball in the collision, the boundingsphere object has an intersects method that will detect if the spheres overlap at any point. Next we cycle through the ballarray, assigning the X and Y coordinates of each ball to the Centre and Radiius values of the bounding sphere by means of a Vector3. A vector3 is a 3D point in space and as our game is 2D, the Z point should be set to 0. The BoundingSphere.Intersects method is called and if a collision is detected, the ball is stopped and the other variables are set to their appropriate values, the sub is then exited. Note that the vector3s and the boundingspheres are declared outside the for each loop so that they are not declared every time the loop runs, this means that the program has to do a little less work on each loop. In a game as small as this it wont make that much of a difference but it is a good idea to get into the way of this way of thinking as early as possible, in bigger games saving CPU and GPU time is a big issue, the more they have to do, the longer each render loop will take and hence the games frame rate will decrease. Keeping the frame rate above 25 is a MUST for any game.

Next, in the ball class i have made an addition to the MoveBall Sub. The entire sub now looks like this:

Public Sub MoveBall()

'move ball in direction of arrow
Dim Vector1 As Vector2 = New Vector2

'Hols the direction of the arrow and hence the trajectory of the ball
Vector1 = New Vector2(BallVectorXPub, BallVectorYPub)

'Selects whether the arrow is pointing left, right or straight up
Select Case MathHelper.ToDegrees(ArrowSBRotate)
Case Is < -0.1 ' Arrow points Left
' if ball is lower than the top of the Playarea
If BallRect.Y >= PlayAreaRect.Y Then
BallRect.Y -= (Vector1.X * (BallXVel + 0.005)) 'ball moves left along vector1 at speed BallXVel + 0.005
BallRect.X -= (Vector1.Y * BallYVel) ' ball moves up along vector1 at speed BallYVel
End If
Case -0.09 To 0.09 ' Arrow points Up
BallRect.Y -= (Vector1.Y * (BallXVel + 0.2)) ' ball moves straight up at speed BallYVel
Case Is > 0.1 ' Arrow points right
BallRect.Y -= (Vector1.Y * BallXVel) ' ball moves up along vector1 at speed BallXVel
BallRect.X -= -(Vector1.X * BallYVel) ' ball moves right along vector1 at speed BallYVel
End Select

' The following code keeps the ball inside the Playarea
If BallRect.Y < (PlayAreaRect.Y + 2) Then ' if ball moves above top of playarea then
BallXVel = 0 ' Stop ball in X direction
BallYVel = 0 ' Stop ball in Y direction
BallRect.Y = (PlayAreaRect.Y + 1) 'bring ball back into playarea if it had moved out of Playarea
IsMoving = False ' set Ismoving to false
IndexOfMovingBallFound = False ' Sets condition so that ball collision can be detected
ABallHasBeenLaunched = False 'Prevents another ball being launched if one is already moving.
End If
If BallRect.X < PlayAreaRect.X Then ' if ball moves passed left of playarea then
BallYVel = -(BallYVel) ' Change x direction of ball from left to right
End If
If BallRect.X > (PlayAreaRect.X + PlayAreaRect.Width) - 38 Then ' if ball moves passed right of playarea then
BallYVel = -(BallYVel) ' Change x direction of ball from right to left
End If

End Sub

The new line of code is displayed in RED, without this line the first ball to be launched would not be affected by the CheckForCollision() sub and hence any subsequent balls would pass straight through it.

Lastly, the Draw ball section of the Render function becomes:

'Draw Ball
If UBound(BallArray) > 0 Then
BallSB.Begin(SpriteBlendMode.AlphaBlend)
For Each SingleBall As Ball In BallArray ' Check every ball in array
BallSB.Draw(SingleBall.BallTex, SingleBall.BallRect, Color.White) 'Draw Each Ball
If SingleBall.IsMoving = True Then 'If a ball is set to move
SingleBall.MoveBall() 'Move the ball
End If
SingleBall.MoveBallLauncherBalls() ' Move the balls in the ball launcher
Next
If ABallHasBeenLaunched = True Then ' A global variable used to tell the program when to start checking for
If UBound(BallArray) > 1 Then ' collisions
CheckForCollision() ' Check for a collision
End If
End If

BallSB.End()
End If

The new code is again displayed in RED. The code says, If a ball has been launched into the game and if the number of balls is bigger than 1 then run the CheckForCollision() sub. Please note that after upgrading to XNA GSE beta 2 the Device.BeginScene and Device.EndScene are no longer used as described in the previous tutorial.

Now, if you run the game you should have something that looks like this:

XNA in VB.NET - Ball Collision Implemented

Excellent, now we are beginning to see the game as we want it to be, however, when the collision is detected and the ball stops there is a little overlapping and i would prefer the it if the balls moved into either 90 or 45 degree angles to the other balls. In the next tutorial we will develop a sub that moves the balls into the required position so that the game looks a bit more symmetrical.

So, once I have completed the next tutorial i will upload it to the tutorials page.

 

BallCollision Source Code - 187Kb
Next Tutorial - Ball Positioning

 

 

     
 
 
     

 

Web site contents © Copyright Alan Phipps 2006, All rights reserved.
Website templates
   
 
 

 

__PayPal

PayPal - Any Amount is Welcome
 
Please Donate to the Nvidia Geforce Go 7950 GTX Fund, All donations welcome. Thanks.

 

XNA in C#

 
 

 

Games at Amazon