Schleiher bzw Nebel - benötige Denkanstoß



  • Ich programmier momentan so just for fun ein kleine 2D-Strategiespiel. Jetzt brauch ich mal einen Denkanstoß von euch, ich hab einfach keine Idee wie ich folgendes realisieren kann:
    Wie in fast allen Strategiespielen soll die gesamte Karte natürlich nicht auf einmal aufgedeckt sein. Dazu gibt es ja meist 2 "Nebel". Einmal komplett schwarz (die Gegend die der Spieler noch gar nicht erkundet hat ) und einfach so eine Art grauen Schleier ( die Gegend, in dem der Spieler von einmal war, aber die momentan nicht sichtbar ist ). Auch genannt "Nebel des Krieges" glaub ich.

    Jedenfalls frag ich mich jetzt wie man so etwas einbauen soll. Wie speichere ich ab wo der Spieler schon war. Die Stellen sind ja "rund". Somit relativ viele Punkte. Und wie zeichne ich den Nebel? Direkt als Bildpunkte oder als Grafik?
    Ich hab wirklich keine Ahnung. Gefunden zu dem Thema hab ich leider auch nichts. Bin für jede Hilfe dankbar!



  • Wie ist denn deine Karte aufgebaut?

    Wenn sie relativ einfach wie ein Schachbrett aufgebaut ist, also im Grunde ein zweidimensionales Array wie Map[128][128], dann kannst du ja einfach für jedes Feld abspeichern, welcher Spieler das schon gesehen hat.

    Was verwendest du? SDL? OpenGL? Du kannst für den Nebel ja einfach eine graue Textur nehmen, und an den Rändern lässt du ihn etwas heller werden.



  • Danke erstmal Powerpaule für deine Antwort!

    Ich verwende SFML, was so ziemlich nah an SDL ran kommt. Die Karte ist jedoch nicht in Quadrate oder ähnlichem aufgeteilt. Man kann sich frei bewegen, an jede x-beliebige Stelle. Also zumindest so groß wie die Pixel sind.
    Ich hab das bis jetzt so gemacht. Die Hintergrundfarbe ist jetzt allgemein grau. Objekte die in einem entsprechenden Sichtradius sind, werden gezeichnet. Eigene Objekte natürlich auch, um diese herum wird ein schwarzer Kreis gezeichnet. Zuerst der Kreis, dann die Objekte. Somit ist der "Nebel" überall dort wo man nicht sehen kann, also eigentlich ist es die "echte" Hintergrundfarbe.

    Nun nur noch das mit dem gar nicht sichtbaren Bereich. Also dort wo der eigene Spieler noch nicht war. Das ist dann wieder etwas dümmer zu lösen. Meine Idee bis her ist, die Karte in gleich große Quadrate zu je 50x50 Pixel aufzuteilen. Passend dazu dann auch ein Array was genau so groß ist ( Kartengröße/50 ). Bereiche die ich gesehen habe, bzw welche nicht werden in dem Array gespeichert. Dannach mit zwei Schleifen immer die entsprechenden gerade sichtbaren Bereiche durchlaufen und dann schwarz drüber zeichnen bzw. nichts zeichnen. Die Ränder kann man dann auch mit einer fließend aufhellenden Textur bekritzeln.

    Meine Frage jetzt aber, wie performant ist das? Für mich klingt das irgendwie sehr ressourcenverschwendend. Gibt es da irgendwelche alternativen oder ist das so schon ok?


  • Mod

    wenn du dir ein paar 2d spiele bzw deren editoren angesehen haettest, haettest du auch gesehen dass die levels aus solchen 2d-arrays bestehen, in 16*16, 32*32 ..) in denen pro feld die eigenschaften des feldes gespeichert sind. beim zeichnen werden die dann einzelt durchgegangen und..emm..jaa, entsprechend ihren eigenschaften gezeichnet.

    wie hast du die karte sonst gezeichnet?



  • Eine Karte in Quadrate einzuteilen und sich überall hinbewegen können schließt sich ja nicht gegenseitig aus. Die Quadrate kannst du nach belieben klein machen um den Genauigkeitsgrad zu erhöhen. Wenn du die ganzen Spiele die du als Beispiel nimmst mal genauer anschaust, siehst du beim Spielen auch, dass sich der Nebel nicht völlig "stufenlos" zurückfährt sondern auch nur in Stückchen-Abschnitten. Das sind die Quadrate.



  • Jo, und was die Performance angeht, ist es nicht schlimm wenn du einen Array mit mehreren Tausend Elementen jedes Mal durchläufst, zumal du ja die Felder, die nicht im Sichtbereich liegen, gleich ausschließen kannst.
    Zeitaufwendiger ist da eher das Rendern, ich kenn mich da mit SFML nicht aus, aber die SDL kommt da schnell an ihre Grenzen.



  • Bei SFML ist das nicht ganz so schlimm wie bei SDL. Mit reinem SDL kommt man da wirklich sehr schnell an seine Grenzen, gerade bei vielen halbtransparenten Sachen, wie eben den Nebel oder sonstiges.

    @rapso: Naja, ich habe jedes Objekt eine X- und eine Y-Position gegeben. Beim zeichnen geht er dann die Liste durch und setzt sie entsprechend. Macht man das so nicht?


  • Mod

    JDieskau schrieb:

    @rapso: Naja, ich habe jedes Objekt eine X- und eine Y-Position gegeben. Beim zeichnen geht er dann die Liste durch und setzt sie entsprechend. Macht man das so nicht?

    aus objektorientierter sicht ist das gut 😉
    falls alle objekte vollkommen frei im raum waeren, waere es auch noch gut.
    aber bei einem spiel, dass auf einem 2d grid aufbaut, kann man zumindestens die tiles vom terrain anhand des grids zeichnen, da musst du keine x,y positionen ablegen, weil du genau weisst wo das tile ist, anhand des eintrags im 2d array. den speicher kannst du dann auch besser dafuer nutzen dir abzuspeichern welche eigenschaften der eintrag im grid hat.

    du hast also dein 2d array fuers terrain

    std::vector<ETerrainType> ...
    

    und deine flags mit eigenschaften

    enum ETerrainType
    {
      ETT_GRASS,
      ETT_WALL,
      ETT_ROCK,
      ETT_WATER,
      ETT_FOG       =BIT(2),
      ETT_HALFFOG   =BIT(3),
      ETT_ENEMY     =BIT(4),
      ETT_PLAYER    =BIT(5)
    };
    

    dieses array von flags kannst du dann fuer allerlei nutzen, z.b. fuer wegfindung, sehr leicht fuer eine minimap (musst ja nur jeden der eintraege als pixel setzen), fuer terrain mit fogofwar, du kannst auch beim zeichnen der einheiten mit einem einfachen lookup rausfinden ob sie im fog sind (also die gegnerischen einheiten).

    du musst das array natuerlich updaten, damit fogofwar aktuell ist und die eintraege mit gegnern stimmen.

    so koennen deine einheiten auch sehr einfach feinde finden, du pruefst im array wo der naechste ist. etc.

    das ist natuerlich nur eine art das ganze zu loesen, aber es ist sehr gaengig.



  • @rapso: Danke. Das ist hilfreich zu wissen. Aber vielleicht sollte ich jetzt hier mal gleich sagen, dass es sich hier um ein Weltraumspiel handelt. So viel mit Terrain ist da nicht. Ein paar Sterne, Nebel, Trümmer... deswegen hat sich die Sache mit dem Terrain-Array bisher hier nicht wirklich gut angeboten.
    Obwohl ich für den Nicht-Sichtbaren-Bereich dann wohl doch so ein Array anlegen würde. Das kann ja ruhig relativ "grob" sein.

    Also erstmal Danke an alle 🙂


Anmelden zum Antworten