I got a question about how to implement multiple selection with drag and drop, and could see how that might be a challenge to implement to a beginning programmer. So I thought I'd make a codesample to learn from.

When I had finished coding, it struck me that I could refactor the code so the drag and drop part was tucked away in a helperclass. Then all that was needed to use it in any solution was to have the draggable objects implement an interface to let the helperclass

know the boundaries of the object

be able to change the position of the object

I expanded the helperclass to notify the object when the mouse was hovering over it, and whether the object was selected, so all that was left for the coder using the helperclass, would be to implement different ways of drawing the object according to what the state of IsMouseOver and IsSelected is.

So without further ado - let me present the DragAndDropController

What you get

It's as easy as this to use the controllerclass in your project:

//declare the controller somewhere on your Game class
private DragAndDropController<Item> _dragDropController;
//instantiate the controller somewhere
_dragDropController = new DragAndDropController<Item>(this, _spriteBatch);
//and add it to the Game class' Components
Components.Add(_dragDropController);
//add the items you want drag-and-drop enabled to the controller
_dragDropController.Add(item);

The items that you add to the controller must implement the IDragAndDropItem interface:

What an interface does

An interface in code is a contract that allows one piece of code (the DragAndDropController in this case) to treat objects of different types in the same way. This means that no matter whether the class implementing the interface is a "PlayerCharacter", a "MoneyToken" or a "PlayingCard", as long as they implement the abovementioned methods, the controllerclass can interact with them .

Video demonstration

The DragAndDropController<T>

Here you can see the public properties and methods of the DragAndDropController

Since it is a generic class you instantiate it to handle the type of your objects, and from then on you can add or remove items of that type to and from the controller.

You can also get the item under the mouse at any time (if any).

Source code

This tutorial shows you a simple to way animate other objects, in a way that doesn't require you to add a lot of extra code to your existing classes. We will end up by creating an AnimationController class, which can be used to animate anything which has a Vector2 Position property, by moving it from point A to point B in a straight line.

Presentation of what we want to achieve

In the video below you can see why I created the AnimationController. I wanted to juice-up the "setup next level" phase of the game board in my Simple Platformer Tutorial. This game was only used to illustrate the concept, you can use the AnimationController for anything you want moved automatically

What we will cover

Designing intuitive APIs

What is the point of putting this functionality in a controllerclass?

Defining what something looks like (creating an interface)

Creating the AnimationController

Putting the level in place in random ways

Getting Funky with "Func"

Learning to love Lambda Expressions

Putting a bow on it

Designing intuitive APIs

An Application Programming Interface (API) is a set of classes which enable you perform complex actions just by calling methods, and instantiating objects from the API. APIs are also frequently referred to as "class libraries". The .NET framework is a huge API with thousands of classes. A lot of planning went into making the .NET framework accessible and intuitive. One thing the designers did was ask themselves:

What code would I like to write, if I were the user of this API?

And we will start out by asking ourselves this very same question

My answer is:

I would like to write as little code as possible to be up and running

I would like to be able to add "anything which has a position" to the controller and ask it to move the object automatically from one point to another

I would like to be able to check whether all animations are done

Notice that these are the answers ... in this case. Another time we may want to achieve different objectives

Well - considering the requirements, we would like to be able to write something like this:

//ask the controller to animate all the items
//in the list of game objects
//in a line, ending 500 pixels to the right
//of their starting position
Vector2 fivehundredPixelsRight = new Vector2(500,0);
foreach(var item in listOfItemsWhichHaveAPosition)
{
animationController.MoveTo(item, item.Position + fivehundredPixelsRight);
}

and somewhere in our Game's Update() be able to ask whether all animation is done

if(animationController.Done)
{
//perform normal gameloop
}

...that would be perfect for us, since we could add all the Tiles to the AnimationController, and have it move them back to their ending position from randomly selected starting positions we provide.

What is the point of putting this functionality in a controllerclass?

Q: why don't we just add all the animation functionality inside the classes we want to animate?

A: because this way we can

keep our other classes (the ones we want moved) much leaner which increases readability, and...

have the animation functionality as a separate little toolbox which can be used to animate classes which don't inherit any of our code, as long as the class has a Vector2 Position property

Defining what something looks like (creating an interface)

(If you are familiar with interfaces, you can skip to "Creating the AnimationController")

Okay - I've mentioned it a couple of times already:

"as long as the class has a Vector2 Position property"

Q: how do we go about defining that restriction in C#? A: By using an interface!

Here is the definition we will use:

Note: The prefixed "I" in IPositionable is a convention used in .NET, so interfaces are easily recognized in code.

How do we benefit from this?

With this definition, a new "Type" like string or bool has been created. It can't perform anything but we can use it to describe any class which fulfills the requirements described in the interface.

Note: it isn't enough that a class fulfills the requirements, it must declare it in its class declaration.

Both sprites have the same functionality, but only one of them explicitly tells the compiler that it can be used anywhere that an IPositionable is needed.

What this means is that we can reference very different kinds of classes through the same datatype (interface): IPositionable. Let's consider a control we've made for a game, a TextBox, which we want to move on to the screen for receiving input and then move back out of the screen:

Note that we use the total seconds passed since last update in the equation. This will usually be around 1/60th of a second, which means that one step will even out at around 6/60ths or 1/10th (10%) of the remaining movement each update. This gives us a nice slowing down effect as 10% becomes fewer and fewer pixels as the remaining movement is diminished.

Move the IPositionable that step

positionable.Position += oneStep;

Remove all the IPositionable which have reached their goal from the dictionary

Now we *could* just run through the list again, and remove all the keyvaluepairs, where the position of the IPositionable and the destination are the same, but since we already iterate over the list once, let's just create another list "FinishedPositionables" and store all the finished IPositionables in that. Then we can run through that (presumably much shorter) list of finished positionables afterwards and remove those from the dictionary.

Adding a useful method

In our case we have a level setup, with all the tiles in their final positions, and we want to animate them from somewhere else to where they already are. This means that we will have to move the tiles away (maybe to individually random places) while storing their original position, and then pass the moved Tile along with the original position to the MoveTo() method. This complicates things unnecessarily . So why don't we just add a method which does exactly this for os.

Introducing the MoveBackFromPosition() method . Try reading it and see whether you can figure out how this method will help us make cleaner code outside, by just sending it some IPositionable and where to move it back from.

Basically it stores the current position (endPosition) of the IPositionable, and then moves the IPositionable out to the startingPosition, and then calls the MoveTo method to start the long move back - nifty, eh? .

Putting the level in place in random ways

Since we now have the AnimationController class working, let's test it .

All we need is a way to insert the original tiles and some starting point.

The easiest way to perform this would be to have all the tiles start out in the top left corner (0,0) and then move to their respective places. Like this:

Well, that's because in SimplePlatformerGame.Update(), I've put an IF around the update of the Jumper:

if (_board.AnimationController.Done)
{
_jumper.Update(gameTime);
}

..so it doesn't move before we're done setting up the board .

Getting Funky with "Func"

To spice things up even further, we want to randomize things a bit, by having different ways of putting the tiles in place. We can then "roll a die" and see which method to use for this "setting up the level", or just take them one at a time.

...but it tends to get long-winded and has the loop-code in every case in the switch. And as soon as we start writing the same code over and over - programmers think "do this in a function!".

Here, what we want to swap out is what happens inside the foreach loop, so we would need some way of changing what code is called from there.

Func to the rescue!

In recent versions of C# we are able to reference functions using the Action (for functions which don't return a value) and Func (for functions which do). This way we can add a method to our AnimationController which accepts a Func with this signature:

Func<IPositionable, Vector2>

This means: The Func variable of this type accepts an IPositionable and returns a Vector2.

Now we can store a list of these kinds of references and just pass them to this method on AnimationController:

At the top we declare and instantiate a Random for rolling dice, we create three methods which fit our Func signature, and in the RandomizeTilePositions, we find a reference to one of the three, and then use that in the foreach loop.

Very elegant - I like it!

Let's see it in action:

Learning to love lambda expressions

Since we're not doing a whole lot in our "IPositionable to Vector2" methods, we could sum them up using Lambda Expressions. If you don't feel ready to take this last step, just stick with the code we have created already. It's fine, and Lambda Expressions, though elegant, are not guaranteed to make you happier. Basically, they are an even more compact way of writing methods. If you're still up to a bit more learning, you can follow along and see what the benefits are .

The central part of a Lambda Expression is an arrow

=>

... which separates the parameter(s) on the left and the return value on the right.

Notice that we don't have the return keyword either, as the Lambda knows that "I should return whatever is to the right of the arrow".

Syntactically you can't place a Lambda Expression on the class like we do with regular methods. Lambda Expressions are meant to be used right away (as a parameter to a method which accepts a Func/Action of that type) or stored in a variable for use later. Now we can rewrite the RandomizeTilePositions as follows:

When replacing regular methods (with a meaningful name) with a Lambda Expression, what you have to be careful about is losing readability. Your code will almost invariably be harder to understand the more succinct it is. You must choose how to find that balance

So why don't we go ahead and store a little toolbox of positioning methods in a class where we can get the Funcs from when needed?

Putting a bow on it

I have taken eight different ways of animating the tiles into place (see video at the top of this tutorial), and stored them in variable with meaningful names. This is a principle of Clean Code, to avoid comments and use self-commenting code.

This is nice! We have definitions of the setup logic in variables with meaningful names. We have stored them in a list (which I have now made private to only enable access through the readonly NextPositioningFunction property), and we have an autoincrement for every get().

Enabling Jumper to jump

First of all, we only want Jumper to be able to jump when he has a solid surface under his feet. We can test this by checking if a Rectangle one pixel lower than Jumper's bounding rectangle would be blocked. If that is the case, we let him jump.

So go ahead and introduce this method in the Jumper class. Notice the "!" in front of the last line. That means not. Which means that if HasRoomForRectangle is true (Jumper is floating) then we return NOT true (we're not on firm ground) and vice versa.

because no matter whether we were falling fast when we hit the floor, we don't want our upward momentum to have any memory of our downward speed (which would be the result of using the -= operator), so we just set it to a firm negative 25 upward.

Go ahead and fiddle around with the values in AffectWithGravity and SimulateFriction until you are satisfied with how Jumper moves.

Updating debug information

Go ahead and add some additional debug information to the game, so you can see whether Jumper is on firm ground.

And since our Draw method is getting pretty long, refactor the it, so you extract the writing of debug information in a separate method.

What happens in StopMovingIfBlocked is that we get the last movement by subtracting where Jumper was before he moved from where he ended up. If there was no movement on an axis, we set that part of the current movement to zero.

We will then call StopMovingIfBlocked as the last line of Jumper's Update():

If we could get that down to about ten lines we might increase readability. So see what I do here, and if you like it, copy it. If you don't - then don't .

Wrapping multiple variables and related functionality into a wrapper

First of all we have four lines which are just initialization. We could wrap all those variables and the math up into a structure, and initialize it with the same data that WhereCanIGetTo receives. Add a new class to your SimplePlatformerGame project, name the file MovementWrapper.cs and move all this code

We use a struct instead of a class, since objects (instantiated from classes) are only cleaned out (garbage collected) at irregular intervals, which might make our game stutter. Structs (like int, float, Vector2, etc.) are garbage collected the moment you leave the "{...}" in which they were created.

The most important gotcha to remember when working with structs is that you always get a copy of it when you pass it to a method, so you can't just pass it to a method, change some values on the struct in the method, and then expect to see the changes reflected in the reference to the struct that you had outside the method (see example 2 for more info on this).

That not only made four lines into one, it also collected all the information about the move we're about to perform into one neat little package, which makes it easier to refactor further, and extract methods from whatever else we're performing, just wait and see . Now see what our WhereCanIGetTo method looks like

Basically, we just updated the references to the four variables to use the variables contained in MovementWrapper instead.

Refactor nondiagonal movement out into a separate method

Since we have all the variables for moving in the MovementWrapper struct, we can easily refactor the nondiagonal part of the movement out in a separate method. First create the method CheckPossibleNonDiagonalMovement, and move the code there.

And add a new method call CheckKeyboardAndReact to listen for keyboard input in SimplePlatformerGame.Update. In This method will react to someone pressing F5, and call a new method RestartGame() which creates a new Board and puts Jumper back in the top left corner:

There are many small changes you can make. I added some functionality which adds a shadow under our debug text, and changed the jump key to SPACE instead of UP. You go ahead and do whatever you wish - it's your code now

Here's the final result

Play around with it, expand it and have fun!

If you need help with anything in particular, or you want to give feedback on improving my tutorial feel free to leave a comment

This line adds half a pixel of vertical movement (downward) using the constant UnitY

(which is (0,1) you may recall :)). We may have to adjust this later, but for now we have something to work with ;).

I'm stuck!!

Now you can see that Jumper will fall whenever he is unsupported, but we also get some unwanted sideeffects, the most annoying being - we can't move once we've hit the floor :(, and sometimes we don't even hit the floor:

In situations like this one, it is a good idea to add some debug info to your game so you can see what is going on.

Adding debug info to the game

To write something onscreen you will need a SpriteFont in your content project. So go ahead and add a SpriteFont to your contentproject:

and name it "DebugFont"

Add a SpriteFont membervariable to the SimplePlatformerGame class

private SpriteFont _debugFont;

and load the font in the LoadContent method of SimplePlatformerGame

_debugFont = Content.Load<SpriteFont>("DebugFont");

Update Draw to show debug info

Then add some lines to the SimplePlatformerGame's Draw method to show where Jumper is, and where he is headed:

If you are unfamiliar with String.Format(), have a look here. Basically you pass it a string with placeholders named "{0}", "{1}", etc. for all the variables you want inserted into it. This makes it easier to read the format of the string, since formatting and data are kept separate.

You can add conversion information inside the brackets, using a separating colon.

E.g. {0:c} for currency or {0:0.0} for one decimal.

When .NET renders the result on screen you will see that the decimal separator on my screendumps is a comma, not a period, as my PC uses european (da-DK) culture :).

Now we can see what is going on

Jumper still has a desired vertical downward movement of 4.5, which makes him want to bury himself.

Q: Why is Jumper sometimes floating?

A: Same reason why we couldn't get close to the wall when moving sideways until we let go of the left/right key: the movement we're attempting would make Jumper end up inside a blocked Tile, and the Board object's HasRoomForRectangle() won't allow that move.

Q: Why can't we move sideways?

A: We haven't stopped Jumper's downward movement when he landed on the ground, which means that even if we try to move sideways, Jumper would still try to move downward and sideways.

Let's fix the floating first by improving how we handle leftover movement for Jumper.

Improving Jumper's movement

Here you can see what we want to accomplish.

In the illustration above, Jumper is moving diagonally down and left. The current Movement for Jumper wants to move him to the end of the diagonal red arrow in this Update().

We want that movement to be stopped right when he hits the horizontal row of blocks, and have the leftover motion carry over into horizontal movement, which only terminates when he hits the vertical wall of blocks a bit later.

Algorithm

What we're going to implement is a function WhereCanIGetTo on the Board class which

gets the origin and destination of a Rectangle

breaks down that movement into a number of half pixel steps

checks for every step whether it is blocked

if it is blocked, tries to carry over any diagonal movement into vertical or horizontal movement

Creating the WhereCanIGetTo() method

The reason we don't send the bounding rectangle of Jumper to the method, is that Rectangle uses ints for positioning, and we need more finegrained movement here.

We're going to do some vector math here, so if you're not used to that, have a look at this :).

Before we begin stepping along the path from origin to destination, we need some variables. These variables will be used to store

the complete movement we want to try (the distance from origin to destination)

the furthest available location we've found so far

the direction only (without distance)

the direction and length of one step

the number of steps we want to break movement into

Add some code to calculate these values. First calculate the movement from origin to destination:

Vector2 movementToTry = destination - originalPosition;

This means that if Jumper was at wants to go to (80, 120) and starts out at (100,100), the movement he wants to carry out is (80 - 100, 120 - 100) = (-20, 20), or in other words, -20 on the x-axis (meaning left) and 20 on the y-axis meaning down.

we assume that the originalPosition is in a nonblocked area, so we use the original position as the furthest possible location we have found along the path we want to travel

Vector2 furthestAvailableLocationSoFar = originalPosition;

to figure out how many steps we want to break the movement into, we multiply the length of the movement by 2 (so we approximately try once per half pixel), and add one, to make sure we at least try one step for very small movements

In the example mentioned above ((-20,20).Length() being approximately 28.3) this would work out at

(28.3 * 2) ≈ 57 + 1 = 58 small steps

And finally figure out how far one step is by dividing the entire move by the number of steps

Vector2 oneStep = movementToTry / numberOfStepsToBreakMovementInto;

Each step would be (-20,20) / 58 ≈ (-0.34, 0.34)

One small step at a time

Now that we have these values we can make a loop where we:

keep trying the next step along the movementToTry and see if we can go there. We do this by creating a Rectangle at that position and asking HasRoomForRectangle whether it is blocked

if that move was unblocked, we store that position in furthestAvailableLocationSoFar and continue

If that place is blocked, we exit the loop and return furthestAvailableLocation

Before we begin coding that, we need functionality to create a new Rectangle at a given position, so we have something to test each step with. So add a new function to the Board class which receives a Vector2 and a width and height, and creates a Rectangle at that position.

We will lose some precision in converting the floats from positionToTry to ints, but we will finetune that later.

Now we have the basic skeleton of our improved collision detection up and running. So update the WhereCanIGetTo method. I suggest you don't copy and paste the code, but code it while making sure you understand every step of it, but suit yourself .

Also update the MoveIfPossible name to MoveAsFarAsPossible, to better reflect that it is no longer a do/don't move decision, but a movement within the confines of the possible. Now your MoveIfPossible method should look like this:

Recycle leftover diagonal movement as horizontal or vertical movement

Right now our movement ends as soon as we take a step which ends in a blocked position.

What we want to do is:

If we get blocked before finishing a move:

find out if we we're moving diagonally when we got blocked, and if we were:

try to move as far horizontally and/or vertically as possible and return the farthest possible location

We can illustrate it like this: Here we hit a blocked Tile about halfway into the move the Jumper is trying to make. When that happens we check whether it is a diagonal move (neither of the X and Y part of the movement vector is zero), and then we test movement using the remaining movement along the X and Y axis.

Remember you can turn a movement vector into horizontal movement by multiplying it by Vector2.UnitX (thereby setting its movement on the y-axis to zero) and into vertical movement by multiplying it byVector2.UnitY (setting its x-axis movement to zero).

"If we get blocked before finishing a move"

The place to add code for this case is inside the else part of the loop in the WhereCanIGetTo() method

"If it is a diagonal move"

Create a boolean variable to store whether it is a diagonal move, and add it to the beginning of the else in WhereCanIGetTo(). As you can see, we store a true if neither the x- nor the y-movement is zero (think about it! :)).

To calculate the steps left, we have to subtract the step we just tried, as that moved us into a blocked area (if HasRoomForRectangle() returned true we wouldn't be down here handling all the messy details :)), and subtract the result from however many steps we were supposed to take on the entire path.

int stepsLeft = numberOfStepsToBreakMovementInto - (i - 1);

Example: We want to move 10 steps in this complete Update(). When testing step 7, we find it to be blocked, so we subtract 1 from 7 to find the last valid position (7-1 = 6), and then subtract that step from the entire trip (10 - 6 = 4) to find out how many steps we still need to try.

"try to move as far horizontally and/or vertically as possible"

We're almost there now - we can see the finishing line ... so let's perform the final sprint!

As mentioned earlier, to get only the horizontal/vertical movement part of a vector, we multiply by Vector2.UnitX or Vector2.UnitY respectively. So for each type of movement, we calculate the remaining movement in that direction, find out where we want to end up of we completed that movement by adding the remaining movement to furthestAvailableLocationSoFar.

Now we have the position to start from, and where we want to end up ... if only there were some way of finding out how far little Jumper could get to along that path...? 😉

"But there IS!" (I hear you cry!)

"Just feed those two positions right back into WhereCanIGetTo(), and it'll tell you!".

Right you are - so here is the final part of our if (isDiagonalMove) {... }

The calling of a function from itself is called recursion. In a lot of cases the calling can be nested many times deep, but we only ever call two layers deep. When calling functions recursively it is very important to have a criteria for when to stop, otherwise the program enters an infinite loop. The reason our calling stops is that the recursion is only performed when movement is diagonal, and the parameters to the second call to WhereCanIGetTo is never diagonal.

Go ahead and try it out, you will see that little Jumper no longer sticks to walls or floors, and slides right along - YAY! Go celebrate with a cup of coffee/cola/juice/water... 😀

The final version of WhereCanIGetTo

Read it through and see if there is something you still don't understand. If there is, now is the time to scroll back up and read the explanation again

This method is too long for my tastes. But simplifying it would mean having to put some of the code into other methods and passing along a lot of parameters (which is also not optimal for readability), or encapsulating the functionality in a small class. At the end of the next and final part of this tutorial, I will show you how that can be achieved.

What we've covered

After this part of the tutorial you should have learnt that

Gravity can be implemented simply by adding a downward momentum in every Update

You can benefit from adding debug information in your games to let you know why something is happening

You can reuse a method inside itself using recursion, and you should always ensure you have a stopping condition, so the program doesn't enter an infinite loop

Previously on xnafan.net

In the last part we looked at movement, and how to respond to keyboard input.

The current codebase lets the Jumper move all over the screen without any constraints at all - not exactly what we had in mind. This must be stopped! And it will ...

The agenda

First we will take a look at a very simple implementation of how to detect collisions in XNA.

Then we will add a boundingrectangle to our Sprite class, so everything we draw has knowledge of its outer bounds

We will add code to test for collisions and stop the Jumper's movement if it hits something

How simple collision detection works

XNA offers us a very simple way of testing whether two items overlap. We define a Rectangle for each of two items, where the rectangles define the outer boundary of the items. Then we send one of the rectangles to the Intersects() method on the other, and it returns a bool telling us whether they intersect.

Here I've illustrated where these three rectangles appear, and whether Intersects() returns true or false.

Adding a bounding rectangle to our Sprite class

Since a Rectangle can be constructed using the coordinates of the upper lefthand corner, plus width and height, it's easy to to create a bounding rectangle, because that's the information we've got in the Position property on the Sprite and the Width and Height of the Texture :).

The easy way of exposing a Rectangle property to the world is to implement a read-only property (a property with no set part) which, when accessed from outside, creates a new Rectangle based on the Position and Texture of the Sprite. Since we want to keep things simple in this tutorial, that's what we'll do! 😀

We need to cast the Position.X and Position.Y to int, since they are of type float, and will lose precision (the decimal part) when stored in an int. A lot of these operations which can introduce subtle, implicit errors are automatically checked by the compiler for us. By writing (int) in front of the value we want to convert, we can silence those warnings.

It's like saying to the compiler: "It's alright, I know what's going on and I explicitly allow it" 😉

Now whenever anybody wants to get the outer boundaries of our Sprite, they can retrieve the current position and size of our Sprite as a Rectangle through the Bounds property.

And remember that since Jumper and Tile inherit Sprite, they now also have a Bounds property.

Simple collision detection

Now, whenever we want to move something in our game, we have to test that object's bounding rectangle against the bounding rectangle of everything else, to see whether we hit something. In a large level we would have to cut the level up into smaller quadrants and store the objects in those quadrants somewhere for fast lookups. If we didn't, our game might slow down due to the large amounts of collision checks performed each Update(). Our gameboard is 15 * 10 tiles, and about one quarter of those will be blocked. This will give us about 15 * 10 /4 = 37.5 collisiondetections per movement we want to perform. That's not even close to being a problem :). When we refine our collision detection, we will get quite a few more checks per Update(), but still nothing to worry about.

Letting the Board tell whether is has room for something

Now we have to figure out where to put the code for detecting collisions.

We could put it in Jumper, but this would mean that we could only reuse that code in classes which inherit Jumper. We could also put it in Sprite, so all other subclasses of Sprite had access to it, but some of those classes might not need it. And the functionality is very closely related to the Board. So we'll add a method to Board to check for a given Rectangle whether there is room for it:

Q: Why do I first check for IsBlocked, and then check Intersects afterwards, and not the other way around?

A: Because the first check takes less computations (a simple true/false lookup) than the other (mathematical comparisons with position, width, height). This way we don't calculate if there is no need

Letting Jumper access the Board object through a static property

To give Jumper access to the Board object and all its tiles, we could just add a Board property to Jumper (or Sprite) and store a reference to the Board object here. This would enable Jumper to detect collisions. But I am going to show you a technique that requires less coding and enables any code in our project to access the Board.

In case you're still a bit wobbly on the concepts of class and object, think of the Class as the definition (the mold) for objects. There is only one class, but from that class you can instantiate ("new up") many objects, each with their own data.

Even though there may be many objects of any given class, there is only one class of that type. So we will create a property on the Board class instead of on the objects which we've done so far. This property will store a reference to the current Board object.

Since we can write "Board" anywhere, and gain access to the class, we will automatically have access to any public properties on the class.

Adding a static property to a class

To tell the compiler that we want a property (or method) stored on the class instead of on the objects created from the class, we add the keyword "static" to the property.

Go ahead and add a static Board property "CurrentBoard" to the Board class:

public static Board CurrentBoard { get; private set; }

We mark the property's setter private, so nobody can accidentally set a new Board outside the Board class. Right now we only want one board instance (object).

In the constructor of the Board class we add a final line to store the newly created Board object in the CurrentBoard property.

Board.CurrentBoard = this;

What's "this"?

"this" is a special word meaning "the object I am currently in. So what we're doing here is getting a reference to the Board object we're constructing through this and storing it on the class. Now we can access the Board object from Jumper :).

IMPORTANT! With the approach we've chosen here, the latest created Board object will always overwrite the previous (if any), so we should only construct the board once.

Try it out - and don't be too sad that it isn't perfect ..yet!

Okay - now go ahead and change the LoadContent() method of SimplePlatformerGame to move the starting point for _jumper to 80 * 80, so he doesn't start out inside the border.

Here I use the shorthand notation for new Vector2(80,80) by multiplying a vector of (1,1) by 80:

_jumper = new Jumper(_jumperTexture, Vector2.One * 80, _spriteBatch);

Okay - now run the game, and check that the code works, but probably not exactly what you had hoped for.

Here's an explanation of what's happening.

The short of it is that because we're still "teleporting" from one position to the next, we are stopped too far out. Look at this illustration:

Jumper wants to update his position from an unblocked tile to a blocked tile. Since that isn't possible, Jumper doesn't move any closer to the wall. Jumper doesn't move till we release the arrow key, and speed decreases to the point where possible movement occurs in Update().

Previously …on xnafan.net

how to specialize that class into a Tile class and create a Board of Tiles (part two)

In this part of the tutorial we will create a specialization of the Sprite class for the little blue guy

and enable him to be moved around. We will do this by storing all the necessary functionality in the Jumper class, including the math for movement, and the Keyboard input.

We will do this by

extending the Sprite class

add an Update() method to Jumper, so we can get keyboard input and update Movement

add a Vector2 Movement variable to update the Position with in every Update()

The Jumper class

First I want you to go ahead and create a new class Jumper which inherits Sprite, like we did with Tile in part two of the tutorial.

Try performing the following steps without peeking at part two, so you practice recalling how to create subclasses, sending parameters to the superclass’ constructor, etc.

Add an Update method with the same signature (name, return type and parameterlist) as the Update() in the Game class. Later I will tell you why we need the GameTime parameter in Jumper, and how it helps us create smooth movement.

Add an automatic property Vector2 Movement to the class.

Add a constructor which accepts all the parameters that Sprite needs, and passes them on to the base class (Sprite).

When you’re done, take a look at the code below and make sure you have something similar

Movement in computergames

It is beneficial to think of movement in computergames as an illusion created by teleporting between locations. We don’t actually move anything. Instead we show an image in a new position 30-60 times per second and our brain just fills in the blanks to maintain the illusion of smooth movement. In fact our Sprite hasn’t been to more than a couple of the positions inbetween the origin and endpoint.

This is important to remember because we may be “moving” so fast that in an Update() we may teleport our object from one side of an obstacle to another and miss the collision. Here that situation is illustrated by an acceleration while falling, where the first call to Jumper.Update() moves him 50 pixels down from top to middle position and second call is moving even faster moving him 70 pixels down and across the 64 pixel tall Tile. We never detect the collision .

Therefore we either:

have to make sure we move slowly enough that each Update() only tries to teleport us a distance shorter than the smallest obstacle on the Board

or

we have to split every Update’s “teleport” into smaller parts and test for obstacles at every little step

We are going to go with the second approach - but more about collisions in next part of this tutorial. Let’s just get something moving already!

Keyboard input

In XNA, keyboard input is obtained through the Keyboard.GetState() method. The GetState() method returns a KeyboardState which is a snapshot of the keyboard which allows you to test which keys were pressed and which weren’t at the time of the snapshot.

Every Update() we will:

get the snapshot

inspect the Left, Right, Up, Down keys

change the amount to move (Movement)

change the Position by the amount in Movement

In case you need to understand a bit more about using Vector2 for movement have a look at this tutorial (you can stop at “How to point a Texture2D in the correct direction”, since our Jumper won’t rotate ).

Updating the Update() method

First – we will get the snapshot of the keyboard state.

KeyboardState keyboardState = Keyboard.GetState();

Converting input to movement – a naïve approach

In a naïve approach we could then change the Movement property like this (NOT the way to to it!)

A: Since all the if checks are performed in order, in case you had Right and Up pressed at the same time, Movement would first be set to +1 on the X-axis and 0 on the Y axis, and then the next if would set Movement to 0 on the x-axis and –1 on the Y axis (up). The player would not get any reaction from his right key.

Converting input to movement – a better approach

What we want to do instead of replacing the Movement is adjust it like this:

The += operator adds the value to the to the right of the operator to the variable on the left. This operator also exists in a lot of other variants, to subtract, multiply and divide (–=, *=, /=) …and more .

BTW: I haven’t added Keys.Down, since gravity will be performing that movement for us later .

This will give us the benefit of gradual acceleration/deceleration, since a fast movement left, say 5 pixels per update, wouldn’t be replaced by a sudden reversal to the right when the right key is pressed. Instead Jumper decelerates to 4 pixels/update, 3 pixels/update, etc. until he stands still and then accelerates slowly right. Right now we don’t know if a whole pixel is too much or not enough, but we can fiddle around with it later till it seems right .

In case you haven’t tried Vector math before, basically all operations are performed on both the X and the Y.

The f after the 5.3 in the third line above is necessary because decimal numbers in C# are doubles by default (larger variables than floats which Vector2 use) so we explicitly declare the 5.3 a float with the “f” suffix.

Updating Position based on Movement

To update Jumper’s Position based on the Movement variable we just add Movement to Position.

call Jumper’s Update() in every call

Changing the _jumper Sprite to a Jumper

On the SimplePlatformerGame class we had a membervariable _jumper of type Sprite:

private Sprite _jumper;

go ahead and change its type to Jumper

private Jumper _jumper;

…change the instantiation in LoadContent(), so we instantiate a Jumper instead of a Sprite:

Your Jumper will fly off screen pretty fast, because we haven’t got any collision detection in place, nor any automatic slowing down. Collision detection is next tutorial, so let’s make sure we slow Jumper down at the end of every Update().

Constraining speed of movement

If we coded a real physics engine we would have an amount of drag (wind-resistance, ground-friction, etc.) which would increase with our speed and at some point we would automatically reach a maximum speed. That would require us to introduce more math though, and the result might not be discernible to the user anyway.

And the basic rule of creating games states that:

“Don’t make it if you can fake it!”

…which we will .

So go ahead and add code to Jumper’s Update to decrease the speed by a tenth every update (right before you add Movement to Position):

Movement -= Movement * new Vector2(.1f, .1f);

Read this as “Multiply both the X and Y values of Movement by .1, subtract the result of that from Movement and store it in Movement again”.

This could also have been written as

Movement *= new Vector2(.9f, .9f);

…but I like to be able to read what I use to change something with (a tenth of the speed), as opposed to what remains (nine tenths of the motion). Suit yourself, just make sure you understand what you’re doing .

Hit F5 and try it again … muuuuch better! (I hope? …otherwise go over your code again. If something is not working, set a breakpoint and look at the math for each Update() to see what is happening).

Smoothing movement

Though you may not notice it right now your Update is called 60 times a second. In a perfect world this would be every 1/60th of a second. But (and I hate to break it to you) it’s not a perfect world!

We may have 3/60ths of a second between two Updates and then two Updates right after each other with close to a millisecond interval to catch up. So what do we do? We compensate!

We just add the elapsed time into our math, so an Update with 1/60th uses 1/60th of the movement for a complete second, and an Update which takes three times that amount of time also performs a three times longer move (it’s a “teleport” – remember? ).

We can get the elapsed time since last Update() in the gameTime parameter in the Update method. So let’s add that to our equation. Change the last line of Update() to:

You don’t need to keep comments in sync, and code never lies – it does what it says

You already have a very readable description of what Update() does inside Update(), just by reading the code.

You have a structure in Update() which makes it easy to build upon it when things get more complicated (and they will )

You don’t need to read every line to understand what it does, if you need to change something, go to that method

You don’t need to spend time writing comments – just stay productive and CODE!

A few pointers on Vector2

There are a few constants on the Vector2 struct which are nice to know

Vector2.One is equivalent to new Vector2(1,1)

Vector2.Zero is equivalent to new Vector2(0,0)

Vector2.UnitX is equivalent to new Vector2(1,0)

Vector2.UnitY is equivalent to new Vector2(0,1)

These are nice to know because they increase readability (once you know what they are), and they are easy to modify movement with.

Stop movement:

Movement = Vector2.Zero;

Constrain to horizontal movement by multiplying X with one and Y with zero:

Movement *= Vector2.UnitX;

Constrain to vertical movement by multiplying X with zero and Y with one:

Movement *= Vector2.UnitX;

What we’ve covered

Now hopefully you’ve store inside that pretty little noggin’ of yours, that

Movement in computergames is “teleportation”, not real movement

To best let the user change movement, we get the state of the controller (Keyboard in this case), we modify the movement we want to perform (accelerate, brake, block, slow, etc.) and then we update the position based on the movement

We use the elapsed time in our movement math, to compensate for computers doing other things while we’re playing our game

We can make our code self commenting by using the Clean Code principles.

In part one of this tutorial we covered how to get something drawn onto the screen.

In this tutorial we will cover how to

create a Tile class which is a Sprite with an IsBlocked property

create a Board class which can create, store and draw a number of Tiles in rows and columns

The Tile class

A tile is basically just an image at a specified position which can be blocked or unblocked. You may have already recognized that this description is an awful lot like the description of our Sprite class: “basically just a help for combining a texture and a position”.

In object-oriented programming we can take the properties and functionality of a class and add to it by inheriting one class in another. So that’s the plan:

Explanation for missing parameterless constructor

When subclassing another class which doesn't have a default constructor (also known as an "empty constructor" or a "parameterless constructor"), we *have* to explicitly pass constructor parameters from the subclass (inheriting class) to the superclass (base class or parentclass).

This is the equivalent of the compiler sitting in a corner, sulking and muttering:

“oh – the programmer wants to control object-creation, I better mind my own business then!!”

In this situation we often choose to pass the parameters for the superclass' constructor to the subclass' constructor, so the subclass’ constructor can pass the parameters on to the superclass. This means that our class will not compile as it is right now, because we can't create a Tile without creating a Sprite. And the Sprite wants a Texture2D, a Vector2 and a SpriteBatch in its constructor.

Making the Tile constructor work

We add a constructor to our Tile class which takes the necessary three parameter we mentioned above. Those we pass on to Sprite’s constructor. We will also add a boolean parameter isBlocked to the constructor’s parameters, and store it in the Tile object:

As you can see above, the constructor on Tile gets four parameters, and calls the base class (Sprite) with three of them, while storing the last one in a public property IsBlocked.

You can’t see a Draw() method nor a Position or Texture property on the Tile class

… but they are there . This is the beauty of object oriented programming - that we get what we need through inheritance.

Q: How do object-oriented programmers get rich?

A: They inherit!(insert canned laughter)

Making nonblocked tiles invisible

The final part we want to modify on the Tile class, before making a whole bunch of’em into a Board, is to have non-blocked tiles not show up. This is easily done, because right now both a Sprite and a Tile draw their Texture at their Position through the Draw() method in Sprite:

So basically we just need to change the drawing of a Tile to *not* use this Draw functionality if the IsBlocked property is false. Piece of cake – let’s get to it

OOP INFO

In Object Oriented Programming, we always build on top of classes that other developers have developed. At the very top of the hierarchy is System.Object, which we subclass if we don’t specifically choose otherwise. Because we always inherit existing code, a very helpful principle has been implemented, to make sure we don’t change functionality by accident in a subclass, by implementing a new method with the same name as one in a superclass. This is two-step security which demands thata superclass must explicitly declare that a given method can be overridden in a subclass, by adding the virtual keyword to the method declaration

a subclass must explicitly declare that a given method is overriding a method from a superclass by adding the override keyword to the method declaration

Read through the code, and make sure you understand what is going on. If you don’t, set a breakpoint in the loops (F9) and run the program to inspect the calculated values. What we’re doing is multiplying the column and rows with the width and height of the texture we’re using, to position each Tile correctly.

Notice that we store the variables columns and rows in the properties first and then use the properties from then on, not the variables. The point being – if we want to ensure that column/row could never be a negative number or exceeed the window size, etc. we could change the automatic properties to properties with a backing variable and only store values we approve of.

By storing the parameters sent to the constructor in properties and from then on always referring to the properties and not the parameters, we retain this possibility of using the properties as a “filter”. To keep our code simple in this tutorial, I will not implement value validation, but feel free to add it if you want

Drawing the Board

Now we’ve got all the data we need, to start drawing the Board. So add a Draw method, where you iterate over the rows and columns and call the Draw() method of each tile.

Simplifying the Draw method

Since we don’t care in which order the tiles are drawn, since none of them overlap each other, we can just use a foreach loop to iterate over the Tiles.

public void Draw()
{
foreach (var tile in Tiles)
{
tile.Draw();
}
}

If you prefer the doble for-loop stick with it, but since I am using the principles of Clean Code, I try to keep my code as succinct as possible. The advantage of the second implementation is that it is very fast to read what is going on: “we’re drawing all tiles”. In the first implementation it is necessary to both look at the values of the two variables we’re using to iterate with and how we’re indexing into the array, to figure out exactly what is going on. It is a very small distinction, but I hope you get the idea .

Q: “Why didn’t we do the same in the double for-loop where we instantiate the tiles?”

A: Because we needed the x and y counter variables to calculate the Position property of the Tile objects.

Using the Board in the game

Finally – let’s create a Board in the SimplePlatformerGame class. Try to figure out what steps you have to perform in order to

instantiate a Board (15x10 tiles)

store it in a member variable so all methods in the SimplePlatformerGame can access it

draw the board

Try implementing it first, and use the following guide and code if you get stuck.

Go ahead and create a Board _board member variable on the SimplePlatformerGame class, and instantiate it in the LoadContent() method.

In the Draw() method of SimplePlatformerGame add a _board.Draw() call.

If you can’t see the _jumper, then you might have drawn it first and the board on top. In that case, switch the draw order

Enlarging the Window

We can’t see the entire board, because the default size of our Game window isn’t big enough. So calculate the window size needed for 15 columns and 10 rows each 64x64 pixels, and set the GraphicsDeviceManager’s PreferredBackBufferWidth and –Height in your constructor.

Creating randomly blocked Tiles and a border

Finally we will set randomly blocked tiles on the Board and then make sure that all bordertiles are blocked.

Randomly blocked Tiles

We instantiate our Tile objects in the Board constructor in this line

Tiles[x, y] = new Tile(TileTexture, tilePosition, spritebatch, true);

The true (fourth) parameter to the Tile constructor makes all Tiles blocked, so we need this to be randomly true or false.

Add a Random member variable to your Board class and instantiate it in the declaring line.

private Random _rnd = new Random();

Now, whenever we create a Tile we can “roll the dice” and set the tile blocked if it is zero. This way we can define what percentage of the tiles should be blocked by rolling a smaller or larger random value. If we roll _rnd.Next(2), then half the time we will get a zero and half the time a one. If we want only 10 % blocked tiles, we can roll _rnd.Next(10) and set the Tile blocked if it is zero, which will only be a tenth of the time.

Go ahead and change the true parameter of the tile instantiation in the constructor of the Board class, so 20 % of the tiles are blocked:

This is the Clean Code way of coding. Express what your code performs via methodnames and keep methods short. A definite advantage of this is that it is easy to see what is going on in a method if it has few lines and most of the code is calls to methods whose names sum up what they perform.

In the SetAllBorderTilesBlocked, create a double loop, and if the x counter is a border column (0 or 14) or the y counter is a border row (0 or 9) then set the tile blocked.

A: Yes - the control statement of the two for loopsshould not have hardcoded values, in case we want to change the size of the Board from the SimplePlatformerGame class. Same thing with the hardcoded values 14 and 9 for border tiles.

Our game now

As you can see we get a random board with borders all around. Go ahead and fix the position of the Jumper if you want to so he isn’t embedded in the border. We will add code to move him in the next part of the tutorial anyway .

Clean Code mini-assignment

Now you’ve seen how to move code into a method which summarizes what it performs in a meaningful name. Try to move the Tiles[,] initialization and the first two loops of the Board initialization into a separate method as well. This should leave our constructor with only

The Class diagram

Here you can see how our Tile class inherits the Sprite class. It also shows that Tile adds an IsBlocked property, a new Draw method and a Tile constructor to the definition of Sprite. The Board has a collection (arrows with double heads) of Tiles.

What we’ve covered

In this tutorial you’ve seen how to

subclass another class (Tile from Sprite)

pass parameters from a subclass’ constructor to the superclass’ constructor

use variables instead of constants in your code (the for loops)

simplify code according to Clean Code principles of using meaningful names

You can see that I’ve renamed the graphics to _graphics and spriteBatch to _spriteBatch. I do this so that I will always know when using a variable somewhere in my code whether this is a local variable or a member variable, which a lot of other methods are using.

The Sprite class

The Sprite class is basically just a help for combining a texture and a position. It will make it easier for us to place all the elements which we will need to create a complete game.

Create a new classfile Sprite.cs in your project class and the variables to store a Texture2D with a Vector2 for position:

Are we satisfied?

Now while this would be enough if we implemented the code for setting Texture and Position outside the Sprite, and had the drawing code outside (e.g. in the SimplePlatformerGame class) we would have a satisfactory class.

We could initialize it like this in the SimplePlatformerGame class’ LoadContent() method:

in the other sample I used a constructor with parameters which ensures that it is no longer possible to instantiate the object like this:

Sprite mySprite = new Sprite();

because the parameterless constructor (or “default constructor”) is removed when you explicitly create one yourself. The logic of the compiler being “oh – the programmer wants to control object-creation, I better mind my own business then ).

Now, whenever we need the Sprite drawn, we just call the Sprite’s Draw() method from the SimplePlatformerGame class’ Draw method:

The call to base.Draw(gameTime) is a best practice when we are overriding a method (notice the override void Draw(…)). Since our SimplePlatformerGame class inherits Microsofts Game class, we actually don’t know what is going on inside the SimplePlatformerGame.Draw method. To ensure we don’t break any internal mechanics, we always call the overriden method’s base implementation (unless we really know what we’re doing ).

Let’s test it

Add two Texture2D member variables to the top of the SimplePlatformerGame class, where the _graphics and _spriteBatch are declared, and a Sprite (just for testing, that variable will be deleted shortly):

What we’ve covered

After reading this part one of the tutorial, you should have learnt that

a class is a nifty way to combine data which should be logically paired, such as the Texture and Position in the Sprite class

a class can be used to encapsulate both data (image, position, spritebatch) and functionality (draw, constructor) in a little package which can then be interacted with using very little code (the Sprite.Draw() method)

you can use a constructor to ensure that an object can only be constructed from a class if all the parameters are passed along (though null values can be substituted)

Override base Update() and Draw() to react to keyboard input and change selection

After building this control in a basic version, which "blinks" from selection to selection, we will improve it, so the selection slides from one selected item to the next.

Subclassing DrawableGameComponent

The benefits of using DrawableGameComponent for basic game mechanics like this one is that once the gameobject is created and added to the Game object's Components collection, our component will automatically have Update() called (if our object's Enabled property is true) and Draw() called (if our object's Visible property is true). This way we can leave a lot of the "housekeeping" to the XNA engine.

So go ahead, whip up a new XNA solution in your favorite editor and add a new class "VisualSelectionControl", which inherits DrawableGameComponent:

public class VisualSelectionControl : DrawableGameComponent
{
}

When subclassing another class which doesn't have a default constructor (a "default constructor" is also known as an "empty constructor" or a "parameterless constructor"), we often choose to pass the parameters for the superclass' constructor to the subclass' constructor, so the subclass can pass the parameters on to the superclass'. This means that our class will not compile as it is right now, because we can't create a VisualSelectionControl without creating a DrawableGameComponent. And the DrawableGameComponent wants a Game object in its constructor - or it just won't play :).

So we add a constructor to our VisualSelectionControl which takes a Game object, which we pass on to DrawableGameComponent's constructor:

public class VisualSelectionControl : DrawableGameComponent
{
//creates a VisualSelectionControl by first creating a DrawableGameComponent
//The constructor takes a Game object, and passes it on to the superclass (the "base" class)
public VisualSelectionControl (Game game) : base(game)
{
}
}

Add basic properties

Since we already know what properties we need for our control to work (se item 2 in "How we will build our control"), let's add them to the class, and as parameters to the constructor, so we can't instantiate a VisualSelectionControl object without these variables:

Calling overridden method from overriding method

As you can see, we call the base class' Draw() method from our new Draw() method. This is important to do whenever you override a method from a class where you're not entirely sure what is going on inside the overriden method. This is to ensure that the functionality in the parent object remains intact.

Then we add our own code to calculate how tall one menuitem is based on the complete menutexture and the number of items in the menu. Finally we create a source Rectangle, which we use to render only that part of our texture to the screen.

Adding the VisualSelectionControl to the Game.Components collection ensures (as we've been over) that our component will automatically:

have Update() called if our object's Enabled property is true (Enabled is inherited from GameComponent)

have Draw() called if our object's Visible property is true (Visible is inherited from DrawableGameComponent)

BUT - if we run the game now, we will get an exception, as our control tries to draw to the SpriteBatch, and we haven't called SpriteBatch.Begin. So let's change the Draw() method in the Game class, to ensure that we call SpriteBatch.Begin() before calling the Draw() of all GameComponents, and SpriteBatch.End() afterwards:

The code in the CurrentIndex property's Set will ensure we don't go beyond the boundaries of the menu.

Add code to handle Keys.Up and Keys.Down presses

The choice of where to implement this functionality is up to you. It can go in your Game class, or in the control we're making. The problem with creating it in the control, is that it will listen to the KeyboardState all the time, and many different controls in the same game could start reacting to the same keypresses. But you can easily set the VisibleSelectionControl's Enabled property to false and by that make sure the Update() method of the control is not called. So we're going to go ahead and implement keyboard handling in the control for now. First we will implement simple keyboard handling with a flaw. Then we will look at why it doesn't work, and improve it by adding a little more code.

Naïve implementation of keyboard handling

We add a variable to the control for storing the keyboard's state:

//stores the state of the keyboard
private KeyboardState _currentKeyboardState;

Then we make a naïve implementation of reacting to the keyboard input in the Update() method:

Go ahead and try it out. You will only see the first and last options in the menu.

"Why?" you ask?

Because the Update() method is called arond sixty times per second, and you probably won't release the Up or Down key fast enough to only trigger MoveToPrevious()/MoveToNext() once or twice, but five or ten times. So we have to only move one step, right when the key is pressed.

We do this by storing the keyboard's state from the previous Update() and then only acting on a new press, i.e. when the key's last state was UP and it is now DOWN.

Improved keyboard handling

So go ahead and update your code:

//stores the state of the keyboard
private KeyboardState _currentKeyboardState, _previousKeyboardState;
public override void Update(GameTime gameTime)
{
//get the keyboard's state
_currentKeyboardState = Keyboard.GetState();
//call the superclass' implementation of the method we're overriding
base.Update(gameTime);
//use input to change state
if (_currentKeyboardState.IsKeyDown(Keys.Up) &amp;amp;&amp;amp; _previousKeyboardState.IsKeyUp(Keys.Up)) { MoveToPrevious(); }
if (_currentKeyboardState.IsKeyDown(Keys.Down) &amp;amp;&amp;amp; _previousKeyboardState.IsKeyUp(Keys.Down)) { MoveToNext(); }
//store this Update()'s keyboard state for use in next Update
_previousKeyboardState = _currentKeyboardState;
}

and try it out again. Now you should only trigger movement when you first press the key, and have to release it again to make another move - COOL huh?

Not good enough you say?

So you think it would be nicer to have a smooth, scrolling motion - huh? Well okay - for a final encore, let's implement scrolling and call it a day

Whenever you want movement in a game (even in a menu) you can make a variable to store the amount you want to change an object's position. Then for every update you can add that amount to the position of whatever you want moved. In our case, we want the source rectangle (the place we grab the visible part of the menu from) to move gradually from where it was, to a position based on the new CurrentIndex.

To do that, all we need is to store how far we are from where we want to be, and then gradually diminish that distance every Update.

This technique can be used for a LOT of other animations as well in a game, just so you know

Okay - so let's implement that...

Store where we are currently at, so we can calculate how to get to where we want to be

Since we want the source rectangle to move gradually now, we want to store its current position in a variable, so we can manipulate it in every Update().

So go ahead and move the source rectangle into its own member variable on the control. The position of the source rectangle will change every update and move towards the currently selected index.

//store the source rectangle
private Rectangle _sourceRectangle;

And since we will be needing the height of one menu item more places than one now, move it into its own member variable as well

//stores the height of one menu item
private float _heightOfOneMenuItem;

All we need to do now is move the source rectangle towards its destination in the Update() method:

//calculate where the sourcerectangle is supposed to be on the Y axis of the texture
float sourceRectangleYDestination = _heightOfOneMenuItem * CurrentIndex;
//get the difference between where it is now and where it is supposed to be
float differenceOnYAxis = sourceRectangleYDestination - _sourceRectangle.Top;
//calculate a thrirty percent movement
float thirtyPercentMovement = differenceOnYAxis * .3f;
//move the source rectangle
_sourceRectangle.Offset(0, (int)thirtyPercentMovement);

Here we calculate what the difference is between where the source rectangle is now and where it should be. Then we move the source rectangle thirty percent of the distance every Update(). That percentage will result in a slowing down as the absolute distance in pixels gets smaller (30 % of 200 pixels is 60, but 30 % of 40 pixels is only 12 )

This section of code is a functional unit, which performs one operation, so it is a perfect candidate for moving into its own function, so we can call it from the Update() method:

MoveSourceRectangleTowardsDestination();

This method of cutting parts of your code out and making them into their own well-named methods is a good idea. It keeps your code readable for both yourself and others as it gets more complex.

That's it!

We're done - we've got a control which works, and we can use it with very few lines of code in any game.

Your next assigment is to create a control which let's the user slide selections sideways Have fun!

Source code for download

Whew... that title is a tongue-twister , but it is nonetheless as precise as I can describe this way of keeping track of what to render.

If your game-world is tilebased, you can pretty much rely on finding out what tiles the corners of your screen is in, and then render all the tiles in the columns and rows between and including those four tiles.

BUT ... if your objects have random positions and sizes, it may be hard to figure out what to draw (because it is within your screen's borders) and what not to draw (because it is in a part of the world that is currently not visible on the player's screen).

This tutorial will give you an understanding of how you can optimize what your graphics adapter spends its time rendering, but only for your stationary objects. The reason this algorithm can not be used for moving objects is that the calculations for the optimization are performed at startup, and then that data is used every time you redraw the screen.