MonoGame, a próba napisania Snake

0

Witam. Ostatnio zainteresowałem się trochę MonoGame, jako że w końcu, przynajmniej w miarę ogarnąłem C# :)
W tym celu trochę poczytałem tutoriali/samouczków o XNA, jakie znalazłem w j. polskim w necie. Tak, więc podstawy znam, a dalej trzeba sobie jakoś radzić...
Jako, że moje doświadczenie w pisaniu gier jest zerowe, zwracam się do Was z prośbą o pomoc. Próbuję (nieudolnie), napisać na początek prostego snake'a. Oto co udało mi się sklecić:
https://wklej.to/0GaOn
https://zapodaj.net/367c094ab8818.jpg.html

Całość niby działa (sterowanie jest, zbierać "punkty" można, wąż wydłuża się).
Jednakże, kompletnie nie mam pojęcia jak sprawić, żeby wąż poruszał się jak pełnoprawny wąż rodem z gry tego typu. Teraz wygląda to tak, że po wciśnięciu klawisza w prawo wszystkie "kratki" węża na raz skręcają w tym samym kierunku, a jak wiadomo najpierw powinna skręcić głowa, a za nią reszta "ciała".
Pomoże ktoś, kto jest bardziej w to wtajemniczony ? Byłbym mega wdzięczny :)

Co do sposobu pisania, też proszę o jakieś uwagi (jakie wzorce stosować itp), każda rada jest na wagę złota :) ,bo jak mówiłem wcześniej, mam zerowe doświadczenie w pisaniu gier.

2

musisz zrobić coś w tym stylu:

void Snake::move() {
    for(size_t i = body.size(); i --> 1;) {
        body[i].x = body[i - 1].x;
        body[i].y = body[i - 1].y;
    }

    if(direction == Way::up && head().y - 1 > limit.min_y)
        head().y -= 1;
    else if(direction == Way::down && head().y + 1 < limit.max_y)
        head().y += 1;

    else if(direction == Way::left && head().x - 1 > limit.min_x)
        head().x -= 1;
    else if(direction == Way::right && head().x + 1 < limit.max_x)
        head().x += 1;
}
0

Kurczę siedzę nad tym i dalej mi nie wychodzi...
teoretycznie jest podobnie jak u Ciebie:

if (IsMoveToDown)
            {
                PositionPlayerHead.Y++;
                int i = 0;
                PositionPlayerBody[0] = new Rectangle(PositionPlayerHead.X, PositionPlayerHead.Y - 10, 10, 10);
                if (BodyIndex > 0)
                {
                   while (BodyIndex != i)
                    {
                            ++i;
                            PositionPlayerBody[i] = new Rectangle(PositionPlayerBody[i - 1].X, PositionPlayerBody[i - 1].Y - 10, 10, 10);
                    }
                 }
            }

Czemu nie działa, jak należy?

1

Zagalopowałeś się troche;
Bez warunków, przemieszczasz segmenty, a następnie ruszasz głową - nic więcej nic mniej.

Drobna uwaga: nie trzymaj segmentów jako prostokąty. Tym, jaką będą miały wielkość czy wygląd ma się zająć prezenter, bo inaczej niepotrzebnie nosisz ze sobą redudantne informacje.

patrz tu: http://4programmers.net/Forum/1189612

0

Mam coś takiego:

 if (BodyIndex > 0)
            {
                int i = 0;
                while (i != BodyIndex)
                {
                    ++i;
                    if (IsMoveToTop)
                        PositionPlayerBody[i] = new Rectangle(PositionPlayerBody[i - 1].X, PositionPlayerBody[i - 1].Y + 10, 10, 10);
                    if (IsMoveToDown)
                        PositionPlayerBody[i] = new Rectangle(PositionPlayerBody[i - 1].X, PositionPlayerBody[i - 1].Y - 10, 10, 10);
                    if (IsMoveToLeft)
                        PositionPlayerBody[i] = new Rectangle(PositionPlayerBody[i - 1].X + 10, PositionPlayerBody[i - 1].Y, 10, 10);
                    if (IsMoveToRight)
                        PositionPlayerBody[i] = new Rectangle(PositionPlayerBody[i - 1].X - 10, PositionPlayerBody[i - 1].Y, 10, 10);
                }
            }
            if (IsMoveToTop)
            {
                PositionPlayerHead.Y--;
                PositionPlayerBody[0] = new Rectangle(PositionPlayerHead.X, PositionPlayerHead.Y + 10, 10, 10);
            }
            if (IsMoveToDown)
            {
                PositionPlayerHead.Y++;
                PositionPlayerBody[0] = new Rectangle(PositionPlayerHead.X, PositionPlayerHead.Y - 10, 10, 10);
            }
            if (IsMoveToLeft)
            {
                PositionPlayerHead.X--;
                PositionPlayerBody[0] = new Rectangle(PositionPlayerHead.X + 10, PositionPlayerHead.Y, 10, 10);
            }
            if (IsMoveToRight)
            {
                PositionPlayerHead.X++;
                PositionPlayerBody[0] = new Rectangle(PositionPlayerHead.X - 10, PositionPlayerHead.Y, 10, 10);
            }

Wszystkie bloki przemieszczają się razem :(
Kompletnie nie wiem, jak zastosować to co mi podesłałeś..

1

Przecież w tym kodzie nie ma ani krzty mojego wkładu :P
pseudokod:

lecąc od {dupy} po {głowę} posiadając {ten} oraz {nastepny} {element}:
    pozycja(ten_element) = pozycja(nastepny_element)

rusz(głowę) // wedlug kierunku
0

Nie wiem jakim cudem, ale wygląda na to, że działa :D

            if (BodyIndex > 0)
            {
                if (IsMoveToTop)
                {
                    int index = BodyIndex;
                    int i = BodyIndex * 2;
                    while (i != BodyIndex)
                    {
                        PositionPlayerBody[index] = new Rectangle(PositionPlayerBody[index - 1].X, PositionPlayerBody[index - 1].Y + 10, 10, 10);
                        index--;
                        i--;
                        Console.WriteLine(i);
                    }
                }
                if (IsMoveToDown)
                {
                    int index = BodyIndex;
                    int i = BodyIndex * 2;
                    while (i != BodyIndex)
                    {
                        PositionPlayerBody[index] = new Rectangle(PositionPlayerBody[index - 1].X, PositionPlayerBody[index - 1].Y - 10, 10, 10);
                        index--;
                        i--;
                        Console.WriteLine(i);
                    }
                }
                if (IsMoveToLeft)
                {
                    int index = BodyIndex;
                    int i = BodyIndex * 2;
                    while (i != BodyIndex)
                    {
                        PositionPlayerBody[index] = new Rectangle(PositionPlayerBody[index - 1].X + 10, PositionPlayerBody[index - 1].Y, 10, 10);
                        index--;
                        i--;
                        Console.WriteLine(i);
                    }
                }
                if (IsMoveToRight)
                {
                    int index = BodyIndex;
                    int i = BodyIndex * 2;
                    while (i != BodyIndex)
                    {
                        PositionPlayerBody[index] = new Rectangle(PositionPlayerBody[index - 1].X - 10, PositionPlayerBody[index - 1].Y, 10, 10);
                        index--;
                        i--;
                        Console.WriteLine(i);
                    }
                }
            }

Serdeczne dzięki ;)
Pozostał jeszcze tylko jeden mały problem, jak sprawić, żeby te bloki zawijały się wolniej :E ?

1

możesz wprowadzić ogranicznik tępa uzależniony od upływającego czasu / trzymać pozycję jako float i wymnażać prędkość z czase.

ps. w twoim kodzie masz sporo powtórzeń, możesz bez problemu wyprowadzić jakiś wspólny mianownik.

0

Poprawiłem:

 if (BodyIndex > 0)
            {
                int index = BodyIndex;
                int i = BodyIndex * 2;          
                    while (i != BodyIndex)
                    {
                        PositionPlayerBody[index] = new Rectangle(PositionPlayerBody[index - 1].X, PositionPlayerBody[index - 1].Y, 10, 10);
                        index--;
                        i--;
                    }
            }

Tyle, że po zakręcie mam dwa ogony, przez chwilę :E
jeden generuje się w nowym miejscu(nie powinien), a drugi znika tak jak powinien.

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