Суббота, 23 Ноября 2024, 02:20

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Отрисовка карты SFML
veeroteenДата: Пятница, 24 Апреля 2020, 21:42 | Сообщение # 1
был не раз
Сейчас нет на сайте
Подкиньте идей для отрисовки карты, просто зашел в тупик, через tinyxml прорисовка тайликов заканчивается безбожной потерей фпс, вплоть до 4 фпс за зону 20 на 40 по 32px, на самом деле проблема не очень то частая, потому что все это можно бы ло бы залить в строку, и доставать напрямую(так очевидно быстрей), но в таком случае есть конкретные ограничения на размер карты которые меня не очень устраивают, но есть еще идея разделить окно на 2 слоя, а именно самой карты, поверх которой отрисовывать персонажа с прозрачным фоном, но вот вопрос как на эти слои разделить, что бы они отрисовывались отдельно друг от друга shock shock
DivESДата: Пятница, 24 Апреля 2020, 22:13 | Сообщение # 2
заслуженный участник
Сейчас нет на сайте
veeroteen, ты покажи нам код отрисовки, а мы посмотрим, раскритикуем и что-нибудь посоветуем laugh
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, жуть какая laugh
В чём сложность работать с размером буфера?
Я правильно понимаю, что доступ (поиск) тайлов происходит по имени?
veeroteenДата: Суббота, 25 Апреля 2020, 17:07 | Сообщение # 6
был не раз
Сейчас нет на сайте
Цитата DivES ()
Я правильно понимаю, что доступ (поиск) тайлов происходит по имени?

по тегам в xml
Цитата DivES ()
В чём сложность работать с размером буфера?

сложность проста, карта получается маленькой, а сам смысл идеи в бесшовности теряется если использовать массив, но если использовать несколько массивов то как между ними переключаться, и как 2 разных массива будут отрисовываться на краю одного, в итоги я пришел к тому что такая схема будет еще полее затратной вплане кадров
DivESДата: Суббота, 25 Апреля 2020, 17:19 | Сообщение # 7
заслуженный участник
Сейчас нет на сайте
veeroteen, так, а во втором варианте в чём проблема? Мне, вот, не очевидно laugh
veeroteenДата: Суббота, 25 Апреля 2020, 17:21 | Сообщение # 8
был не раз
Сейчас нет на сайте
Цитата DivES ()
так, а во втором варианте в чём проблема? Мне, вот, не очевидно

ну во первых идет постоянное обращение к файлу, а это дело не быстрое, то есть для того что бы отрисовать 25 тайлов, мне нужно 25 раз обратится к нему и это достаточно сильно бьет по скорости обновления кадров
DivESДата: Суббота, 25 Апреля 2020, 17:25 | Сообщение # 9
заслуженный участник
Сейчас нет на сайте
veeroteen, так а почему бы заранее не загрузить тайлы? И потом уже обращаться к ним напрямую?

То что скидывал realm786 отлично подходит же!
И да, не совсем понимаю, что из SFML (Simple and Fast Multimedia Library) — Simple laugh


Сообщение отредактировал 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);


а вот такая штука получается если создать обычный массив
Код
int buff[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, удивительно :D
Ты пришёл из какого-нибудь языка или начинал с ++?
Слышал что-нибудь про new, стэк и его переполнение? И я не про сайт laugh
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++, если и дальше хочешь заниматься разработкой.
Ещё лучше — выбрать другой язык программирования, который более лоялен к таким уникумам, как ты. laugh
Увеличение размера стека — это полная жесть, это просто непростительно.
Ты всего-то и должен был динамически выделить память под твой массив, и не было бы никаких проблем.
Но ты этого не знал. Ведь ты даже не попытался разобраться в C++. Зачем оно надо, да? Увеличу стек, и так сойдёт.
veeroteenДата: Суббота, 25 Апреля 2020, 22:08 | Сообщение # 20
был не раз
Сейчас нет на сайте
DivES, динамически выделить память под массив? насколько я понимаю размер стека подразумевает размер неделимой единицы, то есть компилятор не может сам разделить мой массив на 2 стека, соответственно речи о динамической памяти идти не может, а если ты и прав, то расскажи мне пожалуйста как это делается?
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг