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

21.10.2012, 11:17

[SFML2] Map aus Klasse wird nicht gezeichnet

Hiho.

Habe mir eine Klasse geschrieben, die eine Tilemap aus einer Datei lesen soll und dann in eine RenderTexture zeichnen soll.
Das Laden klappt prima, aber er zeigt mir einfach keine Bilder an. Nichtmal eine fehlende Textur.
Hab alles von mehreren Personen durchschauen lassen, aber niemand konnte helfen.
Hoffe einer von euch erkennt einen Fehler.

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Map
{
    protected:
        int map_x, map_y;
        static int tile;
        int map[100][100];

    public:

        Map()
        {
            map_x = 0;
            map_y = 0;
        };
        ~Map(){};

        void LoadMap(const char *filename)
        {
            int loadCounterX = 0, loadCounterY = 0;
            std::ifstream file(filename);
            if(file.is_open())
            {
                file >> map_x >> map_y;
                while(!file.eof())
                {
                    file >> map[loadCounterX][loadCounterY];
                    loadCounterX++;
                    if(loadCounterX >= map_x)
                    {
                        loadCounterX = 0;
                        loadCounterY++;
                    }
                }
            }
        }

        void DrawMap(sf::RenderTexture &rMap, sf::RenderWindow &Spiel)
        {
            sf::Image image;
            sf::Texture textur;     

            image.loadFromFile("graphics/boden.png");
            if(!image.loadFromFile("graphics/boden.png"))
            {
                std::cout << "boden.png konnte nicht geladen werden!\n";
            }
            textur.loadFromImage(image);

            for(int i = 0; i < map_x; i++)
            {
                for(int j = 0; j < map_y; j++)
                {
                    sf::Sprite sprite;
                    sprite.setTexture(textur);
                    if(map[i][j] >= 0)
                    {
                        sprite.setTextureRect(sf::IntRect(map[i][j]*32, 0, 32, 32));
                        sprite.move(i, j);
                    }

                    rMap.draw(sprite);
                }
            }

            sf::Sprite sMap(rMap.getTexture()); // Karte laden
            Spiel.draw(sMap); // Karte zeichnen
        }
};


MfG

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

21.10.2012, 11:39

Deine Renderfunktion macht viel mehr als sie sollte. Sie läd die Texture, weißt diese zu und und und. Eigentlich sollte das in einer anderen Methode passieren und hier sollte nur gezeichnet werden.
Und man möge mich steinigen, aber sollten die Streamoperatoren nicht eigentlich die anderen sein? "<<" statt ">>"? Da bin ich mir nicht sicher weil ich ewig kein C++ mehr benutzt hab, aber check mal ob in der Map wirklich Daten drin stehen nach dem laden.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

3

21.10.2012, 11:45

Habe es schon an mehreren Stellen durchgecheckt, in dem Array map stehen die richtigen Zahlen.
Genauso wie in map_x und map_y.

Nein, ">>" ist schon richtig, hätte ja sonst wahrscheinlich auch eine Fehlermeldung ausgegeben und die richtigen Werte würden nicht drin stehen.

4

21.10.2012, 11:47

Und man möge mich steinigen, aber sollten die Streamoperatoren nicht eigentlich die anderen sein? "<<" statt ">>"? Da bin ich mir nicht sicher weil ich ewig kein C++ mehr benutzt hab, aber check mal ob in der Map wirklich Daten drin stehen nach dem laden.





Dieser Operator stimmt schon, weil man vom Filehandle aus die Integer überlädt. Wenn der Operator anders wäre, dann würde das bei einem Input-Filehandle gar nicht funktionieren, sondern nur bei einem Output-Filehandle, da würde man in den Datei reinschreiben.

Edit: Wie Schorsch schon erwähnt hat, solltest du die Textur nicht in der Draw-Funktion laden, usw.

FSA

Community-Fossil

  • Private Nachricht senden

5

21.10.2012, 11:49

Streamoperatoren stimmen.
@Kaev: Du weißt das du in jedem Frame die Texturen neu lädst?
EDIT: Da war jemand schneller

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

6

21.10.2012, 11:54

Ja, dass ich die Textur immer neu lade ist mir nun bewusst und ich werds gleich ändern.
Aber das ist nicht der Grund, warum nichts angezeigt wird, oder?

EDIT: Nein, ist es nicht. Habs nun in den Standardkonstruktor gepackt.

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

7

21.10.2012, 13:31

Du hast auch ganz sicher irgendwo ein Spiel.display()?
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

8

21.10.2012, 13:36

Und du rufst die Draw-Methode auch auf?

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

9

21.10.2012, 16:12

Zeig mal etwas mehr Code. Die überarbeitete Version der Klasse und die Stelle an der es aufgerufen wird wäre wichtig.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

10

21.10.2012, 17:24

Natürlich habe ich Spiel.display() in meinem Code und die Drawmethode aufgerufen. :P

map.cpp:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <fstream>
#include <SFML/Graphics.hpp>

using namespace std;

class Map
{
    protected:
        int map_x, map_y;
        static int tile;
        int map[100][100];
        sf::Image image;
        sf::Texture textur; 

    public:

        Map()
        {
            map_x = 0;
            map_y = 0;

            image.loadFromFile("graphics/boden.png");
            if(!image.loadFromFile("graphics/boden.png"))
            {
                std::cout << "boden.png konnte nicht geladen werden!\n";
            }
            textur.loadFromImage(image);
        };

        ~Map(){};

        static int getTile()
        {
            return 32; // 1 Tile = 32 Pixel
        }

        void LoadMap(const char *filename)
        {
            int loadCounterX = 0, loadCounterY = 0;
            std::ifstream file(filename);
            if(file.is_open())
            {
                file >> map_x >> map_y;
                while(!file.eof())
                {
                    file >> map[loadCounterX][loadCounterY];
                    loadCounterX++;
                    if(loadCounterX >= map_x)
                    {
                        loadCounterX = 0;
                        loadCounterY++;
                    }
                }
            }
        }

        void DrawMap(sf::RenderTexture &rMap, sf::RenderWindow &Spiel)
        {
            for(int i = 0; i < map_x; i++)
            {
                for(int j = 0; j < map_y; j++)
                {
                    sf::Sprite sprite;
                    sprite.setTexture(textur);
                    if(map[i][j] >= 0)
                    {
                        sprite.setTextureRect(sf::IntRect(map[i][j]*32, 0, 32, 32));
                        sprite.move(i, j);
                    }
                    rMap.draw(sprite);
                }
            }

            sf::Sprite sMap(rMap.getTexture()); // Karte laden
            Spiel.draw(sMap); // Karte zeichnen
        }
};


Sehr stark gekürzte main.cpp (unwichtiges is so ziemlich alles weggelassen):

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
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <fstream>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <vector>
#include <sstream>
#include "map.cpp"
#include "player.cpp"

int main(){
    
    //Fenster erstellen, Titel: "Spiel", Auflösung 800x600, Farbtiefe 32 Bit
    sf::RenderWindow Spiel(sf::VideoMode(800, 608, 32), "Spiel", sf::Style::Close);
    
    //Synchronisation mit dem Monitor (60 FPS) - Anschalten
    Spiel.setVerticalSyncEnabled(true);

    Player Hero;

    sf::RenderTexture map;

    Map map1;
    map1.LoadMap("map1.txt");

    // Inhalt löschen (Bildschirm schwarz füllen)
    Spiel.clear();

    map1.DrawMap(map, Spiel);
    // Sprites, Kameras, Texte usw darstellen
    Spiel.draw(Hero.getSprite()); // Helden zeichnen

    // Bild aktualisieren
    Spiel.display();
    }

    return EXIT_SUCCESS;
}


Der Held wird auch angezeigt und ich kann rumlaufen, nur die Map fehlt.

Werbeanzeige