【问题标题】:Snake game collision with tail蛇游戏与尾巴碰撞
【发布时间】:2018-02-08 09:04:25
【问题描述】:

我的蛇游戏中的 TailCollision 功能有问题。现在它根本不起作用。除此之外,这条蛇被画得很好并且移动得很好。在此先感谢指出我在哪里出错的人^-^

Em 我是 sfml 的新手并使用矢量...几乎是我的第一次,所以请不要太苛刻!

这是我的 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;
}

【问题讨论】:

  • 这是学习使用调试器的绝佳时机。我建议阅读此ericlippert.com/2014/03/05/how-to-debug-small-programs
  • 你要求BodyList[i]BodyList.back()的x和y都不同的碰撞,这是你想要的吗?否则,将&amp;&amp; 更改为||
  • 是的,向量的 .back() 会在头部的位置产生,所以如果我将其更改为 | |蛇长了就死了叫^-^"
  • 也感谢您的链接!

标签: c++ sfml stdvector


【解决方案1】:

我认为最好使用 SFML 内置函数,例如 getGlobalBounds()。 如果 Snakey 是 sf::Shape 子类(我希望是),它应该可以工作。

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;
    }
}

或者更短一点,如 cmets 中所建议的:

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

【讨论】:

  • 这里的循环可以换成std::any_of(BodyList.begin(), BodyList.end(), [&amp;](auto &amp; body) { return body.getPosition().getGlobalBounds().intersects(headBounds); })
  • @Caleth 感谢您的建议。
  • 非常感谢!我会试试的!但我的问题是,根据我的理解,最后一个向量元素总是在头部的位置产生,所以一旦增长被称为窗口关闭
【解决方案2】:

我意识到问题出在我的移动功能上,而不是碰撞功能!谢谢大家,很抱歉浪费您的时间! ^-^ 我真的搞砸了……

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();

        }

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多