[Allegro] Wyswietlanie mapy

0

Cześć niemam pomyślu i postanowiłem tu napisać być może wy coś pomożecie :)

 
   for(int y=0;y<10;y++){
        for(int x=0;x<10;x++){
            if(mapa[x][y] == 0)
                blit( obrazek1, bufmap, 0, 0, map_x+(x*48), map_y+(y*48), obrazek1->w, obrazek1->h );
        }
    }

mam o taki kodzik pętli generującej mapy. Z góry mowie że nie mam zamiaru wczytywać całej mapy i tylko nią suwać. Zależy mi bardziej na tym aby stworzyć taki bufor 10x10 (to własnie zrobiłem), wyświetlać tylko 8x8 a resztę wczytywać na bieżąco z tablicy dwuwymiarowej tablicy int.

Kombinowałem w różne sposoby aby to osiągnąć lecz mam jakieś zaciemnienie chyba w mózgu i nie mogę nic logicznego i działającego wykminić.

Pozdrawiam :)

0

może zaproponuję ci jeszcze jedno rozwiązanie. Wyświetlaj obszar:
lewy górny róg - punkt względem ktorego porusza się mapa -4,
prawy dolny róg - punkt względem ktorego porusza się mapa +4,
od razu na głównym buforze

0

Dla tak małych map to nie ma sensu, będziesz miał za duże "lagi" przy odczycie z dysku. Poza tym nie powinno sie tego raczej robić w ten sposób(tzn na pojedynczych polach), ja bym raczej zrobił to tak:

Zakładam że mam mapę np 20'000x20'000 czyli ogromna. Jednorazowo na ekranie mieści się np 10x10 aby móc w miarę płynnie poruszać się po planszy zakładam wczytanie do ram bloków po 100x100. Teraz zostaje podzielić całą mapę 20'000x20'000 na bloki po 100x100 czyli 20'000/100 x 20'000/100 daje 200x200 czyli 40'000 porcji danych po 100x100. Porcje danych 100x100 zapisuje jako jeden ciągły strumień bajtów (zakładając jeden bajt na pole) to daje 10'000 bajtów na jeden blok. Bloki zapisuje jedne po drugim w taki sposób :
(Xb + Yb * bloków w wierszu) * rozmiar bloku.
Xb i Yb to współrzędne X,Y bloku, co to oznacza dla nas? oznacza to że dla Xb = 2 i Yb=1 mamy adres bloku : lewy górny róg (2100, 1100) prawy dolny róg (3100-1, 2100-1). Wzór dla tego przypadku będzie wyglądać tak:

  • (Xb + Yb * 200) * 10000;**

W edytorze map masz ja np wczytana w całości i po edycji chcesz ją zapisać w sposób opisany wyżej, przykładowy kod:

// alokacja pamieci itd
int sizeX = 20000;
int sizeY = 20000;
int bufSizeX = 100;
int bufSizeY = 100;
char mapa[] = new char[sizeX * sizeY];
char buf[] = new char[bufSizeX * bufSizeY];
int BUF_SIZE= bufSizeX * bufSizeY * sizeof(char)

// tutaj edytujemy mapę
...


// Czas na zapis:
for (int y=0; y<200; y++)
   for (int x=0; x<200; x++) {   // dla każdego bufora 

        // przeniesmy go z mapy do tablicy bufora
        for (int yBuf = 0; yBuf < bufSizeY; yBuf++) 
            for(int xBuf = 0; xBuf < bufSizeX;  xBuf++) {
                buf[xBuf + yBuf*bufSizeX] = mapa[x*bufSizeX + xBuf + (y * bufSizeY + yBuf) * sizeX];   
            }

        // zapisujemy do pliku : 
        writeFile(plik, buf, offset_początku_danych_mapy + (x + y*200) * BUF_SIZE, BUF_SIZE);
        // ta funkcja nie istnieje, trzeba ja napisać:
        // plik - uchwyt do pliku
        // buf - źródło danych
        //  offset_początku_danych_mapy + (x + y*200) * BUF_SIZE <- miejsce docelowe w bajtach od początku pliku
        // offset_początku_danych_mapy <- jakas stała która decyduje gdzie w pliku zaczynaja sie dane mapy
        // poczytaj o fseek(..)
        // BUF_SIZE <- ile bajtów chcemy zapisać z buf do tej lokalizacji (cały bufor).
        
   }

Dobra mamy upakowana mapę, jak po niej teraz sie poruszać? PROSTE :)
mamy pozycje gracza x,y wewnątrz tej dużej mapy, musimy wyliczyć :

  1. współrzędne bloku do odczytania
  2. współrzędne gracza wewnątrz tego bloku

Ad1.
Xb = (int)x/100;
Yb = (int)y/100;

Ad2.
Xg = x%100;
Yg = y%100

Zostaje nam odczytać potrzebny blok :
ReadFile(file, buf, offset_początku_danych_mapy + (Xb + Yb*200) * BUF_SIZE, BUF_SIZE)
//analogicznie do WriteFile

Osobiście zeby miec płynne przemieszczanie zrobiłbym tak:

class Buf { 
 /*implementacja */
}  // klasa przechowująca jedne bufor 

Buf buf[4];
int active = 0;
int left_right = 1;
int bottom_up = 2;
int edge  = 3;

Czemu 4 bufory? buf[active] to obecnie aktywny bufor po którym sie przemieszczamy (ten wskazywany przez Xb,Yb). Do czego pozostałe? do wczytywania dynamicznego.
Jeżeli gracz zbliża sie do lewej granicy lub prawej naszego bufora (np zostało mu jeszcze 10 pól i wyjdzie z niego to wczytujemy nową porcję danych do buf[left_right] w osobnym wątku. Kiedy zbliży sie do góry lub dołu wczytujemy nowa porcje do buf[bottom_up]; buf[edge] to narożnik w przypadku gdy gracz zbliży sie mocno do obu granic( lewa i dolna, prawa i dolna, prawa i górna, lewa i górna).
Po przekroczeniu granicy trzeba sensownie pozamieniać wskaźniki. np po wyjściu z lewej strony :
int tmp = active;
active = left_right;
left_right = active;
Gdyby nagle gracz sie cofnął to nadal mamy potrzebny blok w pamieci...
uff.

1 użytkowników online, w tym zalogowanych: 0, gości: 1