Dobra Panie i Panowie powiem wam jak to jak na razie u mnie wylgąda. Gdyż projekt się rozwija.
Mam dwa kontenery w jednym wszystkie obiekty razem w drugim quadTree to kolizji, które swoją drogą nie działają najlepiej na granicach jednego drzewka z drugim, ale mniejsza o to. Wiadomo marnotrawienie pamięci ale nic lepszego nie wymyśliłem.
Algorytmem PerlinNoice generuję jakąś wysokość i do wysokości minimalnej dodaję wygenerowaną z klucza wysokość daje to ładny efekt.
Następnie robię pętlę i,j i dodaję kolejno do obu kontenerów każdy obiekt.
Wygląda to mniej więcej tak
PerlinNoise * noise = new PerlinNoise( SEED, CHUNK );
p = new Quadtree( 0.0f, 0.0f,(( worldSizeMin.x + worldSizeMax.x ) * 32 ),(( worldSizeMin.y + worldSizeMax.y ) * 32 ), 0, 3 );
float width = 32;
float height = 32;
long long int summator = 0;
for( int i = 0; i < worldSizeMax.x + worldSizeMin.x; i++ )
{
int columnHeight = 2 + noise->getNoise( i - worldSizeMin.x, worldSizeMax.y - worldSizeMin.y - 2 );
mapIndex.push_back( sf::Vector3f( i,( worldSizeMin.y + columnHeight ), summator ) );
summator = summator + worldSizeMin.y + columnHeight;
for( int j = 0; j < worldSizeMin.y + columnHeight; j++ )
{
sf::Vector2f currentPosition( i * width,(( worldSizeMax.y + worldSizeMin.y ) - j ) * height );
DirtGrass * dirtGrass = new DirtGrass( currentPosition, sf::Vector2f( width, height ) );
p->AddObject( dirtGrass );
worldContainer.push_back( dirtGrass );
}
}
Jak widać mam jeszczę kontener o nazwię mapIndex dzięki któremu mogę sobie ograniczyć generowany obszar do rysowania:
jak widać summator dodawany do mapIndex to ilość klocków które znajdują się przed elementem. jak dla x=0 tworzymy 7 klocków to dla x=1 sumator=7 ... a jeśli w x1 zrobimy już 10 kolejnych klocków to dla x2 sumator = 17 i tak dalej. tak więc wiemy że jak mamy rysować od np x1 do x10 to robimy zwykłą petlę w której od i=0 dodajemy summator gdyż wiadomo, że w kontenerze od i = 7 są już klocki z x1 (przynajmniej zakładamy że od 7 aż do końca wysokości zapisanej w mapIndex będą klocki z pozycją odpowiadającą x1).
Rysowanie wygląda jak narazie tak:
for( int i = cam.mX ; i < cam.screenSizeX + cam.mX ; i++ )
{
for( long long int j = abs( cam.mY ) - int( cam.screenSizeY ); j < abs( cam.mY ) + int( cam.screenSizeY ) / 2; j++ )
{
WindowApp->draw( w1->cont[ w1->mapIndex[ i ].z + j ]->drawableObject );
}
}
Mam nadzieję że kod jest dość jasny i że da się go ogarnąć. Tylko takie rozwiązanie ma jednak wadę. Jak będziemy chcieli usunąć albo dodać jakiś klocek to będziemy musieli znaleść go w mapIndex i potem dla każdego x zmiejszyć wartość summatora o jeden gdyż liczba klocków zmniejszyła się.
O usuwaniu z quadTree i z vektora ze wszystkimi klockami nie wspomnę.
Dodawanie byłoby jeszcze gorsze gdyż trzebaby go dodać w odpowiednim miejscu w kontenerze aby się nie posypało.
Druga sprawa jak chce mieć nieskończony świat to przecież nie mogę wszystkiego trzymać w kontenerze myślałem żeby generować tylko trochę ponad rozdzielczość ekranu i na bieżąco usuwać (jak gracz idzie w prawo) obiekty po lewej i generować nowe po prawej i analogicznie odwrotnie jakby gracz szedł w drugą stronę. i zrobić dodatkowy kontener dla zmian jaki gracz wprowadził czyli np idę w lewo generuję np 10 klocków ale w kontenerze ze zmianami jest zapisane że na pozycji x,y klocek został usunięty więc go pomijam przy generowaniu... Fajna opcja do zapisu gry by to była.
Czy to co napisałem ma jakikolwiek sens?