蛇矩形矢量碰撞

时间:2014-09-22 15:22:04

标签: c++ sfml

我是SFML和C ++的新手,所以我试图同时学习它们。我决定写一个Snake游戏。对于我的蛇身体,我使用的是RectangleShapes矢量。我在屏幕中央画了一个浆果,我可以检测到我的蛇头与浆果发生碰撞,但我不知道如何测试蛇是否与自身发生碰撞。

我已经考虑过测试蛇的头部与整个块的矢量之间的碰撞,但是当蛇的头部与自身碰撞时,这将始终返回。

我很感激对我的代码提出任何建议和批评,谢谢!

#include <iostream>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <string>
#include <sstream>
using namespace sf;

constexpr int windowWidth{800}, windowHeight{600};

Vector2f blockLocation{0, 0};

struct Block
{
    RectangleShape shape;
    Vector2f blockSize{15,15};
    Block(float posX, float posY)
    {
        shape.setPosition(posX, posY);
        shape.setSize(blockSize);
        shape.setFillColor(Color::Blue);
        shape.setOutlineColor(Color::Green);
        shape.setOutlineThickness(3);
    }



};

struct Berry
{
    CircleShape shape;
    Berry(float posX, float posY)
    {
        shape.setPosition(posX, posY);
        shape.setRadius(8);
        shape.setFillColor(Color::Red);
        shape.setOutlineColor(Color::Magenta);
        shape.setOutlineThickness(3);
    }
};

bool keyUp(void)
{
    if(Keyboard::isKeyPressed(Keyboard::Key::Up)) return true;
    return false;
}
bool keyDown(void)
{
    if(Keyboard::isKeyPressed(Keyboard::Key::Down)) return true;
    return false;
}
bool keyLeft(void)
{
    if(Keyboard::isKeyPressed(Keyboard::Key::Left)) return true;
    return false;
}
bool keyRight(void)
{
    if(Keyboard::isKeyPressed(Keyboard::Key::Right)) return true;
    return false;
}
int stat(std::vector<Block> *blocks, RenderWindow *window)
{
    sf::Font font;
    if(!font.loadFromFile("Oswald-Bold.ttf"))
    {
        std::cerr << "Cannot load font!" << std::endl;
        return 1;
    }
    sf::Text text;
    text.setFont(font);
    std::ostringstream message;

    message << "x: " << blockLocation.x << std::endl
    << "y: " << blockLocation.y << std::endl
    << "blocks: " << blocks->size() << std::endl;


    text.setString(message.str());
    text.setCharacterSize(24);
    text.setColor(sf::Color::Magenta);
    text.setOrigin(0, 0);
    window->draw(text);
    return 0;
}


bool collision(Block *shapeA, Berry *shapeB)
{

    if( shapeA->shape.getGlobalBounds().intersects(shapeB->shape.getGlobalBounds())     )
    {
            std::cout << "collision with ";
            std::cout << "x: " << shapeA->shape.getPosition().x << "y: " << 
            shapeA->shape.getPosition().y << "and x: " << shapeB->shape.getPosition().x << "y: " << shapeB->shape.getPosition().y << std::endl;

            return true;
    }   
    else
        return false;   

}


int main(void)
{
    Clock clock;
    Time timeSinceLastUpdate = Time::Zero;
    const Time TimePerFrame = seconds(3.0f/30.f);
    std::vector<Block> blocks;
    RenderWindow window{ {windowWidth, windowHeight} , "blocks!"};

    bool up(false);
    bool down(false);
    bool left(false);
    bool right(false);
    window.setFramerateLimit(60);
    Berry berry(400, 300);

    blocks.emplace_back(blockLocation.x, blockLocation.y);

    while(window.isOpen())
    {

        if(Keyboard::isKeyPressed(Keyboard::Key::Escape)) return 0;

        Time elapsedTime = clock.restart();
        timeSinceLastUpdate += elapsedTime;

        while(timeSinceLastUpdate > TimePerFrame)
            {
            timeSinceLastUpdate -= TimePerFrame;

            window.clear(Color::Black);


            // Get the Head of the snake
            auto first = blocks.back();

             if(keyUp())
            {
                up = true;
                down = false, left = false, right = false;


                blocks.emplace_back(blockLocation.x, blockLocation.y);
                blocks.erase(blocks.begin());

            }
            else if(keyDown())
            {
                down = true;
                up = false, left = false, right = false;


                blocks.emplace_back(blockLocation.x, blockLocation.y);
                blocks.erase(blocks.begin());

            }   
            else if(keyLeft())
            {
                left = true;
                right = false, up = false, down = false;


                blocks.emplace_back(blockLocation.x, blockLocation.y);
                blocks.erase(blocks.begin());
            }   
            else if(keyRight())
            {
                right = true;
                left = false, up = false, down = false;


                blocks.emplace_back(blockLocation.x, blockLocation.y);
                blocks.erase(blocks.begin());
            }

            if(up) { blockLocation.y-=19; blocks.emplace_back(blockLocation.x, blockLocation.y); blocks.erase(blocks.begin());  

            }
            if(down) { blockLocation.y+=19; blocks.emplace_back(blockLocation.x, blockLocation.y); blocks.erase(blocks.begin()); 

            }
            if(left) { blockLocation.x-=19; blocks.emplace_back(blockLocation.x, blockLocation.y); blocks.erase(blocks.begin());

             }
            if(right){ blockLocation.x+=19; blocks.emplace_back(blockLocation.x, blockLocation.y); blocks.erase(blocks.begin()); 

            }
            if (collision(&first, &berry)) blocks.emplace_back(blockLocation.x, blockLocation.y);

            if(blocks.size() > 50)
            {
                blocks.erase(blocks.begin());
            }



            for(auto a : blocks)
            {


                window.draw(a.shape);

            }

            window.draw(berry.shape);
            stat(&blocks, &window);
            window.display();

        }


    }


    return 0;
}

0 个答案:

没有答案