Nov 242013
 

Another needed feature in games is the ability to display multiple screens : intro, help, main game screen, etc …
For sure we could use one unique screen and redraw the whole thing each time but that would quickly become messy with lots of cases.

Here attached a demo that can be used as a basis.
As always our main module will call the first xna class (clsmain) : standard stuff.

From there we will call the menu screen.
In that screen, you can either call the help screen the game screen.
In these 2 screens, you can always go back to the menu screenpushing F10.

xna_screens

The code to go from one screen to the other is always :

my_screen_name= New class_name(Me.game)
ScreenManager.ShowScreen(my_screen_name)
Me.Close()

The source code : xna_demo_01 .
A project template to help starting new projects : XNA_SCREENMANAGER.

A video to illustrate.

 Posted by at 18 h 48 min
Nov 242013
 

Quick and dirty : buttons for XNA with mouse over and mouse click.

3 rectangles, 3 textures, mouse inputs…

The source code : XNA_demo_13 .

The video to illustrate.


Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework.Audio
Imports Microsoft.Xna.Framework.Content
Imports Microsoft.Xna.Framework.Media
Imports Microsoft.Xna.Framework.Input

Public Class Game
Inherits Microsoft.Xna.Framework.Game
Dim graphics As GraphicsDeviceManager
Dim SpriteBatch As SpriteBatch

Private easy As Texture2D
Private medium As Texture2D
Private hard As Texture2D

Dim color_a As Color
Dim color_b As Color
Dim color_c As Color

Dim rec_a As Rectangle
Dim rec_b As Rectangle
Dim rec_c As Rectangle

Public Sub New()
graphics = New GraphicsDeviceManager(Me)
Window.Title = "Test"
Me.IsMouseVisible = True
End Sub

Protected Overrides Sub Initialize()
MyBase.Initialize()
End Sub
Protected Overrides Sub LoadContent()
MyBase.LoadContent()
SpriteBatch = New SpriteBatch(GraphicsDevice)
easy = Content.Load(Of Texture2D)("easy")
medium = Content.Load(Of Texture2D)("medium")
hard = Content.Load(Of Texture2D)("hard")

rec_a = New Rectangle(40, 40, easy.Width, easy.Height)
rec_b = New Rectangle(40, 140, medium.Width, medium.Height)
rec_c = New Rectangle(40, 240, hard.Width, hard.Height)

End Sub
Protected Overrides Sub UnloadContent()
MyBase.UnloadContent()
End Sub
Private Sub update_mouse()
Dim mouse_state As MouseState = Mouse.GetState()
Dim x As Integer = mouse_state.X
Dim y As Integer = mouse_state.Y

If rec_a.Contains(x, y) Then color_a = Color.Red Else color_a = Color.White
If rec_b.Contains(x, y) Then color_b = Color.Red Else color_b = Color.White
If rec_c.Contains(x, y) Then color_c = Color.Red Else color_c = Color.White

If rec_a.Contains(x, y) And mouse_state.LeftButton = ButtonState.Pressed Then color_a = Color.Yellow
If rec_b.Contains(x, y) And mouse_state.LeftButton = ButtonState.Pressed Then color_b = Color.Yellow
If rec_c.Contains(x, y) And mouse_state.LeftButton = ButtonState.Pressed Then color_c = Color.Yellow
End Sub

Protected Overrides Sub Update(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
update_mouse()
MyBase.Update(gameTime)
End Sub

Protected Overrides Sub Draw(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
GraphicsDevice.Clear(Color.CornflowerBlue)
SpriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend)
SpriteBatch.Draw(easy, rec_a, color_a)
SpriteBatch.Draw(medium, rec_b, color_b)
SpriteBatch.Draw(hard, rec_c, color_c)
SpriteBatch.End()
MyBase.Draw(gameTime)
End Sub

End Class

 Posted by at 14 h 39 min
Nov 242013
 

In previous articles, we have seen many basics which should help to make a game : scrolling, moving shapes, collision, inputs (mouse, keyboard, gamepad)…

However, you may sometimes need to implement some physic principles : gravity, friction, restitution, etc.

This is where Farseer Physics Engine comes to the rescue.
Farseer Physics Engine is a collision detection system with realistic physics responses.

2 importants concepts to start with :
World
The world object is the manager of it all. It iterates all the objects in the world each time you call the Step() function and makes sure everything is consistent and stable.
Body
The body keeps track of world position. It is basically a point is space that is affected by forces such as impulses from collisions and gravity.

Lets add a project reference to farseer (note : I used msbuild /property:configuration=release « Farseer Physics XNA.csproj » to build it).
Then we will create a world, add a body to it and draw a texture based on the body position.

I encourage you to play with the world properties such as restitution, friction etc to see how it affects your world.
Also, notice how easy it is to detect collision (although I manage only plain shape for now, no convex shapes).

The source code : XNA_DEMO_19

A video to illustrate it.

 Posted by at 13 h 53 min
Nov 232013
 

We have seen in previous article 8 how to perform pixel collision.
Altough it worked perfectly, it only worked on non rotated shapes.

But in some cases, your shape will rotate (like a car in a racing game – see article « A racing car game »).

To perform pixel collision for a rotated shape, here below the steps :

-you first need to draw a rotated rectangle around your shape
-you then need to draw a bounding rectanle around that rotated rectangle (also called AABB : Axis Aligned Bounding Box)
-finally you can check whether 2 AABB intersects, and if so, if in the intersected region, we have 2 non transparent pixels (colliding) or not

The source code : XNA_DEMO_18
Note : the project contains a class named primitives2d which is used only to draw lines/rectangles around my objects.

Lets illustrate this with some screenshots.

Lets rotate our rectangle along with my rocket
pixel2

Lets define our bounding box
pixel3

Despite bounding boxes intersecting, we dont detect collision yet
pixel4

Here we go ! In the intersection region, there are 2 non transparent pixels
pixel5

 Posted by at 17 h 41 min
Nov 232013
 

One annoying fact around XNA is that it supports natively only xbox gamepads.

Well Nuclex fixes that for us : )
See here : http://nuclexframework.codeplex.com/ .
Download, unzip and add a reference in your project to nuclex.input.dll.

The source code : XNA_DEMO_21 .

Now lets see the code.

All the magic is in the object inputmanager.
Then, just like we would check the state of keyboard keys, we will do the same with the gamepad buttons.

If you want to check the state of the first DirectInput game pad in your system instead, just write:
If (input.GetGamePad(ExtendedPlayerIndex.Five).GetState().Buttons.X = ButtonState.Pressed) Then ...
Notice that DirectInput Gamepads (as opposed to xbox gamepads) starts at index 5. However, if you have an xbox pad plugged, index 5 will also work.


Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework.Audio
Imports Microsoft.Xna.Framework.Content
Imports Microsoft.Xna.Framework.Media
Imports Microsoft.Xna.Framework.Input
Imports Nuclex.Input

Public Class Game
Inherits Microsoft.Xna.Framework.Game
Dim graphics As GraphicsDeviceManager
Dim SpriteBatch As SpriteBatch
Dim input As InputManager
Dim myfont As SpriteFont
Dim msg As String = "."
Dim dummyTexture As Texture2D
Dim rc As Rectangle

Public Sub New()
graphics = New GraphicsDeviceManager(Me)
input = New InputManager(Services, Window.Handle)
Components.Add(input)
Window.Title = "Test"
End Sub

Protected Overrides Sub Initialize()
MyBase.Initialize()
End Sub
Protected Overrides Sub LoadContent()
SpriteBatch = New SpriteBatch(GraphicsDevice)
myfont = Content.Load(Of SpriteFont)("xnb\myfont")
dummyTexture = New Texture2D(GraphicsDevice, 1, 1)
'
Dim c(0) As Color
c(0) = Color.White
dummyTexture.SetData(Of Color)(c)
'
rc = New Rectangle(100, 100, 10, 10)
'
MyBase.LoadContent()

End Sub
Protected Overrides Sub UnloadContent()
MyBase.UnloadContent()
End Sub

Protected Overrides Sub Update(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
'right
If (Keyboard.GetState.IsKeyDown(Keys.Right)) Or (input.GetGamePad(ExtendedPlayerIndex.Five).GetState().Buttons.X = ButtonState.Pressed) Then
msg = "right"
rc.X += 1
End If
'left
If (Keyboard.GetState.IsKeyDown(Keys.Left)) Or (input.GetGamePad(ExtendedPlayerIndex.Five).GetState().Buttons.A = ButtonState.Pressed) Then
msg = "left"
rc.X -= 1
End If
'up
If (Keyboard.GetState.IsKeyDown(Keys.Up)) Or (input.GetGamePad(ExtendedPlayerIndex.Five).GetState().Buttons.RightShoulder = ButtonState.Pressed) Then
msg = "up"
rc.Y -= 1
End If
'down
If (Keyboard.GetState.IsKeyDown(Keys.Down)) Or (input.GetGamePad(ExtendedPlayerIndex.Five).GetState().Buttons.LeftShoulder = ButtonState.Pressed) Then
msg = "down"
rc.Y += 1
End If
MyBase.Update(gameTime)
End Sub

Protected Overrides Sub Draw(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
GraphicsDevice.Clear(Color.CornflowerBlue)
SpriteBatch.Begin()
SpriteBatch.DrawString(myfont, msg, New Vector2(10, 10), Color.White)
SpriteBatch.Draw(dummyTexture, rc, Color.White)
SpriteBatch.End()
MyBase.Draw(gameTime)
End Sub

End Class

 Posted by at 13 h 18 min
Nov 222013
 

Sometimes you need a simple progressbar in your XNA game to display game points, life, etc.

Lets do it quick and simple with rectangles only:
-One gray rectangle for the fix bar, and one red rectangle for the moving bar (use +/- keys).
-a very simple math formula to draw the current value against the width of the bar : progressbar_width * progressbar_value / progressbar_max

The sourcecode : Here


Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework.Audio
Imports Microsoft.Xna.Framework.Content
Imports Microsoft.Xna.Framework.Media
Imports Microsoft.Xna.Framework.Input

Public Class Game
Inherits Microsoft.Xna.Framework.Game
'Fields in our game graphic manager etc'
Dim graphics As GraphicsDeviceManager
Dim spritebatch As SpriteBatch
Dim dummyTexture As Texture2D
Dim progressbar_max = 100
Dim progressbar_value As Integer = progressbar_max
Dim progressbar_width As Integer = 250
Dim font As SpriteFont

Public Sub New()
graphics = New GraphicsDeviceManager(Me)
Window.Title = "Test"
graphics.PreferredBackBufferWidth = 400
graphics.PreferredBackBufferHeight = 200
End Sub

Protected Overrides Sub Initialize()
MyBase.Initialize()
End Sub
Protected Overrides Sub LoadContent()
spritebatch = New SpriteBatch(GraphicsDevice)
dummyTexture = New Texture2D(GraphicsDevice, 1, 1)
Dim c(0) As Color
c(0) = Color.White
dummyTexture.SetData(Of Color)(c)
'
font = Content.Load(Of SpriteFont)("xnb\myfont")
MyBase.LoadContent()
End Sub
Protected Overrides Sub UnloadContent()
MyBase.UnloadContent()
End Sub

Protected Overrides Sub Update(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
If Keyboard.GetState.IsKeyDown(Keys.Add) Then progressbar_value += 1
If Keyboard.GetState.IsKeyDown(Keys.Subtract) Then progressbar_value -= 1
If progressbar_value >= progressbar_max Then progressbar_value = progressbar_max
If progressbar_value <= 0 Then progressbar_value = 0 MyBase.Update(gameTime) End Sub Protected Overrides Sub Draw(ByVal gameTime As Microsoft.Xna.Framework.GameTime) GraphicsDevice.Clear(Color.Blue) spritebatch.Begin() spritebatch.DrawString(font, progressbar_value, New Vector2(10, 10), Color.White) spritebatch.Draw(dummyTexture, New Rectangle(100, 10, progressbar_width, 10), Color.Gray) spritebatch.Draw(dummyTexture, New Rectangle(100, 10, progressbar_width * progressbar_value / progressbar_max, 10), Color.Red) spritebatch.End() MyBase.Draw(gameTime) End Sub End Class

 Posted by at 23 h 40 min
Nov 172013
 

A new version is out (nov 12).

As always, many bug fixes and new features, such as a new BCD editor.

A must have.

Find it here.

 Posted by at 20 h 45 min
Nov 172013
 

So now you have made this sweet little XNA game of yours and you want to distribute it to friends.

Sure you could give them the content of your debug/release folder but thats a lot of files in there may be not needed for simple execution.
Not to mention you would like to distribute the XNA run time with it.
Why not package all this in a friendly setup that allow one to install/deinstall?

Well lets use Inno Setup.

Bere below a script that will allow you to make one standalone package handling it all.

Adapt paths and filenames to your project.


[Files]
Source: XNA_BASE1.exe; DestDir: {app}
Source: *.dll; DestDir: {app}
Source: xnb\*; DestDir: {app}\xnb
Source: xnafx40_redist.msi; DestDir: {tmp}; Flags: deleteafterinstall
[Icons]
Name: "{group}\Shooting"; Filename: "{app}\XNA_BASE1.exe"; WorkingDir: "{app}"
Name: "{group}\Uninstall Shooting"; Filename: "{uninstallexe}"
[Run]
Filename: {tmp}\xnafx40_redist.msi; Check: ask_; Flags: shellexec waituntilterminated; StatusMsg: "running"
[Code]
function Ask_():Boolean;
begin
result:=false;
if MsgBox('Install XNA Runtime? Needed to run the game', mbConfirmation, MB_YESNO) = IDYES then result:=true
end;
[Dirs]
Name: {app}\xnb
[Setup]
AppName=Shooting
AppVersion=1.0
DefaultDirName={pf}\shooting
DefaultGroupName=Shooting
UninstallDisplayIcon={app}\uninstall.exe
Compression=lzma2
SolidCompression=yes
SourceDir=C:\Projects\XNA_DEMO_12_shooting\XNA_BASE1\bin\Debug
OutputDir=C:\Projects\XNA_DEMO_12_shooting\installer

inno1

inno2

inno3

 Posted by at 18 h 34 min
Nov 172013
 

A short recap of recent articles around VB.Net and XNA :

VB.Net and XNA : Article 9 – A Pong Game
VB.Net and XNA : Vroom V1
VB.Net and XNA : Article 8 (pixel collision)
VB.Net and XNA : Article 7 (Scrolling)
VB.Net and XNA : Article 6 (move a texture, add a background, play some sound)
VB.Net and XNA : Article 5 (mouse input)
VB.NET and XNA : Article 4 (keyboard input)
VB.NET and XNA : Article 3 (draw text)
VB.Net and XNA : Article 2 (moving texture)
VB.Net and XNA : Article 1 (skeleton class)
VB.Net and XNA : Article 0 (introduction)

 Posted by at 12 h 57 min
Nov 162013
 

This time lets see how, without any external texture, we will animate forms and use collision detection.

To illustrate this, lets make a Pong game.

We will need to draw 3 rectangles : 2 bars and one ball.
The update method will manage check the keyboard, move the positions of each rectangle and check collision thru the intersect rectangle method.

The code : XNA_DEMO_17
up/down for player2, z/s for player1 : as simple as that.

See below a short video.

Enjoy

 Posted by at 18 h 58 min