Tagged: game, gaming, microsoft, pong, programming, racquetball, visual basic, xna
This topic was published by Jarret Buse and viewed 2674 times since "". The last page revision was "".
- AuthorPosts
The best way to learn programming concepts is to go through a sample program. In this article, we will cover a sample program for XNA in a Windows game. The game is very simple, but shows the various parts of an XNA program. The game is a one-person version of Pong (racquetball).
Download Source Code - https://dcjtech.info/wp-content/uploads/2014/11/Racquetball.zip
The game works as the user controls a "paddle" which they can move up and down. A ball bounces off the top, bottom and right wall of the window. The ball cannot pass the paddle which is placed to the left of the window. If the ball passes the paddle, the game is over. In the case of this game, the ball reappears on the screen and the game continues. Managing a "game over" screen is a simple thing, but let's start with the basics first and improve the game as we go along.
Let's start with something similar to Pong, but a one player game. We'll look at Racquetball. In Racquetball there are three walls: top, right and bottom. The ball will bounce off of these walls. A paddle is placed on the left side of the screen which is moved up and down by the player. If the ball gets past the paddle, the game resets. The code is as follows:
''' <summary> ''' This is the main type for your game ''' </summary> Public Class Game1 Inherits Microsoft.Xna.Framework.Game Private WithEvents graphics As GraphicsDeviceManager Private WithEvents spriteBatch As SpriteBatch Dim t_paddle1 As Texture2D Dim t_ball As Texture2D Dim paddle1 As Paddle1 Dim ball As Ball Dim rand As New Random() Dim currentState As KeyboardState Dim currentPad As GamePadState Dim r As Integer ''' <summary> ''' Allows the game to perform any initialization it needs to before starting to run. ''' This is where it can query for any required services and load any non-graphic ''' related content. Calling MyBase.Initialize will enumerate through any components ''' and initialize them as well. ''' </summary> Protected Overrides Sub Initialize() ' TODO: Add your initialization logic here MyBase.Initialize() ResetGame() End Sub ''' <summary> ''' LoadContent will be called once per game and is the place to load ''' all of your content. ''' </summary> Protected Overrides Sub LoadContent() ' Create a new SpriteBatch, which can be used to draw textures. spriteBatch = New SpriteBatch(GraphicsDevice) t_paddle1 = Content.Load(Of Texture2D)("paddle1") t_ball = Content.Load(Of Texture2D)("ball") ' TODO: use Me.Content to load your game content here End Sub ''' <summary> ''' UnloadContent will be called once per game and is the place to unload ''' all content. ''' </summary> Protected Overrides Sub UnloadContent() ' TODO: Unload any non ContentManager content here End Sub ''' <summary> ''' Allows the game to run logic such as updating the world, ''' checking for collisions, gathering input, and playing audio. ''' </summary> '''Provides a snapshot of timing values. Protected Overrides Sub Update(ByVal gameTime As GameTime) ' Allows the game to exit If GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed Then Me.Exit() End If UpdateBall() UpdatePaddles() CheckCollisions() ' MyBase.Update(gameTime) ' TODO: Add your update logic here MyBase.Update(gameTime) End Sub ''' <summary> ''' This is called when the game should draw itself. ''' </summary> '''Provides a snapshot of timing values. Protected Overrides Sub Draw(ByVal gameTime As GameTime) ' TODO: Add your drawing code here GraphicsDevice.Clear(Color.LightBlue) spriteBatch.Begin() spriteBatch.Draw(t_paddle1, New Rectangle(paddle1.pos.X, paddle1.pos.Y, t_paddle1.Width, t_paddle1.Height), Color.White) spriteBatch.Draw(t_ball, New Rectangle(ball.pos.X, ball.pos.Y, t_ball.Width, t_ball.Height), Color.White) spriteBatch.[End]() MyBase.Draw(gameTime) End Sub Sub ResetGame() paddle1 = New Paddle1(10, 200) ball = New Ball(385, 285) End Sub Public Sub New() graphics = New GraphicsDeviceManager(Me) Content.RootDirectory = "Content" End Sub Sub UpdateBall() 'update positions ball.pos.X += ball.h_speed ball.pos.Y += ball.v_speed 'check for boundaries 'bottom If ball.pos.Y > (Window.ClientBounds.Height - t_ball.Height) Then ball.v_speed *= -1 End If 'top If ball.pos.Y < 0 Then ball.v_speed *= -1 End If 'right If ball.pos.X > Window.ClientBounds.Width - t_paddle1.Width + 1 Then ' Fill in this part ball.h_speed *= -1 End If End Sub Sub UpdatePaddles() 'get keyboard keys currentState = Keyboard.GetState() Dim currentKeys As Keys() = currentState.GetPressedKeys() 'check for up and down arrow keys For Each key As Keys In currentKeys If key = Keys.Up Then paddle1.pos.Y -= paddle1.speed End If If key = Keys.Down Then paddle1.pos.Y += paddle1.speed End If If key = Keys.Escape Then Me.[Exit]() End If Next 'check for up and down arrow keys If currentPad.Triggers.Left > 0.0 Then paddle1.pos.Y -= paddle1.speed End If If currentPad.Triggers.Right > 0.0 Then paddle1.pos.Y += paddle1.speed End If 'check boundaries If paddle1.pos.Y <= 1 Then paddle1.pos.Y = 1 End If If paddle1.pos.Y + t_paddle1.Height + 1 >= Window.ClientBounds.Height Then paddle1.pos.Y = Window.ClientBounds.Height - t_paddle1.Height + 1 End If End Sub Sub CheckCollisions() 'check paddle1 if ball moving left If ball.h_speed < 0 Then 'check if ball has surpassed paddle If ball.pos.X < paddle1.pos.X + 43 Then 'check if ball has hit paddle or went through If (ball.pos.Y + t_ball.Height < paddle1.pos.Y) OrElse (ball.pos.Y > paddle1.pos.Y + t_paddle1.Height) Then 'LOST! ResetGame() Else 'ball hit - calculate new speeds 'speed of ball changes randomly - 3 to 6 If ball.h_speed < 0 Then ball.h_speed = rand.[Next](3, 7) Else ball.h_speed = rand.[Next](-6, -2) End If If ball.v_speed < 0 Then ball.v_speed = rand.[Next](3, 7) Else ball.v_speed = rand.[Next](-6, -2) End If End If End If End If End Sub End Class Public Class Paddle1 'position of paddle Public pos As Point Public speed As Integer 'constructor - position Public Sub New(x As Integer, y As Integer) pos = New Point(x, y) speed = 6 End Sub End Class Public Class Ball 'position of ball Public pos As Point Public h_speed As Integer, v_speed As Integer 'constructor - position Public Sub New(x As Integer, y As Integer) pos = New Point(x, y) Dim rand As New Random() h_speed = rand.[Next](3, 7) If rand.[Next](0, 2) = 0 Then h_speed *= -1 End If rand = New Random() v_speed = rand.[Next](3, 7) If rand.[Next](0, 2) = 0 Then v_speed *= -1 End If End Sub End Class
The game can be copied and pasted into a Visual Studio window to be played or is attached to the article with the images. If you read the previous article: XNA Parts of the Program, then some of this may look familiar. I will go into each section in more detail.
The Initialize subroutine is as follows:
Protected Overrides Sub Initialize() ' TODO: Add your initialization logic here MyBase.Initialize() ResetGame() End Sub
The subroutine is the basic auto-generated sub for every XNA program. In this instance, nothing is done here except the call to ResetGame().
The ResetGame() sub is the following:
Sub ResetGame() paddle1 = New Paddle1(10, 200) ball = New Ball(385, 285) End Sub
Here, a paddle and ball instance are created or overwritten.
The next main subroutine is LoadContent() as follows:
Protected Overrides Sub LoadContent() ' Create a new SpriteBatch, which can be used to draw textures. spriteBatch = New SpriteBatch(GraphicsDevice) t_paddle1 = Content.Load(Of Texture2D)("paddle1") t_ball = Content.Load(Of Texture2D)("ball") End Sub
This is where the Sprites are created and the textures are loaded for the paddle and ball.
The next sub is the UnloadContent(), which if you look back, it does not have any content in this program.
The next two subroutines are the Game Loop, which are Update and Draw.
The Update() sub is:
Protected Overrides Sub Update(ByVal gameTime As GameTime) ' Allows the game to exit If GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed Then Me.Exit() End If UpdateBall() UpdatePaddles() CheckCollisions() ' MyBase.Update(gameTime) ' TODO: Add your update logic here MyBase.Update(gameTime) End Sub
Here you can see that if the back button is pressed on the GamePad, the program exits. The next thing is to update the Ball (UpdateBall), Paddles (UpdatePaddles) and Check for Collisions (CheckCollisions). If you understand Visual Basic, the subroutines should make sense to you.
The last subroutine is Draw as shown:
Protected Overrides Sub Draw(ByVal gameTime As GameTime) GraphicsDevice.Clear(Color.LightBlue) spriteBatch.Begin() spriteBatch.Draw(t_paddle1, New Rectangle(paddle1.pos.X, paddle1.pos.Y, t_paddle1.Width, t_paddle1.Height), Color.White) spriteBatch.Draw(t_ball, New Rectangle(ball.pos.X, ball.pos.Y, t_ball.Width, t_ball.Height), Color.White) spriteBatch.[End]() MyBase.Draw(gameTime) End Sub
The Draw() sub first sets up the screen color as LightBlue. Next, the Sprite Batch is started to update the textures all at once. First, the paddle is set. Second, the Ball is set. Finally, the Sprite Batch is ended which causes the two textures to be refreshed at once. The final command, MyBase(gameTime), is run to finalize the refresh.
Try the code and play the game a few times. Look over the code to understand it better. In my next article, we'll make modifications.
Further Reading
- XNA Reading Guide - https://dcjtech.info/topic/gaming/#xna
Attachments:
- AuthorPosts