Tuesday, November 15, 2016

C# creating a simple snake game


I was thinking about creating a snake game with C#, so I ran ideas in my head, and some problems came up.


How can I track and output in the correct location the blocks that run after the snake's head?


If the snake is built of five blocks, and the user starts going in a circle, how can I print the snake body in the right location?


Also, how can I create an action that will run on the background, which will move the snake forward, no matter what the user does?



What structure should my code have? (code design structure)


This should be a console application, since it's the only framework I am familiar with.


I am not looking for finished code, since I want to really understand how it should work.



Answer



Representing the Snake


Creating a Snake game is pretty simple. The first thing you need is a way to represent your snake's body. If you consider your snake to be made up of blocks or tiles, your body can simply be a list of these blocks coordinates.


In your case, if you intent do a console application, each of these will be a character on the console, and the position would correspond to one line or row of the console output. So you start with this:


// List of 2D coordinates that make up the body of the snake
List() body = new List();


At this point, your list is empty, so your snake has no body. Let's say you want a snake of length 5 and the head should start in position (5,2) and grow towards the bottom. Just add those positions to the list when the game starts, for instance:


// Initialize the snake with 5 blocks starting downwards from (5,2)
for(int i=0; i<5; ++i)
{
body.Add(new Point(5, 2 + i));
}

Rendering the Snake


For rendering just draw a character at each position on the body list. The example above for instance could be drawn as:


...................

...................
.....O............. -- y = 2
.....#.............
.....#.............
.....#.............
.....V.............
...................
|
x = 5


You can get more complicated by choosing different characters for the character's head (first element on the list) and tail (last element on the list) and even orient them depending on the positions of the adjacent blocks. But for starters, just render everything as a # or something.


You could for instance start with a 2D char array containing the background like this:


// Array with map characters
char[,] render = new char[width, height];

// Fill with background
for(x=0; x for(y=0; y render[x,y] = '.';


And then iterate over the snake's body drawing it to the array:


// Render snake
foreach(Point point in body)
render[point.X, point.Y] = '#';

And finally iterate over the array again and write each character to the console, with a linebreak at the end of each row.


// Render to console
for(y=0; y{
for(x=0; x
{
Console.Write(render[x,y]);
}
Console.WriteLine();
}

Moving the Snake


Finally, movement. The first thing you need is to keep track of the Direction the snake is moving. This can be a simple enum:


// Enum to store the direction the snake is moving
enum Direction { Left, Right, Up, Down }


And the act of moving the snake can be done just by removing the last block from the list and adding it on the front, in the correct direction. In other words something like:


// Remove tail from body
body.RemoveAt(body.Count - 1);

// Get head position
Point next = body[0];

// Calculate where the head should be next based on the snake's direction
if(direction == Direction.Left)

next = new Point(next.X-1, next.Y);
if(direction == Direction.Right)
next = new Point(next.X+1, next.Y);
if(direction == Direction.Up)
next = new Point(next.X, next.Y-1);
if(direction == Direction.Down)
next = new Point(next.X, next.Y+1);

// Insert new head into the snake's body
body.Insert(0, next);

No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...