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

[SFML] Ruch obiektu - podstawa

Ostatnio zmodyfikowano 2017-01-03 21:38
Autor Wiadomość
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

C/C++
#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.
P-155352
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ż
Frazy, które należy wpisać w wyszukiwarkę google:

ż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
C/C++
Clock clock;
float dt = 0;
Event event;

bool pause = false;
float timeMultiplier = 1.f;

while( gameWindow.isOpen() )
{
    if( gameWindow.pollEvent( event ) )
    {
        // "close requested" event: we close the window
        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;
    }
   
    //logic
    mainObject.update( dt );
   
    clock.restart();
   
    gameWindow.clear( Color::Black );
   
    //draw
    gameWindow.draw( mainObject );
   
    gameWindow.display();
}
P-155355
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
C/C++
#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; //liczby również dawałem
    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 ...
P-155373
michal11
» 2016-12-24 15:31:52
Wywołaj
shape.setPosition()
 przed window.clear
P-155374
wokub
Temat założony przez niniejszego użytkownika
» 2016-12-24 15:37:07
C/C++
#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; //liczby również dawałem
    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.
P-155375
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.
P-155925
« 1 »
  Strona 1 z 1