XNA in VB .Net

From XNAWiki
Jump to: navigation, search

XNA in VB .Net

  • Level: Intermediate
  • Platform: Windows only
  • IDE: Visual Studio .Net 2008 VB/C# XNA 3.0.0

Introduction

While it is still highly recommended that you use C# as default programming language, some may find this article useful when dealing with large projects that are written in Visual Basic and are to be ported to the XNA framework (Like an old graphic depended application of some kind).

This article only applies to Windows applications (not XBox). If you want your game to be easily ported between windows and xbox, use only C#.

This article is a redo on the following article that I've done before (XNA Content Pipeline using VB.NET) Since this one has problems on 64-bit systems it seems (or even 32-bit Vista I'm not sure). In this article I will be using a technique that is used in other popular game engines dealing with multiple programming languages. This means that we will be creating 2 projects instead of 1, both in the same solution.

The first project will be made in C# and will be a host application hosting the game engine. The other project will be the XNA engine (or some may call it an interface, it's basically our Game1 class) written in VB. This sort of application is often called a client, because it acts as a client to our host application written in C#. The host application will be compiled in an EXE and the client application into a DLL.

Preparing the Solution

  • Links to Images:
  1. Image A (xnavb_newcsproj.jpg)
  2. Image B (xnavb_delgame1cs.jpg)
  3. Image C (xnavb_newvbproj.jpg)
  4. Image D (xnavb_vbrefs.jpg)
  5. Image E (xnavb_csrefs.jpg)


A bit of C#

This is the easy part (not that I wish to tell you that the rest of this article is hard :)), just create a new project and choose a C# Windows XNA Game project (Image A). When the project is created, remove the Game1.cs file from the project (Image B).

After all that is done, move on the next section.

The Client application in Visual Basic

The client application is a standard Class Library project containing a class (Game1) that will be referenced in the host application. So add a new project to the solution that you already have, and under Visual Basic, select a Class Library (Name this project Client) (Image C). When the project is created, rename the default class that is created with this project (Class1.vb) to a more suitable name. (I call it CBaseClient.vb). Also add all the XNA references to this Visual Basic project (by going to the menu Project >> Add Reference...; Hit the .Net tab and scroll down till you see the XNA references; Select them all and click OK; Check Image D for more specific info). After you've done that, add the namespaces to the class file (CBaseClient.vb) and let the CBaseClass inherit "Microsoft.Xna.Framework.Game".

You're not done just yet. We need to translate the game code that was generated with the C# project in Game1.cs. Since you no longer have that class by now, I've translated it for you. Along with the translated game code, the CBaseClient class should look like this:

Option Explicit On
Option Strict On
 
Imports System
Imports System.Collections.Generic
Imports System.Linq
 
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Audio
Imports Microsoft.Xna.Framework.Content
Imports Microsoft.Xna.Framework.GamerServices
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Media
Imports Microsoft.Xna.Framework.Net
Imports Microsoft.Xna.Framework.Storage
 
 
''' <summary>
''' This is the main type for your game
''' </summary>
Public Class CBaseClient ' You could also call this class "Game1" I suppose
    Inherits Microsoft.Xna.Framework.Game
 
    Dim graphics As GraphicsDeviceManager
    Dim spriteBatch As SpriteBatch
 
    Dim font As SpriteFont
 
    Public Sub New()
        graphics = New GraphicsDeviceManager(Me)
        Content.RootDirectory = "Content"
    End Sub
 
    ''' <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 base.Initialize will enumerate through any components
    ''' and initialize them as well.
    ''' </summary>
    Protected Overrides Sub Initialize()
 
        ' TODO: Add your initialization logic here
 
        MyBase.Initialize()
    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()
        MyBase.LoadContent()
        ' Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = New SpriteBatch(GraphicsDevice)
 
        font = Content.Load(Of SpriteFont)("Test")  ' A test font to display "Hello World"
        ' TODO: use this.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()
        MyBase.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>
    ''' <param name="gameTime">Game time snapshot</param>
    Protected Overrides Sub Update(ByVal gameTime As GameTime)
        ' Allows the game to exit
        If Keyboard.GetState().IsKeyDown(Keys.Escape) Then Me.Exit()
 
        ' TODO: Add your update logic here
 
        MyBase.Update(gameTime)
    End Sub
 
    ''' <summary>
    ''' This is called when the game should draw itself.
    ''' </summary>
    ''' <param name="gameTime">Game time snapshot</param>
    Protected Overrides Sub Draw(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
        GraphicsDevice.Clear(Color.CornflowerBlue)
 
        spriteBatch.Begin(SpriteBlendMode.AlphaBlend)
 
        ' TODO: Add your drawing code here
 
        ' Prints "Hello World!" on screen
        spriteBatch.DrawString(font, "Hello World!", _
            New Vector2(50, 50), _
            Color.White, 0.0F, New Vector2(0, 0), _
            1.0, SpriteEffects.None, 0)
 
        spriteBatch.End()
 
        MyBase.Draw(gameTime)
    End Sub
 
End Class

I took the liberty of adding a test font that we'll be using to test the content pipeline soon. If everything works, it should display "Hello World!" at runtime.

All right, this part is done.

Save and build this project (Only this project, not the whole solution). To do this, right click the "Client" project in the project explorer and select "Build".

Next thing to do is reference this class with our host application, so that we can use it.

Go back to you C# project and open Program.cs. Before we can continue, we need to add a reference, so go to the menu "Project >> Add Reference...". In the window that pops up select the Projects tab. In there you'll find a project call "Client" (how convenient :)), select it and click ok (Image E).

Add the namespace for the VB project to the Progfram.cs code file ("using Client;"). Now find and replace everything that is "Game1" with "CBaseClient". (Or if you called the CBaseClass "Game1", just leave it how it was)

Your Program.cs codefile should now look like this:

using System;
using Client;
 
namespace WindowsGame1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            using (CBaseClient game = new CBaseClient())
            {
                game.Run();
            }
        }
    }
}

You're done. Head to the next section.

The Content Pipeline

There are no special things that you need to do with this project (unlike in my previous article), which is a very good thing. Just use the content pipeline from the C# project to add assets to your project.

To test it, we'll be adding a spritefont used to display "Hello World!" on the scene.

To do this, right-click the "Content" project in you C# project (in project explorer) and select "Add" >> "New Item". Select "Sprite Font" under the Templates and give it "Test.spritefont" as name and click OK.

An XML file should automatically open, if not, double-click "Test.spritefont" under the Content project (in project explorer).

The XML file should look like this:

<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains an xml description of a font, and will be read by the XNA
Framework Content Pipeline. Follow the comments to customize the appearance
of the font in your game, and to change the characters which are available to draw
with.
-->
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
  <Asset Type="Graphics:FontDescription">
 
    <!--
    Modify this string to change the font that will be imported.
    -->
    <FontName>Verdana</FontName>
 
    <!--
    Size is a float value, measured in points. Modify this value to change
    the size of the font.
    -->
    <Size>14</Size>
 
    <!--
    Spacing is a float value, measured in pixels. Modify this value to change
    the amount of spacing in between characters.
    -->
    <Spacing>0</Spacing>
 
    <!--
    UseKerning controls the layout of the font. If this value is true, kerning information
    will be used when placing characters.
    -->
    <UseKerning>true</UseKerning>
 
    <!--
    Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
    and "Bold, Italic", and are case sensitive.
    -->
    <Style>Regular</Style>
 
    <!--
    If you uncomment this line, the default character will be substituted if you draw
    or measure text that contains characters which were not included in the font.
    -->
    <!-- <DefaultCharacter>*</DefaultCharacter> -->
 
    <!--
    CharacterRegions control what letters are available in the font. Every
    character from Start to End will be built and made available for drawing. The
    default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
    character set. The characters are ordered according to the Unicode standard.
    See the documentation for more information.
    -->
    <CharacterRegions>
      <CharacterRegion>
        <Start>&#32;</Start>
        <End>&#126;</End>
      </CharacterRegion>
    </CharacterRegions>
  </Asset>
</XnaContent>

You're done. Head to the next section.

Testing the project

Save and build the solution (Yes now the whole solution :))

Hit F5 to launch, you should see Hello World! in white on a corn flower blue background.

I hope this article has helped you a lot! :)

XNA 4.0

To make this work under XNA 4.0 with the "High-Def" profile, change the public sub new to read as follows.

Public Sub New()
        graphics = New GraphicsDeviceManager(Me)
        Content.RootDirectory = "Content"
        graphics.GraphicsProfile = GraphicsProfile.HiDef
    End Sub

Also See

XNA Content Pipeline using VB.NET