Windows Phone 7 - Snakes on a Phone Part 1
Written by Harry Fairhead   
Monday, 13 September 2010
Article Index
Windows Phone 7 - Snakes on a Phone Part 1
Building the Snake
Animating the snake

Banner

Off one side, back on the other

The only complicated part of the method is the use of the mod % operator. This simply wraps the arithmetic around so the when the head reaches the edge of the grid at column=GridSize it goes back to the first column.  The reason we have to add GridSize into the expression is to deal with negative values. For example suppose the head is at column zero and the velocity is -1 - then its next position is at column -1 which doesn't exist. By adding GridSize the position becomes GridSize-1 and hence the position wraps round to the right hand side of the Grid.

The removeOldTail method is remarkably simple thanks to the use of a queue:

private void removeOldTail()
{
Ellipse Tail = Positions.Dequeue();
Tail.Visibility = Visibility.Collapsed;
}

Notice that we only set the Ellipse to be invisible - no attempt is made to remove it from the Grid. In some games this could be a problem and removing it would be a better design.

With the UpdateSnake method complete all we need return to the page's constructor and add an animation timer.

S = new snake(PlayArea);
setupTimer();
timer.Start();

The setupTimer method is fairly simple:

private void setupTimer() 
{
timer.Interval =
new TimeSpan(0, 0, 0, 0, 100);
timer.Tick +=
(obj, evnt) => { S.UpdateSnake(); };
}

The timer Tick event handler is set to be the snake's UpdateSnake method.

Now if you run the program you will see the snake move horizontally across the screen and disappear off the right hand edge only to reappear on the left.

Random velocities and growing snakes

At this point we have a completely working snake animation but one that only shows a horizontal movement. To make the demonstration slightly more impressive let's add a random factor to the velocity so that the snake can wriggle about the screen.This will also get us one step on the way to allowing the user to control the snake's direction.

Usually the best eay to control a snake is to make it's direction of motion turn either to the right or the left. So we simply need two "turn" methods:

private void turnRight()
{
double t = velocity.Y;
velocity.Y = -velocity.X;
velocity.X = t;
}
private void turnLeft()
{
double t = velocity.Y;
velocity.Y = velocity.X;
velocity.X = -t;
}

Each method turns the velocity 90 degrees to the right or left. How are the formulas used worked out? Simple. They are based on the standard formula for rotating a vector through T degrees:

 x' = x Cos(T) - y Sin(T)
y' = x Sin(T) + y Cos(T)

and as T= 90 degrees to turn right Cos(90)=0 and Sin(90)=1 and so

 x'=-y
y'=x

Who says that math isn't essential to computing?

Now we can modify the UpdateSnake method to randomly call the turn methods. We can also make the snake grow by one segment every now and again by simply not calling the removeOldTail method at random intervals:

public void UpdateSnake()
{
head.X = (head.X + velocity.X +
GridSize) % GridSize;
head.Y = (head.Y + velocity.Y +
 GridSize) % GridSize;
if (R.NextDouble() < 0.1) turnRight();
if (R.NextDouble() < 0.1) turnLeft();
addHead(head);
if (R.NextDouble() > 0.01) removeOldTail();
}

We also need a random object at the start of the program:

private  Random R = new Random();

Now if you run the program the snake will wiggle its way around the screen, occasionally growing longer.

 

final

 

There is still a lot to do -  in particular we need to allow the user to drive the snake, Then we need to add some obstacles and some food for the snake to feed on and some sound effects and...

Next time we make a start on this list.


To access the code for this project, once you have registered,  click on CodeBin.

 

If you would like to be informed about new articles on I Programmer you can either follow us on Twitter, on Facebook, Digg or you can subscribe to our weekly newsletter.

 

Banner

 

 

<ASIN:0735643350>

<ASIN:1449388361>

<ASIN:1430233060>



Last Updated ( Sunday, 19 September 2010 )