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

[SFML] Gładki ruch spirte'a (postaci).

VPS Starter Arubacloud
0 głosów
851 wizyt
pytanie zadane 27 lutego 2017 w C i C++ przez R4leY Nowicjusz (180 p.)
Clock clock;
Time dt = clock.restart();
        //Poruszanie się postaci
        if (Keyboard::isKeyPressed(Keyboard::Left))  sprite1.move(-10,0 * dt.asSeconds());
        if (Keyboard::isKeyPressed(Keyboard::Right))  sprite1.move(10,0 * dt.asSeconds());
        if (Keyboard::isKeyPressed(Keyboard::Up))  sprite1.move(0,-10 * dt.asSeconds());
        if (Keyboard::isKeyPressed(Keyboard::Down))  sprite1.move(0,10 * dt.asSeconds());

 

Ruch postaci (sprite'a) jest taki "szarpany" co jakis czas zatrzymuje sie na 1 sec i potem wznawia ruch.

Chce uzyskac ten sam efekt tylko bez tego zatrzymywania sie. Jest ktos w stanie mi pomoc ?

komentarz 27 lutego 2017 przez draghan VIP (106,230 p.)
Umieściłeś za mało kodu. Na podstawie tych siedmiu linijek nie można wywnioskować, z czego wynika niepożądany efekt.
komentarz 27 lutego 2017 przez R4leY Nowicjusz (180 p.)
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace std;
using namespace sf;

int main()
{
    //Utworzenie okna + Ustawienie t³a
    RenderWindow oknoAplikacji( sf::VideoMode( 1920, 1080, 64 ), "TEST", Style::Fullscreen );

    oknoAplikacji.setMouseCursorVisible(false);
    View fixed = oknoAplikacji.getView();
    Texture tekstura;
    tekstura.loadFromFile( "box.jpg" );
    Sprite obrazek;
    obrazek.setTexture( tekstura );

    //Wyœwietlanie Tekstu
    Font font;
    if(!font.loadFromFile("Tribal_.ttf"))
    {return -2;}
    Text text;
    text.setFont(font);
    text.setString("Wiedzminska Muzyka");
    text.setCharacterSize(100);
    text.setColor(Color::Yellow);
    text.setPosition(200,50);
    Text text1;
    text1.setFont(font);
    text1.setString("PT.'Oczy Wiedzmina'");
    text1.setCharacterSize(100);
    text1.setColor(Color::Yellow);
    text1.setPosition(300,900);
    Texture texture1;
    texture1.loadFromFile("kursor2.png");
    texture1.setSmooth(true);
    Sprite sprite(texture1);
    Texture texture2;
    texture2.loadFromFile("test.png");
    Sprite sprite1(texture2);
    //oknoAplikacji.setFramerateLimit(60);
    Clock clock;

    while( oknoAplikacji.isOpen() )
    {
        Event zdarzenie;
        while( oknoAplikacji.pollEvent( zdarzenie ) )
        {
           if(zdarzenie.type == sf::Event::KeyPressed)
            {
                if(zdarzenie.key.code == sf::Keyboard::Escape)
                    oknoAplikacji.close();
            }
        }

        double dt = 0;

        while(dt <= (double)1/120)
        {
           dt+=clock.getElapsedTime().asSeconds();
        }
        clock.restart();


        //cout<<dt<<endl;


        //double dt = clock.restart().asSeconds();
        sf::Vector2f ds;
        double max_speed = 60;

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)) ds.y -= max_speed*dt;
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::S)) ds.y += max_speed*dt;
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::A)) ds.x -= max_speed*dt;
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::D)) ds.x += max_speed*dt;
        sprite1.move(ds);

        //Wyrzucenie wszytkiego do okna
        sprite.setPosition(Vector2f(Mouse::getPosition(oknoAplikacji)));
        //oknoAplikacji.clear( Color::Black );
        oknoAplikacji.setView(fixed);

        oknoAplikacji.draw( obrazek );
        oknoAplikacji.draw(text);
        oknoAplikacji.draw(text1);
        oknoAplikacji.draw(sprite1);
        oknoAplikacji.draw(sprite);
        oknoAplikacji.display();
    }
    return 0;
}

 

komentarz 27 lutego 2017 przez draghan VIP (106,230 p.)
No cóż... Jak to mawiają najstarsi admini - "u mnie działa"...

2 odpowiedzi

0 głosów
odpowiedź 27 lutego 2017 przez Caspariano Użytkownik (760 p.)

spróbuj sterowanie dać za pętle która zbiera eventy, też tak miałem i to pomogło.
 


while (window.pollEvent(event))
{
//jakieś eventy
}


 if (Keyboard::isKeyPressed(Keyboard::Left))  sprite1.move(-10,0 * dt.asSeconds());
 if (Keyboard::isKeyPressed(Keyboard::Right))  sprite1.move(10,0 * dt.asSeconds());
 if (Keyboard::isKeyPressed(Keyboard::Up))  sprite1.move(0,-10 * dt.asSeconds());
 if (Keyboard::isKeyPressed(Keyboard::Down))  sprite1.move(0,10 * dt.asSeconds());

komentarz 27 lutego 2017 przez niezalogowany
To nie jest przypadkiem wina deklaracji Clock clock; w pętli głównej?
komentarz 27 lutego 2017 przez Caspariano Użytkownik (760 p.)
Być może, jednak jak sobie klepałem jakiegoś snake'a w SFML'u to nie miałem deklaracji Clock'a w głównej pętli a pomimo wszystko występowało małe opóźnienie pomiędzy wciśnięciem klawisza a akcją.
Problem występował też wcześniej.
1.Miałem sprite postaci z animacją poruszania się,
2.po naciśnięciu klawisza odpalała się animacja poruszania się jednak zanim nastąpiło przemieszczenie obiektu minęła krótka chwila,
3.czyli można wywnioskować że pomimo iż główna pętla gry wykonała się już kilka razy(widać po animacji, a ona była sprzężona z instrukcją odpowiedzialną za ruch obiektu) to z niewiadomego powodu ruch następował dopiero po kilku iteracjach pętli głównej.
4.Czyli postać chodziła w miejscu przez moment. Nie udało mi się konkretnie ustalić przyczyny ale za każdym razem wyciągniecie sterowania za pętlę (window.pollEvent(event)) naprawiało problem.
komentarz 27 lutego 2017 przez niezalogowany
Już rozumiem! Nigdy nie miałem sterowania w pętli eventów. Więc nie mogłem wywnioskować, że tak mógł mieć R4leY. Na szybko sprawdziłem jedynie deklarację clocka przy jego sczytywaniu i było widać przeskoki. Tobie działało pewnie dlatego, że pomiędzy definicją clocka, a sczytaniem wartości była pętla eventów - więc był jakiś sensowny czas do zmierzenia. Nie mylę się?
komentarz 27 lutego 2017 przez R4leY Nowicjusz (180 p.)
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Audio/Music.hpp>
#include <SFML/System.hpp>
#include <SFML/Window/Keyboard.hpp>
using namespace sf;
int main()
{
    //Utworzenie okna + Ustawienie tła
    RenderWindow oknoAplikacji( sf::VideoMode( 1920, 1080, 64 ), "TEST", Style::Fullscreen);
    oknoAplikacji.setMouseCursorVisible(false);
    View fixed = oknoAplikacji.getView();
    Texture tekstura;
    tekstura.loadFromFile( "box.jpg" );
    Sprite obrazek;
    obrazek.setTexture( tekstura );
    //Puszczanie muzyki
 Music music;
if (!music.openFromFile("test.ogg"))
    {return -1;}

music.setVolume(100);
music.setLoop(true);
music.play();
//Wyświetlanie Tekstu
Font font;
    if(!font.loadFromFile("Tribal_.ttf"))
    {return -2;}
    Text text;
    text.setFont(font);
    text.setString("Wiedzminska Muzyka");
    text.setCharacterSize(100);
    text.setColor(Color::Yellow);
    text.setPosition(200,50);
    Text text1;
    text1.setFont(font);
    text1.setString("PT.'Oczy Wiedzmina'");
    text1.setCharacterSize(100);
    text1.setColor(Color::Yellow);
    text1.setPosition(300,900);
    Texture texture1;
    texture1.loadFromFile("kursor2.png");
    texture1.setSmooth(true);
    Sprite sprite(texture1);
    Texture texture2;
    texture2.loadFromFile("test.png");
    Sprite sprite1(texture2);
    oknoAplikacji.setFramerateLimit(60);
    Clock clock;
    while( oknoAplikacji.isOpen() )
    {
        Event zdarzenie;
        while( oknoAplikacji.pollEvent( zdarzenie ) )
        {
            if( zdarzenie.type == Event::Closed )
                 oknoAplikacji.close();
                 //Wyłączenie Aplikacji Escape'm
                 if(Keyboard::isKeyPressed(Keyboard::Escape))
        {
         oknoAplikacji.close();
        }
        }
        double dt = clock.restart().asSeconds();

        sf::Vector2f ds;
        double max_speed = 232;

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)) ds.y -= max_speed*dt;
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::S)) ds.y += max_speed*dt;
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::A)) ds.x -= max_speed*dt;
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::D)) ds.x += max_speed*dt;
        sprite1.move(ds);
        //Wyrzucenie wszytkiego do okna
        sprite.setPosition(static_cast<Vector2f>(Mouse::getPosition(oknoAplikacji)));
        oknoAplikacji.setView(fixed);
        oknoAplikacji.clear( Color::Black );
        oknoAplikacji.draw( obrazek );
        oknoAplikacji.draw(text);
        oknoAplikacji.draw(text1);
        oknoAplikacji.draw(sprite1);
        oknoAplikacji.draw(sprite);
        oknoAplikacji.display();
    }
    return 0;
}

komentarz 27 lutego 2017 przez R4leY Nowicjusz (180 p.)
Działa tak samo jak przed zmianami
komentarz 27 lutego 2017 przez niezalogowany

Przycisk Escape zrób normalnie (tzn zwykłe naciśniecie klawisza w pętli eventów):

            if(zdarzenie.type == sf::Event::KeyPressed)
            {
                if(zdarzenie.key.code == sf::Keyboard::Escape)
                    oknoAplikacji.close();
            }

 

komentarz 27 lutego 2017 przez R4leY Nowicjusz (180 p.)
To nic nie zmienia dalej podczas ruchu postacią "szarpie"
0 głosów
odpowiedź 27 lutego 2017 przez Pajdas Mądrala (5,930 p.)

Poniższy kod jest poprawionym kodem który umieściłeś w komentarzu po pytaniem:

#include <SFML/Graphics.hpp>
#include <iostream>
using namespace std;
using namespace sf;

int main()
{
    int speed = 30;
    RenderWindow oknoAplikacji( sf::VideoMode( 1920, 1080, 64 ), "TEST", Style::Fullscreen );

    oknoAplikacji.setMouseCursorVisible(false);
    View fixed = oknoAplikacji.getView();
    RectangleShape obrazek;
    obrazek.setSize(Vector2f(50,50));
    obrazek.setPosition(100,100);
    obrazek.setFillColor(sf::Color::White);
    Clock clock;

    while( oknoAplikacji.isOpen() )
    {
        Event zdarzenie;
        while( oknoAplikacji.pollEvent( zdarzenie ) )
        {
           if(zdarzenie.type == sf::Event::KeyPressed)
            {
                if(zdarzenie.key.code == sf::Keyboard::Escape)
                    oknoAplikacji.close();
            }
        }

        double dt = 0;

        while(dt <= (double)1/120)
        {
           dt+=clock.getElapsedTime().asSeconds();
        }
        clock.restart();

        double max_speed = 60;

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)) obrazek.move(0,-(dt*speed));
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::S)) obrazek.move(0,dt*speed);
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::A)) obrazek.move(-(dt*speed),0);
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::D)) obrazek.move(dt*speed,0);


        oknoAplikacji.draw( obrazek );
        oknoAplikacji.display();
    }
    return 0;
}

P.S. Nie czyściłem ekranu bo fajny efekt się tworzy :)

Podobne pytania

0 głosów
0 odpowiedzi 555 wizyt
0 głosów
1 odpowiedź 564 wizyt
pytanie zadane 9 lipca 2021 w JavaScript przez Zawoj11 Użytkownik (850 p.)
0 głosów
1 odpowiedź 210 wizyt
pytanie zadane 31 marca 2018 w C i C++ przez miedziakk Nowicjusz (120 p.)

93,013 zapytań

141,977 odpowiedzi

321,266 komentarzy

62,355 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

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...