• Go DevMENTAL

    Introducing XNA: A tri-platform game development framework – Part 3

    • 0 Comments

    Introducing XNA: A tri-platform game development framework – Part 3

     

    In parts 1 and 2 of this series, we setup a multiplatform XNA solution that deploys to the PC, Xbox 360 and Windows Phone 7 devices seamlessly. In this 3rd and final part of the series, we’ll implement platform-specific behavior within the same codebase. And we’ll finally make our ship do something!

     

    Conditional compilation symbols

    When you created the three projects, Visual Studio set project-specific Conditional compilation symbols. These flags can be used with preprocessing directives to create conditions in the compilation process.

     

    To view and edit these symbols, Right-click on a game project, select Properties, and go to the Build tab.

     

     

     

    By default, Visual Studio added the WINDOWS symbol for the Windows project, XBOX and XBOX360 symbols for the Xbox project and WINDOWS_PHONE symbol the Windows Phone 7 project. In this article, we’ll use these to set certain platform-specific properties and capture hardware-specific input.

     

    Settings up graphics properties

    We’ll use the GraphicsDeviceManager to setup the screen properties for each platform. In the Initialize() method of the Game1 class, add the three #if preprocessor directives:

                                                        

    protected override void Initialize()

                       {

                         // TODO: Add your initialization logic here

     

    #if WINDOWS

     

    #endif

     

    #if XBOX

     

    #endif

     

    #if WINDOWS_PHONE

     

    #endif

     

                                 base.Initialize();

                       }

     

    For the purpose of this tutorial, we’ll run all three platform builds in full-screen. However, we’ll need to set an appropriate resolution for each one:

     

    protected override void Initialize()

                       {

                                 // TODO: Add your initialization logic here

     

    #if WINDOWS

                                 graphics.PreferredBackBufferWidth = GraphicsDevice.DisplayMode.Width;

                                 graphics.PreferredBackBufferHeight = GraphicsDevice.DisplayMode.Height;

    #endif

     

    #if XBOX

                                 graphics.PreferredBackBufferWidth = 1280;

                                 graphics.PreferredBackBufferHeight = 720;

    #endif

     

    #if WINDOWS_PHONE

                                 graphics.PreferredBackBufferWidth = 800;

                                 graphics.PreferredBackBufferHeight = 480;

    #endif

     

                                 graphics.IsFullScreen = true;

                                 graphics.ApplyChanges();

     

                                 base.Initialize();

                       }

     

    For the PC, we retrieve the desktop resolution and set our back-buffer (the viewport) to match it. For the Xbox, we use its native 720p high-definition output by setting the back-buffer bounds to 1280 by 720 pixels. For the phone, we simply set the resolution to the maximum resolution dictated by the Windows Phone 7 platform. Finally, we set the IsFullScreen property to true and call the ApplyChanges() method to commit the above changes. Note that these 2 lines of code are outside of any platform-specific preprocessor directives, since we want these two things to apply to all three of our builds.

     

    When building the solution, depending on the target project, each flag in the processing directive will be checked. If it is set, the code inside the #if-#endif pair will be built. This means that you must be careful about fragmenting your code. For example, if you declare a field in a #if-#endif directive, but assign to it outside of the same condition, you will get an error for a specific platform (or a specific condition) about a missing declaration.

     

    At this point, if you were to run the project on any platform, the resolution will be automatically adjusted and you should see the ship in platform’s native full-screen resolution, without any scaling or stretching!

    Note: IsFullScreen is not strictly needed for the Xbox version, as all XNA games on the Xbox run in full-screen by default.

     

     

    Capturing platform-specific input

    Let’s make things a bit more interesting and challenging, by rotating the ship with a platform specific input device. On the PC, the input comes primarily from the mouse/keyboard combination; on the Xbox 360 from the Xbox controller; on the Windows Phone 7 from the touch panel. The Xbox controller can also be used as a gamepad in Windows. A keyboard can be used on the Xbox 360, but you should avoid this scenario, since most Xbox 360 owners don’t have a keyboard connected to their console. Windows Phone 7 devices also have additional buttons such as the “back” button, which can be read in XNA.

     

    First, we’ll add platform independent code that will rotate the ship around the y-axis (also known as “Yaw”). Add a float to hold the yaw angle:

     

    public class Game1 : Microsoft.Xna.Framework.Game

              {

                       ...

     

                       float yawAngle = 0.0f;

     

                       public Game1()

                       {

                                 ...

                       }

     

                       ...

    }

     

    To rotate the ship, we’ll set the world matrix to the rotation about the y-axis matrix that is constructed with the yawAngle, which we set with an input device.

     

    protected override void Update(GameTime gameTime)

                       {

                                 ...

     

                                 world = Matrix.CreateRotationY(yawAngle);

                                

                                 base.Update(gameTime);

                       }

     

    Next we will capture input from the keyboard to rotate the ship with the arrow keys. Remember that keyboard input should be captured on Windows only; we check if WINDOWS is set.

     

    protected override void Update(GameTime gameTime)

                       {

                       ...

     

    #if WINDOWS

                                 if (Keyboard.GetState().IsKeyDown(Keys.Left))

                                          yawAngle += 0.05f;

     

                                 if (Keyboard.GetState().IsKeyDown(Keys.Right))

                                          yawAngle -= 0.05f;

    #endif

     

    ...

                       }

     

    We’ll use the Xbox controller’s left thumb-stick to rotate the ship left and right as well.

     

     

    protected override void Update(GameTime gameTime)

                       {

                       ...

     

    #if XBOX

                                 yawAngle += GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X;

    #endif

     

    ...

                       }

     

    If you were to test this code now, you’ll notice a little quirk. On Windows we’re incrementing/decrementing the angle by a constant of 0.05 radians every update. But on the Xbox the angle depends on the X position of the thumb-stick, which can result in a large value. The easiest solution is to simply dampen the value by a constant:

     

    yawAngle += GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X * 0.05f;

     

    On Windows Phone 7, input is not as simple as keyboard strokes and thumb-stick positions. The phone captures input by recording touches. Touch points and displacement between them can be determined from raw touch data. Common higher level motions – known as gestures ­– are already provided by the XNA framework, so you don’t have to write your own. We’ll use the horizontal drag gesture to rotate the ship. Before we go any further, however, we need to include a reference to the Microsoft.Xna.Framework.Input.Touch assembly. It wasn’t included because our Windows Phone 7 project was created from the Windows project.

     

    Expand the Windows Phone Copy of XNAIntro project, Right-click on References and select Add Reference. Under the .NET tab select Microsoft.Xna.Framework.Input.Touch.

     

     

     

    We can now use the namespace in Game1. Since it is to be used for the phone only, be sure to place it in a proper compilation condition:

     

    using Microsoft.Xna.Framework;

    using Microsoft.Xna.Framework.Audio;

    using Microsoft.Xna.Framework.Content;

    using Microsoft.Xna.Framework.GamerServices;

    using Microsoft.Xna.Framework.Graphics;

    using Microsoft.Xna.Framework.Input;

    using Microsoft.Xna.Framework.Media;

     

    #if WINDOWS_PHONE

    using Microsoft.Xna.Framework.Input.Touch;

    #endif

     

    namespace XNAIntro

    {

              /// <summary>

              /// This is the main type for your game

              /// </summary>

              public class Game1 : Microsoft.Xna.Framework.Game

              {

                       ...

              }

    }

     

    Before we can detect the horizontal drag gesture, we need to let the touch panel know that this gesture needs to be enabled.

     

    protected override void Initialize()

                       {

                                 ...

     

    #if WINDOWS_PHONE

                                

    ...

     

                                 TouchPanel.EnabledGestures = GestureType.HorizontalDrag;

    #endif

     

                                 ...

                       }

     

    Once the gesture is enabled, you can access the gesture with the TouchPanel.ReadGesture() method:

     

    protected override void Update(GameTime gameTime)

                       {

                                 ...

     

    #if WINDOWS_PHONE

                                 while (TouchPanel.IsGestureAvailable)

                                 {

                                          GestureSample gesture = TouchPanel.ReadGesture();

     

                                          yawAngle += gesture.Delta.X * 0.005f;

                                 }

    #endif

     

                                 ...

                       }

     

    We first check whether or not a gesture is available with the TouchPanel.IsGestureAvailable property. Failure to check for this condition will result in an exception thrown by the first TouchPanel.ReadGesture() call. We then read the gesture from the touch panel, which will return the next available gesture. This means that when you have multiple gestures enabled you would need to check the gesture.GestureType property to determine which gesture this is. In this case, the check is not required because the horizontal drag gesture is the only one we enabled. Also note that since the input feedback is different between all devices, we use a different dampening value.

     

    Ready, Steady, Go!

    We’re done! Select any platform and run the little “game” to enjoy a truly breathtaking experience. Using a single codebase, you effectively created not one or two, but three game versions. All three are identical, and yet all three run on different hardware architectures and accept platform-specific input.

     

    Although this is the conclusion of the series, you can find plenty of resources to get you going further on the App Hub at http://create.msdn.com. Enjoy!

     

     

  • Go DevMENTAL

    Introducing XNA: A Tri-Platform Game Development Framework – Part 2

    • 0 Comments

    Introducing XNA: A tri-platform game development framework – Part 2

     

    In part 1 of this series, we set up a tri-platform XNA solution that can be deployed to three platforms simultaneously. While the cornflower blue screen we saw in the previous part is a truly breathtaking achievement, in this part we’ll write a little bit of code to make our game do something.

     

    XNA is a game development framework. Games often render stuff. Therefore, if A = B and B = C and Albatrosses feed on both fish and krill, then we must conclude that by the end of this article we’ll be drawing something!

     

    Be sure to download the space ship model included in this article. This model was stolen borrowed from the AppHub catalog, where it is used in numerous XNA samples.

     

    Open up the solution that we created in part 1 and brace yourself for the extremely complex and time-consuming process of importing the model into our project. Ready? Drag-and-drop Ship.fbx and ShipDiffuse.tga directly into the XNAIntroContent project in Visual Studio. Right-click on ShipDiffuse.tga and click Exclude From Project. You’re done! While you might be relieved to know how quick and simple the process really is, you are probably wondering why we excluded the texture from the Content project.

     

    ShipDiffuse.tga is Ship.fbx’s UV map – a texture that is mapped on to the model when it is rendered in 3D. It is referenced directly by the model file, which means that the Content Pipeline will be aware of its physical location on disk during build time. When we drag-and-dropped the two files into the Content project, they were physically copied to the project’s folder, where they are expected to be. Since the texture is used by the model, we don’t need to load or use it explicitly in our project, hence its exclusion.  Inclusion of the texture in the project would not cause any technical issues, but it will be built twice (once by the model’s processor and once by the default texture processor) resulting in a warning, “Asset was built 2 times with different settings”.

     

    Now that we have the model in our content project, let’s write some code to load it and draw it on the screen. We’ll begin by declaring a field for it:

     

              public class Game1 : Microsoft.Xna.Framework.Game

              {

                       Model ship;

     

                       ...

     

    public Game1()

                       {

                                 graphics = new GraphicsDeviceManager(this);

                                 Content.RootDirectory = "Content";

                       }

     

                       ...

    }

     

    You’ll notice that the ContentManager’s RootDirectory property is set to “Content”. This is to reference the name of the Content project set in the Content project’s properties under Content Root Directory.

     

     

     

    This means that if you have two or more Content projects in one solution, the ContentManager of each game project could have its RootDirectory property set to the desired Content project name.

     

    Let’s use the ContentManager to load our model. In the LoadContent() method add:

     

    ship = Content.Load<Model>("Ship");

     

    The string Ship is the relative path to the asset in the Content project (our model in this case) minus the extension. There is no need to add Content in the path. Note that ContentManager’s Load method is generic and can therefore be used to load any type of an asset, including models, sounds, textures, XML files and custom types.

     

    Now that we loaded our 3D model, we want to draw it. In the perfect world, this would be done by simply calling a Model.Draw() method that would somehow magically read our minds and draw the model just as we want it. In the real world, things are not quite as simple.

     

    First, we need to use a number of Matrices to define various properties needed to draw a 3D scene. Add the following matrix declarations after your model.

     

    Matrix world;

                       Matrix view;

                       Matrix projection;

     

    Before we do anything else, a quick rundown of what each Matrix is and what it does:

     

    • The world matrix defines the positioning of the 3D model in world space. Multiplication by the world matrix achieves the effect of transforming the model from its own space (object space) to our scene (world space).
    • The view matrix defines the view parameters of the virtual scene camera. This matrix often determines the view direction as well as the orientation of the camera about the Up Vector (the vector that specifies which way is “up”)
    • The projection matrix specifies how the 3D scene is projected on to the final frame that eventually makes it to our screen. In the – more common – perspective view, this often means specifying the field of view, aspect ratio of the frame/viewport, and the near/far planes, which will result in a view frustum.

     

    We’ll set these parameters in the LoadContent() method. Right after loading our model, add the following:

     

    world = Matrix.Identity;

                       view = Matrix.CreateLookAt(Vector3.Backward * 5000.0f, Vector3.Zero, Vector3.Up);

                       projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 1.0f, 10000.0f);

     

    We set the world matrix to identity, which essentially translates to the world’s “origin”. We specify the “3D origin” (Vector3.Zero) as the target (this is where our model will be), place the camera an arbitrary distance backwards (Vector3.Backward * 5000.0f) and specify the positive Y-Axis as the camera’s “Up” direction (Vector3.Up). Our projection matrix will have the aspect ratio of the viewport (GraphicsDevice.Viewport.AspectRatio), Pi over 4 radians (or 45 degrees) field of view, and fairly arbitrary value for the near and far planes.

     

    The reason for so many arbitrary values is due to the limited scope of this article. Their exact meaning is simply not important here.

     

    We are ready to draw our model. Add the following private method in the Game1 class:

     

    private void DrawModel(Model model)

                       {

                                 foreach (ModelMesh mesh in model.Meshes)

                                 {

                                          foreach (BasicEffect effect in mesh.Effects)

                                          {

                                                    effect.World = world;

                                                    effect.View = view;

                                                    effect.Projection = projection;

     

                                                    effect.EnableDefaultLighting();

                                          }

     

                                          mesh.Draw();

                                 }

                       }

     

    This method does three simple things. The first foreach loop iterates over all of the meshes in the model. The second loop iterates over each effect; where the all of the mandatory and optional parameters are set. In actual fact, foreach Effect in ModelMesh.Effects is a shortcut for iterating over each MeshPart and setting each MeshPart Effect individually. Needless to say, this is definitely not within the scope of this article.

     

    The third and last step is drawing the mesh with mesh.Draw(). Notice that we make use of our three key matrices – world, view and projection – to set the three properties required to correctly draw the geometry (but not necessarily the color and lighting) of the model. We also use EnableDefaultLighting() method to light our model using the Three-point lighting method (http://en.wikipedia.org/wiki/Three-point_lighting).

     

    We’re almost ready to draw, but there is one last piece of the puzzle missing in our drawing code. We need to account for transforms that were applied to each mesh when the model was created. The transforms are specified in each Bone of the model. The collection of Bones defines the mesh hierarchy where each mesh has a relation to its parent, and the transform specifies the mesh’s transformation relative to its parent. For example, if a tree model has a mesh for each of its branches, then each branch (and ultimately the leaves) will be positioned relative to a parent branch.

     

    We look up the transforms with two simple lines of code:

     

                                                    Matrix[] transforms = new Matrix[ship.Bones.Count];

                       ship.CopyAbsoluteBoneTransformsTo(transforms);

     

    And then account for each transform when multiplying by the world matrix:

     

    World = transforms[mesh.ParentBone.Index] * world;

     

    Our final drawing code now looks like this:

     

    private void DrawModel(Model model)

                       {

                                 Matrix[] transforms = new Matrix[ship.Bones.Count];

                                 ship.CopyAbsoluteBoneTransformsTo(transforms);

     

                                 foreach (ModelMesh mesh in model.Meshes)

                                 {

                                          foreach (BasicEffect effect in mesh.Effects)

                                          {

                                                    effect.World = transforms[mesh.ParentBone.Index] * world;

                                                    effect.View = view;

                                                    effect.Projection = projection;

     

                                                    effect.EnableDefaultLighting();

                                          }

     

                                          mesh.Draw();

                                 }

                       }

     

    Let’s draw our ship by calling the DrawModel(ship) in the Draw() method of the Game1 class:

     

    protected override void Draw(GameTime gameTime)

                       {

                                 GraphicsDevice.Clear(Color.CornflowerBlue);

     

                                 // TODO: Add your drawing code here

     

                                 DrawModel(ship);

     

                                 base.Draw(gameTime);

                       }

     

    By this point, you might be wondering which platform this code was meant for. After all, we have three separate projects, which will be built for three separate and architecturally unique hardware platforms. You might even be convinced that at least some conditions must be placed in code to ensure that it runs on three different CPUs and is rendered by three different GPUs.

     

    Oddly enough, it is with this concern that I would like to formally welcome you to the wonderful world of XNA – a true, tri-platform game development framework.

     

     

     

     

    Stay tuned for part 3!

  • Go DevMENTAL

    Game Development Tutorial

    • 0 Comments

    Bite-Sized Lessons, A Great Single-Screen Experience

    This combination video and text tutorial set teaches basic 2D game development on Windows, Xbox 360, and Windows Phone 7 using XNA Game Studio 4.0 my be found here

    • Videos are each less than 5 minutes in length
    • Accessible with a web browser, no special installs needed
    • All source code is plaintext, easy to copy and paste
    • Assets and code projects downloadable for a quick jumpstart
    • Downloadable checkpoints throughout to keep learners on track
    • Entire experience can be run windowed, side-by-side with Visual Studio

    COMPREHENSIVE EDUCATION

    Learn the following lessons in our easy-to-follow chapters:

    • Game Design from Start to Finish
    • Animated and Static Art Creation
    • The Game Loop Explained
    • The XNA Content Pipeline
    • Rendering Static and Animated Sprites
    • Player Input on Windows, Xbox 360, and Phone
    • Collision Detection and Response
    • Debugging Game Code
    • User Interface Design and Rendering
    • Sound Playback
    • Information on Xbox LIVE Indie Games and Windows Phone Marketplace

    YOU’ll ALSO FIND…

    On this new Game Development Page

    • A full “graduation path” for game developers from Beginner to Pro
    • Step-by-Step guidance for each level
    • Information about Xbox LIVE Indie Games and Windows Phone 7 marketplaces.
    • Links to “Going Professional” guidelines and contact points for Xbox LIVE Arcade and Microsoft Game Studios

     

  • Go DevMENTAL

    Microsoft DigiGirlz Day

    • 0 Comments

    Microsoft's DigiGirlz programs give high school girls the opportunity to learn about careers in technology, connect with Microsoft employees, and participate in hands-n computer and technology workshops at the  NERD Center in Cambridge, designed to provide high school girls with a better understanding of what a career in technology is all about.

    During the event, students interact with Microsoft employees and managers to gain exposure to careers in business and technology and to get an inside look at what it's like to work at Microsoft. This exciting event provides girls with career planning assistance, information about technology and business roles, thought-provoking exercises, and interesting Microsoft product demonstrations. By participating in the Microsoft DigiGirlz Day, young women can find out about the variety of opportunities available in the high-tech industry and can explore future career paths.

    There is no cost associated with this event. Microsoft provides the day free of charge for the girls who attend. Microsoft accepts girls and schools on a first-come, first-served basis. Local high schools are encouraged to send in registration requests for their interested girls for this event as soon as possible.

    How do girls register to attend a DigiGirlz Day?

    High schools can request to register girls for a DigiGirlz Day in their city by contacting msgirlz@microsoft.com.

    An individual girl who is currently in high school is welcome to register for a DigiGirlz Day in her area by sending an e-mail message with her name, her city and state, and the name of her high school to msgirlz@microsoft.com.

    Release Forms: All students and parent/legal guardian (if under 18) must complete and sign a media release form in order to attend the DigiGirlz event. The form can be obtained by e-mailing msgirlz@microsoft.com.

  • Go DevMENTAL

    Windows Phone Ad SDK - Grossing Revenue with you WP7 mobile application

    • 0 Comments

    Jake Poznanski and his classmate Sam Kaufmann are computer science majors and first time mobile app developers that started with one rule… develop simplistic quality. Choosing the Windows Phone 7 platform because it was a clean slate for development, Jake and Sam have created several apps with the aim of infusing all the entertainment quality and nuances of a paid app in the form of an ad supported app.  Some of the apps are 'Spades, Word Search, Solitare, Ice Ball, Free Cell, Word Chief, Hearts' 

    You may find the tool set here

    Tutorials and more information about the SDK can be located here

     

Page 72 of 82 (408 items) «7071727374»