Отрисовка карты SFML
| |
veeroteen | Дата: Пятница, 24 Апреля 2020, 21:42 | Сообщение # 1 |
был не раз
Сейчас нет на сайте
| Подкиньте идей для отрисовки карты, просто зашел в тупик, через tinyxml прорисовка тайликов заканчивается безбожной потерей фпс, вплоть до 4 фпс за зону 20 на 40 по 32px, на самом деле проблема не очень то частая, потому что все это можно бы ло бы залить в строку, и доставать напрямую(так очевидно быстрей), но в таком случае есть конкретные ограничения на размер карты которые меня не очень устраивают, но есть еще идея разделить окно на 2 слоя, а именно самой карты, поверх которой отрисовывать персонажа с прозрачным фоном, но вот вопрос как на эти слои разделить, что бы они отрисовывались отдельно друг от друга
|
|
| |
DivES | Дата: Пятница, 24 Апреля 2020, 22:13 | Сообщение # 2 |
заслуженный участник
Сейчас нет на сайте
| veeroteen, ты покажи нам код отрисовки, а мы посмотрим, раскритикуем и что-нибудь посоветуем
|
|
| |
realm786 | Дата: Суббота, 25 Апреля 2020, 02:34 | Сообщение # 3 |
был не раз
Сейчас нет на сайте
| Цитата veeroteen ( ) слои разделить, что бы они отрисовывались отдельно друг от друга
Код
class layer : public sf::Drawable, public sf::Transformable
...
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
tile map
Не?
|
|
| |
veeroteen | Дата: Суббота, 25 Апреля 2020, 09:13 | Сообщение # 4 |
был не раз
Сейчас нет на сайте
| Цитата DivES ( ) veeroteen, ты покажи нам код отрисовки, а мы посмотрим, раскритикуем и что-нибудь посоветуем
Код void drwTile() { for (int i = 0; i < MapY; i++) { for (int n = 0; n < MapX; n++) { MapSprite.setTextureRect(sf::IntRect(0 + 32 * std::atoi((TileMap[(int(actor.GetActorPos().y) / 32) - (MapY / 2) + 1 + i][(int(actor.GetActorPos().x) / 32) - (MapX / 2) + 1 + n]).c_str()), 0, 32, 32));//достаем определенный тайл MapSprite.setPosition(((int(actor.GetActorPos().x) / 32) - (MapX / 2) + 1 + n) * 32, (int((actor.GetActorPos().y) / 32) - (MapY / 2) + 1 + i) * 32);//выставляем позицию window.draw(MapSprite); } }
}
это старый вариант отрисовки, он отлично работает, но требует буфер, и соответственно я упираюсь в размер этого самого буфера
Код void SetMap() { for (int y = 0; y < MapY; y++) { for (int x = 0; x < MapX; x++) {
jj = "tile" + std::to_string((int(actor.GetActorPos().x) / 32)- MapX/2 + x) + "x" + std::to_string((int(actor.GetActorPos().y) / 32)-MapY/2 + y);//имя элемента
text = level->FirstChildElement(jj.c_str());//достаем элемент
MapSprite.setTextureRect(sf::IntRect(0 + 32 * std::atoi(text->GetText()), 0, 32, 32));//номер тайла
MapSprite.setPosition( (int((actor.GetActorPos().x) / 32) - MapX/2 + x) * 32, (int((actor.GetActorPos().y) / 32) - MapY/2 + y) * 32 );
window.draw(MapSprite); } } }
а тут для меня очевидно в чем проблема, но зато в таком виде я ограничен только оперативной памятьюДобавлено (25 Апреля 2020, 09:14) ---------------------------------------------
Цитата realm786 ( ) tile map
Не?
ограничения на размер массива
|
|
| |
DivES | Дата: Суббота, 25 Апреля 2020, 16:02 | Сообщение # 5 |
заслуженный участник
Сейчас нет на сайте
| veeroteen, жуть какая В чём сложность работать с размером буфера? Я правильно понимаю, что доступ (поиск) тайлов происходит по имени?
|
|
| |
veeroteen | Дата: Суббота, 25 Апреля 2020, 17:07 | Сообщение # 6 |
был не раз
Сейчас нет на сайте
| Цитата DivES ( ) Я правильно понимаю, что доступ (поиск) тайлов происходит по имени? по тегам в xml
Цитата DivES ( ) В чём сложность работать с размером буфера? сложность проста, карта получается маленькой, а сам смысл идеи в бесшовности теряется если использовать массив, но если использовать несколько массивов то как между ними переключаться, и как 2 разных массива будут отрисовываться на краю одного, в итоги я пришел к тому что такая схема будет еще полее затратной вплане кадров
|
|
| |
DivES | Дата: Суббота, 25 Апреля 2020, 17:19 | Сообщение # 7 |
заслуженный участник
Сейчас нет на сайте
| veeroteen, так, а во втором варианте в чём проблема? Мне, вот, не очевидно
|
|
| |
veeroteen | Дата: Суббота, 25 Апреля 2020, 17:21 | Сообщение # 8 |
был не раз
Сейчас нет на сайте
| Цитата DivES ( ) так, а во втором варианте в чём проблема? Мне, вот, не очевидно ну во первых идет постоянное обращение к файлу, а это дело не быстрое, то есть для того что бы отрисовать 25 тайлов, мне нужно 25 раз обратится к нему и это достаточно сильно бьет по скорости обновления кадров
|
|
| |
DivES | Дата: Суббота, 25 Апреля 2020, 17:25 | Сообщение # 9 |
заслуженный участник
Сейчас нет на сайте
| veeroteen, так а почему бы заранее не загрузить тайлы? И потом уже обращаться к ним напрямую?
То что скидывал realm786 отлично подходит же! И да, не совсем понимаю, что из SFML (Simple and Fast Multimedia Library) — Simple
Сообщение отредактировал DivES - Суббота, 25 Апреля 2020, 17:34 |
|
| |
veeroteen | Дата: Суббота, 25 Апреля 2020, 17:42 | Сообщение # 10 |
был не раз
Сейчас нет на сайте
| Цитата DivES ( ) veeroteen, так а почему бы заранее не загрузить тайлы? И потом уже обращаться к ним напрямую? предположим я создаю массив в который записываю id тайлов по их координатам, но в конечном счете упираюсь в размер этого массива, гипотетический массив того же int 5000 x 5000 это 25000000 байтов
|
|
| |
DivES | Дата: Суббота, 25 Апреля 2020, 17:58 | Сообщение # 11 |
заслуженный участник
Сейчас нет на сайте
| veeroteen, ну вообще говоря, для int это 5000 * 5000 * 4, то есть 10 000 000 bytes, то есть около 96 MB. Вопрос в том, зачем тебе int, когда можно использовать unsigned short или попробовать unsigned char. В первом случае массив займёт уже 48 MB, а во втором так вообще 24 MB.
|
|
| |
realm786 | Дата: Суббота, 25 Апреля 2020, 19:05 | Сообщение # 12 |
был не раз
Сейчас нет на сайте
| Цитата veeroteen ( ) бесшовности теряется если использовать массив, но если использовать несколько массивов то как между ними переключаться Я уже плохо это все помню, прошу прощения.
State Machine C++
Код vector<tile_map*> zones;
Код void _class::load_zone(tile_map * zone) { while(!zones.empty()) // очистка уровня (смена уровня - набора зон). { zones.back()->функция_очистки_графики_из_памяти(); delete zones.back(); // доступ к последнему элементу, чистк.; ... zones.pop_back(); // или так (плохо помню), del последний элемент; } zones.push_back(zone); zones.back()->подгрузка_массива_из_xml_или_бинарного_файла(аргументы); zones.back()->загрузка_графики(аргументы); }
Код this->load_zone(new tile_map); ...
Код tile_map : public state_pattern ...
Код class state_pattern { public: virtual int подгрузка_массива_из_xml_или_бинарного_файла(аргументы) = 0; virtual int загрузка_графики(аргументы) = 0; virtual void рендер() = 0; virtual void функция_очистки_графики_из_памяти() = 0; };
Сообщение отредактировал realm786 - Суббота, 25 Апреля 2020, 19:30 |
|
| |
veeroteen | Дата: Суббота, 25 Апреля 2020, 19:40 | Сообщение # 13 |
был не раз
Сейчас нет на сайте
| Цитата DivES ( ) DivES
и это только 1 миллион обьектов, и оно уже заходит за рамки дозволеных размеров
Сообщение отредактировал veeroteen - Суббота, 25 Апреля 2020, 19:41 |
|
| |
DivES | Дата: Суббота, 25 Апреля 2020, 19:48 | Сообщение # 14 |
заслуженный участник
Сейчас нет на сайте
| veeroteen, как ты создавал этот миллион?
|
|
| |
veeroteen | Дата: Суббота, 25 Апреля 2020, 19:57 | Сообщение # 15 |
был не раз
Сейчас нет на сайте
| Цитата DivES ( ) veeroteen, как ты создавал этот миллион?
Код std::vector<std::vector<int>> buff; buff.reserve(1000000);
а вот такая штука получается если создать обычный массив
Добавлено (25 Апреля 2020, 20:02) --------------------------------------------- realm786, этот вариант кода делает примерно то же самое, но тут как раз проблема в скорости, из xml файла очень долго доставать в сравнении с нормальным массивом, но у нормального массива есть ограничения на размер
Код void SetMap() { for (int y = 0; y < MapY; y++) { for (int x = 0; x < MapX; x++) {
jj = "tile" + std::to_string((int(actor.GetActorPos().x) / 32)- MapX/2 + x) + "x" + std::to_string((int(actor.GetActorPos().y) / 32)-MapY/2 + y);//имя элемента
text = level->FirstChildElement(jj.c_str());//достаем элемент
MapSprite.setTextureRect(sf::IntRect(0 + 32 * std::atoi(text->GetText()), 0, 32, 32));//номер тайла
MapSprite.setPosition( (int((actor.GetActorPos().x) / 32) - MapX/2 + x) * 32, (int((actor.GetActorPos().y) / 32) - MapY/2 + y) * 32 );
window.draw(MapSprite); } } }
Сообщение отредактировал veeroteen - Суббота, 25 Апреля 2020, 22:09 |
|
| |
DivES | Дата: Суббота, 25 Апреля 2020, 20:12 | Сообщение # 16 |
заслуженный участник
Сейчас нет на сайте
| veeroteen, удивительно Ты пришёл из какого-нибудь языка или начинал с ++? Слышал что-нибудь про new, стэк и его переполнение? И я не про сайт
|
|
| |
DivES | Дата: Суббота, 25 Апреля 2020, 20:13 | Сообщение # 17 |
заслуженный участник
Сейчас нет на сайте
| А вообще, это изначально выглядит сомнительно, твоё вот это желание создавать что-то на миллионы элементов... Оно тебе надо?
|
|
| |
veeroteen | Дата: Суббота, 25 Апреля 2020, 20:15 | Сообщение # 18 |
был не раз
Сейчас нет на сайте
| Всем спасибо, все свободны, проблема решена, мальчик узнал как увеличить размер стека
Код #pragma comment(linker, "/STACK:100000000") если кому понадобиться
|
|
| |
DivES | Дата: Суббота, 25 Апреля 2020, 20:47 | Сообщение # 19 |
заслуженный участник
Сейчас нет на сайте
| veeroteen, тебе нужно изучать основы C++, если и дальше хочешь заниматься разработкой. Ещё лучше — выбрать другой язык программирования, который более лоялен к таким уникумам, как ты. Увеличение размера стека — это полная жесть, это просто непростительно. Ты всего-то и должен был динамически выделить память под твой массив, и не было бы никаких проблем. Но ты этого не знал. Ведь ты даже не попытался разобраться в C++. Зачем оно надо, да? Увеличу стек, и так сойдёт.
|
|
| |
veeroteen | Дата: Суббота, 25 Апреля 2020, 22:08 | Сообщение # 20 |
был не раз
Сейчас нет на сайте
| DivES, динамически выделить память под массив? насколько я понимаю размер стека подразумевает размер неделимой единицы, то есть компилятор не может сам разделить мой массив на 2 стека, соответственно речи о динамической памяти идти не может, а если ты и прав, то расскажи мне пожалуйста как это делается?
|
|
| |
|