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.. |
|
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. |
|
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ł. |
|
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..? 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. |
|
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? |
|
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. |
|
killjoy |
» 2017-07-27 15:35:24 Szybki, brzydki przykład, napisany z nudów, czerwona linia jest wektorem ruchu: ##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; }
|
|
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ć. V * sf::Vector2f( cos( alfa ), - sin( alfa ) )
|
|
« 1 » 2 |