| XNA Game-Themed CS1 Examples (XGC1) | |
|
Release 2.0 (XNA V3.1) |
|
References:
Goals:
1. Obtain the example code
When the game starts, you'll see a screen that looks similar to this:

For this tutorial, there are two paddles on the screen; the right thumbstick controls the right paddle, the left thumbstick controls the left paddle. The paddles can only be moved vertically. The ball appears as soon as the game starts, and it moves (and bounces off walls and paddles) on it's own
1. SoccerBall.cs:
This is effectively identical what was presented in the prior tutorial
2. Paddle.cs:
This is almost identical what was presented in the prior tutorial. The only thing that's different is that when the soccer ball bounces off a paddle, we need to move the ball to the correct side of the paddle, instead of just assuming that the soccer ball must be moved to the right edge. That logic is handled in the BounceTheSoccer method:
|
/// <summary>
/// Bounce the soccer ball.
/// </summary>
/// <returns>true if paddle has
bounced soccer, otherwise false</returns>
public
bool BounceTheSoccer(SoccerBall
theBall)
{
XNACS1Circle
theBallCircle = theBall.GetTheCircle();
bool hit = m_Rec.Collided(theBallCircle);
if (hit)
{
if (theBallCircle.VelocityX >
0) // moving towards right, will collide
with the right paddle
theBallCircle.CenterX = m_Rec.MinBound.X -
theBallCircle.Radius;
else
// moving towards left, will
collide with the left paddle
theBallCircle.CenterX = m_Rec.MaxBound.X +
theBallCircle.Radius;
theBallCircle.VelocityX = -theBallCircle.VelocityX;
}
return hit; }
|
In the previous tutorial, when the ball collided with the paddle, we could safely assume that the ball needed to be placed on the right edge of the one-and-only paddle. Now that there are two paddles, we need to figure out whether the ball has impacted the right paddle, or the left paddle. We'll do that here by asking if the ball's horizontal velocity is positive (meaning that it's moving rightward, and therefore must have collided with the right paddle), or if the velocity is negative (in which case it must have been moving leftward, and therefore have collided with the left paddle):
3. Game1.cs:
If you compare this file to the Game1.cs in the prior tutorial, you'll see what looks like a lot of changes. Given the number of apparent changes, there is surprisingly few conceptual differences. Because this tutorial has two paddles, rather than just one, we define a named constant for the X part of each of their (X,Y) starting locations, we define an instance variable for each of the paddles, and initialize both paddles in InitializeWorld. We also need to make sure that UpdateWorld deals with both paddles, as we'll see below.
For this program, the ball is created in the InitializeWorld method, which simplifies UpdateWorld because we no longer need to react to the 'A' button being pressed, nor do we need to protect any code against the possibility that the soccer ball does not yet exist. For example, we can now just call m_TheBall.UpdateBall() without worrying if ball exists or not.
|
protected
override void
UpdateWorld()
{
if (GamePad.ButtonBackClicked())
this.Exit();
m_LeftPaddle.UpdatePaddlePosition(GamePad.ThumbSticks.Left.Y);
m_RightPaddle.UpdatePaddlePosition(GamePad.ThumbSticks.Right.Y);
m_TheBall.UpdateBall();
m_LeftPaddle.BounceTheSoccer(m_TheBall);
m_RightPaddle.BounceTheSoccer(m_TheBall);
EchoToTopStatus("Left Thumb Stick to
move the left paddle, Right thumb stick to move the right paddle");
EchoToBottomStatus("Current ball
position:" + m_TheBall.CurrentPosition()); }
|
You'll notice that we now call UpdatePaddlePosition on the left, and
then the right paddles:
m_LeftPaddle.UpdatePaddlePosition(GamePad.ThumbSticks.Left.Y);
m_RightPaddle.UpdatePaddlePosition(GamePad.ThumbSticks.Right.Y);
We pass the left thumbstick's information to the left paddle, and the right thumbstick's information to the right paddle. This sort of situation is exactly where OOP shines brightest - since we've defined a single class that describes how all Paddle objects behave, we can how quickly tell each Paddle object the specific information that it needs to move itself on the screen.
Notice that each paddle maintains it's own, separate set of instance variable (of it's own data), so that the left paddle can be at a different location from the right paddle. Again, having defined that all paddles have SOME location, each particular Paddle object can be placed at a unique location.
Similarly, it's very easy to check and see if the ball overlaps with
either paddle, by calling the same method (BounceTheSoccer) on each
separate paddle object:
m_LeftPaddle.BounceTheSoccer(m_TheBall);
m_RightPaddle.BounceTheSoccer(m_TheBall);
FURTHER EXERCISES: