The Write an Online Basketball Shooting Game Using Silverlight 4 and Farseer Engine Series
Part 1 In this series of articles we will develop an online basketball game using the famous two-dimensional physics engine - Farseer (mainly PhysicsHelper 3.0) under Visual Studio 2010 and Silverlight 4.0 environments.
Part 2 In the first article of this series, you’ve learned the fundamentals in using Farseer Engine and its enhanced buddy - PhysicsHelper. Starting from this installment, we are going to develop the online basketball shoot game itself.
Part 3 In the previous article, you've learned all the elementary work in writing the ball shooting game. And also, we've made clear the loop principle under the PhysicsHelper environment. In this article we will study the rest and more interesting parts.
Introduction
In the previous article, you've learned all the elementary work in writing the ball shooting game. And also, we've made clear the loop principle under the PhysicsHelper environment. In this article we will study the rest and more interesting parts.
It's worth noting that we've leveraged two different kinds of collision detections in the game. One lies inside the game loop; the other is achieved in the event handler _physicsController_Collision. Let's delve into the first and 'special' collision problem. In fact, this kind of special collision is also often required in practical game development.
Collision Detection 1
First, let's take a look at the special collision detection achieved in the _physicsController_TimerLoop event handler.
Listing 1: Collision detection in the TimerLoop event handler
To gain an intuitive understanding with the collision introduced here, you can refer to the sketch shown in Figure 1.
Figure 1: The collision detection principle in the TimerLoop event handler

As seen from Figure 1, two rectangles are placed above and below the basket respectively. By intersecting the smallest rectangle (named ballrect in the code) that just encloses the ball with the one named pathScoreTop, we can judge whether the ball hits the edge or the inner part of the basket. If so, we set the value of the variable bHitTop to true. And further, we continue to intersecting the smallest rectangle around the ball with the other one named pathScoreBottom. If the intersecting rectangle is not empty and bHitTop is true, then we have enough reason to say that the ball has hit the basket. So, we update the score board, play the net related animation, and play the congratulation music. After that, we should set the value of the variable bHitTop back to false, making preparation for the next time collision detection.
Next, let's study another kind of collision detection in the game, which is also another issue frequently met in the Farseer engine supported game development.
Collision Detection 2
This kind of collision detection happens in the event handler _physicsController_Collision. You can easily image that this kind of collision detection deals with the collisions between the physics sprites in the game scene. The following gives the related code.
Listing 2: The physics sprites collision detection
Is it difficult to understand? Not at all; it's easy. Here, we first grab the x-direction and y-direction values of the linear velocity of the BodyObject (which is the commonly-handled stuff under the Farseer engine related programming) through the variable flyBallPhysicsSprite. Then, if the two values are large enough (we've used an approximate value of a float typed number 50f), we start the collision detection. If the variable sprite1 is the ball and sprite2 is the Netfront sprite, then the net related animation is played. If the variable sprite1 is the ball and sprite2 is the backboard sprite, we just need to play the hitting backboard sound. If the variable sprite1 is the ball and sprite2 is the ground sprite, then we need to play the hit ground sound. That's all!
In conclusion, we've leveraged two kinds of collisions detection in the basketball shoot game. The first happens between the ball sprite and the Path UIElement while the second occurs between the sprites. As you've seen, the collision detection principle for these two is quite different. You should notice, however, these two kinds of collisions detection are often used in a real-scenario Farseer engine backed Silverlight game.
Next, let's shift our attention to the mouse button related event handlers.
The Mouse Button Related Event Handlers
As is mentioned above, we've introduced two instances of the Usercontrol ucBasketball, one named dragBall and the other named flyBall. We use the dragBall to implement the mouse drag and move operations to finally decide the launching ball point. As soon as the mouse button is released, the ball dragBall disappears and the ball flyBall becomes visible. Since the second ball is a physics sprite we can easily make it fly along a specified parabola trace, with given mass, friction coefficient, and restitution coefficient.
NoteAt the very start of the game the ball flyBall is invisible, with its opacity set to 0. Here, we can not specify the Visibility property to Invisible since we cannot attach the PhysicsObjectBehavior behavior to a user control that owns invisible sub elements.
Next, let's check out all the mouse button related event handlers one by one.
The LayoutRoot_MouseLeftButtonDown Event Handler
The following gives the MouseLeftButtonDown event handler for the root Canvas control LayoutRoot.
Listing 3: The MouseLeftButtonDown Event Handler for the root parent Canvas
Here, you are suggested to research into the above code from two different perspectives. When the game first starts up, the flying ball is set invisible while the dragging ball visible. Then, we set the central point of the dragging ball, ready for dragging. On the other hand, when the match is over and another round of match begins, the flying ball may be still visible. So when the player clicks somewhere on the scene, the flying ball is set invisible while the dragging ball becomes visible which right appears the clicking point, ready for another dragging operation. That's it.
The dragBall_MouseLeftButtonDown Event Handler
The following gives the MouseLeftButtonDown event handler for the dragging ball.
Listing 4: The dragging ball related MouseLeftButtonDown event handler
As is apparently seen, we set the global variable _bDraggingBall to true indicating the dragging starts. And then, the mouse cursor capturing work really begins with the method CaptureMouse invoked.
The dragBall_MouseMove Event Handler
The following gives the MouseMove event handler for the dragging ball.
Listing 5: The MouseMove event handler for the dragging ball
On the surface the above code is easy to apprehend. With the ball being dragged, a new position is decided. And then, the ball will be placed at the corresponding point by invoking the method PositionBall. In fact, things are not as easy as is shown here.
To find the answer, we have to continue to look into the method PositionBall.
First, we place the dragged ball at the right position:
Then, we decide the launching ball point in time remembered using the variable _ptBallLaunchPoint.
Next, if the ball is being dragged, we calculate the offset values between the ball center and the starting point for the horizontal and vertical directions respectively. Then, if deltaX is greater than 10 and deltaY are greater than 10 you will see the red dragged line and arrow which indicate the direction and force to throw the ball. It is worth noting that by dragging the mouse you can easily change the ball dragging direction and force. The related code is listed below.
And also, you may have noticed if the deltaX and deltaY are both two small (less than 10 in the above case), we hide the direction dragging indicator. Figure 2 below illustrates the direction dragging indicator working at the running time.
Figure 2: The direction dragging indicator helps to decide the direction and force

Next, let's delve into the last mouse event handler - ball_MouseLeftButtonUp.
The ball_MouseLeftButtonUp Event Handler
The following gives the MouseLeftButtonUp event handler for the dragging ball.
Listing 6: The MouseLeftButtonUp event handler for the dragging ball
When the dragging action finishes, we no more capture the mouse cursor. And at the same time, we set the value of the variable _bDraggingBall to false, ready for the next dragging. And also, we make the dragging ball and related direction dragging indicator invisible – the task of the dragging ball is accomplished. At last, we invoke the helper method LaunchBall to launch ball.
The following lists the complete code for the method LaunchBall.
Like the previous method PositionBall, we first obtain the center coordinates of the ball. Then, we calculate the offset values between the ball center and the starting point for the horizontal and vertical directions respectively. Then, if deltaX and deltaY are large enough, the code continue to execute. Otherwise, the control will be returned simply.
Next, things become interesting. We first make the flying ball visible. Then, specify the force of throwing the ball by constructing a Vector2 object. If it's the first time to shoot the ball, we start timing and set up related mark. As for how to attach the PhysicsObjectBehavior behavior to the ball, this has already been discussed above.
Note that each time after the flying ball starts the physical movement it gains some forces, impulse, and velocity. Therefore, each time before launching the ball we have to reset all the related values. Then, we specify new position, and apply new force and torque to the ball. At last, we update the score board.
After the ball is sent out, we have done everything, letting the Farseer engine control the ball to move with specific physical features. The last thing for us to do is specify a random horizontal distance from the board, specifying the new start position of the ball and making preparation for the next time launching.
The Unfinished or To-be-improved Functions
First, for simplicity and due to time limit, we've only provided coarse and even ugly user interface in the game.
Second, a real-case ball shooting game should contain multiple collision detections, such as collision with the net, collision with the backboard, collision with the ground, collision with all the objects around the game scene. And also, different sound effects should be provided accordingly.
Third, we've not implemented the backend database support. However, a real shooting game should support this. I recommend your cute readers to supplement this by yourselves. You can resort to the elementary WebClient class, the newest WCF RIA Services or any other techniques you prefer to.
Summary
In this series of articles, we've used PhysicsHelper (a further-encapsulated and simplified version of the Farseer physics engine) to develop a simple ball shooting game under the Silverlight 4 and Visual Studio 2010 environments. As is pointed out beforehand, this series do not aim to be an elementary tutorial to the Farseer engine. So, to understand everything well in this game you should have some basic knowledge with the Farseer physics engine. On the other hand, you can look on this series as an introduction tutorial to PhysicsHelper and Silverlight 4 programming. Happy coding with the Farseer physics engine and PhysicsHelper!
About Xianzhong Zhu
 |
I'm a college teacher and also a freelance developer and writer from WeiFang China, with more than fourteen years of experience in design, and development of various kinds of products and applications on Windows platform. My expertise is in Visual C++/Basic/C#, SQL Server 2000/2005/2008, PHP+MyS...
This author has published 81 articles on DotNetSlackers. View other articles or the complete profile here.
|
You might also be interested in the following related blog posts
The BlogML plan
read more
|
|
Please login to rate or to leave a comment.