Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML] Wiele map w grze - czyli jak wyświetlać tylko widoczne mapy

Ostatnio zmodyfikowano 2024-07-11 21:35
Autor Wiadomość
pekfos
» 2024-07-10 19:13:18
BUG polega na tym, że potworek znika gdy mapa do której jest przypisany jest ustawiona na isVisible = false.
To nie bug, tylko feature. Ten kod wygląda jakbyś włożył trochę pracy w to by to dokładnie tak działało.

Myślałem nad tym, by update'ować potworki niezależnie czy mapa do której są przypisane jest widoczna czy też nie, ale uważam, że to nie jest prawidłowe rozwiązanie, gdyż było by to mocno obciążające jeśli chodzi o CPU.
Tak właśnie to powinno działać, z powodu który sam opisałeś jako BUG. Jeżeli AI potworów nie ma "smyczy", to teoretycznie jesteś w stanie obejść całą mapę i doprowadzić do tego by wszystkie potwory goniły gracza i były wszystkie widoczne naraz, niezależnie od widoczności ich oryginalnego kawałka mapy. Po prostu trzymaj wszystkie jednostki w jednym kontenerze i używaj testu widoczności jednostki by decydować o jej aktualizowaniu i renderowaniu.

C/C++
for( auto & go: gameObjects ) {
   
   
if( go->isVisible == true ) {
       
//....
       
   
}
   
   
gameObjects = new_gameObjects;
   
monsters = new_monsters;
   
natures = new_natures;
}
Pewny jesteś że te przypisania powinny być w pętli, a nie za nią?
P-181301
tBane
Temat założony przez niniejszego użytkownika
» 2024-07-10 19:50:08
Mój błąd, źle kod skopiowałem.
Czyli wszystkie obiekty w każdym przebiegu pętli gry update'ować? No bo przecież trzeba też kolizje sprawdzać. Czyli moja optymalizacja tak naprawdę była zła.
P-181302
pekfos
» 2024-07-10 20:30:45
Optymalizacja ma sens, ale gdy decyzja o aktualizacji/renderowaniu wynika z testu widoczności jednostki, a nie widoczności niezwiązanego kawałka mapy.
C/C++
for( auto & go: gameObjects ) {
   
if( visible( go ) )
       
 go->update();
   
}
P-181303
tBane
Temat założony przez niniejszego użytkownika
» 2024-07-10 21:06:50
Ok, rozumiem. Dodawać elementy gdy mapa jest widoczna oraz usuwać elementy wtedy gdy są niewidoczne niezależnie od mapy.

// Edit. Nie rozumiem. Zrobiłem tak, że za każdym razem przypisuje wszystkie obiekty na nowo do list i wątpie by to było poprawne rozwiązanie. Wiem, że tu jest błąd, bo na logikę coś mi tu nie pasuje. Tylko jeszcze nie wiem co. Myślę, że nie powinno się za każdym razem przypisywać wszystkich obiektów, a dynamicznie dodawać i usuwać z list, ale nie wiem jak to zrobić.

C/C++
// UPDATE ////////////////////////////////////////////////////////////////////////

world->mapVisiblings(); // render map or not render map
clearAllMainListsOfGameObjects(); // clearing main lists of GameObjects
for( auto & map: world->maps )
   
 map->showGameObjects(); // adding Map::GameObjects to main lists of GameObjects

for( auto & go: gameObjects )
   
 go->update( dt );

std::sort( gameObjects.begin(), gameObjects.end(),[ ]( const auto & a, const auto & b ) { return a->position.y < b->position.y; } );

viewUpdate();

C/C++
void showGameObjects() {
   
   
for( auto & monster: _monsters ) {
       
if( visiblings( monster ) ) {
           
monster->isVisible = true;
           
gameObjects.push_back( monster );
           
monsters.push_back( monster );
       
}
    }
   
   
for( auto & character: _characters ) {
       
if( visiblings( character ) ) {
           
character->isVisible = true;
           
gameObjects.push_back( character );
           
characters.push_back( character );
       
}
    }
   
   
for( auto & nature: _natures ) {
       
if( visiblings( nature ) ) {
           
nature->isVisible = true;
           
gameObjects.push_back( nature );
           
natures.push_back( nature );
       
}
    }
   
   
for( auto & item: _itemsOnMap ) {
       
if( visiblings( item ) ) {
           
item->isVisible = true;
           
gameObjects.push_back( item );
           
itemsOnMap.push_back( item );
       
}
    }
   
   
for( auto & inventory: _inventoriesOnMap ) {
       
if( visiblings( inventory ) ) {
           
inventory->isVisible = true;
           
gameObjects.push_back( inventory );
           
inventoriesOnMap.push_back( inventory );
       
}
    }
   
   
for( auto & path: _paths ) {
       
if( visiblings( path ) ) {
           
path->isVisible = true;
           
gameObjects.push_back( path );
           
paths.push_back( path );
       
}
    }
   
   
for( auto & furniture: _furnitures ) {
       
if( visiblings( furniture ) ) {
           
furniture->isVisible = true;
           
gameObjects.push_back( furniture );
           
furnitures.push_back( furniture );
       
}
    }
   
   
for( auto & building: _buildings ) {
       
if( visiblings( building ) ) {
           
building->isVisible = true;
           
gameObjects.push_back( building );
           
buildings.push_back( building );
       
}
    }
   
}
P-181304
pekfos
» 2024-07-11 18:25:50
Piszesz mnóstwo kodu w rozwiązaniu, które szuka problemu. Zrób prosto, jedną dużą mapę i jeden kontener na wszystkie obiekty. Widzę tu sens tylko w wydzieleniu ścieżek do osobnego kontenera, bo to nawet nie są obiekty. Filtruj po widoczności tylko przy renderowaniu i aktualizowaniu obiektów.
C/C++
for( auto & go: gameObjects ) {
   
if( visible2( go ) ) // widoczne na ekranie + kawałek za ekranem, inaczej będzie można zauważyć że czas przestaje płynąć dla obiektów tuż za polem widzenia
       
 go->update();
   
}

for( auto & go: gameObjects ) {
   
if( visible( go ) ) // widoczne na ekranie
       
 go->render();
   
}
Jeśli będzie problem z wydajnością to go zidentyfikuj i wtedy popraw.
P-181305
tBane
Temat założony przez niniejszego użytkownika
» 2024-07-11 21:35:51
Dobra. Zrobiłem tak, jak mi doradziłeś.
P-181306
1 « 2 »
Poprzednia strona Strona 2 z 2