Reply
Thread Tools
Marcus's Avatar
Posts: 173 | Thanked: 72 times | Joined on Mar 2010 @ Denmark
#1
If I'm not allowed to post this here (in case this is only for discussing), please make me aware of that.

I found a source code/tutorial for a very basic snake game in C using SDL, so I decided to try to do a port to C++, and hopefully to the Maemo platform at the end.
Unfortunately, I do not believe I have the needed C++ knowledge etc. yet, so therefore I'm posting the current source code. Basically all I've done so far, is the porting to C++, and a little other changes.
It is not commented, and _definitely_ not perfect. So it can be optimized a lot!

You need to download a font from somewhere and use it. I'm not sure I'm allowed to use the borgnine font I found on dafont.
When you've got a font either edit TTF_OpenFont(); or make a folder called "data", put the font in there and then rename the font to "borgnine.ttf".

Screenshot:


Compile with (Linux):
g++ -o main main.cpp -lSDL -lSDL_image -lSDL_ttf
Code:
#include <stdlib.h>
#include <string>
#include <sstream>
#include <iostream>

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <time.h>

#define N 500 /*snake length*/
#define W 1000
#define NODESIZE 10 /*node height & width*/
#define WINSIZEW 800
#define WINSIZEH 480

typedef enum {Up, Down, Right, Left}TDirection; //Possible directions

SDL_Surface* screen = NULL;
SDL_Surface* Table[N] = {NULL};
SDL_Surface* blank;
SDL_Surface* message = NULL;
SDL_Surface* puce; //Snake puce

//FONT
TTF_Font *font = NULL;
SDL_Color textColor = {0, 0, 0};

SDL_Rect Tabpos[N], ppuce, Wallpos[W];
//WALLS
SDL_Rect left, right, top, bot;

bool running = true;
int NodeCounter;
int score = 0;
TDirection direction;
SDL_TimerID timer;

Uint32 Anime_it (Uint32, void *);
int snakeColl(void);
int consoleOutput(const char* text);
void initWalls(void);
void Quitter(void); //will be executed when exiting
void SetPos(void);
void MoveSnake(void);
void Show(void);
void PurgeScreen(void);
void SetPuce(void);
void Lose(void);
void freeNodes(void);
void AddNode(void);

int main (int argc, char** argv)
{
	Uint32 speed; //game speed
	SDL_Event event;
	int done;
	int i;
	srand (time(NULL));

	i = SDL_Init(SDL_INIT_VIDEO|SDL_DOUBLEBUF|SDL_INIT_TIMER);

	if (i < 0){
		exit(EXIT_FAILURE);
	}

	atexit (Quitter);
        screen = SDL_SetVideoMode(WINSIZEW, WINSIZEH, 16, SDL_HWSURFACE);
	
	if (screen == NULL){
		exit(EXIT_FAILURE);
	}

	

	SDL_WM_SetCaption("SnakeDL", NULL); //S(nake)DL
	//Initialisations of fonts
	if (TTF_Init() == -1)
	{
		consoleOutput("Error TTF_Init");
		return false;
	}

	font = TTF_OpenFont("./data/borgnine.ttf", 28);
	if (font == NULL)
	{
		//consoleOutput(("Error %s", TTF_GetError()));
		return false;
	}

	speed = 80;
	//done = 1;
	NodeCounter = 5;
	direction = Right;
	initWalls();
	Table[0] = SDL_CreateRGBSurface(SDL_HWSURFACE, NODESIZE, NODESIZE, 16, 0, 0, 0, 0);
	SDL_FillRect(Table[0], NULL, SDL_MapRGB(Table[0]->format, 0, 255, 0));
	Tabpos[0].x = screen->w/2;
	Tabpos[0].y = screen->h/2;

	for (i = 1; i < NodeCounter; i++){
		Table[i] = SDL_CreateRGBSurface(SDL_HWSURFACE, NODESIZE, NODESIZE, 16, 0, 0, 0, 0);
		SDL_FillRect (Table[i], NULL, SDL_MapRGB (Table[i]->format, 0, 0, 0));
		Tabpos[i].x = Tabpos[i-1].x - NODESIZE;
		Tabpos[i].y = screen->h/2;
	}

	SDL_ShowCursor(0);

	Show();
	SDL_Flip(screen);
	timer = SDL_AddTimer(1, Anime_it, &speed);
	SetPuce();

	while (running){
	SDL_WaitEvent(&event);
	
	switch (event.type){
		case SDL_QUIT:
			running = false;
			break;
		case SDL_KEYDOWN:
			switch (event.key.keysym.sym){
				case SDLK_w:
					if (direction != Down)
						direction = Up;
						break;
				case SDLK_s:
					if (direction != Up)
						direction = Down;
						break;
				case SDLK_d:
					if (direction != Left)
						direction = Right;
						break;
				case SDLK_a:
					if (direction != Right)
						direction = Left;
						break;
				case SDLK_u: //INCREASE SPEED
					if ((speed-5)>0)
						speed -= 5;
						break;
				case SDLK_l: //DECREASE SPEED
					if ((speed+5)<100)
						speed += 5;
						break;
				case SDLK_q:
					Quitter();
					break;
			}
			break;
		}//SWITCH
	} //WHILE
	
	return 0;
}

int consoleOutput(const char* text)
{
	using namespace std;

	cout << text << endl;
	return 0;
}

void MoveSnake()
{
	switch (direction){
		case Up:
		if ((Tabpos[0].y - NODESIZE) >= 10)
			Tabpos[0].y -= NODESIZE;
		else
			Lose();
			//Tabpos[0].y -= NODESIZE;
			break;
		case Down:
		if ((Tabpos[0].y + NODESIZE) < (screen->h - 10))
			Tabpos[0].y += NODESIZE;
		else
			Lose();
			//Tabpos[0].y += NODESIZE;
			break;
		case Right:
		if ((Tabpos[0].x + NODESIZE) < (screen->w - 10))
			Tabpos[0].x += NODESIZE;
		else
			Lose();
			//Tabpos[0].x += NODESIZE;
			break;
		case Left:
		if ((Tabpos[0].x - NODESIZE) >= 10)
			Tabpos[0].x -= NODESIZE;
		else
			Lose();
			//Tabpos[0].x -= NODESIZE;
			break;
	}

	//Incase teleporting from wall to opposite wall instead of loosing game
	/*if ((Tabpos[0].x == WINSIZEW ))
		Tabpos[0].x = 0;
	else if ((Tabpos[0].x == 0))
		Tabpos[0].x = WINSIZEW;
	else if ((Tabpos[0].y == WINSIZEH))
		Tabpos[0].y = 0;
	else if ((Tabpos[0].y == 0))
		Tabpos[0].y = WINSIZEH;*/

	if ((Tabpos[0].x == ppuce.x) && (Tabpos[0].y == ppuce.y))
	{
		score++;
		AddNode();
	}

	if (snakeColl())
		Lose();
}

void SetPos(void)
{
	int i;

	for (i = (NodeCounter-1); i>0; i--)
	{
		Tabpos[i].x = Tabpos[i-1].x;
		Tabpos[i].y = Tabpos[i-1].y;
	}
}

void initWalls(void)
{
	left.x = 0;
	left.y = 0;
	left.w = 10;
	left.h = WINSIZEH;

	right.x = (WINSIZEW - 10);
	right.y = 0;
	right.w = 10;
	right.h = WINSIZEH;

	top.x = 10;
	top.y = 0;
	top.w = (WINSIZEW - 20);
	top.h = 10;

	bot.x = 10;
	bot.y = (WINSIZEH - 10);
	bot.w = (WINSIZEW - 20);
	bot.h = 10;
}

void Show(void)
{
	int i;
	int y;
	char intScore[32];
	SDL_Rect msgOffset;


	for (i=0; i < NodeCounter; i++)
		SDL_BlitSurface(Table[i], NULL, screen, &Tabpos[i]);
		SDL_BlitSurface(puce, NULL, screen, &ppuce);
	
	SDL_FillRect(screen, &left, SDL_MapRGB(screen->format, 0, 0, 0));
	SDL_FillRect(screen, &right, SDL_MapRGB(screen->format, 0, 0, 0));
	SDL_FillRect(screen, &top, SDL_MapRGB(screen->format, 0, 0, 0));
	SDL_FillRect(screen, &bot, SDL_MapRGB(screen->format, 0, 0, 0));

	msgOffset.x = 20;
	msgOffset.y = (WINSIZEH - 38);

	
	sprintf(intScore, "Score: %d", score);
	message = TTF_RenderText_Solid(font, intScore, textColor);
	if (message == NULL)
	{
		consoleOutput("Error TTF_RenderText_solid in Show()");
	}

	SDL_BlitSurface(message, NULL, screen, &msgOffset);
}

void Quitter(void)
{
	freeNodes();
	SDL_FreeSurface(puce);
	SDL_FreeSurface(screen);
	SDL_FreeSurface(message);
	running = false;
	SDL_Quit();
}

void PurgeScreen(void)
{
	SDL_Rect p;
	p.x = 0;
	p.y = 0;
	blank = SDL_CreateRGBSurface(SDL_HWSURFACE, screen->w, screen->h, 16, 0, 0, 0, 0);
	SDL_FillRect(blank, NULL, SDL_MapRGB(blank->format, 189, 220, 144));
	SDL_BlitSurface(blank, NULL, screen, &p);
	SDL_FreeSurface(blank);
}

void SetPuce()
{
	int genx, geny, flag = 1, cpt;

	while (flag)
	{
		flag = 0;
		genx = (rand() % ((WINSIZEW - 10)/10))*NODESIZE;
		for (cpt=10; cpt < NodeCounter; cpt++)
			if (genx == Tabpos[cpt].x)
			{
				flag = 1;
				break;
		}
	}
	flag = 1;

	while (flag)
	{
		flag = 0;
		geny = (rand() % ((WINSIZEH - 10)/10))*NODESIZE;
		for (cpt=10; cpt < NodeCounter; cpt ++)
			if (geny == Tabpos[cpt].y)
			{
				flag = 1;
				break;
		}
	}

	puce = SDL_CreateRGBSurface(SDL_HWSURFACE, NODESIZE, NODESIZE, 16, 0, 0, 0, 0);
	SDL_FillRect (puce, NULL, SDL_MapRGB (puce->format, 0, 0, 0));
	ppuce.x = genx;
	ppuce.y = geny;
	SDL_BlitSurface(puce, NULL, screen, &ppuce);
}

Uint32 Anime_it(Uint32 interval, void *param)
{
	Uint32 *t = (Uint32*)param;
	SDL_Delay (*t);
	MoveSnake();
	SetPos();
	PurgeScreen();
	Show();
	SDL_Flip(screen);
	return interval;
}

void Lose(void)
{
	SDL_RemoveTimer(timer);
	//running = false;
	Quitter();
}

void freeNodes(void)
{
	int i;
	for (i = 0; i < NodeCounter; i++)
		SDL_FreeSurface(Table[i]);
}

void AddNode(void)
{
	NodeCounter++;

	Table[NodeCounter-1] = SDL_CreateRGBSurface(SDL_HWSURFACE, NODESIZE, NODESIZE, 16, 0, 0, 0, 0);
	SDL_FillRect(Table[NodeCounter-1], NULL, SDL_MapRGB (Table[NodeCounter-1]->format, 0, 0, 0));
	SetPuce();
}

int snakeColl(void)
{
	int i, cl = 0;
	for (i = 3; i < NodeCounter; i++)
		if ((Tabpos[0].x == Tabpos[i].x) && (Tabpos[0].y == Tabpos[i].y))
		{
			cl = 1;
			break;
	}

	return cl;
}
Thanks to:
http://www.cprogrammingreference.com...ming/Snake.php
 

The Following 3 Users Say Thank You to Marcus For This Useful Post:
Posts: 270 | Thanked: 239 times | Joined on Dec 2009 @ Czech Republic
#2
Thankk you and good luck to the future developing. I am developing snake game too
 
Reply


 
Forum Jump


All times are GMT. The time now is 03:28.