Functional Programming in .NET – LINQ and C# 3.0 (Part 2 of 2)

By Giulia Costantini

Source code here, PDF version of this article here

 

Technical specs

Our code is produced using Visual Studio 2008 Team Suite, C# 3.0, .NET Framework 3.5.

We created a Windows project, Console Application. To use LINQ features you have to make sure of two things:

1.       System.Core must be included in your project’s References

2.       using System.Linq; must be in your using statements (at the beginning of the source code)

We are going to explore some of the most useful LINQ operators, using a List<int> for most of our examples.

Note that all LINQ queries don’t work inline: they return a new IEnumerable, which you have to store somewhere. This is especially useful when using multithreading, because the old collection you are manipulating remains intact during the entire execution of your query.

Plus, the IEnumerable returned by a LINQ query is like an “abstract object”, it is not materialized (lazy evaluation, does it ring a bell?); if you want to concretize your query (which means execute the computations in it and effectively store the result) you have to use ToList() or an equivalent (ToDictionary(), ToArray()). Calling  ToList()materializes the query storing it in memory.

 

LINQ operators

A complete list of LINQ operators follows:

Operator type

Operator name

Aggregation

Aggregate, Average, Count, LongCount, Max, Min, Sum

Conversion

Cast, OfType, ToArray, ToDictionary, ToList, ToLookup, ToSequence

Element

DefaultIfEmpty, ElementAt, ElementAtOrDefault, First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault

Equality

EqualAll

Generation

Empty, Range, Repeat

Grouping

GroupBy

Joining

GroupJoin, Join

Ordering

OrderBy, ThenBy, OrderByDescending, ThenByDescending, Reverse

Partitioning

Skip, SkipWhile, Take, TakeWhile

Quantifiers

All, Any, Contains

Restriction

Where

Selection

Select, SelectMany

Set

Concat, Distinct, Except, Intersect, Union

 

Most of the operators should be familiar if you have ever worked with a relational database writing queries in SQL.

Range

Our first LINQ query will be about initializing a list. In the paragraph about C# 3.0 language extensions, we saw that we can initialize a list like this:

List<int> l = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

With LINQ, the initialization can be a lot less painful:

List<int> l =

Enumerable.Range(1, 10)

      .ToList();

The operator Range generates a sequence of integral numbers within a specified range: it takes in input the first integer value of the sequence (1 in our case) and how many contiguous elements have to be in the sequence (10 in our case). The return value of Enumerable.Range is an IEnumerable, so if we want a List<int> we’ll have to use the LINQ operator ToList(). Since Enumerable.Range returns an IEnumerable of integers, the list returned by ToList() will be made of integers. Our list, l, will be made up of ten integers, from 1 to 10, as we wanted.

Remember that, thanks to the local variable type inference, we may also write:

var l =

Enumerable.Range(1, 10)

      .ToList();

and the result is exactly the same.

 

Foreach

Suppose that we want to print our list of integers. To do so, we can use the LINQ operator ForEach: ForEach performs the specified action on each element of the sequence on which is called. The specified action can be a static function, an anonymous delegate, or (better) a lambda expression.

Using the static function your code will look like this:

static void PrintInt(int i)

{

    Console.WriteLine(i);

}

static void Main(string[] args)

{

    List<int> l = Enumerable.Range(1, 10).ToList();

 

    l.ForEach(PrintInt);

}

 

Using an anonymous delegate:

static void Main(string[] args)

{

    List<int> l = Enumerable.Range(1, 10).ToList();

 

    l.ForEach(

        delegate(int i)

        {

            Console.WriteLine(i);

        }

    );

}

 

Using a lambda expressions:

 

static void Main(string[] args)

{

    List<int> l = Enumerable.Range(1, 10).ToList();

 

    l.ForEach(i => Console.WriteLine(i));

}

 

The lambda expression we used, i => Console.WriteLine(i), takes an integer as input (i) and prints it on the Console, just like the static function or the anonymous delegate did, but with less code!

 

Aggregate

If we want to synthesize our list in only one element, then the Aggregate operator is exactly what we need. This operator takes two parameters:

·         A seed, that is the starting value of our computation

·         An accumulator function which takes

o   the current seed value

o   a list element

and computes the next value of the seed

Aggregate applies the accumulator function over the sequence (e.g., our List<int>); the initial accumulator value is the specified seed.

This operator can be used, for example, to find the maximum element of the list:

var max = l.Aggregate(int.MinValue, (seed, val) => Math.Max(seed, val));

The starting value of our computation (the initial seed) is int.MinValue, chose because any integer element will be greater than this.

The accumulator function is a lambda expression:

(seed, val) => Math.Max(seed, val)

Given the current seed value and a list element (called val), the next seed value will be the maximum between them: Math.Max(seed, val).

 

Let’s see another possible use of Aggregate:

var positives = l.Aggregate(true, (seed, val) => seed && (val > 0));

Positives contains a Boolean value, indicating whether or not all the elements in l are greater than zero. Why is that? The starting seed value is true; the accumulator function is the following lambda expression:

(seed, val) => seed && (val > 0)

You can see that, as soon as any list element is less-equal than zero, the seed becomes false forever (because false && “whatever” = false!). If the list does contain only positive integers the seed will remain always true.

 

Select

The  Select operator projects each element of a sequence into a new form: it takes in input a transformation function, which will be applied to all the elements of the sequence, thus generating a new sequence (given as output). The new sequence’s elements can have a type completely different from the one of the initial sequence’s elements.

Let’s start with a very simple example: suppose that we want to create a new  List<int>, containing the original elements increased by 1. Our LINQ query will be the following:

var l1 = l.Select(val => val + 1).ToList();

As you can see, the lambda expression used is:

val => val + 1

which takes an integer (val) in input and return as output the same integer increased by one (val + 1). After Select we have to call ToList() to concretize the query, because Select returns an IEnumerable.

But with Select we can do much more complicate stuff:

var l2 = l.Select(val => new { item = val, itemstr = val.ToString() }).ToList();

The above query produces a list (thanks to ToList(), otherwise it would be an IEnumerable), which elements have an anonymous type (C# 3.0 language extensions) made up by an integer called item and a string called itemstr:

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image005.jpg

val => new { item = val, itemstr = val.ToString() }

The integer contained in item is the same as in the original list, while in itemstr we put the string representation of such integer. What if we’d like to print this list?

l2.ForEach(i => Console.WriteLine(i.item + " – " + i.itemstr));

 

In the lambda expression used, the compiler knows the type of i, so when we write “i. ”  the IntelliSense kicks in and suggests the public field of such type (item and itemstr).

 

Order By

Orderby’s purpose is pretty clear and simple: this operator sorts the elements of a sequence in ascending order according to a key. The key corresponding to each element is produced by a transformation function, the only input parameter of Orderby.

If we want to sort lexicographically our list (using the field itemstr), the query we need is the following:

var orderedList = l2.OrderBy(i => i.itemstr).ToList();

 

Given an element of the list (i) we extrapolate its key (itemstr), which is used for the sorting process. The resulting IEnumerable is then converted in a List with ToList() and saved in orderedList.

Group By

GroupBy groups the elements of a sequence according to a specified key selector function. Let’s see an example of this operator:

var groups = l2

.OrderBy(i => i.item % 3)

      .GroupBy(i => i.item % 3)

      .ToList();

 

What does this query do? It groups the elements contained in l2 according to the key extracted by the lambda expression i => i.item % 3. This means that each element is associated to a key, which is its “modulo 3” value. What is the type of groups?

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image006.jpg

Groups is a list of IGrouping elements; each of these elements is therefore a group. A group contains the group key (modulo 3 in our example) and all the elements in that group (that is, all the elements which modulo 3 is equal to the group key).  We can print the groups with the following query:

groups.ForEach(

group => Console.WriteLine(

group.Key + " -> " +

group.Aggregate("", (str, i) => str + i.item + ", ")));

 

In this query you can a Foreach on the groups, which prints each group on the Console; the printing of the group elements, though, is a little tricky, and requires another query (specifically an Aggregate). The key of the group, instead, is easily accessible with group.Key.

You can see the result of this query in the following picture:

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image007.jpg

 

Each element is in the right group.

But there is an elephant in the room! All this time you may have been wondering why there is an OrderBy in our query:

var groups = l2

.OrderBy(i => i.item % 3)

      .GroupBy(i => i.item % 3)

      .ToList();

We need the OrderBy if we want our results to be sorted according to the groups’ keys. Removing the OrderBy from the query produces the following result:

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image008.jpg

As you can see, the results are not ordered according to the group key, since the “0” group is the last one.

 

Other operators (All, Any, Where, Skip, Take)

There are many other LINQ operators, and they are all very useful. You will find that they are not hard to learn; just in case, let’s see (very briefly this time!) other five operators.

All

This operator determines whether all elements of a sequence satisfy a condition (given as input, for example with a lambda expression). Let’s see a simple example:

var allPositives = l2.All(i => i.item > 0);

The above query determines whether all elements in l2 are positive integers (the condition is i.item > 0).

Any

This operator determines whether any element of a sequence satisfies a condition (given as input, for example with a lambda expression). Let’s see a simple example:

var anyPositive = l2.Any(i => i.item > 0);

The above query determines whether any element in l2 is a positive integer (the condition is i.item > 0).

Where

This operator filters a sequence of values based on a predicate (given as input, for example with a lambda expression). Let’s see a simple example:

var onlyPositives = l2.Where(i => i.item > 0);

The above query produces an IEnumerable containing only the positive elements of l2 (the condition is i.item > 0).

Skip

This operator bypasses a specified number of elements in a sequence and then returns the remaining items. Example:

var fromThird = l2.Skip(3);

The above query skips the first three elements in l2.

Take

This operator returns a specified number of contiguous elements from the start of a sequence. Example:

var first3 = l2.Take(3);

This query takes the first three elements in l2.

 

Manipulating infinite sequences

In this paragraph we are going to see how LINQ query operators can be used to manipulate infinite sequences (in particular we are going to consider lists).

Let’s start by writing an infinite sequence:

static IEnumerable<int> NaturalNumbers()

{

    int n = 0;

    while (true)

    {

        yield return n;

        n++;

    }

}

The sequence IEnumerable<int> NaturalNumbers “contains” (in a lazy evaluation kind of way) the natural numbers. Of course, no PC is capable of containing in memory all natural numbers: this collection is not materialized and it won’t be until someone requires it! The yield keyword works like a “pause button”: it makes possible keeping the collection frozen until someone needs the next element. At the beginning, the only element ready for use is the first, 0; all the others are waiting to be asked for.

This mechanism is very powerful, since it allows you to manipulate without any problem infinite sequences; when you want to, you can iterate the sequence as long as you need (just not forever!).

How can we use such sequence? How can we manipulate it?

var naturals = Naturals();

 

naturals does not occupy any memory: it’s not a List, it’s only an IEnumerable. Obviously, you can’t do this:

 

var naturals = Naturals().ToList();

otherwise you would go into infinite loop trying to materialize all the elements of naturals (which are infinite)!

We can use all the LINQ operators we want on the infinite sequence we built; the only constraint is that, at the end of our manipulations, we take only a finite number of values from the sequence. For example, suppose that we want to isolate the first ten multiples of 27; our code will look like this:

var multiples27 = naturalNumbers.Where(nat => nat % 27 == 0);

var first10multiples = multiples27.Skip(2).Take(10).ToList();

first10multiples.ForEach(n => Console.WriteLine(n));

 

In multiples27 we have the infinite sequence (not materialized, since we rightly didn’t called ToList()) containing the multiples of 27. This sequence has been built with a Where query on naturalNumbers, filtering only the values which modulo 27 was 0. Then we skipped the first two values (we do not want 0 and 27) and took the following 10 values. At this point (only after using a Take query!) we can materialize our query with ToList(), and then print the values on the Console; we can do so because after Take our sequence has a finite number of values. The result can be seen in the following picture:

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image009.jpg

This example, though nice, was pretty useless; let’s make something more interesting, like building the Fibonacci sequence. The Fibonacci sequence definition follows:

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image010.gif

We can put the Fibonacci sequence in an infinite sequence with this code:

static IEnumerable<int> FibonacciNumbers()

{

    int prev = 1, prevprev = 0;

    while (true)

    {

        int curr = prev + prevprev;

        yield return curr;

        prevprev = prev;

        prev = curr;

    }

}

We specified the first two values of the Fibonacci sequence (0 and 1); then, at each step, we compute the next value (sum of prev and prevprev) and update both prevprev and prev (shifting them ahead along the sequence).

var fibo = FibonacciNumbers();

 

As we know, fibo is just an IEnumerable, it is not materialized, and we cannot call ToList() on it. We can call ToList() only after a Take query:

 

var fibo21 = fibo.Take(21).ToList();

fibo21.ForEach(n => Console.WriteLine(n));

 

This code takes the first 21 values of the Fibonacci sequence, and then prints them on the Console:

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image011.jpg

If you are wondering why you should care about infinite sequences, let me tell you that there are many uses for them, even in videogames:

·         as random number generators

·         as perlin noise generators

·         as checkpoint generators

·         as generators of enemies from a spawning point

·        

 

Functional Programming in .NET – LINQ and C# 3.0 (Part 1 of 2)

Functional Programming in .NET – LINQ  and C# 3.0

By Giulia Costantini

Source code here, PDF version of this article here

 

This article wants to be an introduction to the LINQ (Language Integrated Query) library, released on November 2007 by Microsoft as a .Net Framework 3.5 component.

Functional programming

Since LINQ borrows several concepts from functional programming, it may be useful to talk a little about functional programming first.

As you can easily imagine from its name, functional programming focus itself on functions. In functional programming, functions are everything and everywhere:

·         A function can take another function as input parameter

·         A function can return another function as output

·         A function can be anonymous

Functional programming has another peculiar feature, which is static type inference. Type inference refers to the ability to deduce automatically the type of a value in a programming language and it is usually seen in scripting languages like Python. In functional programming, though, the type inference is static: this means that the types are deduced statically by the compiler, instead of being deduced at runtime. This makes the life of a programmer definitely easier.

Why should you be interested in learning the functional programming paradigm? There are plenty of reasons:

·         a functional programmer has to write less code which inevitably leads to less bugs and a more readable code

·         functional code is fast

·         functional code is multithread-ready: with  the escalation in the number of PC cores, the ability to write parallel code is going to become more and more important

If you are interested in these topics or you just want to know more about it, I suggest you try F#, a functional programming language which has been made a first class citizen of .Net Framework and which will be the subject of the next article I’m going to write.

LINQ basic concepts

LINQ comes in four different flavors:

1.       LINQ to SQL

2.       LINQ to DataSets

3.       LINQ to XML

4.       LINQ to Objects

We are going to focus on the last one, LINQ to Objects. We are going to use C# 3.0, since this release of C# implements very interesting features (such as anonymous types), which, together with LINQ, form an explosive combination (in a good way, of course J).

LINQ to Objects is a set of operators which allows you to manipulate sequences; by sequence, I mean any class which implements the IEnumerable interface. For example, List<T>, Array<T>, Dictionary<Tkey,Tvalue> are all implementations of IEnumerable. Note that LINQ works perfectly with generics: List<int> and List<string> are two completely different objects. With LINQ these sequences can be easily iterated, sorted, grouped, used to produce collection of different objects (e.g. from List<int> to List<string>), and so on. LINQ may make you feel like you are writing SQL queries, even if you are writing C# code and you are not manipulating databases!

Delegates and Lambda Expressions

Many LINQ operators take delegates as input parameters, so it’s better if we have a clear idea of what delegates are and what they do.

A delegate is a function pointer used in .Net Framework. You can instantiate a delegate in two ways:

·         With named method

·         With anonymous method

Delegates and named methods

Let’s see an example of using named method:

delegate void SampleDelegate(string message);

class Program

{

    // Regular method that matches signature:

    static void SampleDelegateMethod(string message)

    {

        Console.WriteLine(message);

    }

 

    static void Main(string[] args)

    {

        // Instantiate delegate with named method:

        SampleDelegate d1 = SampleDelegateMethod;

 

        // Call delegate

        d1("Hello World");

    }

}

 

In the above example, you can see:

·         The declaration of SampleDelegate, which is a pointer to a function (= delegate) that takes a string as input and has void output

·         A static method, SampleDelegateMethod, which matches the signature of the delegate SampleDelegate (that is, string as input and void as output)

·         The instantiation of a SampleDelegate, d1, using the static method SampleDelegateMethod; d1 is a delegate which takes a string as input and prints it on the Console.

·         Finally, we use d1 in the same way we would use a simple function, passing to it a string to print (“Hello World”)

As you may have guessed, this code prints “Hello World” on the console.

Delegates and anonymous methods

The other possibility, more concise, involves anonymous methods:

delegate void SampleDelegate(string message);

 

class Program

{

    static void Main(string[] args)

    {

        // Instantiate delegate with anonymous method:

        SampleDelegate d2 = delegate(string message)

        {

            Console.WriteLine(message);

        };

 

        // Invoke delegate d2:

        d2("Hello World");

    }

}

In this second example we have the same declaration of a delegate, SampleDelegate; the only difference is that we don’t have to create a static method (like SampleDelegateMethod), but we can instantiate directly the delegate using an anonymous method using the following syntax:

delegate(input parameter type and name)

{

// do something

};

 

This second example produces the same output as the previous one (prints “Hello World” on the console), but you can see that there is less code and we didn’t have to stain the namespace with a (nearly useless) static method like SampleDelegateMethod.

Lambda Expressions

But with C# 3.0 we have another alternative: Lambda Expressions. Lambda expressions are used to create delegates inline with other code. A lambda expression is generally composed like this:

input_parameter_name => action_to_take;

As you can see, you do not have to specify the input parameter type (the compiler infers it); after the input parameter you write “=>” (which represents an arrow) and then the function body (which goes within curly brackets if it’s more than one line of code). Basically, this syntax means: “take the parameter input_parameter_name as input and execute action_to_take.

Let’s see how our example changes using lambda expressions:

delegate void SampleDelegate(string message);

 

class Program

{

    static void Main(string[] args)

    {

        // Instantiate delegate with a lambda expression:

        SampleDelegate d2 = message => Console.WriteLine(message);

 

        // Invoke delegate d2:

        d2("Hello World");

    }

}

 

In this example, while instantiating d2 (SampleDelegate d2 = message => Console.WriteLine(message);), we have skipped:

·         Writing “delegate” (a SampleDelegate is obviously a delegate!);

·         Writing the type of the input parameter (the compiler knows that a SampleDelegate takes a string as input);

·         Writing the curly brackets (our function is made of a single line of code, so there’s no need to use brackets);

The resulting code is way less than in the other two alternatives we saw before (and it works the same way J).

Using LINQ operators we are going to make a massive use of lambda expressions, so it won’t make any harm seeing a couple more examples:

delegate void SampleDelegate(int number);

class Program

{

    static void Main(string[] args)

    {

        SampleDelegate d2 = number => Console.WriteLine(number.ToString());

        d2(10);

    }

}

In this example, our SampleDelegate delegate takes an integer as input and gives void as output. The lambda expression used to instantiate d2 is the following:

number => Console.WriteLine(number.ToString())

which means: take the input parameter called number and print it on the console. The compiler knows that number is of type int because SampleDelegate delegate takes an int as input.

Let’s see another example, in which the delegate output type is not void:

delegate int SampleDelegate(int number);

class Program

{

    static void Main(string[] args)

    {

        SampleDelegate d2 = number => (number * number – number);

        Console.WriteLine(d2(10));

    }

}

In this example, our SampleDelegate delegate takes an integer as input and gives another integer as output. The lambda expression used to instantiate d2 is the following:

number => (number * number – number)

 

which means: take the input parameter called number and give number * number – number as output. The compiler knows that number is of type int because SampleDelegate delegate takes an int as input.

What would happen if we wrote:

number => (number * number – number).ToString()

? The compiler would give us the following error:

Cannot convert lambda expression to delegate type ‘linq.SampleDelegate’ because some of the return types in the block are not implicitly convertible to the delegate return type.

The compiler is smart, and knows that the return type of d2 must be of type int.

Let’s see another example, in which the delegate body code is longer than one line:

delegate int SampleDelegate(int number);

class Program

{

    static void Main(string[] args)

    {

        SampleDelegate d2 = number => {

            int numberSquare = number * number;

            int result = numberSquare – number;

            return result;

        };

        Console.WriteLine(d2(10));

    }

}

This example is almost the same as before, with only one difference: the body of the lambda expression is longer than one line of code. This means that we have to use curly brackets to wrap it and that we have to use the keyword return.

You could be wondering if lambda expressions work with more than just one input parameter:

delegate int SampleDelegate(int number1, int number2);

class Program

{

    static void Main(string[] args)

    {

        SampleDelegate d2 = (n1,n2) => n1 * n1 – n2;

        Console.WriteLine(d2(5,4));

    }

}

 

This example shows you that lambda expressions can take as many input parameters as you like; you just have to enclose the parameters within round parentheses and separate them with commas:

(input_1, input_2, …, input_n) => action_to_take;

Note that the names of the input parameters in the lambda expression do not have to be the same ones you used in the delegate declaration. In our example, the delegate declaration had input parameters named number1 and number2, while the lambda expression had input parameters named n1 and n2!

Other C# 3.0 Language Extensions

Along with lambda expressions (covered extensively in previous paragraph), C# 3.0 has introduced other language extensions, which are very interesting and useful features (especially when working with LINQ). Let’s explore some of these language extensions, one at a time.

Implicitly typed variables

This feature can also be called local variable type inference and it’s a subset of static type inference (described when talking about functional programming). What does this mean in practice? That you can declare and instantiate a variable without having to specify its type. For example:

int i = 10;

becomes

var i = 10;

If you go over var with the mouse, you will see a box containing the type of i, that is System.Int32:

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image001.jpg

Pay attention to one thing: this type inference is local, which means that you have to declare and simultaneously instantiate the variable if you want the type inference to work. The following source code:

var j;

j = 10;

won’t work, and the compiler will give you the following error:

Implicitly-typed local variables must be initialized.

More than just syntactic sugar, this feature is required for the declaration of anonymous typed variables.

 

Anonymous Types

This feature allows data types with named fields to be created implicitly from the code that requires it. Since anonymous types do not have a named typing, they must be stored in variables declared using the var keyword (that is, the implicitly typed variables feature).

Let’s see an example:

var customer = new { Name = "James" };

 

In this example we create an anonymous type, containing only one field (Name) of type string. If you go over  var with the mouse, you’ll see the description of such type:

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image002.jpg

The anonymous type is identified with ‘a (which stays for alpha).

Let’s see an example of a type with multiple fields of multiple types:

var customerFull = new { Name = "John", Surname = "Smith", Age = 30, City = "Miami", PurchaseRate = 0.75f };

 

In this example, the anonymous type created has many fields, some of type string, one of type int and one of type float, as we can see in the following picture:

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image003.jpg

Note that, when we access one of these anonymous type variables, the IntelliSense works perfectly:

http://tfs08.dsi.unive.it/Sites/VSTeam2009/Shared%20Documents/CSharp%203.0%20-%20Linq%20introduction/EN/page_files/image004.jpg

The variable named customerFull contains the fields Age, City, Name, PurchaseRate and Surname, each with its own right type (in the picture we can see Age being of type int).

 

Object initializer

Thanks to this feature, you no longer have to create an object first and then use a statement for each of its assignments: if you have public properties/fields in the class, you can directly assign values to them while creating an instance of the class.

Let’s see an example:

class Customer

{

    public string name;

    public string city;

    int age;

    public int Age { get { return age; } set { age = value; } }

}

 

We defined the class Customer, which contains two public fields and one public property. Normally, we would initialize a Customer instance like this:

Customer c = new Customer();

c.city = "Miami";

c.Age = 30;

c.name = "John Smith";

 

With the object initializer, though, we can replace the previous code with this one:

Customer c = new Customer { name = "John Smith", city = "Miami", Age = 30 };

 

As  you can see, we have initialized all the public fields/properties of Customer, while creating the instance. The general syntax is quite simple:

ClassName c = new ClassName { field_1 = value_1, …, field_n = value_n };

Using the implicitly typed variables feature, we can reduce the code length and complexity even more:

var cust = new Customer { name = "John Smith", city = "Miami", Age = 30 };

 

We used var instead of Customer, leaving the type inference task to the compiler.

 

Collection initializer

The last language extension we are going to talk about is the collection initializer. This feature allows you to initialize collections way more concisely than usual. For example, before C# 3.0 initializing a list of integers with values 1, 2, 3 would have required you to write:

List<int> list = new List<int>();

list.Add(1);

list.Add(2);

list.Add(3);

 

With the collection initializer, we can now write:

List<int> list = new List<int>() { 1, 2, 3 };

 

which can be further reduced using var:

 

var list = new List<int>() { 1, 2, 3 };

 

 

Audio

Versione italiana

Playing audio into an XNA application

By Giulia Costantini


Introduction

In this tutorial we will learn how to load and play sounds in our XNA applications. The tool we are going to use is XACT (Cross-platform Audio Creation Tool), a multiplatform tool (works for both Windows and Xbox360) to create audio. This program is installed with XNA Game Studio, so if you have already installed XNA you are good to go! You can find XACT following this path: “all programs” –> “Microsoft XNA Game Studio 2.0” –> “tools” –> “Microsoft Cross-Platform Audio Creation Tool”. If you want to be able to listen to sounds within XACT (instead of having to open another player) you will have to open the following program (installed with XNA too): “all programs” –> “Microsoft XNA Game Studio 2.0” –> “tools” –> ”XACT Auditioning Utility”.

clip_image002

 


Basic XACT notions

Let’s start by getting acquainted with the XACT and XNA sounds terminology.

A wave is an audio data buffer, that is a file which contains audio. The XACT supported formats are wav, aiff and xma.

A sound is instead a set of tracks played at the same time; for each track we can set various properties, such as the wave that track plays, its volume, etc…

The term cue refers to the logical sound, that is what is actually used in your source code to play a sound. Each cue can be made up of one or more sounds; if it’s made up of many sounds, when the cue is played one of its sounds is chosen. With XACT we can decide how the choice (of which sound to play) is carried out: for example we can make the choice random, or we can decide that the sounds have to be played sequentially in the order we put them, and so on.

A wave bank is a wave collection, that is a collection of audio files. A wave bank is represented by a file with .xwb extension. For each wave bank we can set various properties, such as the compression method for the audio files, if the execution is carried out in streaming or by storing the entire file, etc…

A sound bank is a collection of sounds and cues. A sound bank is represented by a file with .xsb extension.

We are going to see that a XACT project can be viewed as the whole of three files:

  • a .xgs file which contains the global settings of the project;
  • a .xwb file, that is the wave bank which contains our wave files;
  • a .xsb file, that is the sound bank which contains all the sounds and cues.

 

How to create a XACT project

First of all we are going to create an XNA 2.0 project with Visual Studio (“file” –> “new” –> “project” –> “windows game 2.0”) and we will add a new folder named “Sound” (but you can call it how you want) to the Content project (right click on Content –> “add” –> “new folder”).

image

Now we can create our XACT project. After having opened XACT, click on “file” –> “new project” and set the path to “your_xna_project_path\Content\sound”. Let’s call our XACT project myFirstXACTProject.

image

Now we will have to create a new wave bank and a new sound bank, by right clicking respectively on “Wave Banks” and on “Sound Banks” and select respectively “New Wave Bank” and “New Sound Bank”.

image image

Our banks (which by default are named “Wave Bank” e “Sound Bank” but we can change the name by clicking F2 on each of them and inserting the new name) are now on the right of the screen.

image

Adding audio files to the wave bank couldn’t be easier: we have to select our audio files and drag them on

to the wave bank. Remember that the XACT supported formats are wav, aiff and xma.

image

We imported in our wave bank two files, named “industry.wav” and “menu.wav”. The result is the following:

image

Let’s move on to the sound bank; we said that a sound bank contains a collection of sounds and cues; if you look at the sound bank window you’ll notice that it is made up of two separate parts, one for the sounds and one for the cues:

image

To create a new sound you have to drag a wave from the wave bank into the “sounds part” of the sound bank. Dragging the “industry” wave we obtain:

image

This way we created the “industry” sound (but we can change the sound name) which is made up of only one track, that is the “industry.wav” wave. We can add other tracks to the sounds (by dragging another wave on the sound name), but remember that the tracks of a sound are executed simultaneously.

We can create another sound, linked to the “menu” wav file, by dragging the “menu” wave from the wave bank to the sound bank:

image

At this point we have two sounds, each one linked to only one wave. In order to create a cue we will have to drag a sound into the cues part. Dragging the “industry” sound into the cues we obtain:

image

We created a cue named “industry” (we can change this name too) linked to the “industry” sound.

Remember to save your XACT project when you are done!


Loading a XACT project in XNA

Let’s go back to Visual Studio, precisely in our XNA project. We have to include the just created XACT project into the Content project. To do so, click on Content project, then click on “Show all files” in order to see the XACT file project

image

and now right click on the newly appeared.xap file (“myFirstXACTProject.xap”).

image

and finally select “Include in Project”. Compiling our project we can see in the output window:

image

that the XNA Content Pipeline (which you saw in a previous tutorial) produced 3 files, the one I mentioned at the beginning of this tutorial: a general settings file (.xgs), a w

ave bank file (.xwb) and a sound bank file (.xsb).


Playing sounds into the application

The time has arrived for us to write some code J We’ll start by creating 3 objects (in the Game class):

AudioEngine engine;

WaveBank waveBank;

SoundBank soundBank;

and we’ll initialize them in the“LoadContent” function:

engine = new AudioEngine("Content\\sound\\myFirstXACTProject.xgs");

waveBank = new WaveBank(engine, "Content\\sound\\Wave Bank.xwb");

soundBank = new SoundBank(engine, "Content\\sound\\Sound Bank.xsb");

We have loaded the 3 files our XACT project is made of, that is

1. the settings file .xgs (which goes into the AudioEngine),

2. the wave bank .xwb (which goes into the WaveBank object)

3. the sound bank .xsb (which goes into the SoundBank object).

The waveBank and soundBank need also the engine to be initialized properly.

Now we have two possible way to play a sound. The first one is the following:

soundBank.PlayCue("industry");

which makes use of the sound bank to directly play the cue, identified by its name (we reproduced the “industry” cue). If we insert this line of code into the LoadContent function (just after the creation of the three object engine, waveBank and soundBank) we’ll obtain that the sound linked to the “industry” cue will be played once when the application starts.

The second possibility is to define another object

Cue cue;

of Cue type, and to write in the LoadContent function:

cue = soundBank.GetCue("industry");

cue.Play();

What did we just do? We took the “industry” cue from the sound bank, we stored it into a Cue object and we played it. The results is just the same, which is the “industry” cue is executed at the application launch.

What if we wanted to play some sound only when a certain key is pressed? We will have to write the following code in the “Update” function:

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

{

cue = soundBank.GetCue("industry");

cue.Play();

}

This way, when space is pressed the desired cue will be played.

But we encounter a problem: we know that the function Update is invoked many times per second. So, during our space key pressure the Update function will be called many times and each one of them the execution of the “industry” cue will be started again. The result is that our sound is executed many times, each one some thousandth of second after the previous. Moreover if we press space again (after some seconds) while the executing sound has yet to stop, another instance of the sound will start and it will be overlapped to the first one. How can we avoid this unpleasant situation? Thanks to the isPlaying property of the Cue object! Such property tells us if the cue is being executed; this way we can begin the execution of a cue only when such cue is not already playing. Source code:

if (cue != null && cue.IsPlaying == false)

cue = null;

if (Keyboard.GetState().IsKeyDown(Keys.Space) && cue == null)

{

cue = soundBank.GetCue("industry");

cue.Play();

}

In this code we decided that a cue is null when it isn’t being executed. In fact, if the cue isn’t null and it’s executing a sound and this sound ends, the cue isPlaying property will become false and the cue will be set to null. Pressing space has some effect only if the cue is null, that is if the cue isn’t being executed.

We solved our problem: our cue will be executed if and only if space is pressed and if it wasn’t already executing (which is exactly what we wanted)!

NB: the cue obtained with GetCue can be played only one time; after that the cue has been “consumed” and it’s not valid anymore. Because of this, before each “cue.Play()” we have to obtain again the cue from the sound bank with GetCue.


(Quite) advanced XACT notions

The XACT tool makes the sound technician totally independent from the programmers. Why is that? We saw that we use the cues by name (for example we played the cue named “industry”). If the sound technician modifies only the waves and the sounds linked to the cues, but she leaves the cues names unchanged, she can work on her own and our source code will continue to work. So the sound technician can improve and modify the cues with XACT, and with only a simple recompilation of our XNA project (during which the 3 files xgs, xwb and xsb will be re-created, if necessary) we will have the updated sounds without having to change even a single line of code.

But what can a sound technician exactly do with XACT?

We saw that a sound can be made of more tracks (dragging the name of each wave on the sound name): these tracks will be however executed simultaneously. We can also delete a track from a sound by clicking on the track and then clicking “del”. In the following image you can see a sound (“industry”) which is made of two tracks (the “industry” and the “menu” waves):

image

In a sound bank there can be many sounds, each one linked to certain tracks:

image

Each cue can be linked to many sounds, simply draggin them on the cue name. In the following image we can see the “cue1” cue which is made of both the sounds in the so

und bank, that is “industry” and “menu”.

image

If a cue contains many sounds, we can set how the choice of which sound to play is carried out.

image

In this picture you can see the drop-down menu with which you can set such property: the possibilities are many.

You can find here the source code of this tutorial and here the high-res webcast in which Alessandro Piva explains XACT and shows the code writing on-the-fly. An embedded version (lower res) can be found below:

 if(window.$WebSecurity){window.$WebSecurity.FlashDetection.HandleEmbedCode(‘985ebdc1-aa76-40bf-be09-41350a1f484b’, ‘\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 quality\x3d\x22high\x22 wmode\x3d\x22transparent\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d90b97973-ec2f-43bf-89c5-f01ff5d8e405\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’);}else{if(window.flObj == null){window.flObj = new Object();}window.flObj['985ebdc1-aa76-40bf-be09-41350a1f484b']=’\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 quality\x3d\x22high\x22 wmode\x3d\x22transparent\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d90b97973-ec2f-43bf-89c5-f01ff5d8e405\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’;}

Text and 2D primitives in XNA

Versione italiana

by Giulia Costantini

 

Introduction

XNA has a very neat support for drawing 2-dimensional objects on the screen. Tipically this is accomplished inside your Game.Draw function through the use of a helper object known as the sprite batch:

SpriteBatch spriteBatch;

A sprite batch is a way to group together a series of sprite draw calls to optimize them by rearranging them somehow. By "sprite" we mean some kind of a rectangular object which pixels come from a texture and that we want to render on the screen.

Using a sprite batch means that we have to somehow define which set of draw calls we want our sprite batch to manage. The sprite draw calls that a sprite batch will take care of are those that are made between calls to SpriteBatch.Begin and SpriteBatch.End:

spriteBatch.Begin();

/*...*/

spriteBatch.End();

Begin can optionally take three important parameters that affect rendering:

· SpriteBlendMode to specify whether or not alpha blending is active, additive or disabled

· SpriteSortMode indicates in which order to execute the actual draw calls: from depth = 0 to depth = 1, in the opposite order, immediate execution of each draw call, deferred to the call to End()

· SaveStateMode to save the graphic device flags before Begin() and to restore them when End() is called: this is handy when you want to make the use of SpriteBatch transparent to other rendering modules.

SpriteBatch.Draw

When it’s time to render, it comes the moment of the first draw primitive: SpriteBatch.Draw. That function takes, as basic parameters, a texture, a rectangle (in pixel of the screen) over which the texture has to be drawn, and a color by which multiply the texture’s one. Hence, to insert a texture as background we’d have to write:

spriteBatch.Draw(Content.Load<Texture2D>("background"),
    new Rectangle(0, 0, 800, 600), Color.White);

This Draw call means that we want to draw the “background” texture with its original color (multiplying by Color.White leaves the color unchanged) in the screen area which starts at pixel (0,0) and is large (800,600) pixels:

clip_image002 

Let’s say now that we want to draw a rotating object of some kind on the screen. We know that such object is in position “Position” and is rotated by “Rotation” radiants with respect to its center. We’ll have to call again Draw, but we’ll have to introduce and define a draw parameter which represents the rotation origin. By default a sprite is rotated around its top-left corner, where the object is actually posizioned:

clip_image004clip_image006clip_image008

This effect is not what we want: we would like to sprite to rotate around its center, not its corner. There exists a Draw function form which takes also this parameter: the origin of the rotation. Such parameter indicates the texture origin, used also for its Position parameter. In the picture here we can see that the origin is the texture center, which is  (25,25) assuming that the texture is large (50,50). Any rotation will be now relative to the center and not to the corner, just as we wanted. The resulting function call will be:

spriteBatch.Draw(Content.Load<Texture2D>("rotating_particle"),
    new Rectangle((int)Position.X, (int)Position.Y, (int)Size.X, (int)Size.Y),
    null, Color.White, Rotation, Size / 2, SpriteEffects.None, 0.0f);

You can see that the texture is in position Position, has size Size and is centered on its central point Size/2, in order to rotate the object with respect to the center and not to the corner (0,0).

SpriteBatch.DrawString

Drawing text is not much more complicated. Firstly though we need a spritebatch content file, to describe the font type we’ll be using, its parameters (size, bold, italic, etc.) and the characters set to load (the default is Basic Latin, which covers from the ASCII space to the tilde ~). We create the content file “Arial.SpriteFont”:

clip_image009clip_image010clip_image012clip_image014

clip_image016

In this simple xml file there are specified:

  • the system font type to use for the drawing (arial),
  • its size in points (14),
  • spacing,
  • kerning use,
  • style (bold, regular, italic)
  • characters range to use (the aforementioned Basic Latin set covers characters from 32 to 126).

If we want to draw on the screen the omnipresent “Hello World!” string, then we’ll have to call:

spriteBatch.DrawString(Content.Load<SpriteFont>("arial"), "Hello World!",
    new Vector2(10, 70), Color.LightBlue);

The DrawString function wants the SpriteFont to usare for the text, which text has to draw, its screen position (referred to the string top-left corner) and the text color. This function call produce the desidered string in blue starting at pixel (10,70):

clip_image018

What if we wanted to rotate the string around its center? We’d have to set the Origin of our DrawString to a half of the string size; but in order to do so we have to know how large will be the string on screen. Fortunately SpriteFont can give us this measure:

SpriteFont Arial = Content.Load<SpriteFont>("arial");
Vector2 stringSize = Arial.MeasureString("Hello World!");

Thanks to this measure, we can draw our text string rotating around its center:

float Rotation = (float)gameTime.TotalGameTime.TotalSeconds;
SpriteFont arialBig = Content.Load<SpriteFont>("arialBig");
Vector2 stringSize = arialBig.MeasureString("Hello World!");
spriteBatch.DrawString(arialBig, "Hello World!", new Vector2(400, 300),
    Color.Yellow, Rotation, stringSize / 2, 1.0f, SpriteEffects.None, 0.0f);

clip_image002[4]

Handcrafted Fonts

Until now we saw only true type fonts already installed in our system; however we could have a font drew by an artist, like the one in the following figure:

clip_image004

Instead of directly importing this font as a texture, we will be able to elaborate it with an appropriate content processor and to load it as a sprite font. The first step in reaching this goal is to import the file in the game content project:

clip_image006

From a previous tutorial we know that the file will have to be imported with a texture processor, but we want it to be processed with another processor able to read each single character and offer it to us. Such processor exists and it’s called Sprite Font Texture – XNA Framework. The processor can be activated from the file (“customfont.png”) properties:

clip_image002[6]

In order to work properly the font will have to obey two conditions:

· the alpha channel will have to reflect which texture parts are characters e which are the characters’ background

· Amongst the characters there has to be magenta color with alpha set to opaque

And just like this, you can load and use your custom-made font:

spriteBatch.DrawString(Content.Load<SpriteFont>("customfont"), "test-text",
    new Vector2(10, 10), Color.LightBlue);

Special Unicode Characters

Let’s go back to loading a true type font installed in our system. Assume we want to be able to insert special characters, in order to draw on screen a text which contains, for example, “€ ™ ∞”. We can try simply inserting those characters in our DrawString function call and all we will obtain is a runtime error which will make our game crash! Remember that, when creating the sprite font, at the end of the automatically gneerated file there were a “character regions” series, which indicated the characters set we want to use. By default the only loaded set is Basic Latin, but we can expand it in two different ways. The first way is obviously to find Unicode character list and manually add the desired characters’ codes in the sprite font definition. The second way seems more complicated when actually it gives us a lot more control. We have to create a custom pipeline in our game solution:

clip_image004[4]

The only class that our processor has to contain will be a class which adds the desidered characters to the set of characters which will be loaded and then calls the original processor with the modified character set:

namespace FontProcessor
{
    [ContentProcessor(DisplayName = "ExtendedCharacterSetFontProcessor")]
    public class ContentProcessor1 : FontDescriptionProcessor
    {
        public override SpriteFontContent Process(FontDescription input,
            ContentProcessorContext context)
        {
            input.Characters.Add('€');
            input.Characters.Add('™');
            input.Characters.Add('∞');

            // should load this list of characters from a file!

            return base.Process(input, context);
        }
    }
}

Now we can add this project to the Content project references:

clip_image006[4]

And finally we set the processor for our sprite font file to the just created processor:

clip_image008

The arial font will be exactly as before, but it will support the characters added by the processor, making possible and perfectly valid the call:

spriteBatch.DrawString(Content.Load<SpriteFont>("arial"), "€™∞",
    new Vector2(10, 70), Color.LightBlue);


Conclusion

The source code can be found here, while the webcast in which Giuseppe Maggiore explains all with greater detail and shows you the code writing on the fly can be found here, or you can watch it in its low-res embedded version below:

 if(window.$WebSecurity){window.$WebSecurity.FlashDetection.HandleEmbedCode(‘b2e6b1e5-0832-4165-a9e7-0f7d88411fef’, ‘\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 quality\x3d\x22high\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 wmode\x3d\x22transparent\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d867d427b-4686-4fe7-94f8-8af16571cdf0\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’);}else{if(window.flObj == null){window.flObj = new Object();}window.flObj['b2e6b1e5-0832-4165-a9e7-0f7d88411fef']=’\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 quality\x3d\x22high\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 wmode\x3d\x22transparent\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d867d427b-4686-4fe7-94f8-8af16571cdf0\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’;}

XNA and Windows Forms

Versione italiana

by Alessandro Piva

Hello everyone! During development of a game, there is always need for one or more editors, that is, programs to create maps, missions, levels, and so on. Often it is possibile to find, surfing the net, editors written and freely distributed by other developers – but, if you can’t manage to find one that fits your needs, the only solution is to write your own editor.

To create the user interface of our editors, we can use Windows Forms – those buttons, text boxes, bars, menus we can find in almost all programs. The purpose of this webcast is exactly this: how to insert, in the window of out XNA application, some Windows Forms! Moreover, some examples of usage are shown. Here it is a demo screenshot:

Windows Forms in XNA screenshot

Sadly these controls can’t be used in a fullscreen game, neither on the XBox 360, but as we just said they can be very useful in building editors or similar programs.

Enjoy!

P.S: I almost forgot: obviously you can download the source code, the high-res webcast, while the low-res webcast is just below:

 if(window.$WebSecurity){window.$WebSecurity.FlashDetection.HandleEmbedCode(‘6586a9ff-a2e7-42ce-9150-1e9e8f22c7c6′, ‘\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 quality\x3d\x22high\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 wmode\x3d\x22transparent\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d53238e3b-d7cc-4964-8621-df7feae98067\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’);}else{if(window.flObj == null){window.flObj = new Object();}window.flObj['6586a9ff-a2e7-42ce-9150-1e9e8f22c7c6']=’\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 quality\x3d\x22high\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 wmode\x3d\x22transparent\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d53238e3b-d7cc-4964-8621-df7feae98067\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’;}

Input management in XNA

How to allow user interactions with our game!

by Giuseppe Maggiore

Introduction

Input management is not as straightoforward as one might expect: input happens at a much slower pace than the frequency the application updates itself with. This means that, especially in a simple and casual game the input-based interaction between user and game will be about a few every second (~some Hz), while the game will update itself with the same speed at which it will draw on the screen every frame (~some tens of Hz). This means that we will have to take into account the need to somehow slow down the input (or make it appear so) in order for the two sequences of events to cooperate the proper way.

Supported hardware

XNA fully and natively support the following input peripherals:

- Mouse

- Keyboard

- XBox 360 Controller

These three choices are not random, they just are the entire set of default peripherals you may find on one of the XNA supported platforms, that is Windows or the Xbox 360. Using different input devices is possible, but it will require the usage of external libraries and will most likely not work under the XBox 360…

Querying the status of an input device

Reading a peripheral input means getting a snapshot of that device at a given instant:

GamePadState gps = GamePad.GetState(PlayerIndex.One);
KeyboardState kbs = Keyboard.GetState();
MouseState mss = Mouse.GetState();

Clearly such a snapshot will shortly cease to be reliable, since one of these states does not self update. This is why we will have to update the snapshot of our input devices every frame or (but this would be quite an overkill J) even more often.

Let’s start with a very simple example: we wish to close our game if the player presses the ‘back’ key on the XBox 360 controller. So we add a few lines to our Update function:

protected override void Update(GameTime gameTime)
{
    gps = GamePad.GetState(PlayerIndex.One);

    if (gps.Buttons.Back == ButtonState.Pressed)
        this.Exit();
}

Notice how we update the GamePadStatus at the beginning of each and every call to Update.

Problems with time

Let’s say we just built a simple game with a spaceship located at the center of the screen. Whenever the user presses the ‘A’ button on the XBox Controller the spaceship should launch a missile. A naive (and sadly for us quite wrong) solution to the problemi would look like:

if (gps.Buttons.A == ButtonState.Pressed)
    shoot();

Now let’s say that the user held the button for a short time, something like two tenths of a second, and that the game is running at a smooth 60 fps:

clip_image002[1]

this means that while the user was pressing ‘A’,

 clip_image004[1]

fotograms passed, each with its own call to Update. Every one of these calls to Update spawned a new missile, with the quite unpleasant result shown in this figure:

clip_image006

We will have to take care of events like prolonged (more than one frame) input events, but we would like to do so with some smart move, possibly not with some array of booleans tracking which key is down and which one is not. Well, the easiest way is to store not only the current GamePad state, but also that of the previous frame:

protected override void Update(GameTime gameTime)
{
    prevGamePadState = gamePadState;
    gamePadState = GamePad.GetState(PlayerIndex.One);

    /*…*/
}

Thanks to this second piece of information we can check wether or not the user has just started pressing a button (and in this case we shoot) or has been pressing for a few frames (and these spurious interactions will jsut get ignored):

if (gamePadState.Buttons.A == ButtonState.Pressed &&
    prevGamePadState.Buttons.A == ButtonState.Released)
{
    Missile m = new Missile();

    m.p = Vector3.Zero;
    m.v = Vector3.Forward;

    missiles.Add(m);
}

What happens is that any pressure of the ‘A’ button will now shoot just one missile:

clip_image008

We will now show a more general technique to handle time based input events.

Let’s say we want our ship to shoot a missile in the direction where the right thumbstick is pressed (the right thumstick is highlighted in the left figure):

clip_image010clip_image012

Our first, naive, experiment is similar to what we did before when shooting with pressures of the ‘A’ button: pressing the thumbstick beyond a certain threshold (to make sure we do not shoot because of small, possibily random fluctuations) will spawn a missile in that direction:

if (gamePadState.ThumbSticks.Left.Length() > 0.25f)
{
    Missile m = new Missile();
    m.p = Vector3.Zero;
    m.v = new Vector3(gamePadState.ThumbSticks.Left.X, 0.0f,
    gamePadState.ThumbSticks.Left.Y);
    missiles.Add(m);
}

Clearly too many missiles will be shot, since pressing the thumbstick even shortly will still spawn as many missiles as the frames during which the pressure takes place:

clip_image014

This time using the previous frame GamePadState will not be enough, since we would like to force the user to relieve the pressure to the thumbstick before shooting a new missile. This means that we will not have a single threshold (like 0.25f) below which we do not shoot and over which we shoot. We will have to manually wait for the thumbstick to be put back to a position that is enough close to its resting state:

if (waitThumbstick == true)
{
    if (gamePadState.ThumbSticks.Left.Length() < 0.15f)
        waitThumbstick = false;
}
else
{
    if (gamePadState.ThumbSticks.Left.Length() > 0.25f)
    {
        Missile m = new Missile();
        m.p = Vector3.Zero;
        m.v = new Vector3(gamePadState.ThumbSticks.Left.X, 0.0f, gamePadState.ThumbSticks.Left.Y);
        missiles.Add(m);
    }
}

Thans to the explicit variable waitThumbstick we will force the user to relieve the thumbstick pressureAfter every shot. This way we divide the application status in two: "can shoot" (waitThumbstick = false) and "cannot shoot, release the thumbstic before" (waitThumbstick = true)!

A simple Camera manager

Now that we can read the user input, let’s decide that we will update the camera matrix based on the user directives. In particular, we want the user’s look direction to depend on input coming from either the thumbstick or the mouse.

First of all we declare the camera rotation (horizontal and vertical) as a 2D vector:

Vector2 cameraRotationVector = Vector2.Zero;

then in the Update function we will update the rotation angles based on the thumbstick or mouse movements (multiplying the input amount by the length of last frame, so that movements will be independent of the framerate):

cameraRotationVector += gamePadState.ThumbSticks.Right *
    (float)gameTime.ElapsedGameTime.TotalSeconds;

At this point we will have to build the View, and even though there are literally hundreds of ways to do so, I have chosen the way that requires the less code :) . We will create our View matrix with a call to Matrix.CreateLookAt, and then we will rotate it of cameraRotationVector:

Matrix View
 {
     get
     {
         Matrix cameraRotation = Matrix.CreateRotationY(cameraRotationVector.X) *
         Matrix.CreateRotationX(cameraRotationVector.Y);
         return Matrix.CreateLookAt(Vector3.Up * 5000.0f, Vector3.Zero,
         Vector3.Forward) * cameraRotation;
     }
 }

To move around our camera we could move the eye position by cameraRotation.Forward, cameraRotation.Backward, etc.

Conclusion

You may find the complete source code for this tutorial online. Here (and -other mirror- here) you can download the webcast where I write and explain fully the source code of the tutorial. Also, should you prefer to watch the video directly from the web, here is an embedding of the same video file (just the resolution is lower):

 if(window.$WebSecurity){window.$WebSecurity.FlashDetection.HandleEmbedCode(‘068e74b6-6d66-4b49-bb2e-6e5b2d0974e3′, ‘\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 quality\x3d\x22high\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 wmode\x3d\x22transparent\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d5c0c7e82-a4dc-4ee7-9e77-0283b319a674\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’);}else{if(window.flObj == null){window.flObj = new Object();}window.flObj['068e74b6-6d66-4b49-bb2e-6e5b2d0974e3']=’\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 quality\x3d\x22high\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 wmode\x3d\x22transparent\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d5c0c7e82-a4dc-4ee7-9e77-0283b319a674\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’;}

Speech recognition – not technical

Versione italiana

Hi! I am Giuseppe Maggiore, and in this session I will show you our latest project, the one we are going to submit for the first round of the Imagine Cup of this year. In particular I will focus on how in our game you can control completely everything, from the menu

screenshot1

to the game UI

screenshot3

with voice. This is quite cool to experience, and I hope that this short gameplay video where I control the game with my XBox 360 Controller and with vocal commands is intriguing too. I’ll just add a few more screenshots:

screenshot1 screenshot2 screenshot3

The high-resolution webcast is found here. If you do not want or care to download the entire video file, you can watch the low resolution embedding of the same file here:

 if(window.$WebSecurity){window.$WebSecurity.FlashDetection.HandleEmbedCode(‘7ee1dc41-d5b1-4b4b-8abd-4422837af78d’, ‘\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 quality\x3d\x22high\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 wmode\x3d\x22transparent\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d6dfa2a53-8947-45f4-8e3c-9a6b87ab2a1c\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’);}else{if(window.flObj == null){window.flObj = new Object();}window.flObj['7ee1dc41-d5b1-4b4b-8abd-4422837af78d']=’\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 quality\x3d\x22high\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 wmode\x3d\x22transparent\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d6dfa2a53-8947-45f4-8e3c-9a6b87ab2a1c\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’;}

Basic Content Pipeline

Versione italiana

Hi! I am Giuseppe Maggiore, and in this tutorial I will talk to you about one of the less glamorous, yet most useful, features of XNA. We will build a custom content pipeline, that is a series of classes stored into an assembly used to load in your game the content of some file. Unclear? Of course, at first it may sound like something a bit overcomplicated for something as simple and straightforward as loading a file. But in reality, it is much more. First of all, XNA works on both the XBox 360 and Windows. While loading a file might be straightforward in Windows, it is not when working with the XBox 360. Also, keep in mind that any kind of game will need to do at least some basic sort of processing to convert the raw data files into the various classes and objects. So basically, the logical diagram is the following:

image

an artist or a designer creates a data file. Then this file has to be read in its raw format (importer), parsed and turned into an appropriate class (processor) and finally stored in an intermediate .xnb file (writer). When the game is fired, the .xnb file will be turned back into the container class (or a refinement of it) through the content manager (reader). The solution of a game with a content processor looks a little like this:

image

on the top you can see the custom pipeline project, which contains an importer, a processor, a writer and a reader. The other project is the actual game, which contains two references to the custom pipeline (one for the actual processing, that is import-process-write, and another for the loading, that is the reader). Also, in the game content you can see a .custom file, which is the custom data file that our custom pipeline is capable of loading.

You can find the source code of this sample here, while the webcast is found here. If you do not want or care to download the entire video file, you can watch the low resolution embedding of the same file here:

 if(window.$WebSecurity){window.$WebSecurity.FlashDetection.HandleEmbedCode(‘f989ae7c-2ef9-476c-bffc-8a209e560b71′, ‘\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 quality\x3d\x22high\x22 width\x3d\x22385\x22 height\x3d\x22325\x22 wmode\x3d\x22transparent\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d546b8c16-7b04-4fe4-822d-3025ca731d32\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’);}else{if(window.flObj == null){window.flObj = new Object();}window.flObj['f989ae7c-2ef9-476c-bffc-8a209e560b71']=’\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 quality\x3d\x22high\x22 width\x3d\x22385\x22 height\x3d\x22325\x22 wmode\x3d\x22transparent\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d546b8c16-7b04-4fe4-822d-3025ca731d32\x26amp\x3bfrom\x3dwriter\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’;}

We want you!

Versione italiana

we-want-youHi, I am Giulia Costantini, and, surprisingly, I am not here to talk to you about some XNA tutorial!

If you were wondering what we have been doing the last weeks, the answer is simple: we are working at our Imagine Cup project! Imagine Cup is a world-wide competition for university and high-school students; this year they added the "Game Development" category, for which you have to create a videogame with XNA. The videogame has to pertain to a specific theme: "How technology can help environmental sustainability".

Why are we talking to you about this? Because we are quite far along in the development of our game, but we are all programmers… we need a graphic artist, we need models and textures!!!

If you are a university student, you can join our team officially and try winning the Imagine Cup with us! If you are not, do not worry! Contact us anyway and we will find some agreement.

So, what are you waiting for…? Write to us (xnalearners _at_ hotmail.com)!

Bye! Giulia

Put a Python in your game!

Versione italiana

Hello, I’m Giulia Costantini and in this tutorial you will be shown how to put a Python console in your game. Why Python? Simple, because it is one of the most powerful, flexible and easy to use scripting languages out there.

The Python console is actually a game component (see our previous tutorial about components if you do not know what a component is). With this console, we can modify our in-game objects without the need to recompile, modify the configuration files, etc… and we can also dynamically read and execute Python scripts at run-time!

In the video-tutorial Giuseppe Maggiore will explain to you how you can embedd Python into your project and how you can create the Python GameComponent.

piramide

As you will see in the webcast, we will be able to modify the public objects in the game via the Python console: for example, we could clear the list of drones and all the drones will disappear from the screen! Then we could add some other drones (the drones list is publicly accessible from the ‘game’ global variable) and voila’: new drones would appear!

The console looks like this:

console

Here you can find the source code used in this tutorial. Have fun!

Here is a low-res version of the videotutorial:

 if(window.$WebSecurity){window.$WebSecurity.FlashDetection.HandleEmbedCode(‘49502aa3-a6e9-4c5e-a941-7aa7d5f7f3ee’, ‘\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d003b275b-f1a9-4c20-a19a-f7dbef4e6e74\x26amp\x3bfrom\x3dwriter\x22 wmode\x3d\x22transparent\x22 quality\x3d\x22high\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’);}else{if(window.flObj == null){window.flObj = new Object();}window.flObj['49502aa3-a6e9-4c5e-a941-7aa7d5f7f3ee']=’\x3cembed src\x3d\x22http\x3a\x2f\x2fimages.video.msn.com\x2fflash\x2fsoapbox1_1.swf\x22 width\x3d\x22432\x22 height\x3d\x22364\x22 type\x3d\x22application\x2fx-shockwave-flash\x22 flashvars\x3d\x22c\x3dv\x26amp\x3bv\x3d003b275b-f1a9-4c20-a19a-f7dbef4e6e74\x26amp\x3bfrom\x3dwriter\x22 wmode\x3d\x22transparent\x22 quality\x3d\x22high\x22 pluginspage\x3d\x22http\x3a\x2f\x2fwww.macromedia.com\x2fgo\x2fgetflashplayer\x22 allowscriptaccess\x3d\x22never\x22 allownetworking\x3d\x22internal\x22 \x2f\x3e’;}

Giulia Costantini

P.S.: special thanks to Alessandro Piva for the great idea of putting IronPython into our games.