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

NukeNoob

Frischling

  • »NukeNoob« ist der Autor dieses Themas

Beiträge: 48

Beruf: Student

  • Private Nachricht senden

1

22.11.2012, 21:31

[Erledigt] [SFML/Graphics] Fenster mit Sprites Füllen, Array

Hallo an Alle,
hab mich nach all dem anderen Kram jetzt mal damit beschäftigt, mal was richtig interaktives zusammen zu bauen. Was genau das ist, weiß ich noch nicht, aber ich brauche auf jeden Fall schonmal ein Spielfeld. Dies habe ich versucht mit einem 2-Dimensionalen Array anzulegen, und jedem besetzen Feld "true", sowie jedem freien Feld "false" zu zuweisen. Das klappt eigentlich auch schon ganz gut. Leider wird das Spielfeld nur in der Konsole so gezeichnet wie ich es erwartet habe, nicht aber im Fenster von SFML. Hier der Code:

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
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <SFML/Graphics.hpp>

 int main()
 {
 
    // Fenster erstellen
    sf::RenderWindow window(sf::VideoMode(240, 360), "SFML-Fenster");

    // Konstanten
    const int Breite = 10;
    const int Hoehe = 15;

    // Variablen
    int  x;
    int  y;
    bool nGame  [Breite][Hoehe];

    sf::Texture txBlockDef;
    if(!txBlockDef.loadFromFile("BlockDef.png"))
        return EXIT_FAILURE;
    sf::Sprite      sBlockDef(txBlockDef);

    sf::Vector2f    vBlockDef;

    sf::Texture txBlack;
    if(!txBlack.loadFromFile("Black.png"))
        return EXIT_FAILURE;
    sf::Sprite      sBlack(txBlack);

    // Spielfeld erstellen
    for (y=0; y<Hoehe; y++)
    {
        for(x=0; x<Breite; x++)
            {
                if((x == 0) || (x == 9) || (y == 14))                   // Ränder auf "true" setzen
                    nGame[x][y] = true;
                else
                    nGame[x][y] = false;
            }
    }

    // Spielfeld zeichnen
    for (y=0; y<Hoehe; y++)
    {
        for(x=0; x<Breite; x++)
            {
                if(nGame[x][y] == true)
                    {
                     window.draw(sBlockDef);                            // schwarzen Block mit weißem Rand als Abgrenzung
                     std::cout << "X";                              // in der Konsole "X" ausgeben
                    }
                else
                    {
                    window.draw(sBlack);                                // für später nutzbare Felder, schwarzen Block mit weißem Kreis in der Mitte 
                    std::cout << " ";                               // " " in der Konsole ausgeben
                    }

                vBlockDef.x += 24;                                  // Pro durchlauf die X-Pos um 24 Px erhöhen ( 24x24Px Block)
                sBlockDef.setPosition(vBlockDef.x, vBlockDef.y);        // Position setzen
                sBlack.setPosition(vBlockDef.x, vBlockDef.y);           //        ""
            }

        vBlockDef.y += 24;                                              // Das Gleiche mit der Y-Pos
        sBlockDef.setPosition(vBlockDef.x, vBlockDef.y);                //
        sBlack.setPosition(vBlockDef.x, vBlockDef.y);                   //
        std::cout << std:: endl;                                        // Neue Zeile in Konsole
    }
    

    // Programm solange laufen lassen, bis Fenster geschlossen wird
    while (window.isOpen())
    {

        sf::Event event;
        while (window.pollEvent(event))
        {
            switch(event.type)
                {
                    case (sf::Event::Closed):
                        window.close();
                        break;
                }
        }

        window.display();
   }

    return (0);
 }



LG
NukeNoob

EDIT: Komischerweise werden den Sprites im Fenster auch nicht immer dargestellt, d.h. das Bild im Fenster ist total am flackern.
»NukeNoob« hat folgendes Bild angehängt:
  • Problem.JPG

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »NukeNoob« (22.12.2012, 13:57)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

2

22.11.2012, 21:43

Wieso korrigierst du die Position beider Sprites in jedem Frame? Du kannst die Position doch erst dann anpassen wenn es wirklich nötig ist.
Dein Problem ist, dass du in der äußeren Schleife die vBlockDef.x Position nicht zurücksetzt.

An deiner Stelle hätte ich für jedes Tile ein eigenes Sprite, würde std::vector benutzen, mir die ungarische Notation abgewöhnen und Variablen wie x und y so spät wie möglich(in dem Fall also in den Schleifenköpfen) definieren.

edit: ganz übergesehen... Du musst in jedem Frame(= durchlauf der Hauptschleife) window.clear aufrufen, das Bild zeichnen und danach window.display aufrufen.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

NukeNoob

Frischling

  • »NukeNoob« ist der Autor dieses Themas

Beiträge: 48

Beruf: Student

  • Private Nachricht senden

3

22.11.2012, 21:53

Hallo NachMan,
danke, wie doof, es bringt ja wenig rechts aus dem Fenster heraus zu zeichnen. Das mit der Position verstehe ich noch nicht so genau. Ich muss diese doch nach Jedem mal setzen?
Die ungarische Notation, ja ... ist eigentlich unnötig, stimmt. X und Y in der for-Schleife erstellen, auch eine Möglichkeit. Nun zu dem Thema mit dem Flackern, wie meinst du das genau? So:

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
    // Spielfeld zeichnen
    for (y=0; y<Hoehe; y++)
    {
        for(x=0; x<Breite; x++)
            {
                if(nGame[x][y] == true)
                    {
                     window.clear();
                     window.draw(sBlockDef);                            // schwarzen Block mit weißem Rand als Abgrenzung
                     window.display();
                     std::cout << "X";                                  // in der Konsole "X" ausgeben
                    }
                else if (nGame[x][y] == false)
                    {
                    window.clear();
                    window.draw(sBlack);                                // für später nutzbare Felder, schwarzen Block mit weißem Kreis in der Mitte 
                    window.display();
                    std::cout << " ";                                   // " " in der Konsole ausgeben
                    }

                vBlockDef.x += 24;                                      // Pro durchlauf die X-Pos um 24 Px erhöhen (ein Block ist 24x24 Px groß)
                sBlockDef.setPosition(vBlockDef.x, vBlockDef.y);        // Position setzen
                sBlack.setPosition(vBlockDef.x, vBlockDef.y);           //        ""
            }

        vBlockDef.y += 24;                                              // Das Gleiche mit der Y-Pos
        vBlockDef.x = 0;                            
        sBlockDef.setPosition(vBlockDef.x, vBlockDef.y);                //
        sBlack.setPosition(vBlockDef.x, vBlockDef.y);                   //
        std::cout << std:: endl;                                        // Neue Zeile in Konsole
    }



Danke nochmal!
LG

EDIT: So macht es garkeinen Sinn, wieder zu wenig nachgedacht. Könntest du mir trotzdem erklären wie du es meintest?

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

4

22.11.2012, 21:57

Nein, clear und display dürfen nur jeweils einmal in der Hauptschleife aufgerufen werden.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

NukeNoob

Frischling

  • »NukeNoob« ist der Autor dieses Themas

Beiträge: 48

Beruf: Student

  • Private Nachricht senden

5

22.11.2012, 22:09

Alles klar, danke.

Werbeanzeige