From Chromesville to the mythical land of XBox 360
By Dominique Louis
Introduction
It all began back in January 2007 when I decided that there needed to be some example code showing how to use an Object Pascal compiler with XNA. I had done some Delphi for .NET and Managed Direct X ports in the past, so was vaguely familiar with how managed code worked, but XNA was a totally new managed API, which is said to replace Microsoft's current managed API. When I looked at Delphi for .NET it did not support the compact framework ( which is needed for XNA ) or MSBuild, and at the time I knew very little about what Chrome was capable of, only that it supported .NET and more importantly the v2.0 compact framework.
Pre-requisite Downloads
To create games that target the XNA API you will need to have the following installed on your PC, before you start( all free downloads ):
- DirectX 9.0c
- .NET Framework 2.0
- Microsoft Visual Studio Express 1.0
- Microsoft XNA Game Studio Express 1.0 Refresh
- Chrome compiler either Command line or as part of their Visual Studio Edition ( there is a trail version available )
- A PC graphics card that supports Shader model 1.1 and upwards
- Xbox 360 with Creators Club subscription account( not required for development on PC, but required if you plan to deploy your creation on an Xbox 360 costs $49 for 3 months or $99 for a year )
Article Downloads
Once you have installed the above, you will can either download the related Chrome files below as one big package or individually.
- XNA.zip( ~24MB )
- XNA-Projects.zip( ~1k ) IDE Project Links
- XNA-ProjectItems.zip( ~1k ) IDE Project Item Templates
- XNA-Templates.zip( ~700K ) IDE Project Templates
- XNA-Samples.zip( ~23MB ) 4 Tutorials, Simple 3D Animation and Cameras Sample
- ChromeForXNASetup.exe (~18MB) which should automagically install all the above files in the correct locations.
Everything in one BIG download.
As separate downloads
or as an automated installer
Manual Installation of Chrome related files
- Unzip XNA-Projects.zip to *\RemObjects Software\Chrome\Bin\Templates\ChromeProjects.2005\
- Unzip XNA-ProjectItems.zip to *\RemObjects Software\Chrome\Bin\Templates\ChromeProjectItems.2005
- Unzip XNA-Templates.zip to *\RemObjects Software\Chrome\Bin\Templates\
- Unzip XNA-Samples.zip to *\RemObjects Software\Chrome\Samples\
XNA
So what is XNA, I hear you mumble into your magma heated cup of coffee?
Well it is "a set of tools based on Microsoft Visual C# 2005 Express
Edition that allow students and hobbyists to build games for both
Microsoft Windows and Xbox 360. XNA Game Studio Express also includes
the XNA Framework, which is a set of managed libraries based on the
Microsoft .NET Compact Framework 2.0 that are designed for game
development. This documentation collection contains technology
overviews, tutorials, and reference material related to XNA Game Studio
Express.". Essentially it is a comman graphics and sound API which
allows you to deploy games to both PC and XBox 360, but may include
WinCE devices in future. As Shawn
Hargreaves ( XNA Framework developer ) says : “What
we do aim for, and something we think is very important, is 'write
once, compile anywhere' ”.
At the moment, C# is the default language that you can use to target
both PC and XBox 360 via the Game Studio Express IDE ( henceforth
refered to as GSE ), which itself is an add-on to Microsoft's Visual
Studio Express IDE. So far Microsoft has only allowed C# code to be
compiled within the Visual Studio Express and GSE IDEs, but since XNA
is built upon the .NET 2.0 Compact Framework, essentially any managed
language that can target the Compact Framework should be able to handle
XNA. Due to the aforementioned restriction, using Chrome with XNA is
not as easy as it could be, but neither is it overly difficult. It just
requires little bit of manual intervention here and there. Hopefully
that will change in future and Microsoft will allow non-C# language to
work within GSE, thereby avoiding the work-arounds I mention below.
Getting Your Hands Dirty
I will be talking about using Chrome's Visual Studio 2005 add-in, but you should still be able to follow this steps if you are using the Command Line compiler because most of the tweaking takes place in the *.chrome project file. So you should be able to use the Visual Studio 2005 add-in to edit, compile and run your XNA code on your PC once the *.chrome file is correctly set up, but adding images or sound files to the project will need some manual intervention for it to work correctly. This is caused by XNA's content pipeline.The XNA content pipeline
Taken from the GSE help :
“The XNA Game Studio Express Content Pipeline lets you build
assets/resources into your game automatically from whatever file
formats they are being maintained in.
Most games use art in the form of models, meshes, sprites, textures,
effects, terrains, animations, [sounds] and so on. Such art assets can
be created in many different ways and stored in many different file
formats. They tend to change frequently in the course of game
development.
The Content Pipeline is designed to help you include such art assets in
your game easily and automatically. An artist working on a a car model
can add the resulting file to the XNA Game Studio Express game project,
assign the model a name, and choose an importer and content processor
for it.”
In a nut shell the XNA content pipeline takes your assets/resources and
converts them into a common format the XNA understands and uses that
internally. This is required because on the XBox 360 you cannot just
point the game to a particular directory to load an image or sound file
( though this is possible on Windows it is not recommended if you want
your game to be cross-platform ). Instead loading of assets/resources
is handled via the content pipeline and a virtual directory system as
such. Being forced to use the content pipeline is the main reason why
you cannot easily use the Visual Studio 2005 add-in to add files to
your project. The reason for that is the XNA content pipeline
assemblies only work within Visual Studio Express and therefore GSE.
Microsoft do plan to release a version, in future, which will work from
within Visual Studio Profressional ( maybe Orcas?? ), which
theoretically will mean that Chrome will then be able to make use of
that functionality, but I do not know when that will be available. This
is the main difference between using C# and Chrome. When using C#,
adding content to your project automagically creates the link to the
correct content pipeline processor, while with Chrome you need to
associate the content pipeline links manually. At least for now.
Differences between GSE *.csproj and Chrome *.chrome
When you add a source file to a Chrome project, via the Visual Studio 2005 IDE, the entry for it will look something like this in the .chrome file :
| .chrome code : |
<Compile Include="mySourceFile.pas"/> |
While within GSE it will look like this...
| .csproj code : |
<Compile Include="mySourceFile.cs"> |
Source files are not processed by the content
pipeline, hence why the
If you add a content file via Chrome it will more than likely not look
very different to the previous example :
| .chrome code : |
<Compile
Include="myTexture.bmp"/> |
However in GSE that same texture file added to the project would produce something like this...
| .csproj code : |
<Content Include="myTexture.bmp"> |
Notice that now the
<XNAUseContentPipeline>
tag, is now set to true. This will tell MSBuild that it should use the content importer, specified by the
- An importer takes resources ( also called assets ) saved in a particular DCC file format and converts them into objects in the XNA Game Studio Express Content DOM (document object model) that standard content processors can consume, or into some other custom form that a particular custom processor can consume.
- A processor takes one specific type of imported resource, such as a set of meshes, and compiles it into a managed code object that can be loaded and used by XNA Game Studio Express games on Windows and the Xbox 360.
The
Therefore when adding content to your Chrome project you will need to specify the content Importer and Processor for things to work correctly.
Here is a table of file types and the associated importers and processors that come with XNA by default :
| File Types | File Extensions | Importer | Processor |
| Images/Textures | *.bmp; *.tga; *.png; *.jpg; *.dds | TextureImporter | SpriteTextureProcessor |
| Fonts | *.spritefont | FontDescriptionImporter | FontDescriptionProcessor |
| FontTextureImporter | FontTextureProcessor | ||
| Models | *.fbx | FbxImporter | ModelProcessor |
| *.x | XImporter | ModelProcessor | |
| Music | *.xap | XactImporter | XactProcessor |
| Shader Effects | *.fx | EffectImporter | EffectProcessor |
NOTE : If you have a proprietry file format that you wish you use in XNA, you can create you own custom content importer and processor, but that is beyond the scope of this introduction. Refer to the GSE help or the MSDN help if you would like to do that.
Hello Chromesville
Since I have been through the heart ache of getting this all working, I have created a few project templates that at least simplify the basics of setting up an XNA Chrome project for both Windows and XBox 360. Now let's get some text on the screen. This is not an example of how to code using Chrome, so I will assume that you with programming and as such will be able to follow the code. Most of it is, I think, fairly well commented.
- In Visual Studio 2005 goto File->New Project and click on the XNA node on the left. This should list 6 XNA Game project templates on the right. See the screen-shot below.
- Select XNA Windows Game from the right and create the project. Now do the same thing again but this time select XNA Xbox 360 Game, but this time once the project is created, find the XNAXBox360Game1.chrome project file and move it to the same directory as the XNAWinGame1.chrome project file.
- Now press F5 to makes sure that it compiles and runs, thereby confirming that everything is set up correctly. If all goes well you should see the screen shot below.
- In order to display text on the screen we need to add a SpriteFont to our project. I suggest keeping Content such as resources under a "Content" folder so that they are not mixed in with source files ( see below ). Once you have created the Content folder, right click on it, got to Add->New Item... and select "SpriteFont" from the item list and add it and then save the project.

For the benefit of command line users the full Chrome project is available for download and the main game code is listed below.We'll come back to the Xbox project later on. For now ensure the Windows project is loaded.

As mentioned earlier if you were using GSE it would automagically associate this XNA resource to the correct content pipeline for importing and processing. We will need to delve into the .chrome file ensure that it is processed correctly. Notice that if you look inside the .spritefont file it is an XML file describing various attributes of the font we are about to use. Also note that the FontName tag defaults to Tahoma...
| .spritefont Code : |
<FontName>Tahoma</FontName> |
- Open the project's .chrome file ( probably XNAWinGame1.chrome ) and search for .spritefont. It will probably look like this
- Now change it so that it looks like this...
- Now back in IDE make sure you have the latest .chrome project loaded. Open up the game.pas file and add the following code to the private declaration ...
- Now we need to load our font into memory so that we can use it later on to draw onto the screen. Find the LoadGraphicsContent method and add the following code....
- Now find the Draw method and ensure it looks like this...
- Now compile and run the project and you should see "Hello Chromesville" displayed at X pixel position 50 and Y pixel position 100, on the screen
But you can change this name to any valid True Type Font name.
| .chrome Code : |
<Content
Include="SpriteFont1.spritefont"
/> |
| .chrome Code : |
<Content
Include="SpriteFont1.spritefont"> |
then save the changes. This now tells MSBuild to use the respective Importer and Processor to generate an XNA compatible verison of this font.
| Chrome Code: |
// Enables a group of sprites
to be drawn using the same settings//
Used to draw the text on the screenTahomaFont : SpriteFont; |
| Chrome Code: |
|
if (
loadAllContent ) then begin // instantiate our sprite batch object
// Load the sprite font we added
TahomaFont :=
content.Load<SpriteFont>('Content/SpriteFont1'); |
Notice that the content.Load method requires that you specify the generic type you are attempting to load. In this case it is <SpriteFont>. If you were loading a texture it would be <Texture2D> and a model would be <Model> and so on.
| Chrome Code: |
//
Clear the back ground to your choice of color//
Prepares the graphics device for drawing sprites// Draw some text on the
screen at postition 50, 100 in white//
Flushes the sprite bacth and restores the device state to what it was before
Begin was called//
Call the inherited Draw method inherited Draw( aGameTime );
|
So there you have it, 10 relatively easy steps in getting some text on an XNA screen. Once the content pipeline issue is addressed in a future release of Visual Studio, steps 5 and 6 will be taken care of automatically and it will be just a case of fleshing out your game logic and game play just as you would with C#. Now the same basic technique used above to draw the Font could also be used to draw texture ( images to those of you who have not written games before ), but instead of using a SpriteFont Object, you would use a Texture2D
Handling Input and Basic animation
Let's add some quick input handling and basic animation in the form of an in game main menu.
- Add the following private variable declarations
- The following code could be added to the constructor or the overridden Initialize method. Initialize is called after the Game and GraphicsDevice are created, but before LoadGraphicsContent. I personally would probably put it in the Initialize as the List has already been constructed.
- Now lets Draw the menu items with some animation. ( code taken from Microsoft's GameStateManagement sample and modified ). Change the previous Draw method to look like this.
- Compile and Run the application and you should see a pulsating menu item. Here's a screen shot, though of course you won' notice the pulsating ;-).
| Chrome Code: |
|
//
Our List of Menu Items menuItems : List<string> := new List<string>(); // What is the currently selected item selectedEntry : integer := 0; // Previous Input States previousKeyboardState : KeyboardState; previousGamePadState : GamePadState; // Variables to keep track of how we are transitioning transitionOn : boolean := true; transitionPosition : Single := 1; // Indicates how long the screen takes to transition on when it is activated. transitionOnTime : TimeSpan := TimeSpan.FromSeconds(1.5); |
Those of you coming from a standard Object Pascal background may not be familiar with generics, but that is exactly what we are using when we declare the menuItems variable as being of type " List<string> := new List<string>();". It's a strongly typed list of strings.
The other thing you will notice is that Chrome allows us to instantiate our varitable right where we declare it. You could of course do this in the constructor, but at least Chrome gives you both options.
| Chrome Code: |
|
menuItems.Add( 'Play' );
menuItems.Add( 'Options' ); menuItems.Add( 'Credits' ); menuItems.Add( 'Exit' ); |
| Chrome Code: |
| const
overlap : single = 0.3; var position : Vector2; transitionOffset : single; i : integer; time : single; colour : Color; scale : single; pulsate : single; numEntries : integer; origin : Vector2; begin position := new Vector2( 100, 150 ); // Make the menu slide into place during transitions, using a // power curve to make things look more interesting (this makes // the movement slow down as it nears the end). transitionOffset := Math.Pow( transitionPosition, 2 ); if ( transitionOn ) then position.X := position.X - transitionOffset * 256 else position.X := position.X + transitionOffset * 512; // Clear the back ground to your colour of choice graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // Draw each menu entry in turn. SpriteBatch.Begin; for i := 0 to menuItems.Count - 1 do begin if ( i = selectedEntry ) then begin // The selected entry is yellow, and has an animating size. time := aGameTime.TotalGameTime.TotalSeconds; pulsate := Math.Sin( time * 7 ) + 1; colour := Color.Yellow; scale := 1 + pulsate * 0.05; end else begin // Other entries are white. colour := Color.White; scale := 1; end; numEntries := menuItems.Count; transitionOffset := MathHelper.Clamp( ( TransitionPosition - ( 1 - overlap ) * i / numEntries ) / overlap, 0, 1 ); position.X := MathHelper.SmoothStep( 100, -200, transitionOffset ); scale := scale + MathHelper.SmoothStep( 0, 4, transitionOffset ); // Modify the alpha to fade text. colour := new Color( colour.R, colour.G, colour.B, byte( ( 1 - transitionOffset ) * 255 ) ); // Draw text, centered on the middle of each line. origin := new Vector2( 0.0, single( TahomaFont.LineSpacing / 2 ) ); SpriteBatch.DrawString( TahomaFont, menuItems[ i ], position, colour, 0, origin, scale, SpriteEffects.None, 0 ); // LineSpacing position.Y := position.Y + TahomaFont.LineSpacing; end; SpriteBatch.End; inherited Draw( aGameTime ); |

- Now lets add the Input code. Input is handled by polling for the GamePad, Keyboard or Mouse State objects, which each return a respective structure. NOTE : As it is not currently possible to use the Mouse on an Xbox 360 ( only on Windows ) we will not be testing for it in this example. Change the UpdateInput method
- Compile and Run the application and you should now be able to use either the Up or Down arrows to navigate the menu system or the Xbox 360 game pad
You should hopefully notice that when the demo starts the the text flys in from behind you and then places it self in it's correct position.
| Chrome Code: |
| var
currentGamePadState : GamePadState; currentKeyboardState : KeyboardState; menuUpGamePad, menuDownGamePad, menuUpKeyboard, menuDownKeyboard : Boolean; begin //get the gamepad state currentGamePadState := GamePad.GetState( PlayerIndex.One ); if ( currentGamePadState.IsConnected ) then begin // Allows the default game to exit on Xbox 360 and Windows using a Gamepad if ( currentGamePadState.Buttons.Back = ButtonState.Pressed ) then Self.Exit; menuUpGamePad := ((currentGamePadState.DPad.Up = ButtonState.Pressed) and (previousGamePadState.DPad.Up = ButtonState.Released)) or ((currentGamePadState.ThumbSticks.Left.Y > 0) and (previousGamePadState.ThumbSticks.Left.Y <= 0)); menuDownGamePad := (( currentGamePadState.DPad.Down = ButtonState.Pressed) and (previousGamePadState.DPad.Down = ButtonState.Released)) or ((currentGamePadState.ThumbSticks.Left.Y <0>= 0)); end; // get the Keyboard state currentKeyboardState := Keyboard.GetState(); if ( currentKeyboardState <> nil ) then begin // Allows the default game to exit on Xbox 360 and Windows using a Keyboard if ( currentKeyboardState.IsKeyDown( Keys.Escape ) then Self.Exit; menuUpKeyboard := (CurrentKeyboardState.IsKeyDown(Keys.Up) and previousKeyboardState.IsKeyUp(Keys.Up)); menuDownKeyboard := (CurrentKeyboardState.IsKeyDown(Keys.Down) and previousKeyboardState.IsKeyUp(Keys.Down)); end; if ( menuUpGamePad or menuUpKeyboard ) then begin selectedEntry := selectedEntry - 1; if selectedEntry < 0 then selectedEntry := menuItems.Count - 1; end; if ( menuDownGamePad or menuDownKeyboard ) then begin selectedEntry := selectedEntry + 1; if selectedEntry > menuItems.Count - 1 then selectedEntry := 0; end; // keep track of our previous input states previousGamePadState := currentGamePadState; previousKeyboardState := currentKeyboardState; end; |
Lets see it on an Xbox 360
As mentioned earlier, in order to deploy to an Xbox 360 you need to
have a subscribtion to the XNA creators club. You will then need to
have both your PC and your Xbox 360 on the same network. The process of
getting the 2 machines talking to each other is beyond the scope of
this article, but you can watch this
article and video which will walk you though the whole
process. Once you have done that, continue below.
Assuming we have not introduced any Windows specific code, compiling
the code for it to work on an Xbox 360 is fairly straight forward. All
you need to do is to ensure that any resources or source code units
that you added to the Windows project are also added to the Xbox 360
project. Open the Xbox .chrome project file ( probably ) using notepad
and add...
| .chrome Code : |
<Content
Include="SpriteFont1.spritefont"> |
close to where the other source files ( *.pas ) are declared. Once you have done that, close and save the file and open up the Xbox 360 .chrome project in Visual Studio and compile it.
Those of you using the command line compiler should find that
the zip file already contains batch files that compile
Now yet again we are faced with the diffence between developing with GSE and Visual Studio. In GSE when you compile and run an Xbox 360 project, assuming everything is set up correctly, it automatically attempts to connect to your Xbox and it will then upload the game and it's content to the Xbox. With Chrome we have to create a .ccgame package and then use GSE to upload the game package to the console. To achieve this with Chrome we will need to use the command line and thankfully Microsoft anticipated this.
- Go to Start->Microsoft Game Studio Express->Tools and select XNA Game Studio Express Command Prompt. This will set up the correct path to access the XNA Package tool we will use shortly.
- Now via this command line prompt navigate to the directory where your game chrome projects exist.
- At the command line type xnapack XNAXboxGame.exe Xbox360 . This will create a .ccgame package, which is essentially a compressed archive of your executable and it's associated content.
- Now from Explorer, double click on the newly created .ccgame package. Due to it's file association, this should launch Game Studio Express and it will immediately try and connect to your Xbox 360 and then upload and unpack the game and it's resources onto your Xbox.
- Play with the demo on your Xbox
The advantage of distrubuting Xbox games via a .ccgame package is that the recipient is not able to look at your code directly. This can also be done for Windows XNA games as well. Though note that using reflection someone could potentially reverse engineer the executable, but that is true of any .NET executable.
Here is a screen shot of what it looks like on the Xbox 360 Blade before you launch it...

[ Click to see full version ]
Conclusion
As you can see, getting things working on Windows and then on an Xbox 360 is relatively simple once the content pipeline issues are sorted out. If you can determine what content you need up front, even it it's just place holder textures, sounds and models, then using the Visual Studio add-in is easier. It just requires more forward planning than usual to minimise disruptions later on. This is a very small introduction into the process of creating games using Chrome and the XNA api. I would suggest you look at and play with the sample code that I have put together so far to see how easy it is to create both 2D and 3D games using this new API. Another invaluable resource is the XNA help file and also the XNA Creators forum.
Chrome Project Listing
Game ( Game.pas )
| Chrome Code: |
namespace XNAWinGame1; interface uses System, Microsoft.Xna.Framework, Microsoft.Xna.Framework.Content, Microsoft.Xna.Framework.Graphics, Microsoft.Xna.Framework.Input; type TXNAWinGame1 = class( Microsoft.Xna.Framework.Game ) private // these are the size of the output window, ignored on Xbox 360 preferredWindowWidth : integer; preferredWindowHeight : integer; graphics : GraphicsDeviceManager; content : ContentManager; // Enables a group of sprites to be drawn using the same settings. spriteBatch : SpriteBatch; // Used to draw the text on the screen. TahomaFont : SpriteFont; // Our List of Menu Items menuItems : List<string> := new List<string>(); // What is the currently selected item selectedEntry : integer := 0; // Previous Input States previousKeyboardState : KeyboardState; previousGamePadState : GamePadState; // transitionOn : boolean := true; transitionPosition : Single := 1; // Indicates how long the screen takes to transition on when it is activated. transitionOnTime : TimeSpan := TimeSpan.FromSeconds(1.5); protected method Initialize; override; method Update( aGameTime : Gametime ); override; method Draw( aGameTime : Gametime ); override; method LoadGraphicsContent( loadAllContent : boolean ); override; method UnloadGraphicsContent( unloadAllContent : boolean ); override; method UpdateInput( aGameTime : Gametime ); method UpdateTransition( aGameTime : GameTime ; aTime : TimeSpan; aDirection : integer ) : boolean; public constructor; end; implementation constructor TXNAWinGame1; begin inherited; preferredWindowWidth := 853; preferredWindowHeight := 480; Self.graphics := new Microsoft.Xna.Framework.GraphicsDeviceManager( Self ); Self.graphics.PreferredBackBufferWidth := preferredWindowWidth; Self.graphics.PreferredBackBufferHeight := preferredWindowHeight; content := new ContentManager( Services ); end; method TXNAWinGame1.Draw( aGameTime : Gametime ); const overlap : single = 0.3; var position : Vector2; transitionOffset : single; i : integer; time : single; colour : Color; scale : single; pulsate : single; numEntries : integer; origin : Vector2; begin position := new Vector2( 100, 150 ); // Make the menu slide into place during transitions, using a // power curve to make things look more interesting (this makes // the movement slow down as it nears the end). transitionOffset := Math.Pow( transitionPosition, 2 ); if ( transitionOn ) then position.X := position.X - transitionOffset * 256 else position.X := position.X + transitionOffset * 512; // Clear the back ground to your colour of choice graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // Draw each menu entry in turn. SpriteBatch.Begin; for i := 0 to menuItems.Count - 1 do begin if ( i = selectedEntry ) then begin // The selected entry is yellow, and has an animating size. time := aGameTime.TotalGameTime.TotalSeconds; pulsate := Math.Sin( time * 7 ) + 1; colour := Color.Yellow; scale := 1 + pulsate * 0.05; end else begin // Other entries are white. colour := Color.White; scale := 1; end; numEntries := menuItems.Count; transitionOffset := MathHelper.Clamp( ( TransitionPosition - ( 1 - overlap ) * i / numEntries ) / overlap, 0, 1 ); position.X := MathHelper.SmoothStep( 100, -200, transitionOffset ); scale := scale + MathHelper.SmoothStep( 0, 4, transitionOffset ); // Modify the alpha to fade text. colour := new Color( colour.R, colour.G, colour.B, byte( ( 1 - transitionOffset ) * 255 ) ); // Draw text, centered on the middle of each line. origin := new Vector2( 0.0, single( TahomaFont.LineSpacing / 2 ) ); SpriteBatch.DrawString( TahomaFont, menuItems[ i ], position, colour, 0, origin, scale, SpriteEffects.None, 0 ); // LineSpacing position.Y := position.Y + TahomaFont.LineSpacing; end; SpriteBatch.End; inherited Draw( aGameTime ); end; method TXNAWinGame1.Initialize; begin // Your Initialize Code here menuItems.Add( 'Play' ); menuItems.Add( 'Options' ); menuItems.Add( 'Credits' ); menuItems.Add( 'Exit' ); inherited; end; method TXNAWinGame1.LoadGraphicsContent( loadAllContent : boolean ); begin if ( loadAllContent ) then begin // TODO: Load any ResourceManagementMode.Automatic content spriteBatch := new SpriteBatch(graphics.GraphicsDevice); TahomaFont := content.Load<SpriteFont>('Content\SpriteFont1'); end; // TODO: Load any ResourceManagementMode.Manual content end; method TXNAWinGame1.UnloadGraphicsContent( unloadAllContent : boolean ); begin if ( unloadAllContent ) then begin content.Unload; end; end; method TXNAWinGame1.Update( aGameTime : Gametime ); begin //Get some input UpdateInput( aGameTime); // Your Update Code here transitionOn := UpdateTransition( aGameTime, transitionOnTime, -1 ); inherited Update( aGameTime); end; method TXNAWinGame1.UpdateInput( aGameTime : Gametime ); var currentGamePadState : GamePadState; currentKeyboardState : KeyboardState; menuUpGamePad, menuDownGamePad, menuUpKeyboard, menuDownKeyboard : Boolean; begin //get the gamepad state currentGamePadState := GamePad.GetState( PlayerIndex.One ); if ( currentGamePadState.IsConnected ) then begin // Allows the default game to exit on Xbox 360 and Windows using a Gamepad if ( currentGamePadState.Buttons.Back = ButtonState.Pressed ) then Self.Exit; menuUpGamePad := ((currentGamePadState.DPad.Up = ButtonState.Pressed) and (previousGamePadState.DPad.Up = ButtonState.Released)) or ((currentGamePadState.ThumbSticks.Left.Y > 0) and (previousGamePadState.ThumbSticks.Left.Y <= 0)); menuDownGamePad := (( currentGamePadState.DPad.Down = ButtonState.Pressed) and (previousGamePadState.DPad.Down = ButtonState.Released)) or ((currentGamePadState.ThumbSticks.Left.Y <0>= 0)); end; // get the Keyboard state currentKeyboardState := Keyboard.GetState(); if ( currentKeyboardState <> nil ) then begin // Allows the default game to exit on Xbox 360 and Windows using a Keyboard if ( ( currentKeyboardState <> nil ) and ( currentKeyboardState.IsKeyDown( Keys.Escape ) ) ) then Self.Exit; menuUpKeyboard := (CurrentKeyboardState.IsKeyDown(Keys.Up) and previousKeyboardState.IsKeyUp(Keys.Up)); menuDownKeyboard := (CurrentKeyboardState.IsKeyDown(Keys.Down) and previousKeyboardState.IsKeyUp(Keys.Down)); end; if ( menuUpGamePad or menuUpKeyboard ) then begin selectedEntry := selectedEntry - 1; if selectedEntry < 0 then selectedEntry := menuItems.Count - 1; end; if ( menuDownGamePad or menuDownKeyboard ) then begin selectedEntry := selectedEntry + 1; if selectedEntry > menuItems.Count - 1 then selectedEntry := 0; end; // keep track of our previous input states previousGamePadState := currentGamePadState; previousKeyboardState := currentKeyboardState; end; /// <summary> /// Helper for updating the screen transition position. /// </summary> method TXNAWinGame1.UpdateTransition( aGameTime : GameTime ; aTime : TimeSpan; aDirection : integer ) : boolean; var transitionDelta : single; // How much should we move by? begin // Still busy transitioning. result := true; if (aTime = TimeSpan.Zero) then transitionDelta := 1 else transitionDelta := (aGameTime.ElapsedGameTime.TotalMilliseconds / aTime.TotalMilliseconds); // Update the transition position. transitionPosition := transitionPosition + transitionDelta * aDirection; // Did we reach the end of the transition? if ((transitionPosition <=0 ) or ( transitionPosition >= 1)) then begin transitionPosition := MathHelper.Clamp(transitionPosition, 0, 1); result := false; end; end; end. |
Essential XNA Links
- MSDN XNA page
- XNA home page
- XNA Creators - packed full of tutorials, articles and sample code ( albeit C# ) to get you started
- XNA Forums - fairly friendly forum to ask questions. Note : 99.99% of posters on here speak C#
- Shawn Hargreaves blog - Framework developer's blog with lots of tips
- XBox Live Arcade submission details
- The home of Chrome game development
- Forums to discuss all things chrome and game related

