Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

15.04.2011, 11:43

SFML: FPS Rate sehr Niedrig beim Zeichnen meiner 2D Welt

Hallo zusammen,
ich hab folgendes Problem und zwar Zeichne ich mit SFML eine 2D Welt von der Größe 20 * 20 die einzelnen Sprites sind jeweils 64*32 groß. Wenn ich alleine nur die Wiese Zeichne, fällt die Framerate von knappe 400-500 auf unter 30FPS. Jetzt Zeichne ich jedoch noch 3 kleine Bäume zum Testen hinzu und meine FPS zahl sinkt auf unter 20.

Mein Map System habe ich wie folgt aufgebaut.
Zunächst lade ich mit Hilfe meiner Tile klasse alle Tiles in einen vector.
Nun wenn ich meine Map in meiner CMap Klasse Zeichne durchsuche ich jeweils den Vector nach dem Tile was gerade gezeichnet werden soll. Und jetzt beim Zeichnen fällt die FPS Zahl sehr stark ab.

Hier ist einmal mein Code der CTile.cpp welche den Container nach dem Sprite durchsucht.


(Link)


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
void CTile::LoadSprite(unsigned int id, std::string name, std::string type) {
    // Gesammten vector durchsuchen
    for(std::vector<sTile>::iterator m_iterator_tile = m_vector_tiles.begin(); m_iterator_tile != m_vector_tiles.end(); m_iterator_tile++) {
        // Finde Sprite mit folgenden Eigenschaften
        if( ( m_iterator_tile->m_uint_id == id ) && ( m_iterator_tile->m_string_Name == name ) &&  ( m_iterator_tile->m_string_type == type ) ) {
            // Strukt füllen
            Tile = (*m_iterator_tile);
        }
    }
};


Und hier ist der Code wie ich dann mit dieser Load Funktion meine Map Zeichen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    m_ctile_tiles.LoadSprite(1, "wiese", "ground");

    for(int x = 0; x<=m_uint_Width; x++) {
        for(int y = 0; y<=m_uint_Height; y++) {
            float size_x = m_ctile_tiles.GetSprite().GetSize().x;
            float size_y = m_ctile_tiles.GetSprite().GetSize().y;
            
            m_vector2_pos.x = ( m_uint_WinWidth / 2 - size_x / 2) - y * size_x / 2 + x * size_x / 2;
            m_vector2_pos.y = ( m_uint_WinHeight / 4 - size_y / 2*5) + y * size_y / 2 + x * size_y / 2;
            
            m_ctile_tiles.SetPosition(m_vector2_pos);
            game->Window.Draw(m_ctile_tiles.GetSprite());
        }
    }
    
    m_ctile_tiles.LoadSprite(3, "baum6", "ground");
    m_ctile_tiles.SetPosition(sf::Vector2f(400.f, -100.f));
    game->Window.Draw(m_ctile_tiles.GetSprite());

    m_ctile_tiles.LoadSprite(3, "baum6", "ground");
    m_ctile_tiles.SetPosition(sf::Vector2f(300.f, 100.f));
    game->Window.Draw(m_ctile_tiles.GetSprite());

    m_ctile_tiles.LoadSprite(2, "baum", "ground");
    m_ctile_tiles.SetPosition(sf::Vector2f(50.f, 0.f));
    game->Window.Draw(m_ctile_tiles.GetSprite());


Vielen Dank Schonmal für eure Hilfe.

Schöne Grüße
Nero_S

EDIT: So jetzt bin ich grad auf SFML-2 umgestiegen und dadurch ist die FPS zahl von 20 auf ca. 30-40 gestiegen. Könnt ihr mir irgend ein Vorschlag zur Code Verbesserung geben? Denn 30-40FPS bei den paar tiles ist ja noch recht gering.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Nero_S« (15.04.2011, 13:47)


2

15.04.2011, 13:53

Hm, also einen Vektor per Schleife zu durchlaufen ist immer etwas ungünstig. Entweder eine Liste nehmen und die durchlaufen (ist schneller als beim Vektor) oder aber einen Vektor nehmen und direkt über den Index auf das entsprechende Element zugreifen, denn das ist ja der Vorteil des Vektors.

Gruß
SaRu_

3

15.04.2011, 14:16

Für die Images könntest du dir nen kleinen Manager schreiben. Jedes Tile hat dann eben so seine Eigenschaften die du brauchst und ein sf::Sprite.
Beim erstellen der Map setzt du dann einfach das entsprechende Image. Beim zeichnen musst du den Vector setzt einfach schnell durchlaufen, prüfen ob es im Sichtbereich liegt und dann ggf. zeichnen. Das suchen kannst du dir sparen, das wird wohl auch dein Performance Problem lösen.

lg chaia

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

4

15.04.2011, 17:29

In jedem Frame die Bilder laden ist schon semantisch eigentlich keine gute Idee. Das laden ist ja etwas, dass man am Anfang tun sollte und danach hast du die Bilder geladen und kannst sie verwenden. Ansonsten könnte es ja sein, dass irgendwann ein Bild nicht gefunden wird, weil es noch nicht geladen wurde aber es z.B vom User umbenannt wurde. Und so etwas zur Laufzeit festzustellen ist keine gute Idee. Entweder du hast alle Ressourcen oder nicht (nat. mit Ausnahmen für gewisse Sachen) und das ist etwas, was am Anfang geschehen sollte.

Und wenn du einen solchen Lookup hast, dann eher mit einer Art map (z.B std::map), damit das finden in konstanter Zeit und nicht in linearer Zeit geschieht.

5

15.04.2011, 17:45

Ja vielen Dank :) Das hat mir sehr geholfen, nun lade ich alle direkt am Anfang. Und die Render Funtkion macht jetzt nur noch das wofür Sie auch gedacht ist, zum Zeichnen und nicht zum Suchen :)

Danke euch allen.

Werbeanzeige