Tuesday, November 25, 2008

5 DAYS LEFT FOR SUBMISSIONS

To all XNA'ers out there: only 5 days remain to submit your article(s) to Ziggyware's Fall '08 contest.

If you're still in the process of making up your mind whether to enter the compo or not, this may help: you could win an XBox 360 ELITE! And that's only the beginning.

Want to know more? Read about the prizes on this post.

Just, hurry up! The clock is ticking ...

Happy writing!
~Pete

Monday, November 24, 2008

C.N.V. UPDATE: VIDEOS

Uruguay Gamer has published the links to the videos recorded during the closing ceremony of the third annual domestic constest of videogame development held in Uruguay.

On the site you will also find the comments of Chaim Gingold for each videogame.

Note: The presenter in both videos is Gonzalo Frasca, CEO of Powerful Robot Games (one of the most-known uruguayan videogame companies) and main organizer of the compo.

Here's video 1 (the one receiving the first prize is me):

And here's video 2 (here you can see Frank Baxter -ambassador of US in Uruguay- congratulating the grand winner and at the end of the video you will find Chain Gimgold himself):

Enjoy!
Pete

Thursday, November 20, 2008

BEST 3D VIDEOGAME PROMISE

My PC game "The Riegel Battle" (created with XNA GS) has been today awarded first prize in the category "Best 3D Videogame Promise" during the third annual domestic videogame contest in Uruguay.

Even though it wasn't awarded first prize for the whole compo, as a local supporter of XNA, it was a great honor for me to be among the winners.

Along with the organizers, the contest was sponsored by the US Embassy in Uruguay, so ambassador F. Baxter was present today in the closing ceremony to congratulate the winners.

Chaim Gingold (one of the designers of the game Spore) was one of the judges, and it was also present today in the above-mentioned ceremony, not only as a judge but to speak about the design concepts behind Spore's character editor (a great talk, btw).

Here's a video of my entry:

As soon as I get the links to the official pictures of today's ceremony I'll publish them here.

Cheers!
Pete

Monday, November 17, 2008

XNA & EXTENSION METHODS 3

With this third article, I'm closing my introductory series to the world of Extension Methods and XNA.

At first, this article was meant to focus on how to extend the Random class to get new colors, but Ziggy, in his article entitled "Particles Using LINQ" -worth reading, btw- has clearly shown how to achieve this so I will take that great article as a starting point to go a bit deeper in the discussion on the matter.

If you see Ziggy's method named "RandColor" -which from now on I will refer to it as "NextColor" to be in line with the Random class, he's showing one of the new features of the XNA Framework 3: when using floats there's no need to first create a Vector3 in order to then create a Color, anymore.

In previous versions of XNA, to use floats in order to create a color, you would have declared:

public static Color NextColor(this Random rand)
{
    return new Color(new Vector3(rand.NextFloat(), rand.NextFloat(), rand.NextFloat()));
}

But from the XNA Framework 3 and on, this also works:

public static Color NextColor(this Random rand)
{
    return new Color(rand.NextFloat(), rand.NextFloat(), rand.NextFloat());
}

Now, if you see the Particle2D class in the above-mentioned article, you will notice the field named "Color", which is declared as an variable in uppercase; a new extension method could be created for it, as follows:

public static void NextColor(this Random rand, out Color color)
{
    color = new Color(rand.NextFloat(), rand.NextFloat(), rand.NextFloat());
}

Thus, we can use it within the Update method in the referred example to replace this line:

p.Color = rand.NextColor();

By this new line:

rand.NextColor(out p.Color);

Since the type Color is a struct, the advantage of using the latter over the former could be generally deemed as marginal, but eventually you may get to the situation when even the slightest improvement in your code is desired, specially when you're targeting the compact framework.

New question: what if you followed the design guidelines of C#, declaring the color field in lowercase as a private field and instead, a public getter and setter was included in that class, in the form of a public property named "Color".

In that case, the new overloaded method cannot be used since Properties and Indexers cannot be passed as out/ref parameters. Why? Well, just remember that when you're using properties and indexers you're not directly dealing with variables but methods. In that particular case, the first implementation -that is, the one included in Ziggy's article- is the best solution.

Let's face it! You could be tempted to pass the existing instance of Particle2D as "ref" to sort out the above-mentioned constraint, as follows:

public static void NextColor(this Random rand, ref Particle2D particle)
{
    particle.Color = new Color(rand.NextFloat(), rand.NextFloat(), rand.NextFloat());
}

It should compile ok BUT ONLY if you're NOT PASSING to that method the temporary variable created by a foreach loop -as opposed to the base example. This operation is just NOT ALLOWED for the iteration variables of foreach loops. My advice here is simple: avoid this tempting implementation and as I said before just use the one presented by Ziggy. Generally, the simplest solution is the correct one.

One side note: in case you're new to C#, it's important to notice that in this case we are using "ref" instead of "out", since we need an existing (that is, a non-null) instance of the class in order to assign the new color. Otherwise, by using "out" we should have to create an instance of type Particle2D from within the extension method BEFORE assigning the new color to it.

Now, let's move onto an interesting situation. What if:

  1. We are not and will be not inside a foreach loop,
  2. We don't want to expose the whole Particle2D to the extension method, and at the same time
  3. We need to use this method for as many classes that have declared setter properties for colors?

If that is the case, then you should take a look to this implementation:

public interface IColor
{
    Color Color { get; set; }
}
 
public static class HelperMethods
{
    ...
 
    public static void NextColor<T>(this Random rand, ref T instance)
        where T : class, IColor
    {
        instance.Color = new Color(rand.NextFloat(), rand.NextFloat(), rand.NextFloat());
    }
}

As you can see, we are hereby combining the power of Generics with Extension Methods.

But, why the "IColor" constraint? What we are saying here is simple: only types that implement the Color property can call this extension method. And those non-null instances passed to the method as a parameter (remember we are using the "ref" word here) will be handled as IColor types.

Ok, but why the additional "class" constraint? Tricky one. As a corollary of the previous constraint, if we do not specify that only classes are accepted as parameters, then structs can be also passed when calling the method, and for that they will have to implement the IColor interface ... Meaning? ... Tic tac tic tac ... Yeap, boxing. Ugh! That nasty word. Handling structs through interfaces causes boxing. Chilly, isn't it? Now you know it, in case you didn't.

To sum up, as you can see Extension Methods are quite handy, but you have to use them with care if you want to avoid getting into a design trap. As usual, not all the situations can be solved the same way, even though at first it sounds logic to you. You may find your-self saying "Whaaat? Buy whyyy? ...". So, I hope these examples show you what to use and when and what to avoid and why.

Some final thoughts about Extension Methods:

  1. They are great for usual tasks: believe it or not, two common types where I always find my-self repeating usual tasks are TYPE and RANDOM classes, but this feature can be used with as many types as you need,
  2. They are ituitive to use: before this functionality was introduced to the .NET Framework, one usually used to write a static class filled with helpers; please don't misundertsand me, you still have, but now those helpers are presented in a more intuitive and user-friendly way. With Extension Methods, you don't have to look for the methods "by browsing" the static class were you declared and implementem them; instead, you just look on the instances of the types you are using. And last but not least,
  3. They comply with design principles: as said in my first article in the series, we are not breaking any design principles, since we have no direct access to private members of the "extended" types.

In short, if you use Extension Methods with care and wisdom, they can be a true friend at the time of coding your XNA-based game or application: they simply help you extend any types with new methods AS IF these where originally part of those types, what in turn can be handy, for instance:

  1. When you don't want to create a specification of a class, or on the other hand,
  2. When you want to put more functionality into a sealed class somehow -to some extent, of course.

So go ahead, try Extension Methods and share what you find with the XNA Community. It would be great and fun to know what you are using them for!

Well, I hope you have found this series useful. Constructive comments and suggestions are always welcome.

Cheers!
~Pete

Monday, November 03, 2008

XNA & EXTENSION METHODS 2

Continuing with the topic of how to use the handy functionality provided by "Extension Methods" with our XNA-based creations, for this article we are going to need the "FuelCell" tutorial (remember that you shall find this tuto -along with the "TopDownShooter" one- in the help file under the "What's New In This Release" section).

Ok. In the chapter called "Finishing Touches" of the FuelCell' s tutorial, you'll find the following method at the very end of the "FuelCellGame.cs" file:

private Rectangle GetTitleSafeArea(Viewport viewport)
{
Rectangle retval = new Rectangle(viewport.X, viewport.Y, viewport.Width, viewport.Height);

#if XBOX
retval = viewport.TitleSafeArea;
#endif

return retval;
}

If you remember my last article on the subject, you'll be anticipating by now that the Viewport struct could be "extended" so as to retrieve its "unsafe" area with one method call.

If so, you guessed it right! We can use Extension Methods to declare an operation called, say "GetFullArea", and give it the proper implementation.

Not only can we pass again a parameter by reference (using the "out" reserved word) -like we did in Part 1 of this series- but also in this particular case, since we're dealing with a struct, we can afford to implement an overloaded method that locally declares, creates and returns an instance of a Rectangle (I know what you're thinking, but unfortunately, there are no "Extension Properties" in C#, so we need to get the rectangle from a method call).

Using Extension Methods, our solution should look like the following:

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace MyNamespace.Math
{
public static class MathExtensions
{
public static void GetFullArea(this Viewport viewport, out Rectangle area)
{
area = new Rectangle(viewport.X, viewport.Y, viewport.Width, viewport.Height);
}

public static Rectangle GetFullArea(this Viewport viewport)
{
return new Rectangle(viewport.X, viewport.Y, viewport.Width, viewport.Height);
}
}
}


Now, the GetTitleSafeArea(...) method could be re-implemented like this:

private Rectangle GetTitleSafeArea(Viewport viewport)
{
Rectangle retval;

#if
XBOX
retval = viewport.TitleSafeArea;
#else
viewport.GetFullArea(out retval);
#endif

return retval;
}

Or also like this:

private Rectangle GetTitleSafeArea(Viewport viewport)
{
#if XBOX
return viewport.TitleSafeArea;
#else
return viewport.GetFullArea();
#endif
}


Remember two important things:

  • You'll have to add the proper "Using" statement in the file that will use the extension method (in my example: "MyNamespace.Math"), and
  • You'll have to manually add a reference to the "System.Core" assembly in your project.

This technique can be used to get, say -among other things, a Vector2 containing the width and height of the Viewport (as well as for the display and the client area). I leave it as an exercise for you to try (you'll see it's actually quite easy to implement).

I hope you find this article useful.

'till next time,
~Pete

XNA & EXTENSION METHODS 1

With the release of XNA GS 3, two new tutorials were included into the "What's New In This Release" section in the help file: "TopDownShooter" and "FuelCell" games. For what follows, we'll be referring to the first tutorial game: TopDownShooter.

Sometimes we need to get an instance of a sound effect without playing it. The good news is that it can be done. The bad news is that there's no built-in method provided yet to get that instance in one step.

So, what's next then? Open the AudioManager.cs file provided in the TopDownShooter example. You should find the following code on the LoadContent() method:

// We call Play silently to retrieve a specific instance we can
// use for subsequent Pause and Play calls
SeekerInstance = Seeker.Play(0, 0.75f, 0, true);
SeekerInstance.Stop();
SeekerInstance.Volume = FXVolume; // set the real volume

As you can see, the above-mentioned code gives an idea of what you should use to get the instance of a sound effect "without playing it".

But, what if we want to get that functionality in one method (as if it were provided built-in) without extending the SoundEffect class? Well, in that case since we are targeting the .NET Framework 3.5 we can use the magic of "Extension Methods".

I'm not going to explain what Extension Methods are (to get a first read on the subject, please refer to this page), but how we can take advantage of them for this particular case.

Our goal is to extend the SoundEffect class in a way that:

  1. We do not create a specification of that class,
  2. We get a new SoundEffectInstance without playing it,
  3. We do not generate unnecessary garbage when getting a new instance, and
  4. Our method runs efficiently in the .NET Compact Framework.

Thus, our solution should be the following:

  1. We'll use Extension Methods technique,
  2. We'll mimic the code of the "TopDownShooter" tutorial,
  3. We cannot declare a local reference of type SoundEffectInstance within our method, and
  4. We should pass a parameter by reference of type SoundEffectInstance that can be null.

Therefore, our final implementation should be something like this:

using System;
using Microsoft.Xna.Framework.Audio;

namespace MyNamespace.Audio
{
public static class AudioExtensions
{
private static float VolumeLevelByDefault = .5f;

public static void GetCue(this SoundEffect soundEffect, out SoundEffectInstance soundEffectInstance)
{
GetCue(soundEffect, out soundEffectInstance, VolumeLevelByDefault, 0f, 0f, false);
}

public static void GetCue(this SoundEffect soundEffect, out SoundEffectInstance soundEffectInstance, float volume, bool loop)
{
GetCue(soundEffect, out soundEffectInstance, volume, 0f, 0f, loop);
}

public static void GetCue(this SoundEffect soundEffect, out SoundEffectInstance soundEffectInstance, float volume, float pitch, float pan, bool loop)

{
// Play the sound silently and stop it immediately.
soundEffectInstance = soundEffect.Play(0f, pitch, pan, loop);
soundEffectInstance.Stop();

// Set the passed volume level.
soundEffectInstance.Volume = volume;
}
}
}

As you can see, I'm naming the static method "GetCue" but you can call it, say, "GetInstance" if you prefer. Also, since we cannot yet use optional parameters -we'll have to wait for C# 4.0 for that- you will have to create as many overloaded methods as you need.

Now, in the LoadContent() method of the AudioManager.cs file, all we should use instead is:

// Get the new instance of the seeker sound effect.
Seeker.GetCue(out SeekerInstance, FXVolume, 0.75f, 0, true);

Don't forget to add the proper "Using" statement on the AudioManager.cs, linking to the namespace where the extension method was declared and implemented (in my example "MyNamespace.Audio"), or your code won't compile.

Also, you will need to manually add a reference in your project to the "System.Core" assembly -in case it is not already referenced.


Well, this is it. Now you know how to extend the SoundEffect class to get a new instance of a sound effect in just one method call, virtually speaking ;)

One final note: by using "Extension Methods" we are not breaking any design principles, since we have no direct access to private members of the "extended" type (being the latter, in this example, the SoundEffect class).

Enjoy!
~Pete