XNA: Sample Program 1

This topic was published by and viewed 1781 times since "". The last page revision was "".

Viewing 1 post (of 1 total)
  • Author
    Posts
  • Jarret Buse
    Jarret Buse
    Participant
    • Topics - 25
    • @jbuse1

    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 - http://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

    Attachments:
    1. Racquetball.zip
Viewing 1 post (of 1 total)