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

SFML - symulacja deszczu

VPS Starter Arubacloud
0 głosów
291 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 (212,630 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 (212,630 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 285 wizyt
pytanie zadane 20 marca 2017 w Nasze projekty przez QizmoPL Stary wyjadacz (11,440 p.)
+1 głos
2 odpowiedzi 259 wizyt
pytanie zadane 31 grudnia 2016 w C i C++ przez Patryk Krajewski Nałogowiec (26,170 p.)
0 głosów
2 odpowiedzi 421 wizyt
pytanie zadane 5 kwietnia 2016 w C i C++ przez Patryk Krajewski Nałogowiec (26,170 p.)

92,454 zapytań

141,262 odpowiedzi

319,089 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...