не может правильно скомпилировать C ++ / SFML. Как исправить? - PullRequest
0 голосов
/ 04 мая 2020

Добрый день. Я пишу 2D-платформы, используя sfml, крошечные XML и TiledMapEditor. Я создал персонажа, карту, столкновение и анимацию. Я пытался начать, но окно просто закрывается. Компилятор показывает 0 ошибок, я в полной растерянности, что делать. Буду очень признателен за помощь !!!:)

main. cpp file:

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

#include "iostream"
#include "level.h"
#include <vector>
#include <list>

using namespace sf;
/*********************************************Р О Д И Т Е Л Ь   Д Л Я   Г Е Р О Я   Н П С    И   В Р А Г О В****************************************************************************/
class Entity {
public:
    std::vector<Object> obj;//вектор объектов карты
    float dx, dy, x, y, speed, moveTimer;
    int w, h, health;
    bool life, isMove, onGround;
    Texture texture;
    Sprite sprite;
    String name;
    Entity(Image& image, String Name, float X, float Y, int W, int H) {
        x = X; y = Y; w = W; h = H; name = Name; moveTimer = 0;
        speed = 0; health = 100; dx = 0; dy = 0;
        life = true; onGround = false; isMove = false;
        texture.loadFromImage(image);
        sprite.setTexture(texture);
        sprite.setOrigin(w / 2, h / 2);
    }

    FloatRect getRect() {//ф-ция получения прямоугольника. его коорд,размеры (шир,высот).
        return FloatRect(x, y, w, h);//ф-ция для проверки столкновений 
    }
};


/*********************************************С О З Д А Н И Е   Г Л А В Н О Г О   Г Е Р О Я****************************************************************************/


class Hero :public Entity 
{
public:
    enum { left, right, up, down, jump, stay } state;
    int playerScore;

    Hero(Image& image, String Name, Level& lev, float X, float Y, int W, int H) :Entity(image, Name, X, Y, W, H) {
        playerScore = 0; state = stay; obj = lev.GetAllObjects();//инициализируем.получаем все объекты для взаимодействия персонажа с картой
        if (name == "Player1") {
            sprite.setTextureRect(IntRect(0, 0, w, h));
        }
    }


    /******************************** У П Р А В Л Е Н И Е   И   А Н И М А Ц И И    Г Г **********************************/
    void control(float time) //управление персом
    {
        float currentFrame = 0;
        if (Keyboard::isKeyPressed(Keyboard::Left)) {
            state = left;
            speed = 0.1;
            currentFrame += 0.005 * time;//вывод анимации
            if (currentFrame > 3)
            {
                currentFrame -= 3;
            }
            this->sprite.setTextureRect(IntRect(144 * int(currentFrame), 240, 144, 240));
        }
        else if (Keyboard::isKeyPressed(Keyboard::Right)) {
            state = right;
            speed = 0.1;
            currentFrame += 0.005 * time;//вывод анимации
            if (currentFrame > 3)
            {
                currentFrame -= 3;
            }
            this->sprite.setTextureRect(IntRect(144 * int(currentFrame), 480, 144, 240));
        }
        else if ((Keyboard::isKeyPressed(Keyboard::Up)) && (onGround)) {
            state = jump; dy = -0.4; onGround = false;//то состояние равно прыжок,прыгнули и сообщили, что мы не на земле
            this->sprite.setTextureRect(IntRect(144, 240, 144, 240));
        }
        else
        {

            currentFrame += 0.005 * time;//вывод анимации
            if (currentFrame > 1)
            {
                currentFrame -= 1;
            }

            this->sprite.setTextureRect(IntRect(144 * int(currentFrame), 0, 144, 240));

        }
    }

    /****************************************** С Т О Л К Н О В Е Н И Е ************************************************/
        void Collision(float Dx, float Dy)
        {


            for (int i = 0; i < obj.size(); i++)//проходимся по объектам
            {
                if (getRect().intersects(obj[i].rect))//проверяем пересечение игрока с объектом
                {
                    if (obj[i].name == "ground"|| obj[i].name == "wood"||obj[i].name == "limit")//если встретили препятствие
                    {
                        if (Dy > 0) { y = obj[i].rect.top - h;  dy = 0; onGround = true; }
                        if (Dy < 0) { y = obj[i].rect.top + obj[i].rect.height;   dy = 0; }
                        if (Dx > 0) { x = obj[i].rect.left - w; }
                        if (Dx < 0) { x = obj[i].rect.left + obj[i].rect.width; }
                    }
                }
            }
        }

    /*********************************** О Ж И В Л Е Н И Е    П Е Р С О Н А Ж А *****************************************/
        void update(float time)
        {
            control(time);//функция управления персонажем
            switch (state)//тут делаются различные действия в зависимости от состояния
            {
            case right: dx = speed; break;
            case left: dx = -speed; break;
            case up: break;
            case down: break;
            case jump: break;
            case stay: break;
            }

            x += dx * time;
            Collision(dx, 0);//обрабатываем столкновение по Х
            y += dy * time;
            Collision(0, dy);//обрабатываем столкновение по Y
            if (!isMove) speed = 0;
            sprite.setPosition(x + w / 2, y + h / 2); //задаем позицию спрайта в место его центра
            if (health <= 0) { life = false; }
            dy = dy + 0.0015 * time;//делаем притяжение к земле
        }


        float getplayercoordinateX() 
        {
            return x;
        }
        float getplayercoordinateY() 
        {
            return y;
        }
    };






int main()
{

    Clock clock;
    RenderWindow window(VideoMode(1200, 720), "Look");


    Image map_image;
    map_image.loadFromFile("IMAGES/фон1лвл2.png");
    Texture map;
    map.loadFromImage(map_image);
    Sprite s_map;
    s_map.setTexture(map);
    Image hero_image;
    hero_image.loadFromFile("IMAGES/TileSetHero.png");



    Level lvl;
    lvl.LoadFromFile("LookMap.tmx");
    Object player = lvl.GetObject("Hero");//объект игрока на нашей карте.задаем координаты игроку в начале при помощи него
    Hero MainHero(hero_image, "Player1", lvl, player.rect.left, player.rect.top, 144, 240);//передаем координаты прямоугольника player из карты в координаты нашего игрока
    float currentFrame = 0;
    float dX = 0;
    float dY = 0;


    while (window.isOpen())
    {
        float time = clock.getElapsedTime().asMicroseconds();
        clock.restart();
        time = time / 800;
        Event event;


        while (window.pollEvent(event))
        {
            if (event.type == Event::Closed)
                window.close();
        }
        MainHero.update(time);
        window.setView(view);
        window.draw(s_map);
        lvl.Draw(window);//рисуем новую карту


        window.draw(MainHero.sprite);
        window.display();
    }



    return 0;
}

lvl.h:

#ifndef LEVEL_H
#define LEVEL_H

#include <string>
#include <vector>
#include <map>
#include <SFML/Graphics.hpp>
#include <iostream>
#include "TinyXML/tinyxml.h"


struct Object
{
    int GetPropertyInt(std::string name);//номер свойства объекта в нашем списке
    float GetPropertyFloat(std::string name);//номер свойства объекта в нашем списке с точкой
    std::string GetPropertyString(std::string name);//свойства

    std::string name;//название
    std::string type;//тип
    sf::Rect<float> rect;//тип Rect с нецелыми значениями
    std::map<std::string, std::string> properties;//создаём ассоциативный массив. ключ - строковый тип, значение - строковый
    sf::Sprite sprite;//спрайт
};

struct Layer//слои
{
    std::vector<sf::Sprite> tiles;//закидываем в вектор тайлы
}; 

class Level//главный класс - уровень
{
public:
    bool LoadFromFile(std::string filename);//возвращает false если не получилось загрузить
    Object GetObject(std::string name);
    std::vector<Object> GetObjects(std::string name);//выдаем объект в наш уровень
    std::vector<Object> GetAllObjects();//выдаем все объекты в наш уровень

    void Draw(sf::RenderWindow& window);//рисуем в окно
    sf::Vector2i GetTileSize();//получаем размер тайла

protected:

    int width, height, tileWidth, tileHeight;//в tmx файле width height в начале,затем размер тайла
    int firstTileID;//получаем айди первого тайла
    sf::Rect<float> drawingBounds;//размер части карты которую рисуем
    sf::Texture tilesetImage;//текстура карты
    std::vector<Object> objects;//массив типа Объекты, который мы создали
    std::vector<Layer> layers;//слои
};





///////////////////////////////////////
int Object::GetPropertyInt(std::string name)//возвращаем номер свойства в нашем списке
{
    return atoi(properties[name].c_str());
}
float Object::GetPropertyFloat(std::string name)
{
    return strtod(properties[name].c_str(), NULL);
}
std::string Object::GetPropertyString(std::string name)//получить имя в виде строки.вроде понятно
{
    return properties[name];
}
bool Level::LoadFromFile(std::string filename) 
{
    TiXmlDocument levelFile(filename.c_str());//загружаем файл в TiXmlDocument



    /*********************************************** З А Г Р У З К А   X M L   К А Р Т Ы *****************************************************/


    // работаем с контейнером map
    TiXmlElement* map;
    map = levelFile.Child("map");
    // пример карты: <map version="1.0" orientation="orthogonal"
    // width="10" height="10" tilewidth="34" tileheight="34">
    width = atoi(map->Attribute("width"));//извлекаем из нашей карты ее свойства
    height = atoi(map->Attribute("height"));//те свойства, которые задавали при работе в 
    tileWidth = atoi(map->Attribute("tilewidth"));//тайлмап редакторе
    tileHeight = atoi(map->Attribute("tileheight"));
    // Берем описание тайлсета и идентификатор первого тайла
    TiXmlElement* tilesetElement;
    tilesetElement = map->Child("tileset");
    firstTileID = atoi(tilesetElement->Attribute("firstgid"));
    // source - путь до картинки в контейнере image
    TiXmlElement* image;
    image = tilesetElement->Child("image");
    std::string imagepath = image->Attribute("source");


    // пытаемся загрузить тайлсет
    sf::Image img;
    tilesetImage.loadFromImage(img);


    int columns = tilesetImage.getSize().x / tileWidth;// размер тайлсета по х
    int rows = tilesetImage.getSize().y / tileHeight;//по у




    std::vector<sf::Rect<int>> ArrayOfRectangles;// вектор из прямоугольников изображений.Заполняем карту.
    for (int y = 0; y < rows; y++)
        for (int x = 0; x < columns; x++)
        {
            sf::Rect<int> rect;
            rect.top = y * tileHeight;
            rect.height = tileHeight;
            rect.left = x * tileWidth;
            rect.width = tileWidth;
            ArrayOfRectangles.push_back(rect);
        }




    /*********************************************** Р А Б О Т А   С О   С Л О Я М И *****************************************************/
    TiXmlElement* LayerEl;
    LayerEl = map->Child("layer");

    while (LayerEl);
    {
        Layer layer;


        //  контейнер <data> 
        TiXmlElement* DataOfCurrentLayer;
        DataOfCurrentLayer = LayerEl->Child("data");


        //  контейнер <tile> - описание тайлов каждого слоя
        TiXmlElement* tile;
        tile = DataOfCurrentLayer->Child("tile");

        int x = 0;
        int y = 0;
        while (tile)
        {
            int tileGID = atoi(tile->Attribute("gid"));
            int subRectToUse = tileGID - firstTileID;
            // Устанавливаем TextureRect каждого тайла
            if (subRectToUse >= 0)
            {
                sf::Sprite sprite;
                sprite.setTexture(tilesetImage);
                sprite.setTextureRect(ArrayOfRectangles[subRectToUse]);
                sprite.setPosition(x * tileWidth, y * tileHeight);



                layer.tiles.push_back(sprite);//закидываем в слой спрайты 
            }
            tile = tile->NextSiblingElement("tile");
            x++;
            if (x >= width)
            {
                x = 0;
                y++;
                if (y >= height)
                    y = 0;
            }
        }
        layers.push_back(layer);//ЗАКИДЫВАЕМ В ОБЩИЙ ВЕКТОР СЛОЕВ ВСЕ СЛОИ
        LayerEl = LayerEl->NextSiblingElement("layer");
    }
    /************************* Р А Б О Т А  С  О Б Ъ Е К Т А М И ***************************/

    TiXmlElement* GroupOfObjects;
    // если есть слои объектов
    if (map->Child("objectgroup") != NULL)
    {
        GroupOfObjects = map->Child("objectgroup");
        while (GroupOfObjects)
        {
            //  контейнер <object>
            TiXmlElement* objectElement;
            objectElement = GroupOfObjects->Child("object");
            while (objectElement)
            {
                // получаем все данные - тип, имя, позиция, и тд
                std::string objectType;
                if (objectElement->Attribute("type") != NULL)
                {
                    objectType = objectElement->Attribute("type");
                }
                std::string objectName;
                if (objectElement->Attribute("name") != NULL)
                {
                    objectName = objectElement->Attribute("name");
                }
                int x = atoi(objectElement->Attribute("x"));
                int y = atoi(objectElement->Attribute("y"));
                int width, height;
                sf::Sprite sprite;
                sprite.setTexture(tilesetImage);
                sprite.setTextureRect(sf::Rect<int>(0, 0, 0, 0));
                sprite.setPosition(x, y);
                if (objectElement->Attribute("width") != NULL)
                {
                    width = atoi(objectElement->Attribute("width"));
                    height = atoi(objectElement->Attribute("height"));
                }
                else
                {
                    width = ArrayOfRectangles[atoi(objectElement->Attribute("gid")) - firstTileID].width;
                    height = ArrayOfRectangles[atoi(objectElement->Attribute("gid")) - firstTileID].height;
                    sprite.setTextureRect(ArrayOfRectangles[atoi(objectElement->Attribute("gid")) - firstTileID]);
                }
                // экземпляр объекта
                Object object;
                object.name = objectName;
                object.type = objectType;
                object.sprite = sprite;
                sf::Rect <float> objectRect;
                objectRect.top = y;
                objectRect.left = x;
                objectRect.height = height;
                objectRect.width = width;
                object.rect = objectRect;
                // "переменные" объекта
                TiXmlElement* properties;
                properties = objectElement->Child("properties");
                if (properties != NULL)
                {
                    TiXmlElement* prop;
                    prop = properties->Child("property");
                    if (prop != NULL)
                    {
                        while (prop)
                        {
                            std::string propertyName = prop->Attribute("name");
                            std::string propertyValue = prop->Attribute("value");
                            object.properties[propertyName] = propertyValue;
                            prop = prop->NextSiblingElement("property");
                        }
                    }
                }
                objects.push_back(object);
                objectElement = objectElement->NextSiblingElement("object");
            }
            GroupOfObjects = GroupOfObjects->NextSiblingElement("objectgroup");
        }
    }
    else{   }
    return true;
}

/************************* Г Е Т Т Е Р Ы ***************************/
Object Level::GetObject(std::string name)
{
    // только первый объект с заданным именем
    for (int i = 0; i < objects.size(); i++)
        if (objects[i].name == name)
            return objects[i];
}
std::vector<Object> Level::GetObjects(std::string name)
{
    // все объекты с заданным именем
    std::vector<Object> vec;
    for (int i = 0; i < objects.size(); i++)
        if (objects[i].name == name)
            vec.push_back(objects[i]);
    return vec;
}
std::vector<Object> Level::GetAllObjects()
{
    return objects;
};
sf::Vector2i Level::GetTileSize()
{
    return sf::Vector2i(tileWidth, tileHeight);
}

/***************** О Т Р И С О В К А   Т А Й Л О В *****************/
void Level::Draw(sf::RenderWindow& window)
{
    // рисуем все тайлы (объекты не рисуем!)
    for (int layer = 0; layer < layers.size(); layer++)
        for (int tile = 0; tile < layers[layer].tiles.size(); tile++)
            window.draw(layers[layer].tiles[tile]);
}
#endif

и просмотр .h:

#include <SFML/Graphics.hpp>
using namespace sf;

sf::View view;

void setPlayerCoordinateForView(float x, float y) {
    float tempX = x; float tempY = y;


    if (y > 5664) tempY = 5664;

    view.setCenter(tempX, tempY);
}
...