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

C0dR

Frischling

  • »C0dR« ist der Autor dieses Themas
  • Private Nachricht senden

1

24.02.2013, 00:09

Fog of war mit tile basierter Map

Hallo,

ich muss zur Zeit ein 2D Dungeon Spiel für die Uni programmieren und komme beim Fog of war nicht weiter. Programmiert habe ich mit SDL und OpenGL.
Meine map basiert auf tmx (tiles basierte map) und wird mit tmx-parser geladen. Folgendermaßen rendere ich die Map:

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
void Map::RenderBackground()
    {
        if(!m_BackgroundLayer) return;
        for (int x = 0; x < m_BackgroundLayer->GetWidth(); ++x) 
        {
            for (int y = 0; y < m_BackgroundLayer->GetHeight(); ++y) 
            {
                int CurTile = m_BackgroundLayer->GetTileId(x, (m_BackgroundLayer->GetHeight()-y)-1);

                if(CurTile == 0)
                {
                    continue;
                }

                int tileset_col = (CurTile % m_NumCols);
                int tileset_row = (CurTile / m_NumCols);

                int drawX = x * (m_Tileset->GetTileWidth());
                int drawY = y * (m_Tileset->GetTileHeight());

                Rectangle rect_CurTile;
                rect_CurTile.left = (GLfloat)(m_Tileset->GetSpacing() + (m_TileTotalWidth * tileset_col));
                rect_CurTile.bottom =  (GLfloat)(m_Tileset->GetImage()->GetHeight() - (m_Tileset->GetMargin() + (m_TileTotalHeight * tileset_row)));
                rect_CurTile.right = (GLfloat)(rect_CurTile.left + m_Tileset->GetTileWidth());
                rect_CurTile.top = (GLfloat)(rect_CurTile.bottom - m_Tileset->GetTileHeight());

                rect_CurTile.left /= m_Tileset->GetImage()->GetWidth();
                rect_CurTile.top /= m_Tileset->GetImage()->GetHeight();
                rect_CurTile.right /= m_Tileset->GetImage()->GetWidth();
                rect_CurTile.bottom /= m_Tileset->GetImage()->GetHeight();

                m_TilesetTexture->RenderSection(drawX*m_Scale,drawY*m_Scale,&rect_CurTile,m_Scale,m_Scale);
            }
        }}


RenderSection sieht so aus:

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
void Texture::RenderSection(GLfloat x, GLfloat y, Rectangle* _rect, GLfloat scaleX /* = 1 */, GLfloat scaleY /* = 1 */, GLfloat _rotation /* = 0 */, GLfloat _red /* = 1 */, GLfloat _green /* = 1 */, GLfloat _blue /* = 1 */, GLfloat _alpha /* = 1 */)
    {
        glPushMatrix();

        //bind texture
        glBindTexture(GL_TEXTURE_2D, m_Texture);

        glTranslatef(x,  y, 0.0f);
        if(Rotation != 0)
        {
            GLfloat x, y;
            x = ((rect->right - rect->left)/2)   * m_Width;
            y = ((rect->top   - rect->bottom)/2) * m_Height;

            glTranslatef(x ,y, 0.0f);
            glRotatef(Rotation,0.0f,0.0f,1.0f);
            glTranslatef(-x ,-y, 0.0f);
        }
    glScalef(scaleX, scaleY, 0);
        //width for drawing
        int32 box_width = ceil(m_Width * (_rect->right - _rect->left));
        int32 box_height = ceil(m_Height * ( _rect->bottom - _rect->top ));

        GLfloat box_top = 1.0f - _rect->top;
        GLfloat box_bottom  = 1.0f - _rect->bottom;

        //draw the quad
        glBegin(GL_QUADS);
        //bottom-left vertex (corner)
        glColor4f(_red, _green, _blue, _alpha);
        glTexCoord2f(_rect->left, box_top);
        glVertex2f(0, 0);

        //bottom-right vertex (corner) 
        glTexCoord2f(_rect->right , box_top);
        glVertex2f((GLfloat)box_width, 0);

        //top-right vertex (corner)  
        glTexCoord2f(_rect->right , box_bottom);
        glVertex2f((GLfloat)box_width, (GLfloat)box_height);

        //top-left vertex (corner) 
        glTexCoord2f(_rect->left , box_bottom);
        glVertex2f(0, (GLfloat)box_height);

        glEnd();

        //reset the color
        glColor3f(1.0f, 1.0f, 1.0f);

        glPopMatrix();
    }



Ich weist nun einfach nicht wie ich am besten ein Fog of War erstellen soll. Im Idealfall ist er pixelbasiert. Falls das doch (bei meiner Rendermethode :crazy: ) zu kompliziert ist, wäre ein Tiles basiertes Fog of War auch ok. Könnte mir einer erklären wie ich das am besten bewerkstellige?
Achja, die Map scrollt, und die Kamera ist immer zentriert zum Spieler, falls das relevant ist.

gruß
C0dR

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

24.02.2013, 00:47

Du renderst die Welt erst mal normal. Beim rendern der Einheiten darfst du jetzt halt nur die rendern, welche auch im Sichtbereich sind. Das kannst du ja über den Abstand prüfen. Willst du den Nebel jetzt noch irgendwie darstellen, so könntest du in einem letzten Schritt einen Layer über das Ergebnis legen. Du nimmst im Prinzip einfach eine leicht transparente Grafik und renderst die über deine Ausgabe. Die Stellen die nicht vom Nebel beeinflusst werden werden natürlich freigelassen. Diese Grafik könntest du zum Beispiel zur Laufzeit bestimmen. Wenn der Fog pro Tile wäre, könntest du auch über die im Nebel liegenden Tiles eine Grafik rendern. Diese müsste dann natürlich die passende Größe haben. Das wäre mein spontaner Einfall.
„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.“

C0dR

Frischling

  • »C0dR« ist der Autor dieses Themas
  • Private Nachricht senden

3

24.02.2013, 01:57

Hast mich auf die richtige Idee gebracht. Danke!
Hab es jetzt tilebasiert gemacht, war doch am einfachsten. Hab nen 2D bool array genommen und schreib da rein ob ein tile sichtbar ist. Wenn es nicht sichtbar ist, render ich es nicht
So muss ich mich nicht mit alphatexturen o.ä. rumschlagen. Hab ja leider nur begrenzt Zeit für die Studienaufgabe :dash:

Werbeanzeige