Contact

 
Google
Web www.alanphipps.com

 
   
 
   
www.alanphipps.com

.: Positioning a Ball After a Collision

 
 

 

Using the source code from the previous tutorial, we will now create a function that will move a ball into the correct position in the play area after it has stopped moving. If you remember in the last tutorial some balls had overlapped once they had stopped and weren't sitting the way we want them to. The PositionBallCorrectly function that we will be implementing in this tutorial is not too complex and isn't 100% perfect, but to be honest, we really want to get this game finished and make a start with the 3D stuff. So, lets move on, copy the source code folder from the last tutorial and name it BallPositioning, open the project and as always we will start adding code to the Graphics Module.

Add the following Declarations:

 

'Used to tell when a ball has stopped moving and needs positioned correctly
Public ABAllNeedsPositionedCorrectly As Boolean = False

'Set in CheckForCollision() and used in PositionBallCorrectly()
Public BoundingSphereOtherBallPub As BoundingSphere

Still in the Graphics Module, we have the Function itself:

'Move Ball into Correct Position
Public Sub PositionBallCorrectly()

'A Couple of Bounding Spheres to hold the 2 balls that have collided
Dim TempBoundingSphereMovingBall As BoundingSphere = New BoundingSphere(New Vector3(BallArray(IndexOfMovingBall).BallRect.X, BallArray(IndexOfMovingBall).BallRect.Y, 0), 19)
Dim TempBoundingSphereOtherBall As BoundingSphere = BoundingSphereOtherBallPub

'If these 2 balls have overlapped
If TempBoundingSphereMovingBall.Intersects(TempBoundingSphereOtherBall) Then

'If they overlap on each other's side
If TempBoundingSphereMovingBall.Center.Y < TempBoundingSphereOtherBall.Center.Y + 19 Then
'If the collision happened on the left of the other ball
If TempBoundingSphereMovingBall.Center.X < TempBoundingSphereOtherBall.Center.X Then
BallArray(IndexOfMovingBall).BallRect.X -= 1
Exit Sub
'If the collision happened on the right of the other ball
ElseIf TempBoundingSphereMovingBall.Center.X > TempBoundingSphereOtherBall.Center.X Then
BallArray(IndexOfMovingBall).BallRect.X += 1
Exit Sub
End If
End If

'If they overlap on the bottom then move down by one pixel
BallArray(IndexOfMovingBall).BallRect.Y += 1
'Ball Does not stop moving
TempBoundingSphereMovingBall = Nothing
TempBoundingSphereOtherBall = Nothing
Exit Sub

End If

'Dispose the variables
TempBoundingSphereMovingBall = Nothing
TempBoundingSphereOtherBall = Nothing
ABAllNeedsPositionedCorrectly = False

End Sub

This Sub basically locates the 2 balls that have collided and while they are overlapped moves the moving ball by 1 pixel in the direction away from the other ball. The X and Y position of the centre of the moving ball is compared to that of the other ball to decide on what side the collision took place. Also in the Graphics Module we have a change in the CheckForCollision() Function as shown below:

'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
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

'Set Public variable to be used in PositionBallCorrectly()
BoundingSphereOtherBallPub = TempBoundingSphereOtherBall

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
ABAllNeedsPositionedCorrectly = True 'Ball will now be positioned correctly
BallArray(IndexOfMovingBall).IsPositionedCorrectly = False 'Ball will now be positioned correctly
Exit Sub

End If
NextBall:
Next

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

End Sub

The new code is in RED as usual, it simply stores the other ball in the collision as a BoundingSphere that can then be used in the PositionBallCorrectly function.

In the Render function, the Draw Ball Component 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

'If a Ball needs to be positioned correctly
If ABAllNeedsPositionedCorrectly = True Then
If UBound(BallArray) > 1 Then

'Correctly Position Ball
PositionBallCorrectly()
End If
End If

BallSB.End()
End If

The new code is again in RED, it says that if the Boolean ABallNeedsPositionedCorrectly is set to True, which it is when a ball stops moving, then run the PositionBallCorrectly() Sub. Lastly, another declaration is added to the Ball Class:

Public IsPositionedCorrectly As Boolean = True ' Used to move a ball into a rectangle so that it is positioned correctly

i don't actually use this line of code but it might come in useful later. Now run the game and it should look like this:

XNA in VB.NET - All Balls Positioned Correctly

As you can see the game is taking shape, in the next tutorial we will deal with how the balls are removed when 3 or more balls of the same colour touch. So once i have completed it i will upload it to the tutorials page. Enjoy.

 

BallPositioning Source Code - 189Kb
Next Tutorial - Code Cleanup Round 2

 

     
 
 
     

 

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