Skocz do zawartości

Stosy- cofnięcie ruchu


nomyzs

Rekomendowane odpowiedzi

Witam! :)

Próbuję zrobić, aby spacja cofała ruch, ale niestety gdy ją naciskam obiekt przenosi się do krawędzi ekranu(choć tam w ogóle nie stał), a nie do poprzedniej pozycji.

GML
stos=ds_stack_create()

if(keyboard_check(vk_right))

{

x+=1

}

if(keyboard_check(vk_space))

{

x=ds_stack_pop(stos)

}

else

{

ds_stack_push(stos,x)

}

Co jest w tym kodzie źle?

Odnośnik do komentarza
Udostępnij na innych stronach

I tak będziesz miał dalej ten problem bo próbujesz odczytać z pustego stosu (cofnij bardzo daleko). Aby się zabezpieczyć sprawdzaj czy stos nie jest pusty. Jakiś czas temu zrobiłem przykład tego zagadnienia.

Odnośnik do komentarza
Udostępnij na innych stronach

Właśnie inspirowałem się twoim przykładem :) Zrobiłem coś takiego:

GML
//CZAS

if(keyboard_check_pressed(vk_space)) //WYZEROWUJE PREDKOSC PRZY COFANIU CZASU

{

vspeed=0

hspeed=0

}

 

if(!keyboard_check(vk_space)) //TWORZY DANE NA STOSIE, GDY NIE COFAMY CZASU

{

ds_stack_push(stosx,x)

ds_stack_push(stosy,y)

}

 

if(keyboard_check(vk_space) and !ds_stack_empty(stosx) and !ds_stack_empty(stosy)) //SCIAGA DANE ZE STOSU, JESLI NIE SA PUSTE

{

x=ds_stack_pop(stosx)

y=ds_stack_pop(stosy)

}

//END CZAS</span>

Wszystko jest ok?

Teraz chciałbym zrobić obrazek pokazujący, czy jest dostępna przeszłość i nie wiem jak to zrobić, żeby działało. Jak na razie stworzyłem zmienną globalna "przeszlosc" i w stepie dałem taki kod:

GML
//KONTROLER CZASU

if(ds_stack_empty(stosx) and ds_stack_empty(stosy))

{

global.przeszlosc=false

}

else

{

global.przeszlosc=true

}

//END KONTROLER CZASU</span>

I co dalej? Próbowałem stworzyć nowy obiekt, który wyświetlał by sprite'y z takim kodem:

GML
if(global.przeszlosc=true)

{

draw_sprite(spr_przeszlosc, -1, x, y);

}

else

{

draw_sprite(spr_brak, -1, x, y);

}

Ale po umieszczeniu go w room'ie nic się nie pojawia :/

Odnośnik do komentarza
Udostępnij na innych stronach

A twój "KONTROLER CZASU" jest w tym samym obiekcie co "CZAS"? Ogółem to możesz zrobić to tak:

 

GML
//CZAS

if(keyboard_check_pressed(vk_space)) //WYZEROWUJE PREDKOSC PRZY COFANIU CZASU

{

vspeed=0

hspeed=0

}

 

if(!keyboard_check(vk_space)) //TWORZY DANE NA STOSIE, GDY NIE COFAMY CZASU

{

ds_stack_push(stosx,x)

ds_stack_push(stosy,y)

global.przeszlosc=true

}

 

if(!ds_stack_empty(stosx) and !ds_stack_empty(stosy)) //SCIAGA DANE ZE STOSU, JESLI NIE SA PUSTE

if(keyboard_check(vk_space))

{

x=ds_stack_pop(stosx)

y=ds_stack_pop(stosy)

}

else

{

global.przeszlosc=false

}

//END CZAS</span></span>

Chyba będzie optymalnie niż ciągle sprawdzać czy stos jest pusty.

Odnośnik do komentarza
Udostępnij na innych stronach

A twój "KONTROLER CZASU" jest w tym samym obiekcie co "CZAS"?

W tym samym.

Ok, dzięki zrobię tak.

 

A jak zrobić to z pokazywaniem czy jest dostępna przeszłość, tak jak zrobić? Czemu z tym kodem co dałem nic się nie pokazuje?

Odnośnik do komentarza
Udostępnij na innych stronach

A ten twój kod masz w evencie draw? To jest istotne. Jeżeli tak to może ten obiekt jest poza view? Nie wiem, strzelam.

 

Edit:

Sam się machnąłem i powinieneś sprawdzać tylko jeden stos czy jest pusty.

GML
if(!ds_stack_empty(stosx))
Odnośnik do komentarza
Udostępnij na innych stronach

Teraz napotkał mnie kolejny problem, gdyż chcę dodać opcję przyśpieszenia i zwolnienia cofnięcia w czasie. Z przyśpieszeniem poradziłem sobie tak:

GML
if(keyboard_check(global.tyl) and !ds_stack_empty(stosx))

{

if(keyboard_check(global.szybko))

{

xy= ds_stack_pop(stosx)

yx= ds_stack_pop(stosy)

if(!ds_stack_empty(stosx))

{

x= ds_stack_pop(stosx)

y= ds_stack_pop(stosy)

}

else

{

x=xy

y=yx

}

}

else

{

x= ds_stack_pop(stosx)

y= ds_stack_pop(stosy)

}

}

Ale nie mam pomysłu ze zwolnieniem. Kombinowałem coś z alarmami, ale nie wychodziło :/ Jak można byłoby to zrobić?

 

I czy optymalniej byłoby najpierw sprawdzać, czy jest wciskany klawisz odpowiedzialny za cofnięcie czasu, a dopiero później czy stos nie jest pusty?

 

Edit.

W końcu wymyśliłem jak to zrobić i całość wygląda tak:

STEP

GML
if(keyboard_check_pressed(global.tyl)) //WYZEROWUJE PREDKOSC PRZY COFANIU CZASU

{

vspd=0

hspd=0

}

 

if(!keyboard_check(global.tyl)) //TWORZY DANE NA STOSIE, GDY NIE COFAMY CZASU

{

ds_stack_push(stosx,x)

ds_stack_push(stosy,y)

}

 

if(keyboard_check(global.tyl)) //COFANIE

{

if(!ds_stack_empty(stosx)) //CZY STOS NIE JEST PUSTY

{

if(keyboard_check(global.szybko)) //SZYBICIEJ

{

if(!keyboard_check(global.wolno))

{

xy= ds_stack_pop(stosx)

yx= ds_stack_pop(stosy)

if(!ds_stack_empty(stosx))

{

x= ds_stack_pop(stosx)

y= ds_stack_pop(stosy)

}

}

}

 

if(keyboard_check(global.wolno)) //WOLNIEJ

{

if(!keyboard_check(global.szybko))

{

if(slow=true)

{

slow=false

x=ds_stack_pop(stosx)

y=ds_stack_pop(stosy)

alarm[1]=2

}

}

}

 

if(!keyboard_check(global.wolno)) //NORMALNIE

{

if(!keyboard_check(global.szybko))

{

x= ds_stack_pop(stosx)

y= ds_stack_pop(stosy)

}

}

 

}

}

CREATE

GML
stosx=ds_stack_create()

stosy=ds_stack_create()

xy=0

yx=0

slow=true

Alarm zmienia jedynie wartość na true.

 

Czy w kodzie wszystko jest ok? W grze całość działa :)

Odnośnik do komentarza
Udostępnij na innych stronach

A co do prędkości cofania czasu:

Aby przyśpieszać pobieraj n_razy wartości z stosów.

GML
repeat(n_razy)

{

xy= ds_stack_pop(stosx)

yx= ds_stack_pop(stosy)

}

Aby spowolnić wykonuj odczyt co n_razy. Coś takiego:

GML
i+=1

if(i mod n_razy=0)

{

xy= ds_stack_pop(stosx)

yx= ds_stack_pop(stosy)

}

 

Lepiej sprawdzać pierw wciśnięty klawisz bo ten warunek żadziej będzie się sprawdzał, a dzięki temu kolejne (ds_stack_empty()) nie będą się sprawdzać.

Odnośnik do komentarza
Udostępnij na innych stronach

Mój kod pozwala na kontrolowanie prędkości przyśpieszenia/zwolnienia, ale działa tylko na liczbach całkowitych (x2, x3, x4, x100). Co prawda spowalnianie nie jest zbyt widowiskowe przy małej liczbie fps, ale daje radę. Możesz liczyć wartości średnie pomiędzy odczytanym ze stosu, a poprzednim x/y i w ten sposób upłynnić ruch.

Odnośnik do komentarza
Udostępnij na innych stronach

Ok, a więc kod wygląda teraz tak:

STEP

GML
if(keyboard_check_pressed(global.tyl)) //WYZEROWUJE PREDKOSC PRZY COFANIU CZASU

{

vspd=0

hspd=0

}

 

if(!keyboard_check(global.tyl)) //TWORZY DANE NA STOSIE, GDY NIE COFAMY CZASU

{

ds_stack_push(stosx,x)

ds_stack_push(stosy,y)

}

 

if(keyboard_check(global.tyl))

{

if(!ds_stack_empty(stosx))

{

if(keyboard_check(global.szybko)) //SZYBICIEJ

{

if(!keyboard_check(global.wolno))

{

repeat(n_razy_przys)

{

if(!ds_stack_empty(stosx))

{

xy= ds_stack_pop(stosx)

yx= ds_stack_pop(stosy)

}

else

{

xy=xy

yx=yx

}

}

if(!ds_stack_empty(stosx))

{

x= ds_stack_pop(stosx)

y= ds_stack_pop(stosy)

}

else

{

x=xy

y=yx

}

}

}

 

if(keyboard_check(global.wolno)) //WOLNIEJ

{

if(!keyboard_check(global.szybko))

{

i+=1

xy=ds_stack_top(stosx)

yx=ds_stack_top(stosy)

if(i mod n_razy_spo=0)

{

x = ds_stack_pop(stosx)

y = ds_stack_pop(stosy)

i=n_razy_spo

}

else

{

x=(xy+x)/2

y=(yx+y)/2

}

}

}

 

if(!keyboard_check(global.wolno)) //NORMALNIE

{

if(!keyboard_check(global.szybko))

{

x= ds_stack_pop(stosx)

y= ds_stack_pop(stosy)

}

}

 

}

}

CREATE

GML
stosx=ds_stack_create()

stosy=ds_stack_create()

xy=0

yx=0

global.slow=true

i=1

n=1 //JAK DUZE SPOWOLNIENIE/PRZYSPIESZENIE(1 TO 2 RAZY WOLNIEJ/SZYBCIEJ)

n_razy_spo=2*n

n_razy_przys=1*n

 

W spowolnieniu zrobiłem, tak aby liczba nie była duża. Dobrze to jest?

Zrobiłem też wyliczanie średniej, tylko to tak średnio działa, tzn. jest lepiej jak bez tego, tylko sprite tak się "trzęsie", skacze. Czy da się to lepiej zrobić?

I czy reszta jest ok?

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