📜 ⬆️ ⬇️

Introduction to developing games for Windows 8 using XNA and MonoGame

As you probably noticed, a number of materials appeared in our blog that reveal the basics of creating WinRT applications for Windows 8. In this series of articles you will learn how you can create WinRT gaming applications in C #.




If you were interested in creating games for WinRT, then you probably know that the only way Visual Studio 2012 offers is DirectX. This is a very powerful technology, requires knowledge of C ++, and is generally rather a low-level API for working with intensive graphics, its study takes time. If you are taking the first steps, then it is much easier to use higher-level libraries. But due to the youth of the platform while there are not too many game and physical engines, nevertheless their list is updated. Here are some of them:
')


The last two - SharpDX and MonoGame deserve special attention. SharpDX is a wrapper for DirectX and allows you to work with this technology from .NET and also supports WinRT. Even more interesting is that MonoGame - the cross-platform port of the XNA library also works on WinRT.
XNA is a popular library for Windows, Xbox360 and Windows Phone, through which thousands of games are created. Due to the fact that MonoGame has not changed the main areas of visibility, the transfer from XNA does not require large changes in the existing application code.

Configuring the environment



To start developing games for WinRT on MonoGame, you need to configure Visual Studio 2012 and install the necessary components on your computer to compile the project. Of course, you can download the already compiled versions of SharpDX and MonoGame, but it is better to download the source files of these libraries, collect them locally. This will allow you to further perform detailed debugging and increase your understanding of how MonoGame works.

If you decide to go easy, here are the links: sharpdx.org/download (or in the Package Manager console type Install-Package SharpDX) and monogame.codeplex.com/releases/view/96421

If you want to collect everything yourself
:
Create a directory in which we will have the source files of libraries. For example D:\Gamedev

  1. Install Git: msysgit.github.com
  2. Run Git Bash (git console) and go to the D:\Gamedev
  3. Get the SharpDX sources: git clone github.com/sharpdx/SharpDX
  4. Get the MonoGame source: git clone github.com/mono/MonoGame
  5. Launch Visual Studio 2012 x86 Native Command Line Tools (search for the word Native in the start screen)
  6. Go to the cd D:\Gamedev\SharpDX and command the MakeSharpDX.cmd win8 build about 3-4 minutes you will have SharpDX assembled in the D:\gamedev\sharpdx\Bin\Standard-winrt\
  7. Now we need to configure and compile the MonoGame project. To do this, using Visual Studio 2012, open the D:\gamedev\MonoGame\MonoGame.Framework.Windows8.sln project. Now MonoGame does not know where the SharpDX assemblies are located and shows errors in the references:

  8. In the project properties (context menu on the project, Properties ) in the Reference Paths section specify the path D:\gamedev\sharpdx\Bin\Standard-winrt\
  9. We compile the project, after which you will have the assembly D:\gamedev\MonoGame\MonoGame.Framework\bin\Release\MonoGame.Framework.Windows8.dll
  10. Install the MonoGame project templates in Visual Studio. To do this, copy the files from the directory D:\gamedev\MonoGame\ProjectTemplates\VisualStudio2012\ to the directory C:\Users\USERNAME\Documents\Visual Studio 2012\Templates\ProjectTemplates\Visual C#\Mono\ and then restart Visual Studio and create on the base This template project:

  11. Do not forget to also specify the Reference Paths for the newly created project D:\gamedev\MonoGame\MonoGame.Framework\bin\Release\


Then we compile and run the project. Congratulations, you have created your first MonoGame application for WindowsRT. Although it looks quite simple for now, a clean blue screen, since it does nothing and draws nothing but the background.
  public class Game1 : Game { GraphicsDeviceManager _graphics; SpriteBatch _spriteBatch; public Game1() { _graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } /// protected override void Initialize() { base.Initialize(); } ///    protected override void LoadContent() { _spriteBatch = new SpriteBatch(GraphicsDevice); //Content.Load<SpriteFont>... } protected override void UnloadContent() { } ///   protected override void Update(GameTime gameTime) { base.Update(gameTime); } ///   protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); base.Draw(gameTime); } } 


What's next



If you are not at all familiar with XNA, then try searching the Internet for a keyword XNA tutorial. There are many articles that explain the basics of programming graphics based on this technology. You can also download an example of the CastleX platform that runs on Windows 8 .



This is a classic platformer in which the player jumps, climbs and collects some necessary things on the plot, at the same time trying to protect themselves from all sorts of dangers.
While this game is not fully supported by Windows 8 as there are no important components. Made only minimal changes compared to Windows, which allowed to run this application under WinRT.
The Assets directory of Castle X contains a number of files needed for work — these are graphics, sound effects, and levels. Many of these files have an unusual XNB extension.



One of the difficulties that will inevitably be encountered when developing games for MonoGame is the lack of support for the Content Pipeline. In XNA 4.0 and the add-on for Visual Studio 2010, there was a set of extensions that packed the game's graphic and sound resources into a special XNB data format. There is no such extension in Visual Studio 2012, so the recommended way is to additionally install Visual Studio 2010 and XNA Game Studio 4.0 Refresh . Also, be sure to install the update for XNA Runtime under the Windows 8 Desktop platform.
Then you can collect resources in VS2010 or use a third-party utility XNA Content Compiler

How is the game CastleX


The program logic of the game begins with the concept of the displayed screens. There are several types of screens (their classes are in the folder / View / Screens /), such as a splash screen, a demo playback screen, a level screen, a game menu screen, and so on. Screens are managed by a special class ScreenManager inherited from the type DrawableGameComponent that is registered when the application starts.

 Components.Add(screenManager); 


In the Update method of the main class of the game, the state of the screen manager is changed, which, depending on the processed events, affects what the player sees.
ScreenManager itself displays itself in the Draw method, the logic of which is evident from the code:

  public override void Draw(GameTime gameTime) { ViewPort = GraphicsDevice.Viewport; foreach (GameScreen screen in screens) { if (screen.ScreenState == ScreenState.Hidden) continue; try { SpriteBatch.Begin(); } catch { } screen.Draw(gameTime, SpriteBatch); try { SpriteBatch.End(); } catch { } } } 


The screens themselves, in turn, deal with the processing of user input in the HandleInput method and their own display, depending on the events that have been processed.

Game level screen



The main screen of the game level contains the “current level” object in the level variable depending on where the player is. Levels are dynamically loaded. In the Draw method of the screen itself, the call is already transferred to the Draw method of the level itself ( leve.Draw ) and also displays an information panel with the number of lives collected by the keys - DrawHud(gameTime, spriteBatch);

Game level


The level itself is an array of Tile objects that can be in different layers, indicating the order in which they are displayed (which is on top of that):

  private Tile[,] tiles; private Layer[] layers; 


Objects Tile in turn, can be anything - a door, a piece of brick wall, water. Tiles can also be transparent and in fact such tiles are triggers, since the tile handles collisions along with everything else - an important element of the game:

  public enum TileCollision { /// <summary> ///  ,      /// </summary> Passable = 0, /// <summary> ///        /// </summary> Impassable = 1, /// <summary> ///  ,          /// </summary> Platform = 2, /// <summary> /// ,   /// </summary> Ladder = 3 } 


The tile also has a texture - actually what will be displayed on the screen, loaded via the content.Load<>() method.
Also at the level there are other objects that interact with the tiles and with themselves - animated tiles, player character, monsters, keys, coins.

The level itself is entirely encoded in a text file. Different symbols mean different types of tiles and objects in their initial state:

####################
X4001.................!..
.x2..EG0102...............!X1003.
\
##L.######..########
##L.........#CCCCCCX3003.
##L.......N..#CCCCCCx5..
##L.......EG0102..########
##L....N..#####......
##L...EG0102.......#.....X2003.
##L..####....#....x4..
##L..........#W....##
##L...N....N...#....##
##L...EG0102......i#www###
#############www####
wwwwwwwwwwwwwww#####
X6001wwwwwwwwwwwwwww#####
wx6wwwwwwwwwwwww######
2!2!2!2!2!2!2!2!2!2!
tit.Platforms and ghosts
des.Face your first enemies inside the castle!
Layer2.Bricks.Bricks.Bricks


For example, L is a ladder, E is a dangerous character, C is a coin,! - recess tile, and so on. All codes can be found in the LoadTile(char tileType, int x, int y, String code) method LoadTile(char tileType, int x, int y, String code)

Processing of their state and position of objects is carried out in the Level::Update method. For example, in this method, pressing the key to the left can be processed, the player’s object will move to the tile of the moving platform, a collision with this tile will be processed (the properties of the player’s object will change)
 private void UpdateMovingItems(GameTime gameTime) { if (MovingItemsAreActive) { for (int i = 0; i < MovingItems.Count; ++i) { MovingItem movingItem = MovingItems[i]; movingItem.Update(gameTime); if (movingItem.PlayerIsOn) { //         screenManager.Player.Position += movingItem.Velocity; } } } } 


There is no special physics engine in the game, objects that need to be calculated by physics, there are methods that affect their properties (coordinates, color, etc.). For example, how is the position of an object that falls:

 private void ApplyPhysics(GameTime gameTime) { float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; if (isFalling) { velocity.Y = MathHelper.Clamp(velocity.Y + GravityAcceleration * elapsed, -MaxFallSpeed, MaxFallSpeed); Position += velocity * elapsed; } } 


After all the event handling has been performed and the properties of the objects have changed, there comes a time to display the level in the Draw() method, which simply draws all the objects that exist on the level:

 DrawTiles(spriteBatch); foreach (Item item in items) item.Draw(gameTime, spriteBatch); foreach (MultipleStateItem item in multipleStateItems) item.Draw(gameTime, spriteBatch); foreach (AnimatedItem item in animatedItems) item.Draw(gameTime, spriteBatch); foreach (FallingTile FallingTile in FallingTiles) FallingTile.Draw(gameTime, spriteBatch); foreach (Exit exit in exits) exit.Draw(gameTime, spriteBatch); foreach (Boss boss in bosses) boss.Draw(gameTime, spriteBatch); 


In general, the code of the game and its logic are fairly obvious. Spending quite a bit of time you can figure out how everything works.

What's next



Since the game code, in comparison with the original version, is changed very slightly, and only in order to ensure compatibility with WinRT and MonoGame, this application requires additional changes:



These components will be reviewed and refined in the next post.
Link to the project running in Windows 8 and the original game - in case you decide to change XNB files (graphics and sounds).

Source: https://habr.com/ru/post/164217/


All Articles