Strona 1 z 1

Gra Snake

: 17 kwie 2014 18:00
autor: aaddaas
Witajcie!
W ramach samoszkolenia napisałem w LabView znaną grę "Snake". Gra działa i jestem z niej zadowolony, jednak chciałbym usłyszeć opinie bardziej doświadczonych kolegów (i koleżanki). Dokładniej interesuje mnie, co można by poprawić by program był efektywniejszy? Czy może jakieś uwagi odnośnie samej składni (jakieś złe praktyki, których unikać, bądź jak zrobić by było czytelniej).
Będę wdzięczny za każdą opinię.
Jeszcze jedno pytanie: Jak zaimplementować przycisk "start"? Tzn, jak zrobić by program czekał na wciśnięcie tego przycisku? Czy całość powinienem wrzucić do jeszcze jednego event structure ustawionego na reagowanie na przycisk? Czy może jest jakiś sprytniejszy sposób?
Jeszcze raz dzięki za każdą odpowiedź ;)

Re: Gra Snake

: 17 kwie 2014 21:17
autor: PiDi
1) Struktura event w strukturze event... Aż dziw, że świat nie wybuchnął @-) Polecam to: http://zone.ni.com/reference/en-XX/help ... dtnsevnts/ , a w szczególności to: http://zone.ni.com/reference/en-XX/help ... trctonelp/ . A przede wszystkim - po co? Czemu nie obsługujesz tego zdarzenia Key Down w tej głównej strukturze?
2) Krótki eksperyment: spróbuj naciskać szybko różne strzałki po uruchomieniu gry. Zauważ czas reakcji. Wyciągnij wnioski ;)
3) Sugeruję poskładać wszystkie dane przekazywane przez shift register do jednego klastra. Zmniejszysz liczbę latających po diagramie kabli, zwiększysz czytelność kodu. Używaj Bundle by Name i Unbundle by Name.
4) Plus za komentarze i ikony, minus za brak opisów w subVI i za nazwy ich wejść i wyjść (Numeric control 1, Numeric control 2...).

Re: Gra Snake

: 17 kwie 2014 21:47
autor: aaddaas
Dzięki za odpowiedź;)
Stworzyłem event w evencie, ponieważ gdy jeden event będzie obsługiwał timeout oraz naciśnięcie klawisza, w Event Data Node znika mi Vkey i nie wiem, czy muszę w takim wypadku zdobyć id wciśniętego klawisza przez Initialize Keyboar+Acquire Input. Dodatkowo chciałem, by wciśnięcie klawisza nie powodowało natychmiastowej realizacji tego co jest w timeoucie, a jedynie nadawało kierunek (i zwrot) węża w następnym ruchu (jeśli event będzie obsługiwany przez obydwa triggery, to będzie możliwość wywołania eventu "asynchronicznie").
Zdaję sobie sprawę z tego, że blokuje to program przy dużej ilości naciśnięcia klawiszy, ale nie wiem jak zgrać razem oczekiwania wobec programu;) Jeśli masz (macie) jakiś pomysł, czym to zastąpić, to będę wdzięczny za odpowiedź;)

Re: Gra Snake

: 17 kwie 2014 22:25
autor: PiDi
Nie rozumiem, jak to znika Ci Vkey? Nie mówię o obsłudze ramki timeouta i Key down w tej samej ramce, tylko w oddzielnych - zresztą patrz załącznik Snake_main. Co prowadzi automatycznie do jeszcze większego problemu z blokowaniem ruchu węża przy naciskaniu klawiszy.
Jak sobie z tym poradzić? Bardzo prosto - przesunąć logikę aplikacji, czyli przesuwanie węża, do oddzielnej pętli. W ten sposób niezależnie obsłużysz naciskanie przycisków i niezależnie wykonywanie ruchów, które będzie mogło chodzić ze swoim niezakłóconym timingiem. Sugeruję użycie w tym przypadku notifiera do przekazywania danych między pętlami, bo interesuje nas tylko i wyłącznie aktualny kierunek. W załączniku Snake_parallel mały szablon - liczę, że z tego miejsca powinieneś w jakieś 10 minut mieć znów działającego węża :D

Re: Gra Snake

: 20 kwie 2014 01:15
autor: aaddaas
Po pierwsze: bardzo Ci dziękuję za odpowiedź;)
PiDi pisze:Nie rozumiem, jak to znika Ci Vkey? Nie mówię o obsłudze ramki timeouta i Key down w tej samej ramce, tylko w oddzielnych - zresztą patrz załącznik Snake_main. Co prowadzi automatycznie do jeszcze większego problemu z blokowaniem ruchu węża przy naciskaniu klawiszy.
Tak też zrobiłem na początku, ale szybko odrzuciłem tę opcję właśnie ze względu na blokowanie węża;)
PiDi pisze:Jak sobie z tym poradzić? Bardzo prosto - przesunąć logikę aplikacji, czyli przesuwanie węża, do oddzielnej pętli. W ten sposób niezależnie obsłużysz naciskanie przycisków i niezależnie wykonywanie ruchów, które będzie mogło chodzić ze swoim niezakłóconym timingiem. Sugeruję użycie w tym przypadku notifiera do przekazywania danych między pętlami, bo interesuje nas tylko i wyłącznie aktualny kierunek. W załączniku Snake_parallel mały szablon - liczę, że z tego miejsca powinieneś w jakieś 10 minut mieć znów działającego węża :D
Zajęło mi trochę więcej niż 10 min, ale to wynika głównie z braku doświadczenia;)
Mam jednak dalej mały problem/pytanie: Chcę, by pętla "producer" również była zatrzymywana, w momencie, gdy "consumer" stwierdzi, że koniec gry. W tym celu, zgodnie z podpowiedzią internetów, stworzyłem FGV, który obsługuje zatrzymanie pętli. Sprawa polega jednak na tym, że muszę FGV w "producer" umieścić w evencie Timeout, co powoduje, że pęlta "producer" i tak się kręci, niepotrzebnie zużywając procesor i niejako przecząc idei używania eventów. Czy można to załatwić w inny sposób?

No i jeszcze pytanie z innej beczki: Gdybym chciał, by "consumer" odczytywał pierwszą notyfikację, a nie ostatnią w swoim obiegu, zapewne bym musiał stosować Queue operations, ale jakoś nieszczególnie mi to wychodzi. Czy mógłbym i tutaj liczyć na pomoc?

Jeszcze raz dziękuję za każdą odpowiedź. Jestem w trakcie kształcenia się w LabView i moje wątpliwości mogą się wydawać trywialne, ale mi spać nie dają;)
Pozdrawiam

Re: Gra Snake

: 23 kwie 2014 21:31
autor: PiDi
Chcę, by pętla "producer" również była zatrzymywana, w momencie, gdy "consumer" stwierdzi, że koniec gry.
Dlaczego? Widziałeś kiedyś jakąś grę, która całkowicie wyłącza się na "koniec gry"? Wyobraź sobie, że robisz z tego SuperMegaSnake3D.exe i sprzedajesz w znanym sklepie z multimediami wersję kolekcjonerską za 149,99 PLN - z dopiskiem w instrukcji "aha, jeśli chcesz zacząć nową grę, musisz uruchomić program od nowa, bo jak przegrasz, to się program zamknie"... Mogłoby to być irytujące :D
Stąd widzę innym problem, który masz: po zakończeniu gry chciałbyś wyświetlić graczowi wynik i dać mu jakiś przycisk "Nowa gra". Dwa pytania w związku z tym:
1) Czy masz pomysł, jak to zrobić?
2) Czy wiesz, co to jest i jak się robi maszynę stanów w LabVIEW?

Re: Gra Snake

: 24 kwie 2014 12:23
autor: aaddaas
PiDi pisze:Stąd widzę innym problem, który masz: po zakończeniu gry chciałbyś wyświetlić graczowi wynik i dać mu jakiś przycisk "Nowa gra". Dwa pytania w związku z tym:
1) Czy masz pomysł, jak to zrobić?
2) Czy wiesz, co to jest i jak się robi maszynę stanów w LabVIEW?
Słuszna uwaga, nie poświęcałem myśli temu, co się stanie po skończeniu gry.
2) Wiem co to jest maszyna stanów i wiem jak się ją tworzy w labview
1) Sugerując się podpowiedzią (state mashine) skleciłem coś na tej zasadzie tego co jest w załączniku.

Jak teraz uważasz? O to Ci chodziło?
I jeśli mogę, to ponowię jedno pytanie:
Gdybym chciał, by "consumer" odczytywał pierwszą notyfikację, a nie ostatnią w swoim obiegu, zapewne bym musiał stosować Queue operations, ale jakoś nieszczególnie mi to wychodzi. Czy mógłbym i tutaj liczyć na pomoc?

Gra Snake

: 24 kwie 2014 13:33
autor: Jamal79
Witaj.
Kolejki (queue) dzialaja na zasadzie FIFO, wiec tak. Consumer odczyta pierwsza ktora zostala dodana do kolejki.
Dolanczam maly przyklad. Ja podpielem Numerica, ale mozna podpiac wszystko, clustra itd. Nie potrzeba podlanczac kabelkow jak w wiekszosci tradycyjnych ikonek, tzn, wyjscie wejscie.

Re: Gra Snake

: 24 kwie 2014 15:04
autor: aaddaas
Hej! Dzięki za odpowiedź. W sumie nie wiem, dlaczego sam do tego nie doszedłem, ale słowo-klucz (FIFO) zdecydowanie pomogło mi ogarnąć sprawę i oto efekt;)