After creating the blog I decided to post a tutorial to create a snake game in c++ using only text mode.
This program I created as a project for my college
This tutorial is for beginners.
This is not Complete Game because it dont't contain any title screen or score
Now look at the structure of snake game.
There is a snake which player controls
There is obstacle wall.
There is food which make snake grow in length.
Design of game
This program I created as a project for my college
This tutorial is for beginners.
This is not Complete Game because it dont't contain any title screen or score
For those who don’t know this is the game where player
control a snake , when snake eat food it grows in size and get points . Game
ends when snake collide with wall or collide with itself.
Requirement
Basic knowledge of c++ .
Get Started
Before creating our game we have to think what we are
going to make. That is the snake game in c++ using only text mode.
Now look at the structure of snake game.
There is a snake which player controls
There is obstacle wall.
There is food which make snake grow in length.
Design of game
Lets Program the game
Launch Dev C++ and create new c++ file. To
keep it simple it will be a single file program.
First include the basic header file.
#include <iostream>
#include <windows.h>
#include <stdlib.h>
#include <conio.h>
using namespace std;
Now create a stucture to store our snake
position this is double linklist I will explain it later.
typedef struct tailpos
{
int x;
// x cordinate of the snake
int y;
// y cordinate of the snake
struct tailpos *next; // pointer to next node
struct tailpos *prev; // pointer to previous node
} tail;
// d used to set the direction
int d=4; // up = 1 , down = 2 , left =3
, right = 4;
A
variable ‘d’ which will store direction .you can declare this variable inside
class also.
The snake class
class snake
{
public:
int foodx,foody; //
position of the food
HANDLE console_handle; // handle for the console
COORD cur_cord; // COORD
struct to keep the coordinate
/*
tail struct ==>
start = pointer to first
part of body
current = pointer to last
node
newtail = temp node for
new tail
*/
tail *start,*current,*newtail;
snake(); // construct to
initalise tail variable to null
void insert(int x , int y); // insert the body of snake append to next
node
void draw(); // draw the snake
void drawWall(); // draw the wall
void move(); // control the
movement
bool collision(); //check snake
collision with itself or wall
void drawfood(int x=0); // draw food to new position if x==1
};
Looking at the code you can understand
what it will do
For storing snake position you can use
2d array. But i prefer linklist . For those who don’t know let me explain it.
By using this data structure we can
easily store and retrive snake parts position
For
more information ... http://en.wikipedia.org/wiki/Linked_list
Now implement snake class methods:
The constructor
snake::snake()
{
start = NULL; // start node point to
null
current = NULL; // same
newtail = NULL; // same
console_handle=GetStdHandle(
STD_OUTPUT_HANDLE ); // getting console
handle
foodx=12; // starting food positions
foody=14;
}
The drawwall method this will draw boundary for our snake game
void snake::drawWall()
{
/*
for drawing wall you can use variables to store wall starting and ending
position
*/
// draw left column
cur_cord.X=0;
for(int y=0;y<=30;y++)
{
cur_cord.Y=y;
SetConsoleCursorPosition(console_handle,cur_cord);
cout << '#';
}
// draw top row
cur_cord.Y=0;
for(int x=0;x<=30;x++)
{
cur_cord.X=x;
SetConsoleCursorPosition(console_handle,cur_cord);
cout << '#';
}
// draw right column
cur_cord.X=30;
for(int y=0;y<=30;y++)
{
cur_cord.Y=y;
SetConsoleCursorPosition(console_handle,cur_cord);
cout << '#';
}
// draw bottom row
cur_cord.Y=30;
for(int x=0;x<=30;x++)
{
cur_cord.X=x;
SetConsoleCursorPosition(console_handle,cur_cord);
cout << '#';
}
}
Draw the food for our snake
void snake::drawfood(int x)
{
tail *tmp;
tmp=start->next;
if(x==1) // draw new food
{
foodx=rand()%20+7; // rand number
between 2 to 27
foody=rand()%20+7;
/*check
if food not created on snake body
so we will loop
through all snake node and check
if snake body pos meet with food
position
if yes the generate
new position else continue
*/
while(tmp->next!=NULL)
{
if(foodx ==
tmp->x && foody == tmp->y)
{
drawfood(1);
}
tmp=tmp->next;
}
}
}
Increasing snake length
. when snake eat food its length should increase . For this
We have insert method
void snake :: insert(int x , int y)
{
//
check if start is null
if(start == NULL)
{
newtail = new tail;
newtail->x=x;
newtail->y=y;
newtail->next=NULL;
newtail->prev=NULL;
start=newtail;
current=newtail;
}
else // insert new node
to start node
{
newtail = new tail;
newtail->x=x;
newtail->y=y;
newtail->next=NULL;
newtail->prev=current;
current->next=newtail;
current=newtail;
}
}
This method just append a
new tailposition structure to the tailpos structure.
Here ‘start’ varaible points to node1
where as ‘current’ variable points to node3 i.e the last node.
After appending the
new node.
After appending the new node the
‘current’ variable points to newely created last node i.e node4.
Now the best part how
to move snake ? So the tails follow the head.
You know in game
tails follow the head every where it goes.
So first Question how
to move snake head?
Ans : Simple we have
to print snake head at new cordinate at console every cycle.
We can increment the current X,Y
position of console. To move snake in specified direction.
Q: How to make tail follow the head ?
Ans
: The tailpos structure which keep position of every part of snake. We just
have to move value of head to its tail and value of first tail should move to
next tail till last and increment position of head . In simple way remove value
of last tail put previous tail value in it .
This way position of snake parts is shifted
The code to move:
void snake::move()
{
tail *tmp,*cur; //
cur no use
tmp =current; //
point tmp to last node
//cur
=start->next;
while(tmp->prev!=NULL)
{
tmp->x=tmp->prev->x;
// copy val from revious to last
tmp->y=tmp->prev->y;
tmp=tmp->prev; // set tmp to previous node
}
/*
check for the value
of d in order to change its direction
*/
if(d==1)
start->y--;
if(d==2)
start->y++;
if(d==3)
start->x--;
if(d==4)
start->x++;
}
The move method is
called every cycle.
Collision Detection:
To check collision we
can simpily compare snake head posiotion with
1)
Its
tail
2)
Wall
3)
Food
Code to collision:
bool
snake::collision()
{
tail *tmp;
tmp=start->next;
//check collision with
itself
while(tmp->next!=NULL)
{
if(start->x ==
tmp->x && start->y == tmp->y)
return true;
tmp=tmp->next;
}
//check collision with food
if(start->x == foodx
&& start->y == foody)
{
insert(foodx,foody);
drawfood(1); // draw food at new position
}
//check collision with
wall
//collision top
for(int
x=0;x<=30;x++)
{
if(start->x
== x && start->y == 0)
{
return
true;
}
}
//collision left
for(int
y=0;y<=30;y++)
{
if(start->x == 0 && start->y == y)
{
return
true;
}
}
//collision right
for(int
y=0;y<=30;y++)
{
if(start->x == 30
&& start->y == y)
{
return
true;
}
}
//collision bottom
for(int
x=0;x<=30;x++)
{
if(start->x == x && start->y == 30)
{
return
true;
}
}
return false;
}
Rendering the game:
void snake::draw()
{
drawWall(); // draw
wall
tail *tmp;
tmp=start;
while(tmp!=NULL)
{
cur_cord.X=tmp->x;
cur_cord.Y=tmp->y;
SetConsoleCursorPosition(console_handle,cur_cord);
//cout <<
"*" << cur_cord.X <<"-" << cur_cord.Y
;
cout <<
"#"; // print any value you want
tmp=tmp->next;
}
//draw the food
cur_cord.X=foodx;
cur_cord.Y=foody;
SetConsoleCursorPosition(console_handle,cur_cord);
cout << "?"; // print any
value you want
}
This method prints wall , snake , food
at the console.
The game loop:
The game loop which
is repeated every time to draw snake,take input and process , and detect
collision
int main()
{
snake ob; // snake object
ob.insert(10,5); //
insert snake body
ob.insert(10,4); //
insert snake body
ob.insert(10,3);
ob.insert(10,2);
//ob.draw();
int dir=1; // initial
direction
while(1) // main loop
{
ob.draw(); // draw
food snake wall
Sleep(100); // wait
after draw better to use a timer
system("CLS");
// clearthe screen
if(ob.collision())// check for
collision
{
cout << " you died
";
break;
}
if(kbhit())// check if keyboard key
is pressed
{
switch(getch())
{
case 'w':d=1;
break;
case 's':d=2;
break;
case 'a':d=3;
break;
case 'd':d=4;
break;
case 'm':ob.insert(10,7);
break;
}
}
ob.move();
// move the snake
}
// to wait for user
input
getch();
return 0;
}
I have used W,A,S,D key to control .
This is just the core of the game
there is no welcome screen nor end screen . and there is score .
You can implement these your self.
The main problem in
the game screen flicker every time. This problem can be elminated which I will
discuss in Next Part. OR implement it your self thats easy.
I am sorry because The post is not formatted nor any synatx hilighter. I I am just getting started with blog.Maybe I will update it later
Here is the complete code copy and paste it