maemo.org - Talk

maemo.org - Talk (https://talk.maemo.org/index.php)
-   Development (https://talk.maemo.org/forumdisplay.php?f=13)
-   -   [C++ & SDL] Unfinished Snake Game (https://talk.maemo.org/showthread.php?t=49853)

Marcus 2010-04-12 18:55

[C++ & SDL] Unfinished Snake Game
 
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:
http://img683.imageshack.us/img683/1...eenshot2xd.png

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

Figa 2010-04-12 19:14

Re: [C++ & SDL] Unfinished Snake Game
 
Thankk you and good luck to the future developing. I am developing snake game too :)


All times are GMT. The time now is 08:32.

vBulletin® Version 3.8.8