Skocz do zawartości

Losowy wygenerowany przedmiot nie pojawia się ponownie


odex

Rekomendowane odpowiedzi

Witam ponownie.

W dalszym ciągu pracuje nad moją małą gierką w ramach ćwiczenia umysłu. Jest to roguelike bullet heel space shooter. Jak wiadomo, skoro jest to roguelike to mamy wiele do czynienia z losowym generowaniem powerupów. Działa bardzo podobnie do Binding of Isaac (pewnie każdy zna), zdobywamy jakiś przedmiot i ruszamy dalej. Chciałbym tylko by tak samo jak w tej grze, przedmiot który już mamy w inwentarzu nie mógł zostać wylosowany ponownie. Na ten moment wybór przedmiotów to zwykła komenda choose w choose (przedmiotów jest około 50 na ten moment). Wiem, że pewnie musiałbym jakoś porównywać czy wylosowany przedmiot jest już przez nas dotknięty wcześniej i jeśli tak to wylosować go ponownie.

Przedmiot pojawia się poprzez obiekt, który losuje dany przedmiot, tworzy jego instancje w roomie i kasuje sam siebie.

Mam nadzieję, że jakoś to logicznie wytłumaczyłem. Liczę na jakieś sugestie jak można to zrobić.

Odnośnik do komentarza
Udostępnij na innych stronach

Możesz zrobić jednowymiarową tablicę zero - jedynkową, dany indeks odpowiada danemu przedmiotowi.

Jak przedmiot się pojawi to stawiasz jedynkę, jak jeszcze go nie było - jest zero.

Masz zmienną wiedzącą ile przedmiotów zostało (prosty liczący repeat, while, itp), i na podstawie tego losujesz liczbę "n".

Potem algorytm idzie "n" kroków po tablicy omijając jedynki (w sensie, nie odejmuje "n" gdy trafi na jedynkę). Wybierasz przedmiot na którym stanie......

 

I od nowa.

 

Nie wiem czy to najlepszy algorytm, ale przydał mi się parę razy. :D

 

EDIT: możesz drugi indeks tablicy poświęcić na wskaźniki na przedmioty, by wyszukiwanie było szybsze

Odnośnik do komentarza
Udostępnij na innych stronach

Yyyy, okej. To znaczy rozumiem konceptualnie pomysł ale by to przelać na kod - no way :) Jak mówię, nie traktuję game makera jakoś super serio, po prostu jako formę treningu dla mózgownicy. Ale widocznie będę musiał trochę podnieść swój poziom bo zgaduje, że nie ma jakiegoś prostszego rozwiązania, które nie będzie kompletnie tandetne i zamknie się w gigantycznej ścianie kodu.

Odnośnik do komentarza
Udostępnij na innych stronach

Zamiast tablic lepiej w tym wypadku użyć list.

 

Gdzieś przy startowaniu gry tworzysz ds_list_create(), potem dodajesz do niej twoje 50 przedmiotów ds_list_add().

Przy tworzeniu instancji przedmiotów losujesz jeden z tej listy i go usuwasz ds_list_delete();

 

GML
// tworzenie listy

globalvar przedmioty;

przedmioty = ds_list_create();

 

ds_list_add(przedmioty, przedmiot1);

ds_list_add(przedmioty, przedmiot2);

ds_list_add(przedmioty, przedmiot3);

ds_list_add(przedmioty, przedmiot4);

. . .

 

// losowanie

var rand = irandom(ds_list_size(przedmioty));

instance_create(x, y, ds_list_find_value(przedmioty, rand));

ds_list_delete(przedmioty, rand);

 

Tylko trzeba się jeszcze zabezpieczyć przed tym jak lista będzie pusta.

Odnośnik do komentarza
Udostępnij na innych stronach

HuderLord: dzięki za odpowiedź, zrobiłem to Twoim i sposobem i... chyba działa? Główny problem jaki tutaj widzę, że to grze zdarza się teraz zduplikować czasami obiekt gracza. Po prostu pojawiają się nagle dwa statki (potem 4, potem 8 itd). Sprawdziłem w kodzie czy nie dodałem czasem jak głupi po prostu obiektu gracza do listy ale nie ma go tam na pewno.

Plus jakbym chciał zrobić mniejszą jakąś pule przedmiotów z tych obecnie używanych do da się to zrobić jakimś prostym sposobem jak ten powyżej? Np w sekretnym pokoju możemy dostać każdy możliwy przedmiot ale już np boss może rzucić tylko kilka wybranych z listy wszystkich możliwych przedmiotów.

Odnośnik do komentarza
Udostępnij na innych stronach

Zrób parę list a nie jedną w takim przypadku.

Fakt, nie pomyślałem kompletnie, że przecież mogę usuwać na raz przedmiot z kilku list. Ok, to pozostaje mi tylko jeszcze rozwikłać zagadkę dlaczego dupluje mi się gracz.

Wielkie dzięki jeszcze raz za pomoc.

Odnośnik do komentarza
Udostępnij na innych stronach

tylko że jak masz już parę list to pamiętaj że pozycja takiego samego itemku w każdej z tych list będzie inna. Więc jak chcesz jakiś itemek wyeleminować z każdej listy to musisz przeszukać je pod kątem nazwy tego itemu.

 

GML
// usuwamy item o nazwie dupa

pozycja = ds_list_find_index(przedmioty, dupa);

ds_list_delete(przedmioty, pozycja);

No i to nie zadziała jak masz parę itemków takich samych w tej samej liście.

Odnośnik do komentarza
Udostępnij na innych stronach

Okej, rozumiem.

Jeszcze więc ostatnie pytanie bo próbuję rozgryźć tajemnicę dlaczego tworzy mi w pewnym momencie jeszcze jeden obiekt gracza. Z moich obserwacji wynika, że im jesteśmy bliżej końca puli tym coraz większe szansę, że zamiast przedmiotu dostaniemy duplikat statku. Czy to przez to, że funkcja ds_list_delete po prostu usuwa daną wartość, jednak ona sama może znów być wylosowana przez irandom i wtedy pobiera pierwszy możliwy obiekt jaki jest dostępny normalnie z drzewka game makera? W przykładzie - losujemy wartość 15 i pod nią jest tworzy przedmiot jej przypisany. Potem losuje drugim raz 15 ale obiekt już został usunięty przypisany tej pozycji więc zamiast tego dostajemy duplikat statku. To chyba jedyne logiczne wytłumaczenie jakie na ten moment jestem w stanie z tego wyciągnąć. Poza tym wszystko działa bez problemu.

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ę...