Skocz do zawartości

Optymalne wczytanie mapy z pliku


Rekomendowane odpowiedzi

Witojcie moi mili! Mam problem z dosyć szybkim wczytaniem mapy, a konkretnie:

- Mam room_test

- mam plik room_test.lrrm, w którym zapisywane są bloki:

[B_88X96]
o=obj_plot
r=0

Gdzie:

- B_88X96 to Blok x=88, y=96

- o to obiekt

- r to kąt

Wczytuję te bloki skrypcikiem:

GML
switch(room){

case room_test:

if global.wmapa=0{

for(i=0;i<=1024;i+=8){

for(j=0;j<=1024;j+=8){

ini_open('room_test.lrrm')

if ini_section_exists('B_'+string(i)+'X'+string(j)){

var obiekt,obiekt2;

obiekt=ini_read_string('B_'+string(i)+'X'+string(j),'o','')

obiekt2 = ds_map_find_value(global.obiekty,obiekt)

instance_create(i,j,obiekt2)

}

ini_close()

}

}

global.wmapa=1

}

break;

}

global.wmapa sprawdza czy mapa już była wczytana

w global.obiekty zapisane są wszystkie możliwe obiekty do wczytania

Rozmiar takiego rooma to 1024x1024(128x128 obiektów)

Cały mechanizm działa, tylko całe wieki mi się mapa wczytuje.

POMOCY!!!

Odnośnik do komentarza
Udostępnij na innych stronach

No to posortuj sobie obiekty aby mieć gwarancję zachowania kolejności. Ustaw jakąś flagę na początku pliku jaka jest maksymalna szerokość i wysokość. Nie będziesz musiał wtedy odczytywać wartości w stylu "[b_88X96]". W ogóle wrzuć najlepiej cały plik, bo w sumie nie wiem na czym tak naprawdę pracujesz (czy określasz puste pola czy nie).

 

Btw. obczaj to: https://github.com/bjorn/tiled/wiki/TMX-Map-Format

Jest to chyba najbardziej popularny format do tile-map. Możesz sobie dopisać jakiś prosty parser tego, lub po prostu się zainspirować. :)

Odnośnik do komentarza
Udostępnij na innych stronach

Jest też opcja zapisywania tego w bitmapie - w sumie najciekawsza z możliwych. :D Tylko nie wiem jak z prędkością odczytywania kolorów z piksela.

Plus jest taki że nie musisz sobie pisać dedykowanego edytora (jak to ma miejsce w plikach binarnych), a jedynie zwykły Paint wystarczy do edycji.

 

Zapisujesz sobie do kanału R typ obiektu, a na B kąt - zostały ci jeszcze dwa puste (oczywiście nic nie stoi na przeszkodzie aby obsługiwać sobie więcej niż jedną bitmapę).

Odnośnik do komentarza
Udostępnij na innych stronach

Mam teraz taki kod:

GML
//Create

max_x=128

GML
switch(room){

case room_test:

if global.wmapa=0{

for(i=0;i<=1024;i+=8){

for(j=0;j<=1024;j+=8){

var a,b;

a = file_bin_open('room_test.lrrb',2)

if( (max_x*((j/8)-1))+(i/8)<=file_bin_size(a) ){

file_bin_seek(a,(max_x*((j/8)-1))+(i/8))

b = file_bin_read_byte(a)

if b>0{

var obiekt;

obiekt = ds_map_find_value(global.obiekty,b)

instance_create(i,j,obiekt)

}

}

file_bin_close(a)

}

}

global.wmapa=1

}

break;

}

Wywala mi error:

 ___________________________________________
################################################################################
############
ERROR in
action number 1
of  Step Event0
for object obj_ctrl:

Error reading byte.
  at gml_Object_obj_ctrl_StepNormalEvent_1 (line 59) -                         b = file_bin_read_byte(a)
################################################################################
############

Z tego co rozumiem to błąd czytania bajta

Odnośnik do komentarza
Udostępnij na innych stronach

jesli dobrze rozumiem, moze by pomoglo miec objekty v ds_grid

i zapisac je ds_grid_wirte do pliku i pozniej wystarczy jedno czytanie z pliku.

 

mialo by to wyloczyc duze wnurzone pentle bo nawet jak bedzie trzeba wypelnic ekran, to zapewne niebedzie uzywany caly obszar mapy(ds_grid) :)

Odnośnik do komentarza
Udostępnij na innych stronach

jesli dobrze rozumiem, moze by pomoglo miec objekty v ds_grid

i zapisac je ds_grid_wirte do pliku i pozniej wystarczy jedno czytanie z pliku.

 

mialo by to wyloczyc duze wnurzone pentle bo nawet jak bedzie trzeba wypelnic ekran, to zapewne niebedzie uzywany caly obszar mapy(ds_grid) :)

 

Po pierwszym teście plik z gridem zajmuje 24 577 KB :o

 

EDIT: Jak mam to wczytać z powrotem? Wiem że trzeba zacząć od ds_grid_read

Odnośnik do komentarza
Udostępnij na innych stronach

Mam teraz taki kod:

GML
//Create

max_x=128
GML
switch(room){

case room_test:

if global.wmapa=0{

for(i=0;i<=1024;i+=8){

for(j=0;j<=1024;j+=8){

var a,b;

a = file_bin_open('room_test.lrrb',2)

if( (max_x*((j/8)-1))+(i/8)<=file_bin_size(a) ){

file_bin_seek(a,(max_x*((j/8)-1))+(i/8))

b = file_bin_read_byte(a)

if b>0{

var obiekt;

obiekt = ds_map_find_value(global.obiekty,b)

instance_create(i,j,obiekt)

}

}

file_bin_close(a)

}

}

global.wmapa=1

}

break;

}

Wywala mi error:

 ___________________________________________
    ###########################################################################
#####
   ############
    ERROR in
    action number 1
    of  Step Event0
    for object obj_ctrl:
    
    Error reading byte.
     at gml_Object_obj_ctrl_StepNormalEvent_1 (line 59) -                         b = file_bin_read_byte(a)
    ###########################################################################
#####
   ############

Z tego co rozumiem to błąd czytania bajta

To ja może powrócę do tego błędu. Co w moim kodzie jest źle, że wywala error?

Odnośnik do komentarza
Udostępnij na innych stronach

Sprawdź czy działa

GML
switch(room)

{

case room_test:

if global.wmapa=0

{

var a,b;

a = file_bin_open('room_test.lrrb',2)

for(i=0;i<=1024;i+=8)

{

for(j=0;j<=1024;j+=8)

{

if( (max_x*((j/8)-1))+(i/8)<=file_bin_size(a) )

{

file_bin_seek(a,(max_x*((j/8)-1))+(i/8))

b = file_bin_read_byte(a)

if( b>0 )

{

var obiekt;

obiekt = ds_map_find_value(global.obiekty,b)

instance_create(i,j,obiekt)

}

}

}

}

file_bin_close(a)

global.wmapa=1

}

break;

}

 

EDIT: Ewentualnie sprawdź czy dobrze wyliczasz pozycje w file_bin_seek, bo może wychodzisz poza plik.

EDIT2: Wielkość pliku powinna być >= 16384 bajty.

EDIT3: Jeszcze przydało by się sprawdzić czy poprawnie otwiera plik, sprawdź jaka liczba jest pod a ( powinna być większa od -1 )

Odnośnik do komentarza
Udostępnij na innych stronach

ds_.._write jesce niemialem potrzebe uzyc :)

 

prawdopodobnie 1024/8=128 ale for zaczyna sie od 0 co daje 129cykli

 

uzycie file_bin_seek jest konieczne? mozna by tez tak

GML
// w create _s=""; _array_object[0 az 255]= id objektow; max_x=128

_file=file_bin_open("map", 0); //0= reading

// wczytanie z bin do stringu

for(iti=0; iti<file_bin_size(_file); iti+=1){_s+=chr(file_bin_read_byte(_file)); };

 

// wypelnienie roomu instancjami

var _obj;

for(ity=0; ity<1024-8; ity+=8){

for(itx=0; itx<1024-8; itx+=8){

// pobiera z stringu na odpowiednie

_obj=ord(string_char_at(_s, ity/8*max_x+ itx/8))

if (_obj>0 ) {instance_create(itx, ity, _array_object[_obj]); };

};

};

file_bin_close(_file);;

Odnośnik do komentarza
Udostępnij na innych stronach

LMP001.png

Ten właściwy rozmiar to Rozmiar czy Rozmiar na dysku, bo wywala error na 16256 pozycji?

plik ma napewno 13 983 B

drugi rozmiar jest ile zabiera miejsca na hdd, bo hdd jest podzielny na clustery po x KB

zatem w 99% przypadkow computer nieda rady podzielic file tak by vypelnil miejsce na hdd idelnie a te dva dane sie rownaly :)

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy
file_bin_size(fname);

fname The name of the file to get the size of.

 

Zatem nie file_bin_size(_file); a

file_bin_size("map");

 

Edit: chociaż dokumentacja jakaś taka dwuznaczna tutaj :/ http://docs.yoyogames.com/source/dadiospic...e_bin_size.html - jedno pisze, a przykład inny...

Edit2: http://bugs.yoyogames.com/view.php?id=15339 - zgłosiłem buga w razie czego ;)

Odnośnik do komentarza
Udostępnij na innych stronach

Taki kod działa:

GML
switch(room){

case room_test:

if global.wmapa=0{

var a,b,wzor1,wzor2,pliczek;

a = file_bin_open('Projekt366.lrrb',2)

for(i=0;i<=1016;i+=8){

for(j=0;j<=1016;j+=8){

if( j>=8 ){

wzor1=(max_x*((j/8)-1))+(i/8)

if( wzor1<=file_bin_size(a) ){

file_bin_seek(a,wzor1)

b=file_bin_read_byte(a)

if b>0{

var obiekt;

obiekt = ds_map_find_value(global.obiekty,string(b))

instance_create(i,j,obiekt)

}

}

}else if( j=0 ){

wzor2=(i/8)

if( wzor2<=file_bin_size(a) ){

file_bin_seek(a,wzor2)

b=file_bin_read_byte(a)

if b>0{

var obiekt;

obiekt = ds_map_find_value(global.obiekty,string(b))

instance_create(i,j,obiekt)

}

}

}

}

}

file_bin_close(a)

global.wmapa=1

}

break;

}

Teraz chyba wystarczy podzielić to na części i częściami ładować na mapę. Ma ktoś jakiś pomysł?

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...