Я работаю над 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);
}
}
}
в коде я указал возможную строку из-за которой происходит ошибка
ВНИМАНИЕ! ошибка не сборки, а выполнения!
Вы хотите работать с вектором фиксированного размера. Тогда нужно сразу хранить вектора такого размера. Тогда вам не нужно хранить размеры, потому что сами вектора хранят эти размеры, и вам лишь нужно получать их:
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, раз они не меняют свой размер?...
Сборка персонального компьютера от Artline: умный выбор для современных пользователей