Latest News
Mar 27, 2017, 7:26 AM

Today I found out that System.Timers.Timer is buggy and doesn’t work when used in a windows service application. Microsoft suggests we use the System.Threading.Timer object instead.

http://support.microsoft.com/kb/842793

I looked into it, and found that to use the System.Threading.Timer object, you have to supply it with a delegate to a static method that it can call when the timer event is triggered. In my application, that means I would have to change virtually all my methods and variables to being static, not something that I wanted to do. So instead I wrote my own timer, using the System.Threading methods. This is a fairly simple timer system:

using System;
using System.Threading;

class TimerExample
{
static void Main()
{
AutoResetEvent arv = new AutoResetEvent(false);
bool Stop = false;
int called = 0;

while(Stop == false)
{
arv.WaitOne(5000);
called++;
Console.WriteLine(string.Format("Waited: {0}", called));
if(called == 10)
Stop=true;
}
}
}

There’s one thing to keep in mind here; this effectively locks up the current thread until the elapsed time has passed. In the above example, the elapsed time is 5 seconds (5000 milliseconds). It shouldn’t take very much to build this concept into an instantiable class that uses a separate processing thread to prevent locking up your application until the elapsed time, and I’d highly advise that you do so.

Today’s discovery of this bug in a Microsoft system class only serves to validate my belief that you should always fully research any method someone else writes before you use them.

Mar 27, 2017, 7:20 AM

In this tutorial, I’m going to explain the wonders of using a Generic List instead of an array. Please keep in mind that there are times when using an array is better suited for what you need, though I generally tend to use Generic Lists more often than not.

First off, what is a Generic List? A Generic List is basically a one-dimensional array with more features and functionality. Let’s take a look first at declaring an array versus declaring a Generic List.

int[] iVal = {1,2,3,4};

or

int[4] iVal;
List<int> lVal = newList<int>();

Do you see the differences there? When we declared the array, we either had to declare it’s element list right away, or specify how many values it will hold. With the Generic List, we didn’t do either one, that’s because you can add values to the list after it’s declared.

lVal.Add(1);
lVal.Add(2);
lVal.Add(3);
lVal.Add(4);

You can also add values to a generic list when declaring it

List<int> lVal = newList<int>{1, 2, 3, 4};

Notice how you declared variables for the generic list, the same way you did for an array at declaration.

Now, let’s say we’ve got that Generic list declared and populated with values, and we wanted to remove the number 3 from it. In an array, we’d have to create a new array with a length of the first array minus one, then copy each value into the new array, excluding the one we wanted to remove. However, in a Generic List, it’s as simple as this:

lVal.Remove(3);

By this point, your probably wondering if there is anything special you have to do to use a Generic List. To use a Generic List in your code, you must include a using statement like this:

using System.Collections.Generic;

That’s it, you now know the basics behind using a Generic List instead of an array. With the primer behind us, perhaps we should move on to more advanced topics.

Often, in game development you’ll find yourself creating a two-dimensional array to hold X,Y values for object locations. This can be done easily with Generic Lists, and can actually make your code a little bit easier to read. To do this, you’ll first need to create a Coordinate class:

class Coordinates
{
public float X;
public float Y;

public Coordinates(float fX, floatfY)
{
X = fX;
Y = fY;
}
}

With the class created, you can then use a generic list to track the coordinates:

List<Coordinates> Coords = new List<Coordinates>();
Coords.Add(new Coordinates(1.5, 2.6));
Coords.Add(new Coordinates(3, 4.7));

That’s right, we just made a list of the Coordinates class, and added two coordinates to it. But what if we wanted to add those two coordinates while we were creating the list?

List<Coordinates> Coords = new List<Coordinates>
{
newCoordinates(1.5, 2.6),
newCoordinates(3,4.7)
};

Both of these will result in the

Now, let’s get loopy.

When working with lists, its very tempting to use the following loop to iterate through each element in the list:

foreach(Coordinates c in Coords)
{
PerformSomeAction();
}

While this works like a charm in most cases, there is one special case to take note of. If for any reason you are going to remove or add elements t6/from the List while iterating over the list, you can not use a ForEach to loop through the list. Doing so will cause run-time errors. It’ll usually crash saying that the Collection was modified. Here’s the right way to iterate over a List if you’re removing or adding elements:

for(int i = Coords.Length; i > 0; i--)
{
PerformSomeAction();
if(i % 2 == 0)
Coords.RemoveAt(i);
}

Remember I said earlier that a Generic List is a one-dimensional array with extra features and functionality, that means we can iterate over it the same way we do an array.

But why are we going backwards from the end of the list? Well, the if statement in the above code is checking to see if the index is an even number, if it is then we remove this coordinate. Because we are adding or removing items from the list, we process the list in reverse order to prevent potential errors.

Notice also the way we specified which element was to be removed in the list? When using the Remove function of a list, it expect to be passed a copy of the element to be removed. Since we’re iterating over the list as an array, we aren’t grabbing a reference to the element, so we had to specify which element to remove using it’s index in the list, which is what i is holding.

In a ForEach loop, we’re grabbing a reference to each element in the loop, so we don’t know what it’s index is.

As part of good coding practice, even when using a Generic List, it’s better to use a For loop instead of a ForEach loop, not saying it’s bad to use a ForEach loop. If in the loop you call any method outside of the loop, you are taking a chance that the called method will remove an element from the list, which as stated before will cause the “collection was modified” error I spoke of earlier.

What if you wanted to iterate over Coords, adding 1 to X and removing any elements whose X value was over 20? Here’s how you’d do that:

for(int i = Coords.Length(); i > 0; i--)
{
x++;
if(Coords[i].X > 20)
{
Coords.Remove(Coords[i]);
}
}

Likewise, if you weren’t going to remove any elements, but just wanted to add one to Y, then you could use a ForEach like this:

foreach(Coordinates c inCoods)
{
c.Y++;
}

Whoah…what’s up with that c? Well, in each iteration of the ForEach loop, c is made to be a reference to the element being evaluated. This means, that any changes to make to c on the first iteration, are actually being made to the first element in the List. Changes to c in the second iteration are being made to the second element in the List, and so on.

Before I leave, there’s one more thing to take note of, and this is very important.
Let’s say you’ve got the Coords list we’ve been working with above, and it provides coordinates for all enemies in your game. Then all your enemies fire at once, and you want to create a list of coordinates for the bullets. You might think that you can create this second list this way:

List<Coordinates> Bullets = Coords;

You would be wrong, and you’d find out pretty quickly when you start modifying the X and Y values for the bullets. What you would see on the screen would be totally different than what you are expecting. When you go to move all the bullets up 10 points, you’ll actually see all the bullets and the enemies all move up 10 points. Why is this? When you make a copy of a list like we did above, your actually making a reference list to the original list. This means the Bullets list, does not actually contain the coordinates, but pointers back to the Coords list.

Here’s one correct way to make a separate, non referential copy of a list(only works with some compilers):

List<Coordinates> Bullets = new List<Coordinates>();
foreach(Coordinates cor inCoords) Bullets.Add(cor);

The two lines above make an actual separate copy of the Coords list. Now when you move the bullets up 10 points, only the bullets will move and the enemies will stay in place.

The above code may still move all enemies and bullets on some compilers, that’s because not all compilers are built the same. If you use the above code and experience this issue, then that’s because each instance of the Coordinate class stored in Coords is a pointer. To fix this with those compilers, you’d have to rewrite the above code to the following:

List<Coordinates> Bullets = newList<Coordinates>();
foreach(Coordinates cor inCoords)
{
Bullets.Add(newCoordinates(cor.X, cor.Y));
}

That’s right, on those compilers(who implement classes and lists properly), you actually have to add new instances of the Coordinates class for every element in Coords that you want to duplicate. It should be noted, that while the first method may work on some compilers, the second method works on all compilers, and therefore should always be the one used.