• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Poruszanie obiektem względem pozycji

Object Storage Arubacloud
0 głosów
1,592 wizyt
pytanie zadane 27 września 2015 w C i C++ przez Avernis Nałogowiec (27,400 p.)
zmienione kategorie 27 września 2015 przez Avernis
Jak można poruszać obiektem względem pozycji, czyli np obiekt jest na pozycji 0, 0, a ja kliknę myszką i mi zacznie się poruszać do pozycji tam gdzie kliknołem myszkę

3 odpowiedzi

+2 głosów
odpowiedź 27 września 2015 przez Patrycjerz Mędrzec (192,320 p.)
wybrane 27 września 2015 przez Avernis
 
Najlepsza
//Poruszanie obiektu w stronę kursora myszy o podaną prędkość
//2015 Patrycjerz

#include <SFML/Graphics.hpp>
#include <cmath>

int main()
{
    sf::RenderWindow window(sf::VideoMode(600, 600), "Test"); // Stworzenie okna
    window.setFramerateLimit(100); // Nadanie maksymalnej wartości FPS na 100

    sf::Event event; // Obiekt zdarzeń

    sf::Clock clock; // Obiekt zegara

    sf::Time time; // Obiekt czasu

    const float rectangle_x = 50; // Szerokość kwadratu
    const float rectangle_y = 50; // Wysokość kwadratu

    sf::RectangleShape rectangle(sf::Vector2f(rectangle_x, rectangle_y)); // Stworzenie kwadratu
    rectangle.setFillColor(sf::Color::Red); // Nadanie mu koloru czerwonego

    sf::Vector2i mouse_position; // Pozycja kursora myszy

    const float velocity_value = 100; // Wartość wektora prędkości

    sf::Vector2f velocity(0, 0); // Składowe wektora prędkości

    float x; // Różnica pozycji iksowych kursora i kwadratu
    float y; // Różnica pozycji igrekowych kursora i kwadratu
    float z; // Odległość pomiędzy kursorem i kwadratem

    while(window.isOpen())
    {
        // Zdarzenia
        while(window.pollEvent(event))
        {
            if(event.type == sf::Event::Closed)
                window.close();
        }

        mouse_position = sf::Mouse::getPosition(window); // Pobranie pozycji kursora myszy

        if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) // Jeśli naciśnięty lewy przycisk myszy
        {
            x = static_cast<float>(mouse_position.x) - rectangle.getPosition().x - (rectangle_x / 2); // Obliczenie różnicy pozycji iksowych kursora i kwadratu
            y = static_cast<float>(mouse_position.y) - rectangle.getPosition().y - (rectangle_y / 2); // Obliczenie różnicy pozycji igrekowych kursora i kwadratu
            z = sqrtf(x * x + y * y); // Obliczenie odległości pomiędzy kursorem i kwadratem za pomocą twierdzenia Pitagorasa
            velocity.x = (x * velocity_value) / z; // Obliczenie składowej iksowej wektora prędkości za pomocą własności podobieństwa trójkątów
            velocity.y = (y * velocity_value) / z; // Obliczenie składowej igrekowej wektora prędkości za pomocą własności podobieństwa trójkątów

            rectangle.move(velocity.x * time.asSeconds(), velocity.y * time.asSeconds()); // Przesunięcie kwadratu o podany wektor prędkości
        }
        window.clear(); // Czyszczenie ekranu
        window.draw(rectangle); // Narysowanie kwadratu
        window.display(); // Wyświetlenie wszystkiego na ekranie

        time = clock.getElapsedTime(); // Nadanie zmiennej czasowej nowej wartości
        clock.restart(); // Restart zegara (mierzy czas od nowa/od zera)
    }
    return 0;
}

Kolejny raz piszę program "na zamówienie", ale dzięki temu umiem zrobić coś takiego (sam myślałem nad tym chwilę). Więc wilk syty i owca cała smiley

komentarz 27 września 2015 przez Avernis Nałogowiec (27,400 p.)
ok, szczęście że jestem anonimowy xD
komentarz 27 września 2015 przez Patrycjerz Mędrzec (192,320 p.)
Szczęście szczęściem, ale praktycznie podałem ci rozwiązanie na tacy, a jakieś modyfikacje możesz robić przecież sam, bo nie są trudne.
komentarz 27 września 2015 przez niezalogowany
@Patrycjerz - ale to po co jest obiekt czasu, sf::Time? Potem, przesuwając obiekt, mnoży się czas w sekundach przez odległość od kwadratu do punktu kliknięcia, ale niezbyt rozumiem po co to O_o
komentarz 27 września 2015 przez Patrycjerz Mędrzec (192,320 p.)

Obiekt sf::Time jest po to potrzebny, aby przetrzymywać czas, bo zegar może być jeden, a czasów trochę więcej. Także dla metody asSeconds.

Z tym mnożeniem się nieco pomyliłeś. Mnoży się czas w sekundach i długość wektora prędkości (może być on jaki chcesz, nawet większy, niż odległość pomiędzy kwadratem i położeniem kursora, tylko wtedy kwadrat będzie ci "zapierniczać", aż miło laugh). Jak już mówiłem, długość wektora prędkości to przesunięcie obiektu w czasie jednej jednostki czasu (dla 10 px/s, po sekundzie obiekt przesunie się o 10 pikseli, w 2,5 sekundy o 25 pikseli, czyli o 2,5 wektora). Po prostu wektor to wartość i także kierunek. Nie ma tu niczego trudnego, mówię ci. Wektory są banalne, wystarczy chwilę z nimi popracować.

Zapomniałem dodać, że długość wektora prędkości w moim kodzie jest stała (masz tam const). Oczywiście możesz ją zmieniać, ale ja zrobiłem ją niezmienialną dla potrzeb przykładu.

komentarz 21 stycznia 2018 przez PsyLisek Użytkownik (570 p.)

@Patrycjerz

Trochę czasu minęło od twoich wypowiedzi, ale chciałbym Ci podziękować. O wiele ułatwiłeś mi pracę, a przy okazji wytłumaczyłeś po co jest potrzeby w pętlach w grze sf::Time.

0 głosów
odpowiedź 27 września 2015 przez Dorion300 Szeryf (90,250 p.)
Analizujesz gdzie jest myszka np. 34x53

I zmieniasz pozycję obiektu na 34x53
komentarz 27 września 2015 przez Avernis Nałogowiec (27,400 p.)
Ok, ale jak amienić na ą pozycję, wim jak zmienić np że się zmienia o 10 pikseli lub więcej/mniej ale nie wiem jak zmienić pozycje względem okna
0 głosów
odpowiedź 27 września 2015 przez niezalogowany

Nie jestem pewny do końca o co ci chodzi:

  1. Posługiwaniem się pozycją obiektów względem okna, a nie pulpitu, czyli (0,0) jest w lewym górnym rogu okna, a nie pulpitu (wtedy wystarczy użyć sf::Mouse::getPosition(window), gdzie window to obiekt sf::RenderWindow)
  2. Liczeniem pozycji wg dowolnego punktu na scenie.
komentarz 27 września 2015 przez Avernis Nałogowiec (27,400 p.)
chodzi o to że obiekt porusza się tam gdzie kliknołem myszką
komentarz 27 września 2015 przez niezalogowany

W takim razie twoje pytanie mnie zmyliło, to akurat jest proste. Po prostu musisz odjąć od pozycji myszy pozycję obiektu, który ma się ruszyć, następnie mnożysz otrzymany wektor przez prędkość jaką chcesz uzyskać i czas pomiędzy klatkami.

Vector2f mouse(sf::Mouse::getPosition(window));

RectangleShape obj; // <- załóżmy że to obiekt, który chcesz przesunąć
Vector2f objPos(obj.getPosition()); // <-pozycja obiektu do przesunięcia


obj.move( mouse - objPos * speed * delta);

Jeżeli obiekt ma się poruszać ze stałą prędkością (a nie jak teraz w przykładzie: bliżej do obiektu tym wolniej się porusza) to musisz go znormalizować.

Z tego co pamiętam to nie ma przeładowanych operatorów do Vector2f, więc musisz moje odjęcie wektrów rozbić na:

(mouse.x - objPos.x * speed * delta, ... )

 

Podobne pytania

0 głosów
3 odpowiedzi 550 wizyt
pytanie zadane 1 października 2015 w C i C++ przez Avernis Nałogowiec (27,400 p.)
+1 głos
1 odpowiedź 310 wizyt
pytanie zadane 27 września 2015 w C i C++ przez Avernis Nałogowiec (27,400 p.)
0 głosów
1 odpowiedź 105 wizyt
pytanie zadane 19 listopada 2015 w C i C++ przez sofnir Gaduła (4,690 p.)

92,536 zapytań

141,376 odpowiedzi

319,452 komentarzy

61,920 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...