SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › Не рисуется карта
В этой теме 1 ответ, 2 участника, последнее обновление KindRedSand 6 года/лет, 11 мес. назад.
-
АвторСообщения
-
После выполнения 9 урока выдает ошибку Expression: string subscript out of range. Несколько раз все перепроверил, код такой же как в уроке. Подскажите, пожалуйста, как избавиться от этой проблемы?
///////////////map.h/////////////
#pragma once
#include <SFML/Graphics.hpp>
const int HEIGHT_MAP = 25;
const int WIDTH_MAP = 40;sf::String TileMap[HEIGHT_MAP] = {
“0000000000000000000000000000000000000000”
“0 0″
“0 s 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0 0″
“0000000000000000000000000000000000000000”
};/////////////main.cpp////////////////////
#include <SFML/Graphics.hpp>
#include “map.h”
using namespace sf;class Player {
public:
float x, y, w, h, dx, dy, speed = 0;
int direction = 0;
String File;
Image image;
Texture texture;
Sprite sprite;
Player(String F, int X, int Y, float W, float H)
{
File = F;
w = W; h = H;
image.loadFromFile(“images/” + File);
image.createMaskFromColor(Color(255, 255, 255));
texture.loadFromImage(image);
sprite.setTexture(texture);
x = X; y = Y;
sprite.setTextureRect(IntRect(w, h, w, h));
}
void update(float time)
{
switch (direction)
{
case 0: { dx = speed; dy = 0; } break;
case 1: { dx = -speed; dy = 0; } break;
case 2: { dx = 0; dy = speed; } break;
case 3: { dx = 0; dy = -speed; } break;
}
x += dx*time;
y += dy*time;
speed = 0;
sprite.setPosition(x, y);
}
};int main()
{
RenderWindow window(VideoMode(640, 480), “my game”);Image map_image;
map_image.loadFromFile(“images/map.png”);
Texture map;
map.loadFromImage(map_image);
Sprite s_map;
s_map.setTexture(map);Player hero(“tileset2.png”, 25, 25, 32, 48);
float CurrentFrame = 0;
Clock clock;
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();
}if (Keyboard::isKeyPressed(Keyboard::Left) || (Keyboard::isKeyPressed(Keyboard::A)))
{
hero.direction = 1; hero.speed = 0.1;
CurrentFrame += 0.005*time;
if (CurrentFrame > 3) CurrentFrame -= 3;
hero.sprite.setTextureRect(IntRect(32 * int(CurrentFrame), 48, 32, 48));
}
if (Keyboard::isKeyPressed(Keyboard::Right) || Keyboard::isKeyPressed(Keyboard::D))
{
hero.direction = 0; hero.speed = 0.1;
CurrentFrame += 0.005*time;
if (CurrentFrame > 3) CurrentFrame -= 3;
hero.sprite.setTextureRect(IntRect(32 * int(CurrentFrame), 96, 32, 48));
}
if (Keyboard::isKeyPressed(Keyboard::Up) || Keyboard::isKeyPressed(Keyboard::W))
{
hero.direction = 3; hero.speed = 0.1;
CurrentFrame += 0.005*time;
if (CurrentFrame > 3) CurrentFrame -= 3;
hero.sprite.setTextureRect(IntRect(32 * int(CurrentFrame), 144, 32, 48));
}
if (Keyboard::isKeyPressed(Keyboard::Down) || Keyboard::isKeyPressed(Keyboard::S))
{
hero.direction = 2; hero.speed = 0.1;
CurrentFrame += 0.005*time;
if (CurrentFrame > 3) CurrentFrame -= 3;
hero.sprite.setTextureRect(IntRect(32 * int(CurrentFrame), 0, 32, 48));
}hero.update(time);
window.clear();
for(int i = 0; i < HEIGHT_MAP; i++)
for (int j = 0; j < WIDTH_MAP; j++)
{
if (TileMap[i][j] == ‘ ‘) s_map.setTextureRect(IntRect(0, 0, 32, 32));
if (TileMap[i][j] == ‘s’) s_map.setTextureRect(IntRect(32, 0, 32, 32));
if ((TileMap[i][j] == ‘0’)) s_map.setTextureRect(IntRect(64, 0, 32, 32));
s_map.setPosition(j * 32, i * 32);
window.draw(s_map);
}window.draw(hero.sprite);
window.display();
}
return 0;
}C++123456789101112131415161718192021222324252627sf::String TileMap[HEIGHT_MAP] = {“0000000000000000000000000000000000000000”“0 0″“0 s 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0 0″“0000000000000000000000000000000000000000”};Пробелы тоже символы, и учитываются при подсчёте длинны строки. Поскольку ты используешь константы для итерации по карте то будь добр проверять что длинна строки = этой константе:
C++123456789101112const int HEIGHT_MAP = 25;const int WIDTH_MAP = 40;for(int i = 0; i < HEIGHT_MAP; i++)for (int j = 0; j < WIDTH_MAP; j++){if (TileMap[i][j] == ‘ ‘) s_map.setTextureRect(IntRect(0, 0, 32, 32));if (TileMap[i][j] == ‘s’) s_map.setTextureRect(IntRect(32, 0, 32, 32));if ((TileMap[i][j] == ‘0’)) s_map.setTextureRect(IntRect(64, 0, 32, 32));s_map.setPosition(j * 32, i * 32);window.draw(s_map);}Поскольку c++ не поддерживает string по умолчанию сам он реализован в виде вектора char, и когда ты пытаешься сослатся на элемент которого нет в векторе – хватаешь экзепшен что ищеш обьект вне поля видимости. Выхода 2 – либо иметь строку длинной равной константе, что в данном случае самое уместное, либо считать длинну строки и использовать каждый раз её для итерации по масиву, что повлечёт свои проблемы так как это тайлсет а не строка содержащая в себе локализацию к примеру.
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.