Latest News
Mar 27, 2017, 5:50 AM

In C and C++ there were function pointers. Delegates are C#’s object oriented and type safe answer to function pointers. Let’s say you have the following two methods:

public void WriteOut()
{
Console.WriteLine("WriteOut method called");
}
public void WriteIn()
{
Console.WriteLine("WriteIn method called");
}

In your code, you want to call one of these based on the value of the integer selected, you could write it using an if statement like this:

if(selected == 1)
{
WriteOut();
}
elseif(selected == 2)
{
WriteIn();
}
else
{
Console.WriteLine("Hunh?");
}

But what happens if you add more methods later? You’d have to add more else statements, eventually resulting in unwieldy code and really long source files, especially if you have hundreds of such methods.So what’s a better option? Use an array of delegates. Before I show you how to do this, let me show you how to declare and use a delegate to begin with.First we declare the delegate:

delegate void SimpleDelegate();

Now, let’s create an instance of the delegate and assigne the WriteOut method:

SimpleDelegate d = new SimpleDelegate(WriteOut);

Now, instead of calling WriteOut directly, we can call the delegate like this:

d();

Yes, that’s right, we just called the WriteOut method by calling on the delegate d. But how is this handy? Well, think of it this way, now that we have a reference to a method we can create an array containing the references. This is something we couldn’t do with method names. For instance:

delegate void SimpleDelegate();
SimpleDelegate[] void d() = new SimpleDelegate[2]();
d[0]() = SimpleDelegate(WriteIn);
d[1]() = SimpleDelegate(WriteOut);

Now that we’ve setup our delegate array, the next and final piece of the puzzle is to iterate through the array calling each referenced method.

For(int a = 0; a < 2; a++)
{
d[a]();
}

That’s it, we’ve just called both functions from within a for loop. Realistically we’d never loop through the entire array calling each referenced method, instead we’d want to call just one method based on the value of an integer, but this example provides you all the necessary knowledge to get it done.What if we did want to call every method all at once? Well, there’s another option with delegates that we haven’t yet explored. Let’s rewrite our delegate definitions:

delegate void SimpleDelegate();
SimpleDelegate void d() = new SimpleDelegate();
d() = SimpleDelegate(WriteIn);
d() += SimpleDelegate(WriteOut);
d();

In the above code we’ve declared a single delegate. In the second line we assign the WriteIn method to the delegate, and in the third line we add the WriteOut method to the delegate. When we call the delegate in line four it will call the WriteIn method, then it will call the WriteOut method. We’ve now called all the delegate’s methods without having to use a for loop.But what if we later want to remove a method from a delegate? Continuing the previous example we can do it like this:

d() -= SimpleDelegate(WriteOut);

Now the WriteOut method is removed from the delegate, but the delegate still contains a reference to the WriteIn method.There are several rules regarding delegates that you should know of. First, when using a delegate all methods being assigned must have the same parameter list as when you declare the delegate. You can declare a delegate with parameters like:

Delegate int SimpleDelegate(intNumber1, intNumber2);

All methods being assigned to a delegate must also provide the same type return value as the delegate declared. In the preceeding example, all assigned methods must accept two integer parameters and return one integer value.If you call upon a delegate that contains references to two or more methods, the values passed into the parameters are counted as local variables for as long as the delegate runs. If the first method modifies the value of a passed parameter, the modified value is what is passed to the second method, and so on and so forth until all referenced methods have ran.

Mar 24, 2017, 1:30 PM

These two variables will hold the desired X,Y coordinates for the limited move

float MoveLimitedX;
float MoveLimitedY;

These are the variables being used in the calculations MovementRadius is the distance the unit is allowed to move from it’s starting point

float MovementRadius = 4f;

This is the X and Y coordinates for the unit that’s moving

float UnitX = 6f;
float UnitY = 0f;

These are the x and y coordinates for the target that the unit is moving towards

float TargetX = 0f;
float TargetY = 8f;

With two points, we’re imagining a triangle being formed from the unit to the target with the third point as a virtual point created where the axis from both points meet. This forms a right triangle with the line between the unit and the target as the hypotenuse, so we’ll first calculate the hypotenuse. This uses pythagoreums theorum of A^2 + B^2 = C^2

float hypotenuse = System.Math.Sqrt(((UnitX - TargetX) ^ 2) + ((UnitY - TargetY) ^ 2));

Now that we have the hypotenuse, we can calculate the x and y coordinates for the limited move. In case you can’t tell, we’re actually calculating Sine and multiplying it by MovementRadius to get MoveLimitedY, and we’re calculating Cosine and multiplying it by MovementRadius to get MoveLimitedX

MoveLimitedX = UnitX - (((UnitX - TargetX) / hypotenuse) * MovementRadius);
MoveLimitedY = UnitY - (((UnitY - TargetY) / hypotenuse) * MovementRadius);

MoveLimitedX should be equal to 3.6, and MoveLimitedY should be equal to 3