Snake - problem z poruszaniem

0

Witam, mam problem dotyczący gry Snake. Gra jest właściwie gotowa i działa, tyle, że chciałbym zrobić nieco inne poruszanie wężykiem. Aktualnie porusza się on w ten sposób, że wciśnięcie klawisza przesuwa go o jedno pole, a ja chcę, żeby wciśnięcie jednego klawisza nadawało mu kierunek, a wężyk był cały czas w ruchu.
Nie mam w ogóle pomysłu jak to zrealizować [???] Proszę o pomoc.

W razie potrzeby mogę zamieścić cały mój kod lub jakiś fragment.

0

Jak naciska się klawisz kierunku to ustawiasz odpowiednią zmienną bool,a w pętli programu dopóki program działa badasz które bool-e są true i wywołujesz ten sam kod co teraz masz przy naciskaniu

0

@Force A mógłbyś tak jakoś łopatologicznie wytłumaczyć? ;)

0

Będzie to mniej więcej tak:

bool idz = false;

if( /* wciśnięto klawisz */ ) {
 idz = true;
 /* reszta instrukcji */
}

while( idz ) {
 /* instrukcje chodzenia */ 
}
0

Jeśli chodzi o kierunki to ja bym robił tak:
zmienne kierunkowe int x,y;
plansza char plansza[X][X];
A poruszanie to
plansza[X][Y]=''; //stara pozycja ludzika
plansza[X+x][Y+y]='znak_ludzika'; //nowa pozycja ludzika

W zalezności od tego którą strzałkę ktos wciśnie to zmienne x,y dostaja wartości -1,0, albo 1

Jedyny problem to taki jak wczytywać klawisz jednoczesnie cały cas rysując. Nie wiem, może uzyć dwóch wątków?

0

A to jak jeden ruch weza bedzie na jednym tyknieciu timera juz nie wystarczy? Tutaj żadnych wątków nie potrzeba, odpowiednio ustawiajac timer mozna ustawiac jak szybko chodzi wąż.

0

Ja załozyłem ze mówimy o snaku w konsoli, bez użycia komponentów i tym podobnych zabawek.
Czy autor mógłby sprecyzować z jakiego środowiska korzysta i jak dokładniej ten snake wygląda? (ja załozyłem że plansza to dwuwymiarowa tablica char)

0

Wężyk jest pisany w konsoli (Windows), przy użyciu Dev-C++.
Mapa to: char Mapa[22][79];

Ruch wygląda w ten sposób:

bool ruch()
{
     Poprawnosc = true;
     Kierunek = getch();
     Bufor.X = Glowa.X;
     Bufor.Y = Glowa.Y;
     switch (Kierunek)
     {
            case 'w': ruch_gora();
                     break;
            case 's': ruch_dol();
                     break;
            case 'd': ruch_prawo();
                     break;
            case 'a': ruch_lewo();
                     break;
            default: Poprawnosc = false;
                     return false;
     }
     ruch_tulowiem();
     return true;
}

Poprawnosc - zmienna bool sprawdzająca poprawnosc wejscia
Kierunek - zmienna char, przechowująca kierunek nadany przez gracza
Bufor - struktura przechowująca współrzędne miejsca, gdzie "przed chwilą" była głowa
Glowa - struktura przechowująca współrzędne głowy węża
ruch_tulowiem() - funkcja poruszająca tułowiem, żeby "nadążał" za głową

I tutaj funkcja ruch_gora()
(reszta wygląda analogicznie)

bool ruch_gora()
{
     if (Glowa.X < 1)
     {
        Zderzenie = true;
        return false;
     }
     Mapa[Glowa.X][Glowa.Y] = ' ';
     Glowa.X--;
     Mapa[Glowa.X][Glowa.Y] = 'O';
     return true;
}

Zderzenie - zmienna bool kontrolująca, czy wężyk się zderzył ze ścianą (lub z własnym ogonem)

Aha i jeszcze zaznaczę, że nie umiem korzystać z takich rzeczy jak wątki, czy timer.
I właśnie cały problem polega na tym, że przy każdym wywołaniu funkcji ruch() oczekuje ona na znak i wychodzi na to, że Wężyk... jest grą turową :/

0

No to chyba najprosciej bedzie zrobic drugi wątek, który będzie poruszać wężem. Mozesz na przyklad zadeklarowac zmienna globalna, ktorej wartosc bedzie mówić co ma robic wąż - ruch w dół, górę, prawo, lewo. Funkcja obsługi wątku sprawdza wartość zmiennej co jakiś ustalony czas i podejmuje decyzje w którym kierunku iść, może też dodatkowo wykrywać kolizje.

Wątek działa w tle, a główny program tylko czeka na klawisze i zmienia wartość tej zmiennej w zależności od potrzeb. Wydaje mi sie ze w tym przypadku obejdzie sie bez synchronizacji wątków - i tak bedzie dzialac, wiec nie jest to zbyt skomplikowane zadanie.

0

w takim wypadku jednak 2 wątki...

już kiedyś coś takiego komuś tu napisałem (przykład z dwoma wątkami w jednym while(coś) lastbtn=getchar(); ), poszukać trzeba

0

Dupa Jaś, żaden dodatkowy wątek, nic on nie da. Po pierwsze nie można użyć getchar, ani nic podobnego. Trzeba odczytać wciskany klawisz, a nie tekst ze standardowego wejścia (ten drugi musi być wypluty w oknie konsoli i potwierdzony enterem, poza tym blokuje aplikacje pÓÓÓÓki tego enter nie wciśniemy).

Rozwiązanie jest takie (przy użyciu conio.h i windows.h):

while(!koniec)
{
   Sleep(1000);
   while(kbhit()) kierunek = getch();
   switch(kierunek)
   {
      //...
   }
}
0

A tak właściwie to co to jest to kbhit()?

0

Ale w sumie to rozwiązanie mnie zszokowało ;) najpierw straszą jakimiś wątkami, a później widzę tylko jedną linijkę rozwiązania :-O Dzięki za odpowiedzi ;-)
Pozdrawiam radoslav

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