Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Coder proprement un snake  (Lu 4483 fois)

0 Membres et 1 Invité sur ce sujet

cChaD

  • Full Member
  • ***
  • Messages: 117
    • Voir le profil
Coder proprement un snake
« le: Septembre 07, 2014, 03:09:54 pm »
Bonjour,

je viens de reprendre la SFMLet pour me remettre en condition j'ai coder un snake vraiment basique, mais j'aimerais savoir si il est proprement coder, et si il exploite au mieux les concepts de la POO.

Merci.

#include <iostream>
#include <SFML/Graphics.hpp>
#include "Snake.h"

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 640

int main(int, char const**)
{
    sf::RenderWindow window(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "SFML window");

    window.setFramerateLimit(60);
    window.setKeyRepeatEnabled(false);

    Snake snake(window, 32, 32);

    while (window.isOpen())
    {
        snake.Move();

        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                window.close();
            }

            snake.Update(event);

        }

        window.clear(sf::Color(0,162,255));
        snake.Draw();
        window.display();
    }

    return EXIT_SUCCESS;
}
 


#ifndef SNAKE_H_INCLUDED
#define SNAKE_H_INCLUDED

#include <iostream>
#include <SFML/Graphics.hpp>
#include <cstdlib>
#include <ctime>

class Snake
{
    public:
        Snake(sf::RenderWindow &window, int sSize, int sSpeed);

        void Move();
        void Update(sf::Event &event);
        void Draw();

    private:
        sf::RenderWindow &mWindow;
        sf::Clock mClock;
        sf::CircleShape mFood;
        int mTimeToUpdate;
        int mSize;
        int mSpeed;
        bool mLeft, mRight, mUp, mDown;
        float mCurrentTime;
        std::vector<sf::RectangleShape> mSnakes;

        void CheckCollision();
        void AddCase();
        void FoodGenerator();
};

#endif // SNAKE_H_INCLUDED
 

#include "Snake.h"

using namespace std;
using namespace sf;

Snake::Snake(RenderWindow &window, int sSize, int sSpeed) : mWindow(window), mSize(sSize), mSpeed(sSpeed)
{
    mTimeToUpdate = 250; // 1/4 second
    mCurrentTime = 0.0f;
    mLeft = mUp = mDown = false;
    mRight = true;
    srand(std::time(0));
    AddCase();
    AddCase();

    mFood.setRadius(mSize / 2); // Food circle
    mFood.setFillColor(sf::Color::Green);
    FoodGenerator();
}

void Snake::FoodGenerator() // Generates the new food position
{
    int randomX = rand() % (mWindow.getSize().x / mSize);
    int randomY = rand() % (mWindow.getSize().y / mSize);

    for(unsigned int i = 0; i < mSnakes.size(); i++)
    {
        if((mSnakes[0].getPosition().x != randomX * mSize) && (mSnakes[0].getPosition().y != randomY))
        {
            mFood.setPosition(randomX * mSize, randomY * mSize);
        }
    }
}

void Snake::AddCase() // Add 1 more case
{
    sf::RectangleShape rect;
    rect.setSize(sf::Vector2f(32, 32));
    rect.setOutlineColor(sf::Color::Black);
    rect.setOutlineThickness(1.0f);

    if (mSnakes.empty())
    {
        rect.setFillColor(sf::Color::Red);
        rect.setPosition(320, 256);
    }
    else
    {
        rect.setFillColor(sf::Color::Yellow);
        rect.setPosition(mSnakes[mSnakes.size() - 1].getPosition().x - rect.getSize().x, mSnakes[mSnakes.size() - 1].getPosition().y);
    }

    mSnakes.push_back(rect);
}

void Snake::Move() // Move the snake every 250 ms and check collision
{
    if (mCurrentTime < mTimeToUpdate)
    {
        mCurrentTime += mClock.restart().asMilliseconds();
    }
    else
    {
        mCurrentTime = 0.0f;

        if (mSnakes.size() > 1)
        {
            for (unsigned int i = mSnakes.size() - 1; i > 0; i--)
            {
                mSnakes[i].setPosition(sf::Vector2f(mSnakes[i-1].getPosition().x, mSnakes[i-1].getPosition().y));
            }
        }

        if (mLeft)
        {
            mSnakes[0].move(-mSpeed, 0);
        }

        if (mRight)
        {
            mSnakes[0].move(mSpeed, 0);
        }

        if (mUp)
        {
            mSnakes[0].move(0, -mSpeed);
        }

        if (mDown)
        {
            mSnakes[0].move(0, mSpeed);
        }

        CheckCollision();
    }
}

void Snake::CheckCollision()
{
    for (unsigned int i = 2; i < mSnakes.size(); i++) // Snake's boxes
    {
        if (mSnakes[0].getPosition().x == mSnakes[i].getPosition().x
        && mSnakes[0].getPosition().y == mSnakes[i].getPosition().y)
        {
            mWindow.close();
        }
    }

    if (mSnakes[0].getPosition().x < 0 || mSnakes[0].getPosition().x + mSnakes[0].getSize().x > mWindow.getSize().x // Window collision
    || mSnakes[0].getPosition().y < 0 || mSnakes[0].getPosition().y + mSnakes[0].getSize().y > mWindow.getSize().y)
    {
        mWindow.close();
    }

    if (mSnakes[0].getPosition().x == mFood.getPosition().x // Food collision
    && mSnakes[0].getPosition().y == mFood.getPosition().y)
    {
        AddCase();
        FoodGenerator();
    }
}

void Snake::Update(Event &event) // Check key input
{
    if (event.type == sf::Event::KeyPressed)
    {
        if (event.key.code == sf::Keyboard::Left)
        {
            if(mSnakes[0].getPosition().x - mSnakes[0].getSize().x != mSnakes[1].getPosition().x)
            {
                if(!mLeft && !mRight)
                {
                    mLeft = true;
                    mRight = false;
                    mUp = false;
                    mDown = false;
                }
            }
        }

        if (event.key.code == sf::Keyboard::Right)
        {
            if(mSnakes[0].getPosition().x + mSnakes[0].getSize().x != mSnakes[1].getPosition().x)
            {
                if(!mRight && !mLeft)
                {
                    mLeft = false;
                    mRight = true;
                    mUp = false;
                    mDown = false;
                }
            }
        }

        if (event.key.code == sf::Keyboard::Up)
        {
            if(mSnakes[0].getPosition().y - mSnakes[0].getSize().x != mSnakes[1].getPosition().y)
            {
                if(!mUp && !mDown)
                {
                    mLeft = false;
                    mRight = false;
                    mUp = true;
                    mDown = false;
                }
            }
        }

        if (event.key.code == sf::Keyboard::Down)
        {
            if(mSnakes[0].getPosition().y + mSnakes[0].getSize().x != mSnakes[1].getPosition().y)
            {
                if(!mUp && !mDown)
                {
                    mLeft = false;
                    mRight = false;
                    mUp = false;
                    mDown = true;
                }
            }
        }
    }
}

void Snake::Draw()
{
    mWindow.draw(mFood);

    for (unsigned int i = 0; i < mSnakes.size(); i++)
        mWindow.draw(mSnakes[i]);
}
 

TheKingArthur

  • Invité
Re : Coder proprement un snake
« Réponse #1 le: Septembre 07, 2014, 09:18:59 pm »
Tout est bon. Pour moi ton code est propre.
Après si tu veut optimiser tu pourrait faire une classe pour ton snake, une pour la nourriture et une pour le jeu. Dans le main tu aurait un truc du style :


int main()
{

Game game;

game.run(); //Creation de le fenêtre dans la fonction et affichage du snake et de la nourriture

//Les classes snake et nourriture héritent de sf::Drawable

}

 

Mais sa c'est plus pour les "gros" jeu pour snake ce que tu as fait suffit largement.
« Modifié: Septembre 07, 2014, 09:22:19 pm par TheKingArthur »

cChaD

  • Full Member
  • ***
  • Messages: 117
    • Voir le profil
Re : Coder proprement un snake
« Réponse #2 le: Septembre 08, 2014, 07:09:56 pm »
D'accord merci !

TheKingArthur

  • Invité
Re : Coder proprement un snake
« Réponse #3 le: Septembre 08, 2014, 10:12:22 pm »
De rien :)