在 C++ 中使用 SFML 1.6 的平台游戏 使用 AABB 的碰撞

platform game using sfml 1.6 in c++ collision using AABB's

本文关键字:平台 游戏 使用 碰撞 AABB C++ SFML      更新时间:2023-10-16

我正在使用贴图映射,并让我的地图类通过使用一系列精灵来绘制地图。我用它来设置精灵的位置,然后在它周围创建一个边界框数组,然后绘制精灵。

然后我有一个碰撞类来获取玩家的边界框,并将其与精灵的每个边界框进行比较。我有一个名为platformboundingBox的数组。这将在数组中存储每个精灵的每个边界框。然而,当我比较这些值时,我发现平台边界框在任何位置都没有值,但我已经检查了每个Sprite的值是否都进入了边界框数组。

这是我的map类。看看drawmap和collision函数。如果有人能帮忙,我会非常感激。

#include "Map.h"
#include "Block.h"
#include <sstream>
using namespace std;
Map::Map()
{
    //map ctor;
}
Map::~Map()
{
    // map dtor
}

void Map::Initialise(const char *filename)
{
    if(!BlockImage.LoadFromFile("Images/block.png"))
        cout<<endl<<"failed to load block image"<<endl;
    if(!GemImage.LoadFromFile("Images/Gem.png"))
        cout<<endl<<"failed to load Gem Image"<<endl;
    if(!leftBlockImage.LoadFromFile("Images/blockLeft.png"))
        cout<<endl<<"failed to load left block Image"<<endl;
    if(!rightBlockImage.LoadFromFile("Images/blockRight.png"))
        cout<<endl<<"failed to load right block Image"<<endl;
    std::ifstream openfile(filename);
    std::vector <int>  tempvector;
    std::string line;
    while(std::getline(openfile, line))
    {
        for(int i =0; i < line.length(); i++)
        {
            if(line[i] != ' ') // if the value is not a space
            {
                char value = line[i];
                tempvector.push_back(value - '0');
            }
        }
            mapVector.push_back(tempvector); // push back the value of the temp vector into the map vector
            tempvector.clear(); // clear the temp vector readt for the next value
    }

}
    void Map::DrawMap(sf::RenderWindow &Window)
            {
                Player playermap;
                    for(i = 0; i < mapVector.size(); i++)
                {
                    for(j = 0; j < mapVector[i].size(); j++)
                    {
                          if(mapVector[i][j] == 1)
                         {
                            sprite[j].SetImage(BlockImage);
                            sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
                            platformBoundingBox[j].Bottom = sprite[j].GetPosition().y;
                            platformBoundingBox[j].Left = sprite[j].GetPosition().x - 5;
                            platformBoundingBox[j].Right = sprite[j].GetPosition().x;
                            Window.Draw(sprite[j]);
                         }
                          else if(mapVector[i][j] == 2)
                          {
                              sprite[j].SetImage(GemImage);
                              sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
                              platformBoundingBox[j].Top = sprite[j].GetPosition().y - 5;
                              platformBoundingBox[j].Bottom = sprite[j].GetPosition().y;
                              platformBoundingBox[j].Left = sprite[j].GetPosition().x - 5;
                              platformBoundingBox[j].Right = sprite[j].GetPosition().x;
                              Window.Draw(sprite[j]);
                          }
                          else if(mapVector[i][j] == 3)
                          {
                              sprite[j].SetImage(leftBlockImage);
                              sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
                              platformBoundingBox[j].Top = sprite[i].GetPosition().y - 5;
                              platformBoundingBox[j].Bottom = sprite[i].GetPosition().y;
                              platformBoundingBox[j].Left = sprite[i].GetPosition().x - 5;
                              platformBoundingBox[j].Right = sprite[i].GetPosition().x;
                              Window.Draw(sprite[j]);
                          }
                          else if(mapVector[i][j] == 4)
                          {
                              sprite[j].SetImage(rightBlockImage);
                              sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
                              platformBoundingBox[j].Top = sprite[i].GetPosition().y - 5;
                              platformBoundingBox[j].Bottom = sprite[i].GetPosition().y;
                              platformBoundingBox[j].Left = sprite[i].GetPosition().x - 5;
                              platformBoundingBox[j].Right = sprite[i].GetPosition().x;
                              Window.Draw(sprite[j]);
                          }
                    }
                }
            }
    void Map::collisions(float x, float y)
    {
        Player playermap;
        this->x = x;
        this->y = y;                
        playerboundingbox.Top = y - 5;
        playerboundingbox.Bottom = y ;
        playerboundingbox.Left = x - 5;
        playerboundingbox.Right = x;
        for(i = 0; i < 100; i++)
        {
            if(playerboundingbox.Intersects(platformBoundingBox[i]))
                cout << " praise the lord";     
        }

    }

请切换到SFML 2,因为1.6有很多错误。

假设您创建了一个名为handler的类,您将在其中放置:

handler::handler()
    // window initialization
    Map Map; // here initialize the Map class
    /* why don't use Map::Map( ctor) for initialization? */
    // player initialization
    // run the program as long as the window is open
    while (window.isOpen())
    {
        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
            window.close();
        }
        window.clear();
        //draw player
        Map.DrawMap(); // also need to improve the drawing for less lag
        window.display();
        update(Map &Map, Player &Player);
        // every time to use & because without the compiler will create another object
    }
}   
update(Map &Map, Player &Player)
{
    // verify if exists some interacts
    if (intersects(Map &Map, Player &Player))
    {
        //verify from where and put to the correct position
        /* e.g: if we have a collide with a down tile map will say something like this:
        Player.setPosition(Player.getPosition().x, (Player.getGlobalBounds().top+Player.getGlobalBounds().height)-(Map.getGlobalBounds().top-(Player.getGlobalBounds().top+Player.getGlobalBounds().height)); */
    }
}
intersects(Map &Map, Player &Player)
{
    sf::FloatRect fPlayer = Player.getGlobalBounds();
    for (int i=0; i<Map.NrOfYourTiles; ++i)
    {
        sf::FloatRect fMap = YourTile.getGlobalBounds();
        if (fPlayer.intersects(fMap))
            return 1;
    }
    return 0;
}

希望这将帮助你(代码是在SFML 2.0)。您可以在创建者sfml-dev.org的论坛上找到更多帮助。