Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1

Exclusive offer: get 50% off this eBook here
3D Game Development with Microsoft Silverlight 3: Beginner's Guide

3D Game Development with Microsoft Silverlight 3: Beginner's Guide — Save 50%

A practical guide to creating real-time responsive online 3D games in Silverlight 3 using C#, XBAP WPF, XAML, Balder, and Farseer Physics Engine

£18.99    £9.50
by Gastón C. Hillar | September 2009 | Beginner's Guides Web Development Web Graphics & Video

In this two part article series by Gastón C. Hillar, we will use advanced physics and add special effects to the scenes. We will learn to generate gravity effects, add fluids with movements, and use transitions to determine different states in a game.

By reading this article and following the exercises we will learn to:

  • Add many background models, adding life to the game
  • Control many independent backgrounds
  • Simulate fluids with movement
  • Work with multiple concurrent physics simulators
  • Use advanced physics simulation to create waves

 

A 3D game must be attractive. It has to offer amazing effects for the main characters and in the background. A spaceship has to fly through a meteor shower. An asteroid belt has to draw waves while a UFO pursues a spaceship. A missile should make a plane explode. The real world shows us things moving everywhere. Most of these scenes, however, aren't repetitive sequences. Hence, we have to combine great designs, artificial intelligence (AI), and advanced physics to create special effects.

Working with 3D characters in the background

So far, we have added physics, collision detection capabilities, life, and action to our 3D scenes. We were able to simulate real-life effects for the collision of two 3D characters by adding some artificial intelligence. However, we need to combine this action with additional effects to create a realistic 3D world. Players want to move the camera while playing so that they can watch amazing effects. They want to be part of each 3D scene as if it were a real life situation. How can we create complex and realistic backgrounds capable of adding realistic behavior to the game?

We can do this combining everything we have learned so far with a good object-oriented design. We have to create random situations combined with more advanced physics. We have to add more 3D characters with movement to the scenes. We must add complexity to the backgrounds.

We can work with many independent physics engines to work with parallel worlds. In real-life, there are concurrent and parallel words. We have to reproduce this behavior in our 3D scenes.

Time for action – adding a transition to start the game

Your project manager does not want the game to start immediately. He wants you to add a butt on in order to allow the player to start the game by clicking on it. As you are using Balder, adding a butt on is not as simple as expected.

We are going to add a butt on to the main page, and we are going to change Balder's default game initialization:

  1. Stay in the 3DInvadersSilverlight project.
  2. Expand App.xaml in the Solution Explorer and open App.xaml.cs––the C# code for App.xaml.
  3. Comment the following line of code (we are not going to use Balder's services in this class):
     //using Balder.Silverlight.Services;
  4. Comment the following line of code in the event handler for the Application_Startup event, after the line this.RootVisual = new MainPage();:
    //TargetDevice.Initialize<InvadersGame>();
  5. Open the XAML code for MainPage.xaml and add the following lines of code after the line (You will see a butt on with the ti tle Start the game.):
    <!-- A button to start the game -->
    <Button x:Name="btnStartGame"
    Content="Start the game!"
    Canvas.Left="200" Canvas.Top="20"
    Width="200" Height="30" Click="btnStartGame_Click">
    </Button>
  6. Now, expand MainPage.xaml in the Solution Explorer and open MainPage.xaml.cs––the C# code for MainPage.xaml.
  7. Add the following line of code at the beginning (As we are going to use many of Balder's classes and interfaces.):
    using Balder.Silverlight.Services;
  8. Add the following lines of code to program the event handler for the button's Click event (this code will initialize the game using Balder's services):
    private void btnStartGame_Click(object sender, RoutedEventArgs e)
    {
    btnStartGame.Visibility = Visibility.Collapsed;
    TargetDevice.Initialize<InvadersGame>();
    }
  9. Build and run the solution. Click on the Start the game! butt on and the UFOs will begin their chase game. The butt on will make a transition to start the game, as shown in the following screenshots:
    Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1

 

What just happened?

You could use a Start the game! butt on to start a game using Balder's services. Now, you will be able to offer the player more control over some parameters before starting the game.

We commented the code that started the game during the application start-up. Then, we added a button on the main page (MainPage). The code programmed in its Click event handler initializes the desired Balder.Core.Game subclass (InvadersGame) using just one line:

TargetDevice.Initialize<InvadersGame>();

This initialization adds a new specific Canvas as another layout root's child, controlled by Balder to render the 3D scenes. Thus, we had to make some changes to add a simple butt on to control this initialization.

Time for action – creating a low polygon count meteor model

The 3D digital artists are creating models for many aliens. They do not have the time to create simple models. Hence, they teach you to use Blender and 3D Studio Max to create simple models with low polygon count. Your project manager wants you to add dozens of meteors, to the existing chase game. A gravitational force must attract these meteors and they have to appear in random initial positions in the 3D world.

First, we are going to create a low polygon count meteor using 3D Studio Max. Then, we are going to add a texture based on a PNG image and export the 3D model to the ASE format, compatible with Balder. As previously explained, we have to do this in order to export the ASE format with a bitmap texture definition enveloping the meshes.

We can also use Blender or any other 3D DCC tool to create this model. We have already learned how to export an ASE format from Blender. Thus, this time, we are going to learn the necessary steps to do it using 3D Studio Max.

  1. Start 3D Studio Max and create a new scene.
  2. Add a sphere with six segments.
  3. Locate the sphere in the scene's center.
  4. Use the Uniform Scale tool to resize the low polygon count sphere to 11.329 in the three axis, as shown in the following screenshot:

    Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1

  5. Click on the Material Editor button.
  6. Click on the first material sphere, on the Material Editor window's upper-left corner.
  7. Click on the small square at the right side of the Diffuse color rectangle, as shown in the following screenshot:

    Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1

  8. Select Bitmap from the list shown in the Material/Map Browser window that pops up and click on OK.
  9. Select the PNG file to be used as a texture to envelope the sphere. You can use Bricks.PNG, previously downloaded from http://www.freefoto.com/. You just need to add a reference to a bitmap file. Then, click on Open. The Material Editor preview panel will show a small sphere thumbnail enveloped by the selected bitmap, as shown in the following screenshot:

    Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1

  10. Drag the new material and drop it on the sphere. If you are facing problems, remember that the 3D digital artist created a similar sphere a few days ago and he left the meteor.max file in the following folder (C:Silverlight3DInvaders3D3DModelsMETEOR).
  11. Save the file using the name meteor.max in the previously mentioned folder.
  12. Now, you have to export the model to the ASE format with the reference to the texture. Therefore, select File | Export and choose ASCII Scene Export (*.ASE) on the Type combo box. Select the aforementioned folder, enter the file name meteor.ase and click on Save.
  13. Check the following options in the ASCII Export dialog box. (They are unchecked by default):
    • Mesh Normals
    • Mapping Coordinates
    • Vertex Colors

    The dialog box should be similar to the one shown in the following screenshot:

    Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1

  14. Click on OK. Now, the model is available as an ASE 3D model with reference to the texture. You will have to change the absolute path for the bitmap that defines the texture in order to allow Balder to load the model in a Silverlight application.
3D Game Development with Microsoft Silverlight 3: Beginner's Guide A practical guide to creating real-time responsive online 3D games in Silverlight 3 using C#, XBAP WPF, XAML, Balder, and Farseer Physics Engine
Published: September 2009
eBook Price: £18.99
Book Price: £30.99
See more
Select your format and quantity:

What just happened?

We used a different 3D DCC tool (3D Studio Max) to add a texture based on an image bitmap and link it to a material to envelope the meshes. Then we converted the 3D model to the ASE file format, using 3D Studio Max ASCII Export.

Now, we know how to export models enveloped by textures in both Blender and 3D Studio Max. We do not need 3D digital artists anymore to create simple models. However, we do need them to create complex models.

Time for action – from 3D Studio Max to Silverlight

Now, we are going to add the meteor's ASE 3D model exported from 3D Studio Max in our Silverlight game with Balder's help.

  1. Open the 3DInvadersSilverlight project.
  2. Right-click on the Assets folder and select Add | Existing item… from the context menu that appears.
  3. Go to the folder in which you saved the meteor's 3D model, including the link to the texture, in the ASE format (C:Silverlight3DInvaders3D3DModelsMETEOR). Select the new ASE fi le (meteor.ase) and click on Add.
  4. Click on the ASE file added in the previous step. Change its Build Action property to Resource.
  5. Open the code for the recently added ASE file (meteor.ase).
  6. Search for the line that begins with *BITMAP.
  7. Replace the full path and the file name that follows the *BITMAP (C:Silverlight3DInvaders3D3DModelsSPACESHIP01TexturesBricks.png) with the desired PNG bitmap, Bricks.png, as shown in the following screenshot:

    Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1

What just happened?

The meteor's 3D model is ready to be loaded using Balder. We added it to the assets and we changed the texture's path.

Time for action – creating a subclass for a 3D meteor

Now, we are going to create a specialized subclass of Actor (Balder.Core.Runtime.Actor) to define a meteor. Each meteor will be a 3D character.

Time for action – creating a subclass for a 3D meteor

Now, we are going to create a specialized subclass of Actor (Balder.Core.Runtime. Actor) to define a meteor. Each meteor will be a 3D character.

  1. Stay in the 3DInvadersSilverlight project.
  2. Create a new class—Meteor (a subclass of Actor)—using the following declaration:
    public class Ufo : Actor
  3. Add the following lines of code at the beginning (as we are going to use many classes and interfaces from Balder and Farseer Physics Engine):
    using Balder.Core;
    using Balder.Core.Geometries;
    using Balder.Core.Math;
    using Balder.Core.Runtime;
    using FarseerGames.FarseerPhysics;
    using FarseerGames.FarseerPhysics.Collisions;
    using FarseerGames.FarseerPhysics.Dynamics;
    using FarseerGames.FarseerPhysics.Factories;
    using FarseerGames.FarseerPhysics.Mathematics;
  4. Add the following protected variables to hold references for the RealTimeGame and the Scene instances:
    protected RealTimeGame _game;
    protected Scene _scene;
  5. Add the following protected variable to hold the meteor's 3D model (an instance of Mesh):
    protected Mesh _mesh;
  6. Add the following public properties related to the physics simulator:
    public Body Body { get; private set; }
    public Geom Geom { get; private set; }
    public float Radius { get; private set; }
    public float Mass { get; private set; }
  7. Add the following constructor with three parameters, the RealTimeGame,the Scene, and the PhysicsSimulator instances:
    public Meteor(RealTimeGame game, Scene scene,
    PhysicsSimulator physicsSimulator)
    {
    _game = game;
    _scene = scene;
    Radius = 1f;
    Mass = 1f;
    // Create the body and set its linear drag coefficient
    Body = BodyFactory.Instance.CreateCircleBody(physicsSimulator,
    Radius, Mass);
    Body.LinearDragCoefficient = 0.4f;
    // The meteor is going to rotate forever
    Body.RotationalDragCoefficient = 0f;
    // Create the geometry (Geom) and set its friction coefficient
    Geom = GeomFactory.Instance.CreateCircleGeom(physicsSimulator,
    Body, Radius, 6);
    Geom.FrictionCoefficient = 0.2f;
    // Add a collision event handler
    Geom.OnCollision += OnCollision;
    }

  8. Override the LoadContent method to load the meteor's mesh, set its initial position and assign it to the Body instance:
    public override void LoadContent()
    {
    base.LoadContent();
    _mesh = _game.ContentManager.Load<Mesh>("meteor.ase");
    _scene.AddNode(_mesh);
    _mesh.Position.X = 0;
    _mesh.Position.Y = 0;
    _mesh.Position.Z = 0;
    Body.Position = new Vector2(_mesh.Position.X, _mesh.Position.Y);
    }
  9. Override the Update method to update the meteor's position copying the values for the associated Body's position and to rotate it:
    public override void Update()
    {
    base.Update();
    _mesh.Position.X = Body.Position.X;
    _mesh.Position.Y = Body.Position.Y;
    _mesh.World = Balder.Core.Math.Matrix.CreateRotationY(
    FarseerGames.FarseerPhysics.Mathematics.MathHelper.
    ToDegrees(Body.Rotation));
    }
  10. Add the following public method to change the position for both the mesh in the 3D world and the 2D body representing the circle for the meteor in the 2D physics engine world:
    public void SetPosition(float x, float y, float z)
    {
    _mesh.Position.X = x;
    _mesh.Position.Y = y;
    _mesh.Position.Z = z;
    Body.Position = new Vector2(x, y);
    }
  11. Add the following private method to accept collisions between meteors:
    private bool OnCollision(Geom geom1, Geom geom2, ContactList contactList)
    {
    // We're just working with meteors
    return true;
    }
  12. What just happened?

    Now, we have a subclass of Actor that loads the meteor's model and updates its position according to an associated physics simulator.

    This class is very similar to the Ufo class. However, in this case, we are working with a circular body and a circular geometry.

    We created the body associated with the 3D model using the CreateCircleBody function, as shown in the following line:

    Body = BodyFactory.Instance.CreateCircleBody(physicsSimulator,
    Radius, Mass);

    As we want the meteor to rotate forever, we assigned a 0 to the associated body's rotational drag coefficient:

    Body.RotationalDragCoefficient = 0f;

    Time for action – creating and controlling a meteor rain

    Now, we are going to add another physics simulator with a different gravitational force to control dozens of meteors and to create the illusion of a meteors rain.

  13. Stay in the 3DInvadersSilverlight project
  14. Open InvadersGame.cs for the C# code.
  15. Add the following private variable in the public class InvadersGame public class InvadersGame : RealTimeGame, to hold another PhysicsSimulator (FarseerGames.FarseerPhysics.PhysicsSimulator) instance:
    private PhysicsSimulator _meteorsPhysicsSimulator;
  16. Add the following lines of code at the beginning of the class definition (as we are going to use the System.Collections.Generic.List class):
    using System.Collections.Generic;
  17. Add the following private variables to hold the list of meteors, the number of meteors to create and a random number generator:
    protected List<Meteor> _meteors;
    // A random generator
    protected Random _random = new Random();
    // The number of meteors to create
    private int _meteorsNumber = 30;
  18. Add the following private method to initialize the meteors physics simulator, specifying a specific desired gravitational force as a 2D vector parameter:
    private void InitializeMeteorsPhysicsSimulator()
    {
    _meteorsPhysicsSimulator = new PhysicsSimulator(new
    Vector2(0.15f, 0.35f));
    //50 pixels = 1 meter
    ConvertUnits.SetDisplayUnitToSimUnitRatio(50);
    }
  19. Add the following private method to create and add a certain number of Meteor instances to a list and to add these new actors to the scene:
    private void AddMeteors()
    {
    _meteors = new List<Meteor>(_meteorsNumber);
    for (int i = 0; i < _meteorsNumber; i++)
    {
    Meteor meteor = new Meteor(this, Scene,
    _meteorsPhysicsSimulator);
    _meteors.Add(meteor);
    AddActor(meteor);
    }
    }
  20. Add the following lines of code before the end of the Initialize method:
    InitializeMeteorsPhysicsSimulator();
    AddMeteors();
  21. Add the following line of code before the end of the UpdateWithTime method:
    _meteorsPhysicsSimulator.Update((float)_elapsedTime.
    TotalSeconds);
  22. Add the following private method to define initial random locations for each meteor in the list and to apply a torque to let them roll forever while they move:
    private void SetMeteorsPositions()
    {
    for (int i = 0; i < _meteorsNumber; i++)
    {
    _meteors[i].SetPosition(_random.Next(-20, 10), _random.Next(-
    20, 10), _random.Next(-20, 30));
    _meteors[i].Body.ApplyTorque(1.5f);
    }
    }
  23. Add the following lines of code before the end of the overridden Loaded method to set the initial positions and torques for the meteors:
    SetMeteorsPositions();
  24. Build and run the solution. Click on the Start the game! button and the UFOs will begin their chase game while 30 meteors rain. The models representing the meteors will fall and rotate according to the gravitational force specified in the new physics simulator and the torque applied to them, as shown in the following screenshot:

    Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1

  25. Click on the web browser's viewport to activate its focus. Move the mouse left and right. You will see the entire scene, including the raining meteors, rotating as the mouse is moved. Use the cursor keys to control the camera. Remember that you can also use your gamepad to control the camera. While rotating the camera, the meteors and the UFOs will go on moving, as shown in the following screenshot:

    Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 1

What just happened?

You could add an exciting background to the game. Now, there are meteors raining in the 3D world. Your project manager is astonished with your work.

Using another instance of the 2D physics engine, you could simulate real-life physics for 30 meteors. Now, the game has an attractive 3D background that offers a realistic rain effect.

Advantages of using multiple physics engines

We added a new physics simulator instance to control the 30 meteors' positions and rotations. This way, we could use a different gravitational force than the one applied to the UFOs. In this case, we used a gravitational force that attracts the bodies to positive X and Y values (X = 0.15 and Y = 035):

_meteorsPhysicsSimulator = new PhysicsSimulator(new Vector2(0.15f,0.35f));

We were not interested in collision detections between the meteors and the UFOs. Thus, we could use two independent physics simulators without problems.

The AddMeteors method creates the number of Meteor instances defined in the _meteorsNumber private variable and adds them to the _meteors list. We already explained the importance of lists in the control of multiple models during the game. Besides, it adds the Meteor as a new actor for the scene using the AddActor method :

for (int i = 0; i < _meteorsNumber; i++)
{
Meteor meteor = new Meteor(this, Scene, _meteorsPhysicsSimulator);
_meteors.Add(meteor);
AddActor(meteor);
}

The new independent physics simulator (_meteorsPhysicsSimulator) is going to take control of these actors during the updates. The following line is necessary to update this independent engine in the UpdateWithTime method :

_meteorsPhysicsSimulator.Update((float)_elapsedTime.TotalSeconds);

The SetMeteorsPosition method defines the initial positions for the meteors using a random number generator with boundaries. This way, we introduced random backgrounds. Each time the player runs the game, the background will be slightly different.

>> Continue Reading Applying Special Effects in 3D Game Development with Microsoft Silverlight 3: Part 2

[ 1 | 2 ]
3D Game Development with Microsoft Silverlight 3: Beginner's Guide A practical guide to creating real-time responsive online 3D games in Silverlight 3 using C#, XBAP WPF, XAML, Balder, and Farseer Physics Engine
Published: September 2009
eBook Price: £18.99
Book Price: £30.99
See more
Select your format and quantity:

About the Author :


Gastón C. Hillar

Gastón C. Hillar has been working with computers since he was eight. He began programming with the legendary Texas TI-99/4A and Commodore 64 home computers in the early 80s.
He has a Bachelor degree in Computer Science from which he graduated with honors, and an MBA from which he graduated with an outstanding thesis. Now, he is an independent IT consultant and a freelance author always looking for new adventures around the world.

To date he’s written more than 40 books in Spanish, and for Packt Publishing has written “C# 2008 and 2005 Threaded Programming: Beginner's Guide”. He usually writes articles for Spanish magazines Mundo Linux, Solo Programadores and Resistor.
He contributes to Dr. Dobb's Go Parallel programming portal http://www.ddj.com/go-parallel/ and he is a guest blogger at Intel Software Network http://software.intel.com

Gastón C. Hillar is the author of "Microsoft Silverlight 4 and SharePoint 2010 Integration".

Books From Packt

Blender 3D 2.49 Incredible Machines
Blender 3D 2.49 Incredible Machines

jQuery 1.3 with PHP
jQuery 1.3 with PHP

Symfony 1.3 Web Application Development
Symfony 1.3 Web Application Development

Zend Framework 1.8 Web Application Development
Zend Framework 1.8 Web Application Development

JBoss Tools 3 Developers Guide
JBoss Tools 3 Developers Guide

Seam 2.x Web Development
Seam 2.x Web Development

WordPress Plugin Development: Beginner's Guide
WordPress Plugin Development: Beginner's Guide

Scratch 1.4: Beginner’s Guide
Scratch 1.4: Beginner’s Guide

 

 

 

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software