Autor Wątek: SNAKE - OGON PROBLEM  (Przeczytany 4479 razy)

HIsTronIC

  • Gość
# Maj 31, 2007, 23:25:47
Cześć, robie gre snake, ale napotkałem dziwny problem matematyczny. Otóż jak do tej pory to zrobiłem głowe snake'a(zwykły kwadrat) i głowa poprawnie reaguje na klawisze. Ale problem zaczyna się jak chcę go wydłużyć, do co najmniej dwuch segmentów. Nie wiem jak liczyć współrzędne segmentów ogona tak, aby szły dokładnie tą samą drogą co głowa.

Będę wdzięczny za jakiekolwiek wskazówki.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline nameczanin

  • Użytkownik
    • devlog

# Maj 31, 2007, 23:28:15
np. rekurencja. Niech kazdy segment weza bedzie jakas tam klasa i ma wskaznik or smth do nastepnego segmentu, poczynajac od glowy. Niech sobie wysylaja po kolei komunikaty i kazdy nastepny stwierdza swoj ruch na podstawie ruchu tego poprzedniego.

Nigdy tak nie robilem, bo nigdy nie kodzilem snake'a (taa), ale powinno byc ok.

HIsTronIC

  • Gość
# Maj 31, 2007, 23:31:31
nie lcizysz nowych współrzędnych. zostawiasz te współrzędne z głowy.
Pozycje ostatniego zamieniasz na pozycję pierwszego. Pierwszego na drugiego itd. Jak byś chwile pogłowił to możesz żonglowac indeksami i mniej przypisywania wartości.

HIsTronIC

  • Gość
# Maj 31, 2007, 23:32:31
np. rekurencja. Niech kazdy segment weza bedzie jakas tam klasa i ma wskaznik or smth do nastepnego segmentu, poczynajac od glowy. Niech sobie wysylaja po kolei komunikaty i kazdy nastepny stwierdza swoj ruch na podstawie ruchu tego poprzedniego.

Nigdy tak nie robilem, bo nigdy nie kodzilem snake'a (taa), ale powinno byc ok.
To jest jakiś sposób, ale wydaje mi się, że troche za skomplikowany jak na moją pierwszą gierkę.
No ja myślałem zrobić to w ten sposób:
Zapamiętywać określoną liczbę ruchów głowy, w tablicy zawierającej ilość elementów równej hipotetycznej, maksymalnej liczbie segmentów dozwolonych w grze.
i po prostu wpisywać na bierząco współrzędne głowy do tej tablicy co klatkę i według tego jakoś prowadzić ogon, no ale to też jest troche zbyt skomplikowane i nie wiem jak to zaimplementować w programie.

// EDIT :
Sorki za niepotrzebny bałagan, po prostu za długo nad tym siedziałem.
Zrobiłem sobie chwile przerwy i po prostu zrobiłem coś w tym stylu:

nie lcizysz nowych współrzędnych. zostawiasz te współrzędne z głowy.
Pozycje ostatniego zamieniasz na pozycję pierwszego. Pierwszego na drugiego itd. Jak byś chwile pogłowił to możesz żonglowac indeksami i mniej przypisywania wartości.

Tak jak myślałem z początku, tylko nie potrzebnie sobie zamotałem. Problem rozwiązany.

Dzięki.
« Ostatnia zmiana: Czerwiec 01, 2007, 00:02:16 wysłana przez Hi_Tronic »

Offline Steel_Eagle

  • Użytkownik

# Czerwiec 01, 2007, 01:04:45
nie lcizysz nowych współrzędnych. zostawiasz te współrzędne z głowy.
Pozycje ostatniego zamieniasz na pozycję pierwszego. Pierwszego na drugiego itd. Jak byś chwile pogłowił to możesz żonglowac indeksami i mniej przypisywania wartości.

A w ogole trzeba tutaj jakies wartosci przepisywac? Wystarczy kawalki weza zrobic jako kolejke

push_front() doda nowa pozycje glowy
pop_back() zajmuje sie ogonem  :)

HIsTronIC

  • Gość
# Czerwiec 01, 2007, 09:24:56
No ja właśnie wczoraj nad tym chwilke dłużej pomyślałem...
masz pozycję każdej części w array. no i zmieniasz pozycję ostatniego tylko. i++

Pozycja[] pozycja = new Pozycja[5];
int i = 0;
void ruch(int x, int y)
{
  if(i > 4)
      i = 0;
   pozycja[i].x = x; // kod forum zjada nawiasy kwadratowe z i
   pozycja[i].y = y; // kod forum zjada nawiasy kwadratowe z i
   i++;
}
prościej się chyba nie da. :)

Można listą zamiat array... to łatwiej dodawać nowe części będzie(chociaż ja bym wolał tworzyć nowe array przy wężu, który zazwyczaj jest krótki)... ale nie widzę sensu robić listy łączone. To tylko naszego węża nie potrzebnie skomplikuje. Zawsze szukaj najprostszej/najefektywniejszej metody.

Edit: C#... chociaż w javie prawie tak samo. Miałem błąd przy array.
Kodem jdenka znowu zagmatwałem całe tłumaczenie.
Edit@down: fakt, jest źle.

// EDIT by Q8 - "kod forum nie zjadałby nawiasów kwadratowych z i" gdyby użyć znaczników  [ code ]...
« Ostatnia zmiana: Czerwiec 01, 2007, 13:02:48 wysłana przez Queight »

Offline nameczanin

  • Użytkownik
    • devlog

# Czerwiec 01, 2007, 09:27:43
jak ten kod moze dzialac? -_-'

Offline Liosan

  • Redaktor

# Czerwiec 01, 2007, 10:54:41
a jak moze nie dzialac? :) ja w ten sposob napisalem niedawno weza w asmie :P

Liosan

Offline nilphilus

  • Użytkownik
    • wordpress

# Czerwiec 01, 2007, 11:00:20
Po co ludzie przesuwać każdy element? ja zainspirowany tematem napisałem sobie, tak z 70% wężyka (pod konsole).

Problem przesuwania załatwiłem banalnie ;-]
1. Usuwamy 'ogonek'
2. pobieramy pozycje głowy i zapisujemy ją do zmiennej tymczasowej ;-]
3. modyfikujemy odpowiednio zmienną tymczasową - w zależności od kierunku w którym się poruszamy
4. dodajemy zmienną tymczasową przed głowę ;-]
5. Bazgramy wsio ;-]

i włala ;-]

tylko musisz sobie dopisać sprawdzanie czy nie wpadło się na bonus/siebie/ściankę ;-]

chciałem dać kod, ale stwierdziłem że popsuł bym zabawę ;-]

Offline nameczanin

  • Użytkownik
    • devlog

# Czerwiec 01, 2007, 11:38:58
nilphilus: tak jest latwiej i, zdaje sie, optymalniej. Jednak lepiej niech sie bawi poczatkujacy bardziej jezykiem niz algorytmem :P

RageX: obawiam sie, ze ten kod nawet sie nie skompiluje. Z reszta, napisales funkcje, ktorej uzycia nie podales.

Offline BartMax

  • Użytkownik
    • Mobile Wings

# Czerwiec 01, 2007, 11:53:51
ok ja bym tak zrobil
-w klasie "klocek" zrobilbym 4 zmienne odpowiedzialne za pozycje x,y,prevX,prevY. Na poczatku prevX=x i prevY=y
-w metodzie think() zrobilbym przesuniecie pierwszego elementu, np w prawo klocek[0].x+=5;
- teraz petla
int ileElementow; //- ile elementow ma waz
for(int i=1; i<ileElementow;i++){
klocek[i].x=klocek[i-1].prevX
klocek[i].y=klocek[i-1].prevY

}
Teraz petla ktora ustawia prevX i prevY
for(int i=0; i<ileElementow;i++){
klocek[i].prevX=klocek[i].x
klocek[i].prevY=klocek[i].y

}
A dalej wyrysowanie

// EDIT by Q8 - no ludzie, litości, używajcie znaczników [ code ]
// EDIT by Bart - co to je litość? :P Sorki
« Ostatnia zmiana: Czerwiec 01, 2007, 13:33:52 wysłana przez BartMax »

Offline nilphilus

  • Użytkownik
    • wordpress

# Czerwiec 01, 2007, 11:56:27
no to jest druga opcja. Za pierwszym razem jak próbowałem napisać snejka to miałe Segmencik snejka
struct Segment
{
 int x,y;
 Direction direction;
};
i leciałem od głowy przesuwając w odpowiedni kierunek i zamieniając odpowiednio zmienne direction ;-]

namaczeczanin: No czy ja wiem, ja przesuwając wężyka zawsze wykonuje (2 wypisania znaku, usunięcie ostatniego elementu, modyfikacje elementu, dodanie elementu)
w przypadku przejścia przez całego wężyka dodaje się parę rzeczy wykonywanych dla każdego fragmentu z osobna ;-)
a ja jak napisałem, operuje na głowie i ogonie ;-) (narazie mam vector, ale w wolnym czasie napisze własną klasę która lepiej zrobi to co chcę ;-])
INFO: przypominam, nabazgrałem to pod konsole, zresztą ciekawych zapraszam na joggera ;-)
« Ostatnia zmiana: Czerwiec 01, 2007, 11:59:23 wysłana przez nilphilus »

HIsTronIC

  • Gość
# Czerwiec 01, 2007, 12:16:38
heh, no to moje się skompiluje... ale rzeczywiście, jest to jakaś jedna metoda z której nic nie wynika, tylko namieszałem.
http://www.sendspace.com/file/316hgt
ta moja idea... czyli przesunięcie tylko ostatniego na miejsce pierwszego(tylko tablica z pozycjami wszystkich segmentów i iteracja w dobrym miejscu potrzebna)
oczywiście z dużym śmietnikiem z powodu guzików i takich tam bzdetów. .net 2.0 do odpalenia potrzebne. Mam nadzieję że odpali. :)

TO nie gra, oczywiście.
EDIT: A wracając do listy łączonej. Weź grid 1000000/1000000  i  8000 segmentów dla węża. I wcale to żadna abstrakcja. Szybka gierka dla świrów. Czy wtedy cały ten traversal przez listę nie będzie nadużyciem? Spróbuj podać przykład dla Snake-a, w którym lista łączona, będzie jednak lepsza. Mi nic do głowy nie przychodzi.
« Ostatnia zmiana: Czerwiec 01, 2007, 12:33:15 wysłana przez RageX »

HIsTronIC

  • Gość
# Czerwiec 01, 2007, 13:24:35
No fajnie, że się tak rozpisaliście, bo mój kod poszedł się rypać, będę zmuszony chyba zrobić projekt. Nie chciałem tego robić bo to miała być prosta gierka, ale nie widzę innego wyjścia. Te wskazówki bardzo mi pomogły. Na szczęście większość kodu jest w porządku czyli tak od zera nie muszę znowu zaczynać, ale najlepiej będzie używać do tego klas. Niech segment będzie obiektem, to będe miał bardziej przejrzysty kod.
I wiem, że maksymalna długość węża będzie musiała być ustalona w trakcie działania programu.
Dzięki.
« Ostatnia zmiana: Czerwiec 01, 2007, 13:27:05 wysłana przez Hi_Tronic »

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Czerwiec 01, 2007, 13:51:42
- Panie majorze, melduję, że nie możemy złapać tej muchy!
- Wytoczyć ciężką artylerię!