C++vectors don't work

I'm working on a 2D game in SFMl c++. but I think it is not important.

There is a World class. It has a string type vector (this is the world matrix), and there is a two-dimensional sf::Sprite type vector (from SFML).

From the characters I transform into sf:: Sprite i.e. textures

ATTENTION! The error is not in SFML but in the vector(it seems to be)

In general, here is the code: 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);
        }
    }
}

In the code, I specified a possible string due to which occurs error

ATTENTION! the error is not the build, but the execution!

Author: lofectr, 2020-01-31

1 answers

You want to work with a fixed-size vector. Then you need to immediately store vectors of this size. Then you don't need to store the dimensions, because the vectors themselves store these dimensions, and you only need to get them:

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

Now the member function can be written easier and without errors:

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] != ' ')
            {
                //ваш код
            }
        }
    }
}

And in the supplement:

Think about using std::array instead of vectors, since they don't change their size?...

 2
Author: AR Hovsepyan, 2020-01-31 17:43:37