Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Dwa problemy ( ruxh postaci & view mode )

Ostatnio zmodyfikowano 2015-04-10 20:55
Autor Wiadomość
Crax
Temat założony przez niniejszego użytkownika
Dwa problemy ( ruxh postaci & view mode )
» 2015-04-03 22:59:24
To znowu ja, mam nadzieje że nikt mnie nie pogryzie za dwa problemy w jednym wątku :/

Po pierwsze, do poruszania postaci używam event -ów, przy wciśnięciu i puszczeniu klawisz postać porusza się tak jak chciałem natomiast przy przytrzymaniu przycisku postać porusza się  zbyt szybko, próbowałem rozwiązać to stosując pętle stało krokową jednak nic to nie dało.
Myślałem nad zastosowaniem pauzy tak aby po każdym ruchu postać zatrzymała się na chwile i dopiero ruszyła dalej, jednak nigdy z czegoś takiego nie korzystałem i nie wiem jak to zastosować :/
Przykładowy kod odpowiedzialny za ruch:
C/C++
if( zdarzenie.type == Event::KeyPressed && zdarzenie.key.code == Keyboard::Down )
{
    nazwa = 2;
    if( colision( lvl, x_p, y_p, nazwa ) == true )
    {
        player.move( 0, 32 );
        player.setRotation( 180 );
    }
}

Natomiast drugi mój problem związany jest z funkcją view, mam mapę 512 x 512 z czego w oknie widoczne jest tylko 256 x 256 na mapie znajdują się takie elementy jak schody, dziury, drabinki itd.. Działa to na zasadzie sprawdzania czy pozycja gracza znajduje się na wskazanym kaflu ( mapa kafelkowa, kafle 32 x 32)

C/C++
x_p = player.getPosition().x;
y_p = player.getPosition().y;

if( mapa[ lvl ][ x_p / 32 ][ y_p / 32 ] == 6 )
{
    lvl--; // lvl to właśnie ta wysokość planszy
}

Natomiast po wprowadzeniu view mode ta funkcja nie dział, czytałem gdzieś coś o mapPixelToCoords tutaj też nie wiem jak to zastosować zwłaszcza że odnosi się to pozycji Sprita::player a nie tak jak w przykładach myszki :v

// viev mode ustawiam tak
C/C++
RenderWindow oknoAplikacji( VideoMode( 256, 256, 32 ), "xxx" );

View view;
view.setSize( sf::Vector2f( 256, 256 ) );

// reszta kodu

view.setCenter( sf::Vector2f( player.getPosition() );
oknoAplikacji.display();

Ps. Jestem na etapie ofensywnej nauki angielskiego, ale moja znajomość tego języka nadal jest za mała aby korzystać z angielskich kursów.
P-130043
Quirinnos
» 2015-04-04 00:11:33
Moja kryształowa kula, mówi mi, że coś nie tak jest z ograniczeniem aktualizacji gry/limitem FPS.
P-130058
michal11
» 2015-04-04 13:17:02
Co do prędkości to uzależnij ja od czasu, albo po prostu zmniejsz
P-130095
Crax
Temat założony przez niniejszego użytkownika
» 2015-04-05 20:07:02
Drugi problem rozwiązany, wystarczyło zamienić x_p ( x gracza ) z y_p ( analogicznie y gracza) miejscami.

C/C++
if( mapa[ lvl ][ y_p / 32 ][ x_p / 32 ] == 6 )
{
    lvl--;
}

Co do drugiego, radzicie mi żebym zmniejszył prędkość albo uzależnił ją od czasu... tylko ja z niczego takiego nie korzystam, ale chyba powinienem? Tak, że poszperałem w internetach i z zrobiłem tak:
oknoAplikacji.setFramerateLimit( 60 );
 ograniczyłem sobie ilość klatek na sekundę do 60 // jeżeli dobrze zrozumiałem działanie tej funkcji

Korzystając z bloga: http://quirinnos.pl/kurs-sfml-2-1-7-petla-stalokrokowa/. Dodałem tak że prędkość w postaci:
C/C++
const float speed = 30.f;
Time czas;
// ładowanie texture, rysowanie mapy itp...

if( zdarzenie.type == Event::KeyPressed && zdarzenie.key.code == Keyboard::Down )
{
    nazwa = 2;
    if( colision( lvl, x_p, y_p, nazwa ) == true )
    {
        player.move( 0, 32 * speed * czas.asSeconds() );
        player.setRotation( 180 );
    }
}

Postać w ogóle się nie rusza! Mógł by mi ktoś to wytłumaczyć :<
Jak zaradzić takiemu rozwojowi spraw, jest jakiś wzór jak to wyliczyć? ( W zamyśle postać miała poruszać się z środka jednego pola na drugie pole, beż możliwości przejścia na pół pole... ) 
P-130213
NopeDotAvi
» 2015-04-05 20:36:18
Jeżeli użyjesz funkcji
window.setFramerateLimit( 60 )
 to będzie 60, jeżeli ktoś ma normalnie więcej niż 60. Jednak, jeżeli ktoś ma np. 30 FPS to nie wymusisz u niego 60. Poczytaj o pętli stałokrokowej, o bezpośrednim dostępie do klawiatury.
P-130216
frogi16
» 2015-04-05 21:43:39
Uważam że zbyt kombinujesz. Nie ograniczaj FPSów tylko zrób timer, który będziesz zerował po wykonaniu ruchu. Sam ruch zrób na zasadzie ifa który potrzebuje spełnienia wszystkich warunków (u ciebie eventu), a jednym z tych warunków zrób coś w stylu
timer>=100
Gdzie liczba to oczywiście czas w jednostkach timera (czyli najprawdopodobniej w milisekundach). W środku takiego ifa wykonuj ruch a potem zeruj timer. Dzięki temu będziesz miał ruch nie szybszy niż (wpisz cokolwiek), a FPSy będą nieograniczone.


Natomiast co do samego ruchu, to używasz mapy kaflowej? Jeśli tak to lepiej dla ciebie będzie trzymać pozycję gracza nie w postaci współrzędnych pikseli tylko liczb, które odpowiadają za kafel na którym stoi gracz w tablicy kafli. Dalej: masz kwadraty o boku n, które zaczynają się od jakichś współrzędnych x i y. Wobec tego zamiast ruszać postać możesz ją natychmiast przestawiać na następne pole. Czytasz jaki klawisz jest naciśnięty i zwiększasz odpowiednią  zmienną ( np. jeżeli naciśnięta jest strzałka w górę to zwiększasz zmienną w której masz numer wiersza w tablicy itd.). Potem już tylko banalny wzór.

Pseudokod::

Player.setPosition(pozycjaX*n+x, pozycjaY*n+y);

Gdzie:
pozycjaX to zmienna odpowiadająca za kolumny w tabeli
pozycjaX za wiersze
n to długość boku kafla
x to współrzędna x piksela na którym zaczyna się cała mapa na ekranie
y to samo tylko y
P-130220
Crax
Temat założony przez niniejszego użytkownika
» 2015-04-06 19:37:39
Cały kod przepisałem od nowa - gównie  w celu przejścia na programowanie obiektowe, dodałem pętlę stało krokową:
fragment kodu:
C/C++
Clock zegar;
Time Aktualizacjia = Time::Zero;
const Time KrokCzasowy = seconds( 1.f / 60.f );
const float speed = 10.f;

while( window.isOpen() )
{
    Time Czas = zegar.restart();
    Aktualizacjia += Czas;
    while( Aktualizacjia > KrokCzasowy )
    {
        Aktualizacjia -= KrokCzasowy;
        Event action;
        while( window.pollEvent( action ) )
        {
            if( action.type == Event::Closed )
            {
                window.close();
            }
        }
       
        if( Keyboard::isKeyPressed( Keyboard::Up ) )
        {
            gamer.ruch( 0, - 32 * KrokCzasowy.asSeconds() * speed );
        }
        if( Keyboard::isKeyPressed( Keyboard::Down ) )
        {
            gamer.ruch( 0, 32 * KrokCzasowy.asSeconds() * speed );
        }
        if( Keyboard::isKeyPressed( Keyboard::Left ) )
        {
            gamer.ruch( - 32 * KrokCzasowy.asSeconds() * speed, 0 );
        }
        if( Keyboard::isKeyPressed( Keyboard::Right ) )
        {
            gamer.ruch( 32 * KrokCzasowy.asSeconds() * speed, 0 );
        }
    }
W zamyśle, rodem z tibi postać miała poruszać się z pola na pole < kafla > bez innej możliwości ( na obecną chwilę postać porusza się bez żadnej kontroli ) Co w takim razie muszę zmienić w
const float speed = 10.f;
 lub
const Time KrokCzasowy = seconds( 1.f / 60.f );
 I czy mógł by mi ktoś jak najprościej wytłumaczyć jak dział ta pętla stało krokowa? :/
P-130289
Quirinnos
» 2015-04-06 20:34:41
W prostych słowach, pętla stałokrokowa ma pilnować, aby aktualizacja gry (logika, fizyka, itp) wykonywała się o właśnie ten stały krok. A nie "jak najszybciej to możliwe". Do gry jaką Ty chcesz pisać, pętla ta nie jest wcale potrzebna. Jeśli chcesz możesz ją zostawić. Bo tak naprawdę w niczym nie będzie przeszkadzać.
Co do ruchu rodem z Tibii.
Nie wiem jak wygląda Twój kod dalej, ale domyślam się, że metoda ruch, po prostu wywołuje move, tak? Jeśli tak, to kod należałoby przerobić. Można to zrobić na kilka sposobów. Najłatwiej chybaby było dać ruch nie oparty na bezpośrednim dostępie do klawiatury.
P-130292
« 1 » 2
  Strona 1 z 2 Następna strona