Przesuwanie postaci po kafelkowej mapie o 32px

Odpowiedz Nowy wątek
2011-09-11 19:02
0

Witam.

Piszę sobie prostą grę RPG w Bibliotece SDL C++.
Mam już napisane poruszanie mapą (ludzik stoi na środku, a rusza się mapą). Ludzik poruszał się tak długo, aż nie puściłem klawisza. Poruszał się o 2px. Chcę zrobić poruszanie się o jedną kratkę. Koncept miałem taki: poruszam sobie normalnie mapą o 2px, a w momencie puszczenia klawisza program oblicza odległość pozostałą do pełnej kratki i przesuwa o te piksele bez trzymania przycisku.

Zrobiłem już to prawie, ale mam pewien problem.

else if((!keystate[SDLK_RCTRL]) && (keystate[SDLK_LEFT]))
{
    map_position.x++;
    map_position.x++;
    frame++;
    frame++;
    frame++;
    if( frame > 40) frame=0;  
    if( frame<20) { players_frame = 9;}
    else if( frame>=20 && frame<40) { players_frame = 10; } 
    player_dir=4;
    keyleft1 = true;                // Ustawia zmienną która przechowuje informacje czy strzałka w lewo była wciśnięta
    tilpos_x=position_x;
}

else if ((player_dir == 4) && (!keystate[SDLK_LEFT]) && (collision[til_position_y][til_position_x-2] == 0))
{
    keyleft = true;

    if (keyleft2 == true)
    {
        tilpos_x1=tilpos_x-32;
    }

    if (keyleft1 ==  true)          // Sprawdza czy strzałka w lewo była wciśnięta
    {
        if (keyleft ==  true)
        {
            if (position_x-tilpos_x1 != 0)      // Oblicza odległość do następnej kratki
            {
                map_position.x++;
                map_position.x++;
                frame++;
                frame++;
                frame++;
                if( frame > 40) frame=0;  
                if( frame<20) { players_frame = 5; }
                else if( frame>=20 && frame<40) { players_frame = 6; }      
                keyleft2=false;             // I to mój problem, o tym niżej w poście.
            }
        }
    }

            players_frame = 4;
}

Więc w komentarzach napisane jest co do czego służy. Podczas wciskania przycisku zmienna keyleft1 zmienia się na TRUE, po czym odczytywana jest w innym warunku (przycisk NIE jest wciśnięty), po czym odlicza odległość pozostałą do przebycia i przesuwa o tyle ludzika. Wszystko działa perfekcyjnie, ale tylko jeden raz. Ludzik ładnie przechodzi o 1 kratkę, a jak próbuję następną to nie zatrzymuje się już wcale. Przypuszczam że jest to związane z tym, że zmienianie zmiennej keyleft na FALSE znajduje się w złym miejscu.

Ktoś wie może jak rozwiązać ten problem?

edytowany 1x, ostatnio: madmike, 2011-09-12 19:47

Pozostało 580 znaków

2011-09-12 09:34
Ja
0

A czy nie prościej przesuwać ludzika o te 2 pixele

if(keystate[SDLK_RIGHT]) ludyik.x +=2;

a gdy klawisz jest puszczony obliczać w którym kaflu znajduje się ludzik i go wyrównywać z pozycją kafla?

else{
     Uint8 kafel = ludzik.x  / TILE_WIDTH;
     ludzik.x = kafel * TILE_WIDTH;
}

?

Pozostało 580 znaków

2011-09-12 09:38
0

@up Nie jeśli chce się mieć ludzika cały czas na środku ekranu.


Gdy się nie wie, co się robi, to dzieją się takie rzeczy, że się nie wie, co się dzieje ;-)

Pozostało 580 znaków

2011-09-12 10:16
Ja
0

@up: Od tego się robi viewport.
Poza tym nie wiem czemu kolega w jednym warunku wywołuje
3x frame++, zamiast np frame+=3;
oraz dwa razy inkrementację x'a mapy

Pozostało 580 znaków

2011-09-12 10:40
1

najłatwiej to zrobić trzy rodzaje współrzędnych - wszystkie liczone od lewego górnego rogu:

  • współrzędne na mapie - czyli po prostu (x,y) kafla,
  • współrzędne globalne (piksele) - współrzędne na mapie, z tym że względem lewego górnego rogu kafla o współrzędnych na mapie (0,0) w pikselach,
  • współrzędne na ekranie (piksele)
    najłatwiej jeśli każde z tych współrzędnych będą klasą z operatorami które konwertują je między sobą (w zasadzie mogłby też dziedziczyć po jakimś interfejsie klasy Współrzędnych, ale niekoniecznie - osobiście myślę że byłoby to dość wygodne)

dodatkowo zrobić funkcję/metodę:

  • wyśrodkuj ekran do kafla,
  • wyśrodkuj ekran do współrzędnych (globalnych)

ludzika można np zaprojektować tak:

  • WspolrzedneGlobalne, - gdzie znajduje się dokładnie, na ich podstawie obliczać gdzie jest na ekranie
  • WspolrzedneNaMapie, - miejsce w którym się aktualnie znajduje (obj), miejsce z ktorego idzie (obj), miejsce kolejne do którego idzie (wskaznik)
  • CzyIdzie - boolean ktory mowi czy wlasnie sie przemieszczasz
  • poczatekruchu - czas w ktorym ruch sie zaczal, jesli korzystasz z GetTickCount to jest to DWORD
  • predkosc - czas przemieszczania sie z kafla na kafel

przykład: początkowo ludzik stoi na kaflu (5,5) i nie porusza sie (czyidzie=false).
uzytkownik klika strzalke w prawo:

  • wspolrzedneglobalne=aktualnapozycja, miejscezktoregoidzie=aktualnapozycja, miejsce w ktorym aktuanie sie znajduje zmienia sie na (6,5), czyidzie=true, poczatekruchu=GetTickCount()
    uzytkownik klika strzalke w dol (w trakcie jak jeszcze idzie w prawo):
  • miejscekolejnedoktoregoidzie = new WspolrzedneNaMapie(6,6)

░█░█░█░█░█░█░█░█░█░█░█░

Pozostało 580 znaków

2011-09-12 14:29
0

Tylko problem jest taki, że ta funkcja 'jeśli klawisz jest wciśnięty' wykonuje się cały czas, i jeśli ustawie sobie zmienną mojapozycja = cośtam, to ta zmienna zostanie zmodyfikowana w ciągu ruchu o kratkę około 64 razy, czyli 64 razy zmieni mi się ta zmienna i jeśli będę chciał ją odczytać gdzie indziej (if klawisz nie jest wciśnięty) to odczyta sie ostatnia zapisana przy 64 wykonaniu pozycja, czyli prawie że aktualna.

Ja napisał(a)

A czy nie prościej przesuwać ludzika o te 2 pixele a gdy klawisz jest puszczony obliczać w którym kaflu znajduje się ludzik i go wyrównywać z pozycją kafla?
?

Ale on ma się wyrównać idąc płynnie o 2px, a nie przeskakując na pozycję docelową.

edytowany 1x, ostatnio: Bulkas, 2011-09-12 14:30
to sprawdz sobie stan "Czy klawisz jest wcisniety" i reaguj tylko na zmianę tego stanu (pozytywne zbocze jak to mawiają) - krwq 2011-09-12 15:16

Pozostało 580 znaków

2011-09-12 22:42
0

Już sobie poradziłem. Zamiast poprawiać ten zagmatwany kod co wklejałem tu wcześniej, rozpisałem sobie na kartce "algorytm", napisałem to od nowa i działa.
Dzięki za odpowiedzi, temat można zamknąć.

edytowany 1x, ostatnio: Bulkas, 2011-09-12 22:42

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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