# Variable Spielsteine (Astro Pop)



## Chrisi (18. Nov 2004)

Hallo zusammen,

ich sitze an einer schwierigen (für mich) Stelle fest.

Es geht um einen Nachbau des Spieles Astropop, es gibt dort eine Rakette am unteren Spielrand
und von oben kommt eine Fläche aus einzellen Steinen Schrittweise nach unten, wobei man mit dem Raumschiff die Möglichkeit hat einzellne Steine zu greifen und dann nach Farben aufeinander zu stapeln, sobald man dann 4 gleiche Farben nebeneinader hat explodieren die Steine.
Wenn die Mauer zuweit unten ist hat man verloren.

Soweit komme ich gut vorwärts, allerdings hänge ich bei den Steinen die von oben kommen.

Das Problem ist das jeder Stein einzellen ansprechbar sein muss, weil ich berechnen muss welcher Stein wann wo liegt um die Steine dann bei Bedarf explodieren zu lassen.

Beispiel mit 3x3 Steinen:

 x1 x2 x3
 x4 x5 x6     <-- Spielsteine
 x7 x8 x9

     /\           <-- Rakette


Ich habe gebastellt und gebsatellt, komme aber zu keiner sinnvollen Lösung diese Steinmauer zu generieren.

Hat da vieleicht jemand einen Tipp wie man sowas verwirklichen kann ?

Für alle die das Spiel nicht kennen: http://www.zylom.de (Astro Pop)

Viele Grüße und danke,

Chrisi


----------



## Wildcard (18. Nov 2004)

Hätte jetzt mal auf die Schnelle (ohne das Spiel zu kennen) gesagt das 
du am besten ein Stein Objekt machst.
So ein Objekt erzeugst du jedesmal wenn ein Stein von oben kommt.
Der Stein müsste mindestens wissen wo er ist, seine Farbe kennen und eine move methode haben.
Wie gesagt, war nur mal so mein erster gedanke  :wink:


----------



## Chrisi (18. Nov 2004)

Hallo,

der Gedanke hört sich gut an ;-)

Kannst du mir da noch ein wenig mehr Info geben ?

Ich habe eine Klasse geschrieben die eine Fläche erzeugt, wie ich sie haben will, diese binde ich dann in meinen
Spielthread ein und lasse die "Mauer" von oben nach unten wandern, klappt ;-)

Nur ist die Fläche ein fetter Klumpen, ich muss die Fläche irgendwie zerlegen bzw. so aufbauen das es einzellene Elemente sind auf die ich zugreifen kann ...
Habe da schon über einen Array nachgedacht, weiss aber nicht wirklich ob das Sinn macht.

Ich hatte schon den Einfall in dem Array nur die Koordinaten und die Farbe zu speichern, dann könnte man Prima verschiedene Level realiesieren, bzw. die Steinanzahl und Verteilung ändern ;-)

Also wäre in diesem Falle der Array sowas wie eine Bauzeichnung für das Mauerwerk ...

Kannst du mir deine Gedanken etwas näher erklären ?

Viele Grüße,

Chrisi


----------



## Wildcard (18. Nov 2004)

Ich weiß jetzt leider nicht wie das bei dir aussieht  und was man dann letztendlich im Spiel macht,
aber ich geh jetzt einfach mal davon aus das du auf ein Panel oder so zeichnest.
Wenn du einen neuen Stein brauchst erzeugst du ein neues Stein-Objekt und gibst ihm über den 
Konstruktor eine Startposition und eine Farbe.
Alle Steine auf dem Panel stecken in bspw. einer Hashmap, also brauchen sie noch eine ID die du
als Key benutzt. 
Wird ein Stein angeklickt (oder wie bewegt man die?) müsste dein Controller die Steine fragen
welcher auf diesem Punkt sitzt (da ja nur sie ihre Position kennen), und entsprechend reagieren.
Je nach Komplexität deines Spiels währe auch zu überlegen ob jeder Stein sich selbst zeichnet,
oder ob es reicht, dass das deine Viewer Klasse übernimmt.

Hoffe mal da war wenigstens irgendwas brauchbares dabei  :wink:


----------



## Chrisi (19. Nov 2004)

Danke für deine Hilfe.

Das ganze läuft als Applet.

Die Steine Scrollen Schtittweise von oben auf den unteren Teil des Applets zu, mit der Rakette kann man die einzellnen Steine (wenn keiner davor liegt) greifen, auch mehrer aufeinmal sofern die gleiche Farbe und dann wieder an die Mauer nach oben schmeissen, sobald mehr als 4 sich berühren explodieren die Steine.

Das mit dem greifen ist wohl noch weit weg, mir reicht es wenn ich es hinbekommen kann die Steine so zu generieren, das ich weis wo welcher Stein ist und welche Farbe er hat.

Ich denke das meinst du mit Panel, oder ?

```
public void paint(Graphics g)
  {
    steine.paintSteine(g, steine_move, 2);
  }
```

Jedanfalls Zeichne ich da alle Formen und Figuren für mein Applet.

Hier meine Methode zum Zeichnen der Mauer:

```
public void paintSteine (Graphics g, int y_pos, int color)
  {
    g.setColor (farbe[color]);
    
    int x = width;
    
    // Steine zeichnen
    for(int i=0; i < 10; i++)
    {

      for(int m=0; m < 10; m++)
      {
        g.fillRect (x, y_pos, width, height);
        x += width+1;
      }

      x = width;
      y_pos += 21;

    }
  }
```

Ich zeichne hier zwar jeden Stein einzelln, aber verliere die Infos zu jedem Stein.

Denke da wäre eine Hashmap das was mit fehlt, hast du ein Beispiel für sowas ?

Schau die mal das Original bei zylom.de an, das findest du da direkt unter Action Spiele, ich finde das Speil echt heiss.

"Das kannst du so spielen, kostenlos und ohne Registrierung"

Viele Grüße und danke,

Chrisi


----------



## Chrisi (19. Nov 2004)

hallo,


[url]http://www.galileocomputing....0005256DieKlasseHashMapundassoziativeSpeicher
[/url]

ich habe grade das gefunden, denke ich werde mir da erstmal alles anscheuen, danke für deine hilfe jedenfalls.

viele grüße,

chrisi


----------



## Wildcard (19. Nov 2004)

Beispiel für Hashmap?


```
Map map = new Hashmap();
map.put("key","value");
map.get("key");
```

kannst aber nur Objekte reinmachen, also int keys vorher umwandeln.
raus kommen auch immer nur objects, also casten.

Also entweder in deiner jetzigen paint Methode alle Stones durchgehen und entsprechend ihrer 
daten zeichnen, oder Stone von JComponent erben lassen, die paintComponent Methode 
überschreiben und die Stones sich selbst zeichnen lassen.
Ist zwar komplizierter, aber später besser erweiterbar.

kannst ja posten was dabei rausgekommen ist,
würd mich interessieren  
viel Erfolg  8)


----------



## Chrisi (19. Nov 2004)

danke dir, wenn ich was sichtbares hinbekomme melde ich mich hier wieder.

viele grüße, chrisi ...


----------



## Chrisi (21. Nov 2004)

Hallo zusammen,

nun ich bin noch immer an meinem Spielchen, aber schon ein Paar Schritte weiter ;-)

Die Steine lade ich in einen Array wo ich dann auch die x, y, color werte etc speichere, zeichnen
lasse ich dann anhand der daten im Array.

Nun stehe ich an der Stelle wo ich einen vierer rausfiltern muss ;-)

Hier ein Beispiel Spielfeld:

x x x x x x
x x x x x x 
x x x x x x 
x x x x x x

Jedes x ist ein Stein wie auch oben in den ersten Postings beschrieben, es gibt 4 mögliche Farben die ein Stein haben kann, ich nenne Sie hier 1,2,3,4.

Nun möchte ich alle Steine ermitteln die a. die gleiche Frabe haben und b. sich an berühren ;-)

Also fast so wie bei 4 gewinnt:

    x x x x  <- 4 nebeneinander

    x 
    x 
    x           <- 4 untereinander
    x

    x x
    x x        <- quadrat

der Array in dem die Spielsteine und Ihre Infos liegen schaut in etwa so aus:


```
array {
             {x,y,1},
             {x,y,2},
             {x,y,3},
             {x,y,4}
         }
```

Wobei x und y die Koodinaten sind und die Zahlen 1-4 die jeweilige Farbe des Steins.

Nun frage ich mich wie ich am besten  die 4er da heraus ziehen kann.

Meine Schritte wären:

      // erste Reihe x durchgehen
      // dann schauen wieviele von den Steinen die gleiche Farbe haben
      // dann schauen wie weit die y Koordinaten der gefundenen Steine auseinander sind
      // wenn die entfernung nicht mehr als die hoehe eines spielsteines ist, soll es ein treffer sein ;-)
      // dann die treffer sammeln, und festhalten zur weiterverarbeitung

Das wäre jetzt mein Weg um die 4er auf einer X-Achse zu bekommen, dann wären ja die auf der Y-Achse auch kein Problem, allerdings habe ich meine Quadrate nicht bedacht ;-)

Mir scheint als sei mein Weg irgendwie nicht der Richtige.

Da kann man doch bestimmt irgendwie was berechnen, oder ?

Oder hat jemand von euch eine Idee andere Idee ?

Viele Grüße und danke,

Chrisi


----------



## Wildcard (21. Nov 2004)

Mach dir doch jeweils 1 Array für jede Farbe.
Stopf die unter "rot", "blau", usw. in eine Hashmap
Wenn jetzt ein Stein seine pos ändert hol dir das FarbArray aus der map und
prüfe ob es Einträge an diesen Positionen hat:


```
x
         x
        xxx
      xxxoxxx
        xxx
         x
         x
```
 
wobei o der betreffende Stein ist und du den x,y und quadratbereich getrennt betrachten musst.
Immer noch nicht schön, aber vieleicht fällt mir noch was vernünftiges ein  ???:L 

PS  wenn du das ganze über ein Array machst würde ich auf die Positionen der Steine verzichten,
und die Position über die Array Speicherstelle bestimmen. Wo kein Stein ist bleibt auch das Array leer.


----------



## Chrisi (22. Nov 2004)

Hi Wildcard,

danke für deine Antwort.



			
				Wildcard hat gesagt.:
			
		

> ```
> x
> x
> xxx
> ...



Das schaut gut aus, ich denke das sollte passen, da damit ja alle möglichen 4er um einen Stein
abgedekt sind.

Da muss ich mich gleich mal reindenken und versuchen ein Abfrage zu bastelln die dort greift ;-)

Die Idee mit dem Array für jede Farbe habe ich nicht verstanden, meintest du sowas ?


```
{
   {nur rote}
   {nur grüne}
   {nur blaue}
}
```

Ich verstehe jetzt nicht wie mir die Sortierung der Farbe bei deinem Abfrage Beispiel von oben das treffen der 4er ermöglicht.

Angenommen jeweils der erste äussere Stein bei deinem Beispiel hätte die Farbe Rot, dann wäre ja ein 4er voll obwohl die Steine aber nicht nebeneinander liegen, oder habe ich das nicht verstanden ?  :roll: 

Ich hatte den Array von mir so aufgebaut damit ich ihn anständig durchmischen kann, damit das Spielfeld bei Beginn nicht so gerade aussieht. Evtl. werde ich auch Muster oder Figuren in die Mauer Zeichnen, das sieht dann bestimmt auch schick aus, aber das dann wohl später ...

--

Die Idee die Position aus dem Array zu nehmen finde ich gut, das spart ja eine Menge an Arbeit und vereinfacht die ganze Sache enorm.

Aber halt, (ich ziehe hier gerade meine Steine so rauf und runter), dabei fällt mir ein das ich ja die Position brauch weil ich die Steine ja auf die Rakette ziehen muss und diese am unteren Rand auf der x Achse mitgehen bis ich sie nach oben schiesse ;-)
Dazu kommt das sich ja Steine aus dem Spielfeld lösen sobald 4er vorhanden sind, ohne die x,y pos würden die Steine dann einfach der Reihe nach von links nach rechts ausgegeben, dann würden aber die Steine die über den gelösten lagen nacher nicht richtig positioniert (nachrutschen), obwohl sich hierfür sicher eine Lösung finden lassen würde.

Vieleicht denke ich ja jetzt grade auch etwas zu kompliziert ?

Die Sache mit den Hashmaps werde ich zum Schluss einbauen, das geht dann in die Kategorie Speed, Perfomance und lernen ;-)

Für mein erstes Java Programm habe ich mir aber auch wirklich eine harte Nuss ausgesucht, aber ich muss sagen das macht Spass ...

Viele Grüße,,,

Chrisi


----------



## Wildcard (22. Nov 2004)

Hab gemeint das du so viele Arrays wie Farben im spiel sind, da ja immer nur Steine mit
gleicher Farbe interessant sind?
Wenn du auf die Position verzichtet hättest, und verschiedene FarbArrays genommen hättest,
hatte das den Vorteil gehabt das da nur noch boolean Arrays brauchst, die angeben ob auf Feld x,y ein 
Stein ist(die Farbe ist ja durch das Array schon klar).
Wenn die Steine aber mit zwischenschritten bewegt werden können, also nicht immer im Grid liegen,
dann geht das schlecht. Hab ich nicht dran gedacht.

Das ist genau die schwierigkeit an der Abfrage, es geht um die Steine die ich aufgemalt habe, aber
eben nur in bestimmten Kombinationen. Hab ich jetzt auch keine wesentlich bessere Idee als 
viele if's.   
Schau mal ob du's hinkriegst, wenn nicht zimmer ich dir dafür was zusammen.
Wenn das dein erstes Prog ist hast du dir wirklich ein bißchen was vorgenommen


----------



## Chrisi (22. Nov 2004)

Halloaaa,

nach den Ideen von gestern habe ich gebastellt und gebastellt, ich hab es immerhin hinbekommen Reihen die von links nach rechts gelegt werden aufzulösen und evtl. betroffene Spielsteine die über den aufgelösten liegen runterrutschen zu lassen um die Lücken im Spielfeld zu schliessen.

Hier mal die Methode:


```
public void clearSteine (int i)
  { //Variable i enthält den zuletzt geschobenen Stein
    for(int x=0; x < array.length; x++)
    { //[x][y][color][alpha][position]
      // farbe vergleichen
      // x pos + 1 Steinbreite vergleichen
      // dann y pos, schauen ob die in der gleiche reihe liegen
      // dann schauen ob Stein greifbar/auf dem Spielfeld liegt ist (Position 0)
      if(array[i][2] == array[x][2] && array[i][0] == array[x][0] + 25 && array[i][1] == array[x][1] && array[x][4] == 0)
      {
        for(int xx=0; xx < array.length; xx++)
        {
          // Nochmal durchgehen, aber x pos + 2 Steinbreiten vergleichen
          if(array[i][2] == array[xx][2] && array[i][0] == array[xx][0] + 50 && array[i][1] == array[xx][1] && array[xx][4] == 0)
          {
            for(int xxx=0; xxx < array.length; xxx++)
            {
              // Nochmal durchgehen, aber x pos + 3 Steinbreiten vergleichen
              if(array[i][2] == array[xxx][2] && array[i][0] == array[xxx][0] + 75 && array[i][1] == array[xxx][1] && array[xxx][4] == 0)
              {
                // Treffer ? Dann die gefundenen Steine und den aktuellen (geschobenen) Stein Position auf 2 setzen).
                array[x][4]   = 2;
                array[xx][4]  = 2;
                array[xxx][4] = 2;
                array[i][4]   = 2;
                  
                // Alle Steine die darueber liegen nachziehen, bzw. nachrutschen lassen
                for(int clear=0; clear < array.length; clear++)
                {
                  if(array[clear][1] == array[x][1] + 25 && array[clear][0] == array[x][0])
                  {
                    array[clear][1] -= 25;
                  }
                  if(array[clear][1] == array[xx][1] + 25 && array[clear][0] == array[xx][0])
                  {
                    array[clear][1] -= 25;
                  }
                  if(array[clear][1] == array[xxx][1] + 25 && array[clear][0] == array[xxx][0])
                  {
                    array[clear][1] -= 25;
                  }
                  if(array[clear][1] == array[i][1] + 25 && array[clear][0] == array[i][0])
                  {
                    array[clear][1] -= 25;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
```

Hier werden nur Steine aufgelöst die von links nach rechts eine 4er Reihe ergeben, das ganze soll natürlich auch umgekehrt gehen, nach oben, nach unten etc ... ( aber da wollte ich erstmal hier das Stück posten bevor ich mich da in den Jungel des Codes verlaufe ;-)

Was mich jetzt noch ein bischen stört ist das er immer nur die 4 gefunden Steine auflöst, es wäre natürlich gut wenn er auch die mit wegmacht die unmittelba daneben liegen und die gleiche Farbe haben und und und ...

So wie ich mich kenne habe ich zu kompliziert gedacht und zu oft if() und for() verschachtelt, wenn da jemand Tipps hat wie ich das ganze verkürzen kann würde ich mich freuen.

Oder hat vieleicht jemand eine bessere Idee um den gewünschten Effekt zu erziehlen ?

Viele Grüße und danke,

Chrisi


----------



## Wildcard (22. Nov 2004)

Puh! hab mir schon gedacht dass das ganze nicht so einfach wird, aber wenn auch noch die 
angrenzenden Steine verschwinden müssen wirds noch komplizierte   
Nimm einen Stein der im Muster ist, also gelöscht werden soll.
Schreib eine rekursive Methode die von diesem Stein ausgeht und alle Steine die N,O,S und W davon 
liegen und die gleiche Farbe haben löscht. die Rekursion verschachtelt sich immer weiter, und jeder
Zweig stoppt erst wenn in keiner der 4 Richtungen noch ein Stein gleicher Farbe liegt. Damit erwischst
du sie dann alle.


----------



## Chrisi (22. Nov 2004)

hi,

das sagst du mal so ;-) Hast du evtl. ein Beispiel für mich bzw. einen Ansatz an dem ich sehe wie diese Funktion arbeiten muss ?

Viele Grüße und danke,

Chrisi


----------



## Wildcard (22. Nov 2004)

Aber sicher doch   

habs nicht getestet, muss aber in die Richtung gehen.


```
/**
     * @param x
     * @param y
     * @param color
     * @param a
     */
    private void clearStones(int x, int y,int color, int[][] a)
    {
       if (a[x][y] == color)
       {
           if (a[x+1][y]>0)
           {
               clearStones(x+1,y,color,a);
           }
           if (a[x-1][y]>0)
           {
               clearStones(x-1,y,color,a);
           }
           if (a[x][y+1]>0)
           {
               clearStones(x,y+1,color,a);
           }
           if (a[x][y-1]>0)
           {
               clearStones(x,y-1,color,a);
           }
       }   
    }
```


----------



## Chrisi (22. Nov 2004)

Hi,

danke dir, werde da mal ein bischen mit bastelln und schauen was ich hinbekomme ;-)

Die Ecke mit dem Auflösen der Steine ist die Krone vom ganzen Programm, hätte nicht gedacht das es so ein komplizierter Kram wird.

Wenn ich das hier hinter mir habe, werde ich mal einen Versuch machen ohne x,y Pos, dann allerdings auch ein anderes Spiel, allerdings finde ich die Idee klasse und wenn alle Steine auf einem Grid liegen bleibt das ganze auch sicher ein bisel überschaulicher.

Viele Grüße,

Chrisi

PS.: Bist du eigentlich dauer online ? ;-)


----------



## Wildcard (22. Nov 2004)

unter der Woche mehr oder weniger schon(unfreiwillig). Auf der Arbeit Flat,
in der Wohnung Flat,
kein Geld mehr für die Kneipe weil  das schon letztes Wochenende
in Bier umgesetzt wurde   
Also das übliche Leben eines BA Studenten  :autsch:


----------



## Chrisi (23. Nov 2004)

BA = Berufsakademie ?

Das ist doch im Betrieb und auch in der Schule, also so eine Art Ausbildung mit Studium, oder ?

Edit:

Gibt es da Fächer bzw. versch. Berufe die festgelegt sind, oder kann man da einen Beruf frei wählen ?

Und welches hast du ?


----------



## Wildcard (23. Nov 2004)

BA = Berufsakademie

Man ist immer im Wechsel an der BA und im Betrieb,
wird die ganze Zeit vom Betrieb bezahlt, und hat nach 3 Jahren ein abgeschlossenes Studium 
und i.d.R. einen Arbeitsplatz   

Man sucht sich irgendwas in Richtung Wirtschaft oder Technik aus was in der BA angeboten wird
(du wirst z.B. keine  Philosophie finden  :wink: ),
dann sucht man sich eine Firma die BA Stellen anbietet und bewirbt sich.
Jede BA bietet Listen mit Partnerfirmen an. 
Man kann sich auch bei Firmen bewerben die noch kein BA-Betrieb sind und sie überzeugen,
dass das ein für beide Seiten lohnendes Geschäft ist und sie dich da anmelden sollen.
Ich mach angewandte Informatik


----------

