TileMap berechnung?

bruce85

Bekanntes Mitglied
Hallo,
ich bin gerade dabei ein Spiel zu schreiben und wollte mal wissen, wie ich am einfachsten die Steine bei einer Tile Map berechne, wie bei SAGA Spiele.

z.B. 3 Steiner in einer Reihe oder 5 Steine die in L geformt ist:
0 0 0

0
0
0 0 0

Wenn ich das ganze in einer For-Schleife prüfe, dann wird mein Spiel, denke ich, ziemlich langsam, da ich ja mehrmals die Felder durchgehe, um die Steine zu prüfen, da es ja mehrere Variante gibt und alles nochmal jede 90 Grad erneut prüfen müsste.

Gibt es Vielleicht eine Methode, wie ich das ganze Prüfen kann, ohne viele Schleifen-Durchläufe?

Danke schonmal für die Hilfe.

Gruss
 
Du könntest bestimmte Muster abspeichern (-> häufig auftretende) und diese auf ihr vorkommen abprüfen, damit umgehst du das Problem mit den 90°, aber für den Rest wirst du um viele Schleifendurchläufe nicht herumkommen...
 
Die Schleifendurchläufe sollten kein Problem darstellen. Rein von der Performance her. Ausserdem musst du ja nur um den Stein prüfen, der als letztes gesetzt wurde (Wenn ich das Spielprinzip richtig verstanden habe.) Dann sind es gar nicht mehr so viele Möglichkeiten.
 
Achso das Spielprinzip war mir vorher nicht klar haha XD
Da hat thecain recht ... mit der Performance wirst du echt keine Probleme kriegen.
Wenn du dem User die Benutzung einfacher machen möchtest, würde ich die Funktion mit den Mustern definitiv mit einbauen ... besonders wenn du auch eine Drehen-Funktion anbietest XD
 
Vielen Dank für die antworten.

Aber was ist, wenn die Steine dann gelöscht werden und oben neue Steine runter fallen?
Dann muss ich ja weiter prüfen, da genügt es nicht einfach um den Stein, der als letztes gesetzt wurde, zu prüfen.

z.B. habe ich ein Spielfeld mit 9x9 Felder und darin möchte ich verschiedene Steine prüfen und wenn ich jedesmal bei 81 Felder alle mögliche Steine prüfe, die dann gelöscht werden sollen, dann ist das schon ziemlich viel an durchläufe.

Wie würdet ihr die berechnung durchführen?
z.B. so ein Spielfeld-Array:
Code:
0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0
0  0  0  0  1  0  0  0  0
0  0  0  0  1  0  0  0  0
0  0  0  0  1  1  1  0  0
0  2  2  2  0  0  0  0  0
0  0  0  2  0  0  0  0  0
0  0  0  2  0  0  0  0  0
0  0  0  0  0  0  0  0  0

und hier der Block-Array, der im Spielfeld-Array überprüft werden soll:
Code:
1  0  0
1  0  0
1  1  1
Code:
1  1  1
0  0  1
0  0  1

Überall wo bei den Blocken eine 1 ist, wird im Spielfeld auf verschiedene Frames überprüft.

Ich hab das folgendermaßen gemacht:
Code:
//Spielfeld-Array erstellen
spielfeld = new Spielfeld[countX][countY];
        for (int y=0; y<countY; y++) {
           for (int x=0; x<countX; x++) {
               spielfeld[x][y] = new Spielfeld();
               spielfeld[x][y].frames = getRandomNr(1, 5);
           }
        }
//Block-ArrayList erstellen
block = new ArrayList<Block>();
        Block b = new Block();
        b.frames = new int[][] {{1, 0, 0},
                                {1, 0, 0},
                                {1, 1, 1}};
        b.countX = 3;
        b.countY = 3;
        block.add(b);
        b = new Block();
        b.frames = new int[][] {{1, 1, 1},
                                {0, 0, 1},
                                {0, 0, 1}};
        b.countX = 3;
        b.countY = 3;
        block.add(b);

        //Alle Spielfelder durhcgehen
        for (int y=0; y<countY; y++) {
           for (int x=0; x<countX; x++) {
               if (spielfeld[x][y].frames > 0) {
                  //Wenn frames > 0, dann alle Blocke durchgehen und im Spielfeld vergleichen
                  for (int z=0; z<block.size(); z++) {
                      if ((x < (countX-(block.get(z).countX-1))) && (y < (countY-(block.get(z).countY-1)))) {
                          boolean abbruch = false;
                          for (int y2=0; y2<block.get(z).countY; y2++) {
                              for (int x2=0; x2<block.get(z).countX; x2++) {
                                  if (block.get(z).frames[x2][y2] == 1) {
                                      if (spielfeld[x+x2][y+y2].frames != spielfeld[x][y].frames) {
                                          abbruch = true;
                                      }
                                  }
                              }
                              if (abbruch) break;
                          }
                          if (!abbruch) {
                              System.out.println("Gefunden!");
                          }
                      }
                  }
               }
           }
        }


Funktionieren tut es und bis jetzt sind mir keine Fehler aufgefallen, nur weiss ich jetzt nicht, ob meine Lösung so OK ist.

Gruss
 
Das Spielprinzip ist wie z.B. Candy Crush von Soda.

Edit: z.B. wenn 3 gleiche Steine nebeneinander sind, werden diese gelöscht und neue Steine kommen heruntergefallen usw.
Ich wollte halt wissen, ob es eine bessere Methode gibt, die verschiedene Kombis zu prüfen.

Gruss
 
Gehen die Steine automatisch kaputt wenn sie in einer Formation sind oder nur nach einer Interaktion des Users?

1. Fall:
Du kannst versuchen immer nur die zuletzt bewegten Steine und ihre Nachbarn zu prüfen. Dabei kannst du dir wie bei Candy Bag einfach einen Radius (je nach Größe der möglichen Combis) setzen. ->Nebeneffekt du kannst das in einer Schleifen laufen lassen und brauchst für eine Benutzerreaktion keine zweite.

2. Fall:
Du prüfst nur bei einer Bewegung durch den Benutzer ... dann kannst du von der Performance auch alle Nachbarn prüfen oder eben wieder nur einen bestimmten Radius. 🙂
 
In dem Fall würde ich einen Flood Fill Algorithmus implementieren und ihn an deine Bedürfnisse anpassen.

quasi sowas checkStone(x,y, color) - Dann prüfen ob links rechts oben unten auch die farbe ist. Falls ja nächsten checken, falls nein Abbruch. Dann könntest du pro Check noch prüfen ob mind. 3 vertikal und horizontal gefunden wurde und entsprechend die richtigen Steine entfernen.

Nach den verschiebungen könntest du es dann einfach nochmals laufen lassen. 5-fach verschachtelte loops zeigen meistens das das Problem noch nicht optimal gelöst worden ist. Obwohl auch bei deiner Implementierung rein Performancemässig vermutlich keine Probleme auftreten.

https://en.wikipedia.org/wiki/Flood_fill
 

Zurück
Oben