Areej
Areej

Reputation: 11

Snake game collision with tail

I'm having a problem with the TailCollision function in my snake game. Right now it doesn't work at all. Other than that the snake is drawn and moves perfectly. Thanks in advance to whoever points out where i goofed ^-^

Em i'm new to sfml and using a vector... pretty much my first time so please don't be too harsh!

Here is my Snake.cpp

#include "Snake.h"


Snake::Snake(){

    Snakey.setSize(sf::Vector2f(10, 10));

    Snakey.setFillColor(sf::Color(0,255,0));


    enter code here
    Snakey.setPosition(180,60);

    BodyList.push_back(Body);

}


Snake::~Snake(){
    BodyList.clear();
}

void Snake::Draw(sf::RenderWindow &window){

    window.draw(Snakey);

    for (sf::RectangleShape& Body : BodyList){

    window.draw(Body);
    }

    BodyList.erase(BodyList.begin());
    BodyList.push_back(Body);

}

void Snake::Grow(){

    Body.setSize(sf::Vector2f(10, 10));

    Body.setFillColor(sf::Color(0,100,0));

    Body.setPosition(Snakey.getPosition().x,Snakey.getPosition().y);

    BodyList.push_back(Body);


}



void Snake::Move(sf::Event event, sf::RenderWindow &window){

    if (sf::Keyboard::isKeyPressed && sf::Keyboard::Left == event.key.code && Dir != "Right"){
        Snakey.move(-10, 0);
        Body.move(-10,0);
        Dir = ("Left");
    }

    else if (sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Right == event.key.code && Dir != "Left"){
        Snakey.move(10, 0);
        Body.move(10,0);

        Dir = ("Right");
    }
    else if (sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Up == event.key.code && Dir != "Down"){
        Snakey.move(0, -10);
        Body.move(0,-10);

        Dir = ("Up");
    }
    else if (sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Down == event.key.code && Dir != "Up"){
        Snakey.move(0, 10);
        Body.move(0,10);

        Dir = ("Down");
    }

    else if (sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Down == event.key.code && Dir == "Up" || 
        sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Up == event.key.code && Dir == "Down" ||
        sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Right == event.key.code && Dir == "Left"||
        sf::Keyboard::isKeyPressed && sf::Keyboard::Left == event.key.code && Dir == "Right"){

        window.close();
    }
}

void Snake::TailCollision(sf::RenderWindow &window){

    for (int i = 0 ; i < BodyList.size(); i++){
        if ((Snakey.getPosition().x == BodyList[i].getPosition().x && Snakey.getPosition().y == BodyList[i].getPosition().y)&&
            (BodyList[i].getPosition().x != BodyList.back().getPosition().x &&
            BodyList[i].getPosition().y != BodyList.back().getPosition().y)){

                window.close();

        }

    }
}


sf::RectangleShape Snake::GetShape(){
    return Snakey;
}

Upvotes: 0

Views: 423

Answers (2)

Areej
Areej

Reputation: 11

I've realised the problem was with my move function and not even the collision one! Thank you all and I'm sorry to waste your time! ^-^ I really goofed...

Snake::Snake(){

    Snakey.setSize(sf::Vector2f(10, 10));

    Snakey.setFillColor(sf::Color(0,255,0));

    Snakey.setPosition(180,60);

}


Snake::~Snake(){
    BodyList.clear();
}

void Snake::Draw(sf::RenderWindow &window){

    window.draw(Snakey);

    for (sf::RectangleShape& Body : BodyList){

    window.draw(Body);
    }

}

void Snake::Grow(){

    Body.setSize(sf::Vector2f(10, 10));

    Body.setFillColor(sf::Color(0,100,0));

    BodyList.push_back(Body);

}



void Snake::Move(sf::Event event, sf::RenderWindow &window){

    if (sf::Keyboard::isKeyPressed && sf::Keyboard::Left == event.key.code && Dir != "Right"){

        Body.setPosition(Snakey.getPosition().x,Snakey.getPosition().y);

        BodyList.push_back(Body);
        BodyList.erase(BodyList.begin());

        Snakey.move(-10, 0);

        Dir = ("Left");
    }

    else if (sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Right == event.key.code && Dir != "Left"){

        Body.setPosition(Snakey.getPosition().x,Snakey.getPosition().y);

        BodyList.push_back(Body);
        BodyList.erase(BodyList.begin());

        Snakey.move(10, 0);

        Dir = ("Right");
    }
    else if (sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Up == event.key.code && Dir != "Down"){

        Body.setPosition(Snakey.getPosition().x,Snakey.getPosition().y);        

        BodyList.push_back(Body);
        BodyList.erase(BodyList.begin());

        Snakey.move(0, -10);

        Dir = ("Up");
    }
    else if (sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Down == event.key.code && Dir != "Up"){

        Body.setPosition(Snakey.getPosition().x,Snakey.getPosition().y);

        BodyList.push_back(Body);
        BodyList.erase(BodyList.begin());

        Snakey.move(0, 10);

        Dir = ("Down");
    }

    else if (sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Down == event.key.code && Dir == "Up" || 
        sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Up == event.key.code && Dir == "Down" ||
        sf::Keyboard::isKeyPressed && sf::Keyboard::Key::Right == event.key.code && Dir == "Left"||
        sf::Keyboard::isKeyPressed && sf::Keyboard::Left == event.key.code && Dir == "Right"){

        window.close();
    }
}

void Snake::TailCollision(sf::RenderWindow &window){

    for (int i = 0 ; i < BodyList.size(); i++){
        if ((Snakey.getPosition().x == BodyList[i].getPosition().x && Snakey.getPosition().y == BodyList[i].getPosition().y)){

                window.close();

        }

    }
}

Upvotes: 0

Nikita Smirnov
Nikita Smirnov

Reputation: 862

I think it is better to use SFML built-in functions, like getGlobalBounds(). If Snakey is a sf::Shape subclass (I hope it is), it should work.

const auto & headBounds = Snakey.getGlobalBounds();
for (int i = 0 ; i < BodyList.size(); i++)
{
    const auto & bodyBounds = BodyList[i].getGlobalBounds();
    if( bodyBounds.intersects( headBounds ) 
    {
        // process collision here
        break;
    }
}

Or even a bit shorter, as suggested in comments:

const auto & headBounds = Snakey.getGlobalBounds();
if( 
    std::any_of(
            BodyList.begin()
        ,   BodyList.end()
        ,   [ headBounds ] ( const auto & body ) 
            {
                return body.getGlobalBounds().intersects( headBounds );
            }
   )
)
{
    // process collision;
}

Upvotes: 1

Related Questions