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

SFML - symulacja deszczu

Cloud VPS
0 głosów
483 wizyt
pytanie zadane 1 kwietnia 2019 w C i C++ przez Milo Obywatel (1,180 p.)

Hej, chciałbym poprosić was o subiektywną ocenę mojego projektu w c++, w SFML. Nie pokoi mnie jedna rzecz. Jakby się tak przyjrzeć każdej kropli, to podczas spadania, w pewnym momencie lekko cofa się do góry. Kod wklejam tutaj, bo nie jest długi, ~60 linijek.

#include <SFML/Graphics.hpp>
#include <windows.h>
#include <vector>

using namespace sf;
using namespace std;

class rain : public RectangleShape
{
public:
    float speed; // zmienna przechowujaca predkosc kropli
    rain (float x, float y) : RectangleShape (Vector2f(x, y)) {};
};
vector <rain> RainVector;
RenderWindow window;

int main ()
{
    srand (time(NULL));

    window.create (VideoMode(960, 540), "Rain in SMFL", Style::Titlebar | Style::Close);
    window.setActive (true);
    window.setVerticalSyncEnabled (true);

    Event e;
    while (window.isOpen())
    {
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed || Keyboard::isKeyPressed(Keyboard::Escape)) window.close ();
        }

        /// generowanie 4 nowych kropli na jedna klatke
        for (int i = 0; i < 4; i++)
        {
            RainVector.push_back(rain(2, 20));
            RainVector.back().setFillColor(Color::Blue);
            RainVector.back().setOrigin(0, 0);
            RainVector.back().setPosition(rand()%959, -20);
            RainVector.back().speed = rand()%10+4; // ustawienie losowej predkosci
        }

        /// zrzucenie kazdej kropli
        for (int i = 0; i < RainVector.size(); i++)
        {
            int x, y; // pozycja kropli
            int v; // szybkosc kropli
            x = RainVector[i].getPosition().x;
            y = RainVector[i].getPosition().y;
            v = RainVector[i].speed;
            if (y > 540) RainVector.erase(RainVector.begin()+i); // sprawdzenie czy kropla nie wyszla poza okno
            else
            {
                RainVector[i].speed += 0.10; // przespieszenie spadania deszczu
                RainVector[i].setPosition(x, y+v); // zrzucenie kropli
            }
        }

        window.clear (Color::White);
        /// rysowanie deszczu
        for (int i = 0; i < RainVector.size(); i++)
        {
            window.draw (RainVector[i]);
        }
        window.display();
    }
}

 

1 odpowiedź

+2 głosów
odpowiedź 1 kwietnia 2019 przez niezalogowany
wybrane 1 kwietnia 2019 przez Milo
 
Najlepsza
  1. Nie stosuj globalnych zmiennych
  2. Nie używaj 'using namespace'
  3. Do losowania używaj <random>
  4. Co to za magiczne wartości:
    RainVector.back().setPosition(rand() % 959, -20); // window.getSize().x - 1
    if (y > 540) // window.getSize().y
  5. Brak obsługi czasu. Na różnych komputerach deszcz będzie padał wolniej/szybciej.
  6. Zamiast rain::setPosition możesz użyć rain::move
  7. Można zauważyć, że krople czasami wykonują znaczne skoki. Przyczyna: W momencie gdy usuwasz z vectora obiekt powinieneś zdekrementować i:
    if (y > 540) { 
    	RainVector.erase(RainVector.begin() + i); 
    	--i;
    }
  8. Nie powinieneś nic usuwać z vectora jest to strasznie wolne (za wyjątkiem usuwania ostatniego elementu). Gdy kropla wyjdzie poza ekran przesuń ją na pozycję startową i nadaj nową prędkość.
  9. Możesz używać range-based for z C++11
    /*for (int i = 0; i < RainVector.size(); i++)
    {
    	window.draw(RainVector[i]);
    }*/
    
    for (auto& drop: RainVector) {
    	window.draw(drop);
    }
    
  10. Czemu int, a nie float:
    int x, y; // pozycja kropli
    int v; // szybkosc kropli
komentarz 1 kwietnia 2019 przez niezalogowany

A jeżeli mam w ustawieniach kompilatora zaznaczone C++14, to to też ma jakieś 'bajery'? 

Można to tak ująć :D

Gdzie mogę znaleźć lekcje związaną z plikiem nagłówkowym <random>? Chodzi mi o stronę.

https://diego.assencio.com/?index=6890b8c50169ef45b74db135063c227c

https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution

https://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution

https://en.cppreference.com/w/cpp/numeric/random

https://dsp.krzaq.cc/post/180/nie-uzywaj-rand-cxx-ma-random/

komentarz 1 kwietnia 2019 przez Milo Obywatel (1,180 p.)

Chyba dzisiaj z linków skorzystać nie zdążę, ale naprawdę dziękuje ci za poświęcony dla mnie czas .smiley

komentarz 1 kwietnia 2019 przez Ehlert Ekspert (215,050 p.)

Najprostszym rozwiązaniem byłoby ustawienie dla sf::RenderWindow stałego limitu klatek

IMO to nic nie da, szczególnie na słabszym sprzęcie. winkNajlepszym rozwiązaniem byłaby pętla stałokrokowa która aktualizowałaby całą logikę np 30 razy na sekundę. Ale to chyba nie ten etap żeby tym mieszać laugh

komentarz 2 kwietnia 2019 przez niezalogowany
@Ehlert mógłbyś wyjaśnić czemu to nic nie da? :)
komentarz 2 kwietnia 2019 przez Ehlert Ekspert (215,050 p.)
Bo mimo stałego limitu klatek, to nie każdy komputer go wyrobi. Jeśli masz prędkość 20px/f i poruszasz obiekt per klatkę to inaczej będzie zasuwać przy 60fps a inaczej przy 20fps.

Podobne pytania

+1 głos
2 odpowiedzi 532 wizyt
pytanie zadane 20 marca 2017 w Nasze projekty przez QizmoPL Stary wyjadacz (11,440 p.)
+1 głos
2 odpowiedzi 297 wizyt
pytanie zadane 31 grudnia 2016 w C i C++ przez Patryk Krajewski Nałogowiec (26,170 p.)
0 głosów
2 odpowiedzi 492 wizyt
pytanie zadane 5 kwietnia 2016 w C i C++ przez Patryk Krajewski Nałogowiec (26,170 p.)

93,459 zapytań

142,454 odpowiedzi

322,724 komentarzy

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

Kursy INF.02 i INF.03
...