wokub Temat założony przez niniejszego użytkownika |
[SFML] Ruch obiektu - podstawa » 2016-12-24 00:07:32 Witam. Mam jedno zadanie z użyciem biblioteki SFML i mam pewnie problem, gdyż nie wiem jak to zrobić. Póki co z poprzednich podpunktów zrobiłem taki kod #include <SFML/Window.hpp> #include <SFML/Graphics.hpp>
int main() { int window_w = 800; int window_h = 800; int keyonoff = 1; int kolo_r = 200.f; float x = 200; float y = 200; sf::RenderWindow window( sf::VideoMode( window_w, window_h ), "Okno" ); sf::CircleShape shape( kolo_r ); shape.setPosition( x, y ); shape.setFillColor( sf::Color::Red ); { sf::Event event; while( window.pollEvent( event ) ) { if( event.key.code == sf::Keyboard::Escape ) window.close(); if( event.type == sf::Event::KeyPressed ) keyonoff = 1 - keyonoff; } window.clear( sf::Color::Black ); if( keyonoff ) window.draw( shape ); window.display(); } return 0; }
I teraz za pomocą vx i vy typu float mam określić prędkość koła. Początkowe wartości 0.05 oraz użyć x=x+xy*dt, y=y+vy*dt. Nie wiem skąd to dt ani w jakim formacie to napisać. Podjąłem kilka prób, bez skutku. Już pomijając fakt, że potem mam uwzględnić kolizję z końcem ekranu. Tzn nie może wyjść poza ekran i wtedy element ma się odbić z tą samą prędkością. Ktoś to rozumie? Znaczy, na pewno ktoś to umie, a nawet większość tego forum. Z góry dzięki za podpowiedź albo pomoc. |
|
michal11 |
» 2016-12-24 02:21:29 dt to skrót od delta time czyli różnica czasu od ostatniej klatki, albo czas jaki, dodaj wywołanie clocka na początku pętli zaraz po obsłudze eventów i przekazuj do jakiejś funkcji updateującej logikę twoich obiektów. Polecam też żeby pominąć jakieś wewnętrzne pętle ja w swoich projektach stawiałem po prostu window.setFramerateLimit(60) i tylko pobierałem czas od ostatniego updatu. Odbicie od krawędzi ekranu tez jest proste musisz tylko sprawdzić czy jest kolizja i skorzystać na przykład z tego http://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector twoja normalna będzie prosta do wyliczenia, w zależności od tego od której krawędzi się twój obiekt odbija będzie to (1,0), (0,1), (-1,0), (0,-1), a vektor d to velocity twojego obiektu (pamiętaj o normalizacji). edit. jeszcze nawiązując do pętli, masz kawałek jakiegoś mojego starego kodu z sfml, może ci się przyda Clock clock; float dt = 0; Event event;
bool pause = false; float timeMultiplier = 1.f;
while( gameWindow.isOpen() ) { if( gameWindow.pollEvent( event ) ) { if( event.type == Event::Closed ) { gameWindow.close(); } else if( event.type == Event::KeyPressed ) { if( event.key.code == Keyboard::Space ) { pause = !pause; } if( event.key.code == Keyboard::Add ) { timeMultiplier += 1.f; } if( event.key.code == Keyboard::Subtract ) { timeMultiplier -= 1.f; } } } if( pause ) { dt = 0; } else { dt = clock.getElapsedTime().asSeconds(); dt *= timeMultiplier; } mainObject.update( dt ); clock.restart(); gameWindow.clear( Color::Black ); gameWindow.draw( mainObject ); gameWindow.display(); }
|
|
wokub Temat założony przez niniejszego użytkownika |
» 2016-12-24 15:24:51 Ja już nie wiem. Z HTML jestem ciut bardziej zaawansowany, więc próbowałem na jego podstawie, no ale gdzie nie wkleję tego wzoru na ruch, nie mam błędu, a element i tak się nie porusza #include <SFML/Window.hpp> #include <SFML/Graphics.hpp>
int main() { int window_w = 800; int window_h = 800; int keyonoff = 1; int kolo_r = 200.f; float x = 200; float y = 200; float dt = 0.05f; float vx = x; float vy = y; sf::RenderWindow window( sf::VideoMode( window_w, window_h ), "Nasze okno" ); sf::CircleShape shape( kolo_r ); shape.setPosition( x, y ); shape.setFillColor( sf::Color::Red ); while( window.isOpen() ) { sf::Event event; x = x + vx * dt; y = y + vy * dt; while( window.pollEvent( event ) ) { if( event.key.code == sf::Keyboard::Escape ) window.close(); if( event.type == sf::Event::KeyPressed ) keyonoff = 1 - keyonoff; } window.clear( sf::Color::Black ); if( keyonoff ) window.draw( shape ); window.display(); } return 0; }
Co prawda w linkach, które zamieściłeś, są różne rozwiązania, no ale nikt nie stosuje tego x = x + vx ... |
|
michal11 |
» 2016-12-24 15:31:52 Wywołaj shape.setPosition() przed window.clear |
|
wokub Temat założony przez niniejszego użytkownika |
» 2016-12-24 15:37:07 #include <SFML/Window.hpp> #include <SFML/Graphics.hpp>
int main() { int window_w = 800; int window_h = 800; int keyonoff = 1; int kolo_r = 200.f; float x = 200; float y = 200; float dt = 0.05; float vx = x; float vy = y; sf::RenderWindow window( sf::VideoMode( window_w, window_h ), "Nasze okno" ); sf::CircleShape shape( kolo_r ); shape.setPosition( x, y ); shape.setFillColor( sf::Color::Red ); while( window.isOpen() ) { sf::Event event; x = x + vx * dt; y = y + vy * dt; while( window.pollEvent( event ) ) { if( event.key.code == sf::Keyboard::Escape ) window.close(); if( event.type == sf::Event::KeyPressed ) keyonoff = 1 - keyonoff; } shape.setPosition( vx, vy ); window.clear( sf::Color::Black ); if( keyonoff ) window.draw( shape ); window.display(); } return 0; }
Coś w tym stylu? Pierwszy raz mam styczność z SFML, więc z góry sorka za głupie błędy. Nic się nie zmieniło, a po wpisaniu do shape.setPosition x i y zamiast vx i vy, element po prostu znika. |
|
pekfos |
» 2017-01-03 21:38:25 po wpisaniu do shape.setPosition x i y zamiast vx i vy, element po prostu znika. |
Nie znika, tylko porusza się zbyt szybko. Dostałeś linki do odpowiednich materiałów. |
|
« 1 » |