• 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).

Object Storage Arubacloud
0 głosów
649 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 449 wizyt
0 głosów
1 odpowiedź 418 wizyt
pytanie zadane 9 lipca 2021 w JavaScript przez Zawoj11 Użytkownik (850 p.)
0 głosów
1 odpowiedź 191 wizyt
pytanie zadane 31 marca 2018 w C i C++ przez miedziakk Nowicjusz (120 p.)

92,551 zapytań

141,393 odpowiedzi

319,523 komentarzy

61,936 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!

...