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

[SFML] Sterowanie samochodem - realizacja pomysłu

Ostatnio zmodyfikowano 2017-07-27 17:31
Autor Wiadomość
soniacz
Temat założony przez niniejszego użytkownika
[SFML] Sterowanie samochodem - realizacja pomysłu
» 2017-07-26 23:26:17
Cześć. Tak jak w tytule, chciałbym napisać grę, w której m.in. będę poruszał się samochodem na mapie dwuwymiarowej, lecz nie mam zielonego pojęcia jak zacząć. Chodzi mi głównie o sterowanie - zmianie kierunku (rotacji) w trakcie przyśpieszania itp.. Jakby mógł mnie ktoś naprowadzić od czego mógłbym zacząć to byłbym wdzięczny, próbowałem kombinować z wbudowaną w bibliotece funkcją move, ale działa to tylko w czterech kierunkach..
P-163596
pekfos
» 2017-07-26 23:44:29
próbowałem kombinować z wbudowaną w bibliotece funkcją move, ale działa to tylko w czterech kierunkach..
To mieszaj kierunki. Od czegoś są funkcje trygonometryczne.
P-163597
latajacaryba
» 2017-07-27 01:44:37
Ja zrobiłbym to tak:
Najpierw rysunek do przemyśleń
Wprowadzasz sobie kąt, pod jakim porusza się pojazd. Najlepiej jeśli to będzie kąt 0-90 stopni (dla czterech ćwiartek). Dlaczego cztery ćwiartki? Dlatego, że jeśli pojazd porusza się w lewo, to jego prędkość będzie "na minusie" (im bardziej w lewo w układzie kartezjańskim tym mniejsze wartości), dlatego poruszając się w lewo musimy zmniejszać zmienną X. Analogicznie oś Y.
W zasadzie możesz po prostu wprowadzać kąt np. 243 i brać modulo z tego:
243 % 90 = 63

Pojazd jedzie pod kątem 63 stopni odnosząc się do prawej górnej ćwiartki (zakładając, że 0 stopni to poruszanie się pionowo w dół i kąt mierzymy zgodnie z ruchem wskazówek zegara)
Obliczasz zgodnie z powyższym rysunkiem wartości i implementujesz to jako prędkość na sekundę, czy jaką tam jednostkę sobie ustalisz.
Dodajesz tarcie i opór powietrza (żeby coś naturalnie hamowało pojazd) jak i same hamulce (co w sumie też polega na tarciu, ale tarcie klocków a opon z podłożem to dwa różne tarcia :P)
I to powinno wystarczyć. Sumujesz to wszystko i masz. Przynajmniej ja bym tak zrobił.
P-163598
pekfos
» 2017-07-27 14:15:58
zakładając, że 0 stopni to poruszanie się pionowo w dół i kąt mierzymy zgodnie z ruchem wskazówek zegara
Jest jakiś powód, dlaczego odchodzisz od układu przyjętego w matematyce..?

Ja zrobiłbym to tak
Jest jakiś powód, dlaczego tak to komplikujesz? Nic z tych obliczeń i dziwnych założeń nie jest potrzebne. Funkcje sinus i cosinus działają poprawnie na wszystkich ćwiartkach i niczego nie trzeba robić z kątem, poza podaniem go do tych funkcji.
P-163612
latajacaryba
» 2017-07-27 14:47:20
Jest jakiś powód, dlaczego odchodzisz od układu przyjętego w matematyce..?
Nie wiem jaki jest układ przyjęty w matematyce.

Funkcje sinus i cosinus działają poprawnie na wszystkich ćwiartkach i niczego nie trzeba robić z kątem, poza podaniem go do tych funkcji.
Wiem, że działa poprawnie w każdej ćwiartce, ale jeśli chcesz ustawić auto pod kątem 137 stopni, to przecież nie obliczysz sin czy cos ze 137 stopni, tylko z 47. Nie jestem pewien, czy o to ci chodziło?
P-163615
Luq
» 2017-07-27 15:10:03
Wiem, że działa poprawnie w każdej ćwiartce, ale jeśli chcesz ustawić auto pod kątem 137 stopni, to przecież nie obliczysz sin czy cos ze 137 stopni, tylko z 47.

Czemu nie? Funkcje sinus i cosinus są zdefiniowane dla dowolnego kąta.
P-163617
killjoy
» 2017-07-27 15:35:24
Szybki, brzydki przykład, napisany z nudów, czerwona linia jest wektorem ruchu:

C/C++
##include <SFML/Graphics.hpp>
#include <windows.h>

#define _USE_MATH_DEFINES
#include <cmath>

#include <iostream>
using namespace std;

int main()
{
    sf::RenderWindow window( sf::VideoMode( 1200, 800 ), "Sinus, cosinus" );
    sf::CircleShape shape( 10 );
    shape.setFillColor( sf::Color::Green );
   
   
    float PosX =( 1200 - 10 ) / 2;
    float PosY =( 800 - 10 ) / 2;
   
   
    float Angle = 0;
    float Speed = 0;
    const float MaxSpeed = 15;
   
    float Vx = cos( Angle ) * Speed;
    float Vy = - sin( Angle ) * Speed;
   
   
    sf::VertexArray line( sf::LinesStrip, 2 );
   
   
    line[ 0 ].color = sf::Color::Red;
    line[ 1 ].color = sf::Color::Red;
   
   
   
   
    sf::Clock clock, clock2, clock3;
    clock.restart();
    clock2.restart();
    clock3.restart();
   
    while( window.isOpen() )
    {
        sf::Event event;
        while( window.pollEvent( event ) )
        {
            if( event.type == sf::Event::Closed )
                 window.close();
           
        }
       
       
       
       
        if( clock.getElapsedTime().asSeconds() >= 0.01 )
        {
            if( sf::Keyboard::isKeyPressed( sf::Keyboard::Left ) ) Angle += 0.02;
            else if( sf::Keyboard::isKeyPressed( sf::Keyboard::Right ) ) Angle -= 0.02;
           
            clock.restart();
           
            Vx = cos( Angle ) * Speed;
            Vy = - sin( Angle ) * Speed;
           
            float d = fmod( Angle *( 180.0 / M_PI ), 360 );
            cout << "Angle deg: " <<( d < 0 ? 360 + d: d ) << " Vx: " << Vx << " Vy: " << Vy << "    " << endl;
        }
       
       
       
       
        if( clock3.getElapsedTime().asSeconds() >= 0.015 && sf::Keyboard::isKeyPressed( sf::Keyboard::Up ) )
        {
            Speed += 0.1;
            Speed =( Speed > MaxSpeed ? MaxSpeed: Speed );
           
           
           
            clock3.restart();
        } else if( sf::Keyboard::isKeyPressed( sf::Keyboard::Space ) && clock3.getElapsedTime().asSeconds() >= 0.005 && Speed > 0 )
        {
            Speed -= 0.1;
            Speed =( Speed < 0.02 ? 0: Speed );
           
            clock3.restart();
        }
       
        else if( clock3.getElapsedTime().asSeconds() >= 0.02 && Speed > 0 )
        {
           
            Speed -= 0.1;
            Speed =( Speed < 0.02 ? 0: Speed );
           
            clock3.restart();
        }
       
       
       
        if( clock2.getElapsedTime().asSeconds() >= 0.03 )
        {
            PosX += Vx;
            PosY += Vy;
           
           
           
           
            if( PosX < 0 ) PosX = 0;
           
            if( PosY < 0 ) PosY = 0;
           
            if( PosX > 1200 - 20 ) PosX = 1200 - 20;
           
            if( PosY > 800 - 20 ) PosY = 800 - 20;
           
           
            shape.setPosition( PosX, PosY );
           
            line[ 0 ].position = sf::Vector2f( PosX + 10, PosY + 10 );
            line[ 1 ].position = sf::Vector2f(( PosX + 10 ) +( Vx * 5 ),( PosY + 10 ) +( Vy * 5 ) );
           
            clock2.restart();
        }
       
       
       
       
       
       
       
       
       
       
       
        window.clear();
        window.draw( line );
        window.draw( shape );
       
        window.display();
    }
   
    return 0;
}
P-163621
pekfos
» 2017-07-27 16:18:14
Wiem, że działa poprawnie w każdej ćwiartce, ale jeśli chcesz ustawić auto pod kątem 137 stopni, to przecież nie obliczysz sin czy cos ze 137 stopni, tylko z 47.
To czego teraz uczą w szkołach.. Funkcje trygonometryczne są okresowe, wiec możesz obliczyć sinusa choćby i z miliona stopni. W końcu taki jest wzór na sinusoidę, nie ma w nim żadnego modulo.

Nie wiem jaki jest układ przyjęty w matematyce.
Taki jaki jest w polarnym układzie współrzędnych. W końcu to, o czym tu mowa to konwersja współrzędnych polarnych prędkość i kąt na wektor w układzie kartezjańskim. Zero stopni leży na dodatniej półosi X i kąty rosną przeciwnie do ruchu wskazówek zegara. Do tego na ekranie oś Y jest odwrócona i to jest jedyna zmiana którą trzeba wprowadzić.
C/C++
V * sf::Vector2f( cos( alfa ), - sin( alfa ) )
P-163623
« 1 » 2
  Strona 1 z 2 Następna strona