www.xbdev.net xbdev - software development
Friday October 18, 2019
home | about | contact | Donations
>>
     
 

Programming..

With C# and .Net...

 

Snake

(Creating a simple Demo Game)

 

Its on all the mobile phones today...such a simple game...but it can be really addictive :)  But how do we go about doing it in C#?  Well hold on...I'll take you through some simple principles of building your own snake game.

 

Lets take a look at how our snake will move...from there we can put a simple peudo code approximation for the movement of our snake together....once where sure how we are going do do that...the rest is easy.

 

 

As we can see...a direction value is important....as you would expect for a snake...the head moves in the direction we are moving, and the body simply trails the heads old position.  Using this we can say:

HEAD = HEAD + DIR;

BODY[0] = HEAD;

BODY[1] = BODY[0];

...

Of course that won't work....why?  Well we would need to save BODY[0] before we write over it, as our following line needs it.  A better approach is to update our snake from the tail...and discard the last value...as we know from the sketch above...the tails old position is just thrown away. 

With this, lets make the assumption that our snake is an array....where BODY[0] will be the head and it will have a length BODYLENGTH....which tells us BODY[BODYLENGTH-1] is its tail.....lets do a piece of code for that:

 

// Assume we have a body length of 10

int BodyLength=10;

for(int i=BodyLength; i>0; i--)

{

      Body[i] = Body[i-1];

}// End for loop i

// Update our new snakes head pos

Body[0] = Body[0]+Dir;

 

This is our snakes movement......we would call this each second or half a second and update a single position of movement.... we would adjust the time delay between updates for faster or slower movement.

 

For our first piece of code, I'll do a small program that uses the cursor keys....but it will only move when the key is pressed.... so you press the up key and the snake moves up one section....this way we can check that our snakes body is doing it all properly.

 

DownloadSourceCode

 

Our first piece of code, and if I say so myself, its a dam great one.  Of course its only simple...but all the best idea's start simple.  Once you have the snake moving around the rest is easy.  Its just a matter of collision detection and graphics from then on.


Those who run the demo might notice that the screen flickers now and then when we move our snake around...this is because we arn't double buffering our background...so you see the background getting cleared then repainted.  Don't worry...we'll fix that in a bit.

 

How our code works is easy if you break up what happens.... we first setup our array of Rectangle values called Body in the stSnake structure to a set of fixed values....these value aren't anything special....I just chose a point then incremented bock after bock down from the head until I'd intilised all enough snake body parts for the snake's length.

 

Code: snake.cs

using System;

using System.Drawing;

using System.Windows.Forms;

 

 

// We have a seperate snake structure, which tells us the snakes position

// etc... this is so we could have an array of stSnake's...for multiplayer

// later on if we wanted :)

public struct stSnake

{

      public Rectangle   Dir;        // Direction our snake is moving

      public int         iLength;    // How many squares long it is

      public Rectangle[] Body;       // Array of positions of each body part

      public int         BodySize;   // Size of each body part

     

}// End stSnake

 

 

class CSnakeGame : System.Windows.Forms.Form

{

      public stSnake m_Snake;

 

      private void OnPaint(object sender, System.Windows.Forms.PaintEventArgs e) [...]

 

 

      void MoveBody()

      {

            Rectangle Dir = m_Snake.Dir;

            Dir.X = m_Snake.Dir.X * m_Snake.BodySize;

            Dir.Y = m_Snake.Dir.Y * m_Snake.BodySize;

 

            // Body Length

            int BodyLength=m_Snake.iLength;

            for(int i=BodyLength; i>0; i--)

            {

                  m_Snake.Body[i] = m_Snake.Body[i-1];

 

            }// End for loop i

            // Update our new snakes head pos

            m_Snake.Body[0].X = m_Snake.Body[0].X + Dir.X;

            m_Snake.Body[0].Y = m_Snake.Body[0].Y + Dir.Y;

 

      }// End of MoveBody()

 

      private void AKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)

      {

            string result = e.KeyData.ToString();

            switch (result)

            {

                  case "Left":

                        m_Snake.Dir.X = -1;  m_Snake.Dir.Y = 0;

                        break;

                  case "Right":

                        m_Snake.Dir.X = 1;   m_Snake.Dir.Y = 0;

                        break;

                  case "Up":

                        m_Snake.Dir.X = 0;   m_Snake.Dir.Y = -1;

                        break;

                  case "Down":

                        m_Snake.Dir.X = 0;   m_Snake.Dir.Y = 1;

                        break;

                  default:

                        break;

            }// End switch(..)

 

            MoveBody();   // Update our snakes new position

            Invalidate(); // Invalidate our screen so it gets redrawn

      }// End of AKeyDown(..)

 

 

      private void InitializeComponent()

      {

            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.AKeyDown);

            this.Paint   += new System.Windows.Forms.PaintEventHandler(this.OnPaint);

 

 

            m_Snake.Dir.X = 0;

            m_Snake.Dir.Y = 1;

            m_Snake.iLength=10;

            m_Snake.Body = new Rectangle[50];

            m_Snake.BodySize = 10;

            int xstartpos = 30;

            int ystartpos = 30;

            for(int i=0; i<m_Snake.iLength+5; i++)

            {

                  m_Snake.Body[i].X = 0 + xstartpos;;

                  m_Snake.Body[i].Y = i * m_Snake.BodySize + ystartpos;

                  m_Snake.Body[i].Width  = m_Snake.BodySize;

                  m_Snake.Body[i].Height = m_Snake.BodySize;

            }// End for loop i

 

      }// End of InitializeComponent()

 

      public CSnakeGame() [...]

 

      // Our program entry point.

      static void Main() [...]

 

}// End of Snake Game Class 

 

 

The snake only moves when we press a key, so each time you press a cursor key...(Up,Down,Left or Right) the snake moves in that direction once.... in the final version though, we would call the MoveBody() and Drawing code from our timer...so the snake keeps moving in that direction until we press a key and change its direction.

 

Going off screen

Well our snake moves around okay...but what about when it reaches the edges?  Should that indicate that the games over, or should it scroll from the right to the left hand side?  Well I decided to have it scroll...as if I wanted to keep the snake on screen I would only have to put a wall around the edge and check for a collision.  So to do this scrolling effect, we only need to add in an additional few lines in our MoveBody() function as shown:

 

Code: snake.cs

....

      void MoveBody()

      {

            Rectangle Dir = m_Snake.Dir;

            Dir.X = m_Snake.Dir.X * m_Snake.BodySize;

            Dir.Y = m_Snake.Dir.Y * m_Snake.BodySize;

 

            // Body Length

            int BodyLength=m_Snake.iLength;

            for(int i=BodyLength; i>0; i--)

            {

                  m_Snake.Body[i] = m_Snake.Body[i-1];

 

            }// End for loop i

            // Update our new snakes head pos

            m_Snake.Body[0].X = m_Snake.Body[0].X + Dir.X;

            m_Snake.Body[0].Y = m_Snake.Body[0].Y + Dir.Y;

 

            // New ** New ** New ** New ** New ** New ** New ** New ** New **

            // If our snakes head is outside the screen, then we scroll it

            // to the opposite side

            Rectangle r = this.ClientRectangle;

            // Check the left and right first

            if( m_Snake.Body[0].X < 0 ) m_Snake.Body[0].X = r.Right;

            if( m_Snake.Body[0].X > r.Right ) m_Snake.Body[0].X = 0;

            // Check the top and bottom

            if( m_Snake.Body[0].Y < 0 ) m_Snake.Body[0].Y = r.Bottom;

            if( m_Snake.Body[0].Y > r.Bottom ) m_Snake.Body[0].Y = 0;

 

      }// End of MoveBody()

...

 

Growing?

If our snake eats certain types of food it will go faster...but also, certain foods will make our snake grow in length.  So we need to do a Grow(int iLength) function...and we can call it, and say how much we want our snake to grow by.  I chose to pass a length, as I thought that we could have it grow by larger amounts for advanced levels?  ...well it gives us a little flexibility for later on, we can always just fix it at one if we want :)

 

Hmmm....now I looked at the code...and I thought to myself, its not going to be easy... as for example, if we want to have the snake grow by 2...we don't want its tail or head to suddenly shoot out by 2...it could hit an obstacle or cause a problem.  So I decided that the snake will grow from its tail, and will only grow from the old positions...so if for example we grow by 3...this means that the tail will seem not to move for 3 steps...so the snake grows by 3 body parts.... it means that I had to add a bit of code to the MoveBody() function...

 

So altering the MoveBody() and Grow(..) function.... I added in the next part of the code.  One other thing...I added a iGrowLength variable to the stSnake structure...so it can determine if our snake needs to grow :)

 

I've pasted all the code below...with the exception of some of the code being commented out so its not to large...but you an download it if you click on the code link....  It should be the same as before but for the added grow code.

 

Code snake.cs

using System;

using System.Drawing;

using System.Windows.Forms;

 

 

// We have a seperate snake structure, which tells us the snakes position

// etc... this is so we could have an array of stSnake's...for multiplayer

// later on if we wanted :)

public struct stSnake

{

      public Rectangle   Dir;        // Direction our snake is moving

      public int         iLength;    // How many squares long it is

      public Rectangle[] Body;       // Array of positions of each body part

      public int         BodySize;   // Size of each body part

     

      public int         iGrowLength;

}// End stSnake

 

 

class CSnakeGame : System.Windows.Forms.Form

{

      public stSnake m_Snake;

 

      private void OnPaint(object sender, System.Windows.Forms.PaintEventArgs e)[...]

 

 

      void MoveBody()

      {

            Rectangle Dir = m_Snake.Dir;

            Dir.X = m_Snake.Dir.X * m_Snake.BodySize;

            Dir.Y = m_Snake.Dir.Y * m_Snake.BodySize;

 

            // Make sure the end element is correct incase we grow

            m_Snake.Body[m_Snake.iLength] = m_Snake.Body[m_Snake.iLength-1];

 

            // Body Length

            int BodyLength=m_Snake.iLength;

            for(int i=BodyLength; i>0; i--)

            {

                  m_Snake.Body[i] = m_Snake.Body[i-1];

 

            }// End for loop i

            // Update our new snakes head pos

            m_Snake.Body[0].X = m_Snake.Body[0].X + Dir.X;

            m_Snake.Body[0].Y = m_Snake.Body[0].Y + Dir.Y;

 

            // If our snakes head is outside the screen, then we scroll it

            // to the opposite side

            Rectangle r = this.ClientRectangle;

            // Check the left and right first

            if( m_Snake.Body[0].X < 0 ) m_Snake.Body[0].X = r.Right;

            if( m_Snake.Body[0].X > r.Right ) m_Snake.Body[0].X = 0;

            // Check the top and bottom

            if( m_Snake.Body[0].Y < 0 ) m_Snake.Body[0].Y = r.Bottom;

            if( m_Snake.Body[0].Y > r.Bottom ) m_Snake.Body[0].Y = 0;

 

            // Snake grows as it moves

            if( m_Snake.iGrowLength > 0 )

            {

                  // Add an extra block to the end of our snake

                  m_Snake.iLength++;

                  m_Snake.iGrowLength--;

            }// End if

 

      }// End of MoveBody()

 

      void Grow(int iGrowLength)

      {

            m_Snake.iGrowLength += iGrowLength;

           

      }// End of Grow(..)

 

      private void AKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)

      {

            string result = e.KeyData.ToString();

            switch (result)

            {

                  case "Left":

                        m_Snake.Dir.X = -1;  m_Snake.Dir.Y = 0;

                        break;

                  case "Right":

                        m_Snake.Dir.X = 1;   m_Snake.Dir.Y = 0;

                        break;

                  case "Up":

                        m_Snake.Dir.X = 0;   m_Snake.Dir.Y = -1;

                        break;

                  case "Down":

                        m_Snake.Dir.X = 0;   m_Snake.Dir.Y = 1;

                        break;

                  default:

                        break;

            }// End switch(..)

 

            MoveBody();   // Update our snakes new position

            Invalidate(); // Invalidate our screen so it gets redrawn

 

            // DEBUG ** DEBUG ** DEBUG ** DEBUG ** DEBUG ** DEBUG ** DEBUG **

            // To test that our grow function works, I call the functino here...but

            // it means that the snake never stops growing...it won't be here

            // in our release version!

            Grow(1);

      }// End of AKeyDown(..)

 

 

      private void InitializeComponent()

      {

           

            ......commented out code

           

            m_Snake.iGrowLength = 0;

      }// End of InitializeComponent()

 

      public CSnakeGame()[...]

 

      // Our program entry point.

      static void Main() [...]

}

 

 

Timer - moving on its own

Well our snake at the moment only moves when we press one of the cursor keys.... but we need to have it move by itself.  Which brings us to the timer.  We set up a timer function which gets called one or twice a second, depending upon or snakes speed.  The timer function will call our MoveBody() and OnPaint() function.... Simple?  Each little addition brings us closer to our finished game :)

 

Code: snake.cs

...... [Cutting of the changed code].......

 

                  case "Down":

                        m_Snake.Dir.X = 0;   m_Snake.Dir.Y = 1;

                        break;

                  default:

                        break;

            }// End switch(..)

 

      }// End of AKeyDown(..)

 

      private void OnTimer(object sender, System.EventArgs e)

      {

            MoveBody();   // Update our snakes new position

            Invalidate(); // Invalidate our screen so it gets redrawn

 

      }// End of OnTimer(..)

 

 

      private void InitializeComponent()

      {

            this.KeyDown     += new System.Windows.Forms.KeyEventHandler(this.AKeyDown);

            this.Paint       += new System.Windows.Forms.PaintEventHandler(this.OnPaint);

           

            // --- Timer --- //

            this.Ticker = new System.Windows.Forms.Timer();

            this.Ticker.Interval = 200;

            this.Ticker.Tick += new System.EventHandler(this.OnTimer);

            Ticker.Enabled = true;

 

            m_Snake.Dir.X = 0;

            m_Snake.Dir.Y = 1;

......

 

With those altered lines of code, we now have a zooming snake!  Yup...watch it go ..wahooo....try changing the timer interval speed from 200 to 25, and its like a speeding bullet then :)

 

Food And Collision Detection

At random positions on the screen we need to put food ... but we also need to check if our snake has eaten them, the reason for the collision detection.  So we need a food member variable...now rather than put it in the class...I decided to put it in a new structure called stGameData.... which will hold global game info, like game over, number of food ...food positions etc.

 

Next, how is our food going to appear..and where will we do the checking of being eaten?  Well I thought that for every five moves a new food would appear....up to a max of 2 foods... so in our OnTimer(..) function, we'll call a FoodUpdate() function..which will do all the work in there for us :)

 

Well its a mad piece of code the FoodUpdate() one...loads of checking for this...and checking for that... as we can't randomly place food on top of our snake...and we need to check if our snakes eaten it..... but most of the code is checking.

 

 

Code: snake.cs

// snake.cs

// csc /t:winexe snake.cs

 

using System;

using System.Drawing;

using System.Windows.Forms;

 

 

// We have a seperate snake structure, which tells us the snakes position

// etc... this is so we could have an array of stSnake's...for multiplayer

// later on if we wanted :)

public struct stSnake

{

      public Rectangle   Dir;        // Direction our snake is moving

      public int         iLength;    // How many squares long it is

      public Rectangle[] Body;       // Array of positions of each body part

      public int         BodySize;   // Size of each body part

     

      public int         iGrowLength;// How much it needs to grow by

}// End stSnake

 

public struct stGameData

{

      public int         iNumFoods;

      public Rectangle[] Food;

      public bool[]      bFoodAlive;

      public int         iFoodSize;

 

}// End stGameData

 

class CSnakeGame : System.Windows.Forms.Form

{

      private stSnake                      m_Snake; // Snake data

      private stGameData                   m_Data;  // Game Information

      private System.Windows.Forms.Timer   Ticker;  // Our game timer

 

      private void OnPaint(object sender, System.Windows.Forms.PaintEventArgs e)

      {

            ....... cut out to keep down on size

 

            // --- Draw Food --- //

            int iNumFoods = m_Data.iNumFoods;

            for(int i=0; i<iNumFoods; i++)

            {

                  if( m_Data.bFoodAlive[i] )

                  {

                        g.FillRectangle(System.Drawing.Brushes.Blue, m_Data.Food[i]);

                  }// End if

            }// End for loop i

 

      }// End of OnPaint(..)

 

 

      void MoveBody() [...]

 

      bool IntersectsWithBody(Rectangle rCheck)

      {

            // Check if our Rectangle overlaps any of our body parts

            bool bOnTop = false;

            int BodyLength=m_Snake.iLength;

            for(int c=0; c< BodyLength; c++)

            {

                  if( m_Snake.Body[c].IntersectsWith( rCheck ) )

                  {

                        bOnTop = true;

                        break;

                  }// End if

            }// End for loop c

 

            return bOnTop;

      }// End of IntersectsWithBody(..)

 

      int m_FoodTimer = 0;

      void FoodUpdate()

      {

            // First part, check if we've eaten any food

            int iNumFoods = m_Data.iNumFoods;

            for(int i=0; i<iNumFoods; i++)

            {

                  if( m_Snake.Body[0].IntersectsWith( m_Data.Food[i] ) &&

                        m_Data.bFoodAlive[i] )

                  {

                        // If we are here, then we've grabbed some food! ..so

                        // we should do something..increase the score...change

                        // speed..grow etc..

                        Grow(1);

                        m_Data.bFoodAlive[i] = false;

                  }// End if

            }// End for loop i

 

            // Second part, only add food if we have move 10 places

            // This is hard coded as 10 here...but you could put it in the

            // stGameData structure later on, so its easier to change.

            m_FoodTimer++;

            if( m_FoodTimer < 10 ) return;

            m_FoodTimer=0;

 

            // If our snakes head is outside the screen, then we scroll it

            // to the opposite side

            Rectangle r = this.ClientRectangle;

 

            // Initilise our Random number variables

            long Seed = DateTime.Now.Ticks;

            Random TheRandom = new Random( (int)Seed);

 

            // Note how I've added the food size, so we don't get food which is touching

            // the wall...padding :)

            int randX = TheRandom.Next(0+m_Data.iFoodSize, r.Width-m_Data.iFoodSize);

            int randY = TheRandom.Next(0+m_Data.iFoodSize, r.Height-m_Data.iFoodSize);

 

            for(int i=0; i<iNumFoods; i++)

            {

                  // Generate a random position for our food

                  Rectangle newFood = new Rectangle();

                  newFood.X = randX;

                  newFood.Y = randY;

                  newFood.Width = newFood.Height = m_Data.iFoodSize;

                 

 

                  // Check that where not putting the food on top of the snake

                  // Check that we have space in our array for it..as we are only allowed

                  // a maximum number of foods at once on the screen

                  if( !IntersectsWithBody(newFood) && !m_Data.bFoodAlive[i] )

                  {

                        m_Data.Food[i] = newFood;

                        m_Data.bFoodAlive[i]= true;

                        break;

                  }// End if

 

            }// End for loop i

 

      }// End of FoodUpdate()

 

      void Grow(int iGrowLength) [...]

 

      private void AKeyDown(object sender, System.Windows.Forms.KeyEventArgs e) [...]

 

      private void OnTimer(object sender, System.EventArgs e)

      {

            MoveBody();   // Update our snakes new position

            Invalidate(); // Invalidate our screen so it gets redrawn

            FoodUpdate(); // Add food randomly positions every 5 moves, and check for eaten

 

      }// End of OnTimer(..)

 

 

      private void InitializeComponent()

      {

            .........cut out to keep size down

           

            // How much our snake has to grow by

            m_Snake.iGrowLength = 0;

 

            // Game Data

            m_Data.iNumFoods = 3; // Maximum Number Of Foods At Once On The Screen.

            m_Data.iFoodSize = 10;

            m_Data.Food = new Rectangle[10]; // Assume Max foods possible of 10

            m_Data.bFoodAlive = new bool[10];// Hence max bFoodAlives is 10

 

      }// End of InitializeComponent()

 

      public CSnakeGame() [...]

 

      // Our program entry point.

      static void Main() [...]

}

 

 

 

One of the main reasons I use the 'Rectangle' structure a lot, is so I can use the simple collision detection of 'IntersectsWith(..)' function to check if our snake or food collide.  I can also use this to check if our snakes head collides with its head later on.

 

GameOver

At the moment the way it is, our snake is importal....nothing can kill it...it can eat and eat and go anywhere...  So we can't have that... a rule of snakes is that it's head can't make contact with its body.  So I've added a function called 'ChkGameOver()' to our OnTimer(..) function...so we constantly check in there to see if our snakes head has touched its body...if so, I set a varible called bGameOver in our stGameData structure to true!  Telling us its all over!

 

One final thing.... using this GameOver information, if we find that its all over...we display a 'Game Over' message and pause the game until the player presses Enter.  Its only simple but it gives the game a purpose.  We've not added scores yet... but we can do that in a bit.

 

 

Code: snake.cs

.....

 

public struct stGameData

{

      public bool        bGameOver;  // If false, then the game is over

 

      public int         iNumFoods;

      public Rectangle[] Food;

      public bool[]      bFoodAlive;

      public int         iFoodSize;

 

}// End stGameData

 

class CSnakeGame : System.Windows.Forms.Form

{

      private stSnake                      m_Snake; // Snake data

      private stGameData                   m_Data;  // Game Information

      private System.Windows.Forms.Timer   Ticker;  // Our game timer

 

      private void OnPaint(object sender, System.Windows.Forms.PaintEventArgs e)

      {

            Rectangle r = this.ClientRectangle;

 

            System.Drawing.Graphics g = e.Graphics;

            // Clear the screen to a specific colour

            //g.FillRectangle(System.Drawing.Brushes.Blue, r);

 

            /* --- Draw Snake ---- */

            int BodyLength=m_Snake.iLength;

            for(int i=0; i<BodyLength; i++)

            {

                  int x = m_Snake.Body[i].X;

                  int y = m_Snake.Body[i].Y;

                  int width  = m_Snake.Body[i].Width;

                  int height = m_Snake.Body[i].Height;

 

                  g.FillRectangle(new SolidBrush(Color.Green), x, y, width, height);

            }// End for loop i

 

            // --- Draw Food --- //

            int iNumFoods = m_Data.iNumFoods;

            for(int i=0; i<iNumFoods; i++)

            {

                  if( m_Data.bFoodAlive[i] )

                  {

                        g.FillRectangle(System.Drawing.Brushes.Blue, m_Data.Food[i]);

                  }// End if

            }// End for loop i

 

            // --- Display GameOver Message If Where Dead --- //

            if( m_Data.bGameOver == true )

                  g.DrawString("\tGameOver\n        Press Enter To Cont.",

                          this.Font, Brushes.Black, r.Right/4, r.Bottom/3);

 

      }// End of OnPaint(..)

 

......

 

      private void AKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)

      {

            string result = e.KeyData.ToString();

            switch (result)

            {

                  case "Left":

                        m_Snake.Dir.X = -1;  m_Snake.Dir.Y = 0;

                        break;

                  case "Right":

                        m_Snake.Dir.X = 1;   m_Snake.Dir.Y = 0;

                        break;

                  case "Up":

                        m_Snake.Dir.X = 0;   m_Snake.Dir.Y = -1;

                        break;

                  case "Down":

                        m_Snake.Dir.X = 0;   m_Snake.Dir.Y = 1;

                        break;

                  case "Enter":

                        m_Data.bGameOver = false;

                        break;

                  default:

                        break;

            }// End switch(..)

 

      }// End of AKeyDown(..)

 

 

      void ChkGameOver()

      {

            // Check if our snakes head intersects with any parts of its long long body

            // if so, then its game over.

            int BodyLength=m_Snake.iLength;

            for(int c=1; c< BodyLength; c++)

            {

                  if( m_Snake.Body[c].IntersectsWith( m_Snake.Body[0] ) )

                  {

                        m_Data.bGameOver=true;

                        break;

                  }// End if

            }// End for loop c

 

      }//End of ChkGameOver()

 

      private void OnTimer(object sender, System.EventArgs e)

      {

            if( m_Data.bGameOver == true ) return;

 

            MoveBody();   // Update our snakes new position

            Invalidate(); // Invalidate our screen so it gets redrawn

            FoodUpdate(); // Add food randomly positions every 5 moves, and check for eaten

 

            ChkGameOver();

 

      }// End of OnTimer(..)

 

 ......

 

 

Score And Reset

One final thing is needed for our Snake game, is the ability to keep track of score and when the game is over to restart our game back to its starting conditions.  This is simply a matter of putting the data initialisation code from "InitializeComponent()" function into a ResetGame(..) function that we can call when we need to set the game all back to its start.

 

 

DownloadSourceCode

 

I've added a few lines of code so that you can see the score, and put in a ResetGame(..) function in... so now when you die it displays the gameover message....waiting for you to press Enter and start the game again from scratch.

 

I've not added any speedups....or different food types...which shouldn't be to hard to add on.  Just use different colours for the different foods...also it might be better to have bonus foods that only appear for a short amount of time :)

 

 

 

What Next?

Well the next step would be to use a back buffer for you graphics...instead of rendering directly to the screen surface.  Once you have that done, I would recommend improving the graphics... the game looks fantastically better if you where to use small bitmaps for the food...and gave you snake a head and a tail :)

A bonus would be to do mazes.... so that level 2 would have obstacles that you must avoid...walls etc....tunnels...

 

And for the final elite version, a multi-player option would be good.  Which isn't to hard to implement....as we have "stSnake m_Snake" currently....for a 4 player we could change this to an array "stSnake m_Snake[4]"...... of course how everyone is going to share the keyboard I don't know.  Definitely worth making it into a network game?  Great stuff to improve you networking skills.

 

 

 

 

 

 

 

 

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.