Не работают вектора C++

72
21 марта 2022, 21:00

Я работаю над 2D игрой на SFMl c++. но думаю это не принципиально.

есть класс World. В нем есть вектор типа строка(это матрица мира), и есть двумерный вектор типа sf::Sprite(из SFML).

из символов я преобразую в sf::Sprite т.е. текстуры

ВНИМАНИЕ! Ошибка не в SFML а в векторе(вроде бы)

вообщем вот код: World.h:

#ifndef WORLD_H
#define WORLD_H
#include <SFML/Graphics.hpp>
#include <vector>
#include <string>
typedef unsigned short int _usi;
class World : public sf::Transformable, public sf::Drawable
{
public:
    World();
    void draw(sf::RenderTarget& target, sf::RenderStates states) const;
    void generateWorld();
private:
    sf::Texture textureTile;
    //level one
    const _usi worldLevelOneHeight = 10;
    const _usi worldLevelOneWidth = 20;
    std::vector<std::string> worldLevelOne;
    std::vector<std::vector<sf::Sprite>> worldSpriteLevelOne;
};
#endif // WORLD_H

World.cpp:

#include "world.h"
#include <iostream>
World::World()
{
    textureTile.loadFromFile("media/Tiles.png");
}
void World::generateWorld()
{
    std::cout<<"test1\n";
    worldLevelOne.push_back("                    ");
    worldLevelOne.push_back("                    ");
    worldLevelOne.push_back("                    ");
    worldLevelOne.push_back("                    ");
    worldLevelOne.push_back("                    ");
    worldLevelOne.push_back("                    ");
    worldLevelOne.push_back("====================");
    worldLevelOne.push_back("                    ");
    worldLevelOne.push_back("                    ");
    worldLevelOne.push_back("                    ");
    worldLevelOne.push_back("                    ");
    std::cout<<"test1\n";
    for(_usi h = 0; h < worldLevelOneHeight; ++h)
    {
        for(_usi w = 0; w < worldLevelOneWidth; ++w)
        {
            worldSpriteLevelOne[h].push_back(sf::Sprite());
            //set textures
            if(worldLevelOne[h][w] != ' ')
            {
                worldSpriteLevelOne[h][w].setTexture(textureTile); //ошибка вродебы вот тут
                if(worldLevelOne[h][w] == '=') worldSpriteLevelOne[h][w].setTextureRect(sf::IntRect(0,0,73,73));
                else  worldSpriteLevelOne[h][w].setTextureRect(sf::IntRect(73,0,73,73));
                worldSpriteLevelOne[h][w].setPosition(w*73, h*73);
            }
        }
    }
}
void World::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    states.transform *= getTransform();
    for(_usi h = 0; h < worldLevelOneHeight; ++h)
    {
        for(_usi w = 0; w < worldLevelOneWidth; ++w)
        {
            target.draw(worldSpriteLevelOne[h][w], states);
        }
    }
}

в коде я указал возможную строку из-за которой происходит ошибка

ВНИМАНИЕ! ошибка не сборки, а выполнения!

Answer 1

Вы хотите работать с вектором фиксированного размера. Тогда нужно сразу хранить вектора такого размера. Тогда вам не нужно хранить размеры, потому что сами вектора хранят эти размеры, и вам лишь нужно получать их:

class World : public sf::Transformable, public sf::Drawable
{
public:
    //...
    void generateWorld();
private:
    sf::Texture textureTile;
    //вектор для 10 строк с  20 _ тью пробелами
    std::vector<std::string> worldLevelOne =
        std::vector(10, std::string(" ", 20));
    //вектор для 10 векторов, содержащихся 20 sf::Sprite()
    std::vector<std::vector<sf::Sprite>> worldSpriteLevelOne =
        std::vector(10, std::vector<sf::Sprite>(20)) ;
};

Теперь функция член может быть написан проще и без ошибок:

void World::generateWorld()
{
    std::cout << "test1\n";
    //вам же нужно только одну строку заполнить символом '='
    worldLevelOne[6] = std::string("=", 20);
    //теперь получаем размеры векторов
    size_t height = worldSpriteLevelOne.size(),
        width = worldSpriteLevelOne[0].size();
    //и можете работать с элементами по своему усмотрению:
    for (_usi h = 0; h < height; ++h)
    {
        for (_usi w = 0; w < width; ++w)
        {
            //тут не нужно инициализировать вектор
            //set textures
            if (worldLevelOne[h][w] != ' ')
            {
                //ваш код
            }
        }
    }
}

И в дополнении:

Подумайте, не стоит ли вместо векторов использовать std::array, раз они не меняют свой размер?...

READ ALSO
Как добавить элементы в двусвязный список?

Как добавить элементы в двусвязный список?

Помогите пожалуйста дописать программуНужно написать процедуру, которая, получив в качестве параметра указатель на один из элементов двусвязного...

415
Двойное нажатие ЛКМ

Двойное нажатие ЛКМ

Я хочу сделать программу, которая при одном клике делает второй(нужно для копирования от 1 клика)Но,что я не пробовал, всё-равно выполняется...

81
Java. Прозрачность формы. @Override

Java. Прозрачность формы. @Override

Новый вопросЕсть появляющаяся форма (на ней элементы), задача сделать ее полупрозрачной

53
Установка библиотек Spring на сервер

Установка библиотек Spring на сервер

Каждый раз когда мне надо обновить Spring приложение, мне необходимо закачивать на сервер файл размером 30 мегабайт, 29 из которых занимают библиотеки...

106