# Schiffe Versenken Frage zum Spielbrett



## Neolity (29. Sep 2007)

Hallo,

ich wollte mich jetzt mal an einem kleinen Schiffe versenken Klon versuchen.
Da meine bisherigen Programme meistens relativ ungeplant gelaufen sind, wollte ich das ganze dieses Mal etwas anders angehen.

Im Augenblick stecke ich also in der Planung und habe mir folgendes zusammen gebastelt:

- Fensterklasse Fenster.java
   (enthält Grafik und GUI)

- Spielerklasse Spieler.java
   (enthält Variablen und Methoden des Spielers)

- Computerklasse Ki.java
   (enthält die Variablen und Methoden des Computergegners, beispielsweise auch zur Berechnung des nächsten Zuges)

- Logikklasse Logik.java
   (enthält alles was für den Spielablauf benötigt wird, beispielsweise eine Methode Spielzug)

Ist alles noch nicht sonderlich ausgereift, aber zumindest eine grundsätzliche Idee.

Gedacht habe ich mir, dass 2 Felder für den Spieler existieren und 2 für den Computergegner.
Feld A enthält die eigenen Schiffe und speichert Treffer bzw. daneben gegangene Schüsse.
Feld B ist zu Beginn des Spiels leer und speichert die im weiteren Spiel gemachten Spielzüge ab, sprich ich schieße auf A3, dann wird der entsprechende Eintrag auf "nicht getroffen", "getroffen" oder "versenkt" gesetzt.

Mein erste Idee sah vor ein Koordinatensystem zu zeichnen und praktisch in ein Rechteck zu klicken, um auf das jeweilige Feld zu schießen. Aber wenn ich ehrlich bin, dann stellt mich das schon vor ziemlich unlösbare Schwierigkeiten. Wie kann ich erkennen, dass innerhalb eines Rechtecks geklickt wurde? Muss man da jedes Rechteck einzeln zeichnen, oder kann man durch längere Linien das ganze Gitternetz auf einmal erzeugen?

Das sind jetzt alles ziemlich unkonkrete Fragen, aber mir fehlt einfach eine grundsätzliche Idee, wie ich ein Spielbrett aufbauen kann. Ich mag im Augenblick nicht weiter planen, wenn ich nicht weiß, ob ich da nicht evt. in einer Sackgasse stecke.... 

Für eine Idee, wie man so ein Spielbrett für ein "Schiffe versenken" erstellen könnte, wäre ich dankbar!


----------



## Black_Divil (29. Sep 2007)

hi,
Ich hab zwar noch kein schiffe versenken geschieben ...
aber ich finde das klingt schon ganz gut...

Weis allerdings nicht ob ich alles richtig verstanden hab.



> Gedacht habe ich mir, dass 2 Felder für den Spieler existieren und 2 für den Computergegner.
> Feld A enthält die eigenen Schiffe und speichert Treffer bzw. daneben gegangene Schüsse.
> Feld B ist zu Beginn des Spiels leer und speichert die im weiteren Spiel gemachten Spielzüge ab, sprich ich schieße auf A3, dann wird der entsprechende Eintrag auf "nicht getroffen", "getroffen" oder "versenkt" gesetzt.



Also würde Feld A wohl alle spielerschiffe speichern?
Egal ob spieler1 oder spieler2(bzw. Computer.)
und Feld B alle schüsse...

Das sollte funktionieren...


das mit dem versenkt ist denk ich gar nicht so einfach...
ich denke ich würde eine schiffsklasse erstellen würde dann darüber jedes schiff konstruieren also sprich schiff ist 4 felder gross oder 3 wie auch immer... dann noch ne variable die die Treffer zählt... dann ist das ziemlich einfach abzufragen wann das schiff versenkt ist.

das mit dem setzen der schiffe auf dem spielplan wird denke ich auch noch so ein knackpunkt sein...
aber ist sicher machbar... 
die Felder würde ich jedes für sich einzeln erstellen ... schon wegen den klicks... ist ja mit zwei  for-schleifen auch nicht so viel aufwand... und einzeln zeichnen muss mann auch nicht da ja jedes Kästchen quasi gleich aussieht.

dummer weise häng ich gerade an einen Problem was dabei vieleicht auch entstehen könnte.
siehe hier:
Java Forum - Problem beim Mühle Programmieren


----------



## madboy (29. Sep 2007)

Neolity hat gesagt.:
			
		

> Mein erste Idee sah vor ein Koordinatensystem zu zeichnen und praktisch in ein Rechteck zu klicken, um auf das jeweilige Feld zu schießen. Aber wenn ich ehrlich bin, dann stellt mich das schon vor ziemlich unlösbare Schwierigkeiten. Wie kann ich erkennen, dass innerhalb eines Rechtecks geklickt wurde? Muss man da jedes Rechteck einzeln zeichnen, oder kann man durch längere Linien das ganze Gitternetz auf einmal erzeugen?


Einfacher wäre es wohl mit einzelnen Rechtecken.
Zur Abfrage, in welches Feld geklickt wurde, könntest du dann durch alle Felder iterieren und schauen, ob da rein geklickt wurde mittels Rectangle#contains(Point p)

Alternativ könntest du auch Buttons oder Labels nehmen. Da wäre dann die Entscheidung, wo hin geklickt wurde trivial  :wink:


----------



## Neolity (29. Sep 2007)

hmm, ich hab jetzt mal folgendes in einer kleinen Testklasse geschrieben:

- Ein Array spielbrett nimmt die x- und y-Koordinate der einzelnen Quadrate auf, Breite und Höhe sind ja immer gleich (41 Pixel), brauchen also nicht separat gespeichert werden. (8 x 8, also insgesamt 64 Quadrate, das erste soll bei x=600, y=200 liegen)

- Paint Methode zeichnet die Quadrate

- MouseListener reagiert auf Mausklicks, ermittelt, ob innerhalb eines Quadrates geklickt wurde => Ausgabe von "Drin!!!" und den geklickten Koordinaten auf Konsolenebene. Wenn ich jetzt auf die obere, linke Ecke des ersten Quadrates klicke, dann würde ich als Ausgabe "Drin!!!" und x=600, y=200 erwarten. Das ist aber leider nicht so! Die obere, linke Ecke ist bei mir 604, 230, wird aber als "Drin!!!" akzeptiert?! Auch Mausklicks einige Pixel über den Quadraten werden als "Drin!" bezeichnet. In der untersten Reihe der Quadrate ist das genau umgekehrt. Klickt man ganz unten, wird der Klick nicht als drin bezeichnet.
Irgendwie scheint das alles etwas nach oben verschoben zu sein?!

Vielleicht kann mir hier jemand helfen....

Und weil Code mehr als tausend Worte sagt, hier noch meine "Test.java":


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class Test extends JFrame
{
	int[][][] spielbrett = new int[8][8][2];
	
	Test()
	{
		super("Test zur Maus");
		
		setSize(1024, 768);
		
		setContentPane(new Zeichenflaeche());
		
		addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent we)
			{
				System.exit(0);
			}
		});
		
		/* MouseListener, der auf die Mausklicks reagiert. Liegt ein Klick innerhalb eines Rechtecks, werden
		die Koordinaten und der String "Drin!!!" auf Konsolenebene ausgegeben */
		addMouseListener(new MouseAdapter()
		{
			public void mouseClicked(MouseEvent me)
			{
				
				for (int i = 0; i < 8; i++)
				{
					for (int j = 0; j < 8; j++)
					{
						Rectangle r = new Rectangle(spielbrett[i][j][0], spielbrett[i][j][1], 41, 41);
						if (r.contains(me.getPoint()))
						{
							System.out.println("DRIN!!!" + " " + me.getPoint());
						}
					}
				}
			}
		});
		
		/* Hier werden die Koordinaten für die einzelnen Rechtecke berechnet und im Array spielbrett abgelegt */
		int k = 600;
		int l = 200;
		for (int i = 0; i < 8; i++)
		{
			l = 200 + i * 41;
			for (int j = 0; j < 8; j++)
			{
				spielbrett[i][j][0] = k;
				spielbrett[i][j][1] = l;
				k += 41;
			}
			k = 600;
		}
		
		System.out.println(spielbrett.toString());
		
		setVisible(true);
	}
	
	private class Zeichenflaeche extends JPanel
	{
		public void paintComponent(Graphics g)
		{
			super.paintComponent(g);
			
			((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			
			/* Zeichnen der Rechtecke */
			for (int i = 0; i < 8; i++)
			{
				for (int j = 0; j < 8; j++)
				{
					g.drawRect(spielbrett[i][j][0], spielbrett[i][j][1], 41, 41);
				}
			}
			
			g.fillOval(spielbrett[0][0][0], spielbrett[0][0][1], 41, 41);
		}
	}
	
	public static void main(String[] args)
	{
		Test t = new Test();
	}
}
```


----------



## Marco13 (30. Sep 2007)

Wenn du weißt, die groß die Rechtecke sind, die gezeichnet werden, brauchst du garnicht mit irgendwelche temporär erstellten Rectangles und 'contains' rumzumurksen. Du kannst die angeklickte Position einfach _ausrechnen_. Wenn z.B. ein MouseListener an der Component hängt, in der (NUR) die Rechtecke gezeichnet werden:


```
mouseClicked(event)
{
    int feldX = event.getX() / feldBreite;
    int feildY = event.getY() / feldHoehe;
    feuereAuf(spielfeld[feldX][feldY]);
}
```


----------



## Neolity (30. Sep 2007)

So wirklich hilft mir das jetzt nicht unbedingt weiter...

Von getX und getY bekomme ich doch nicht die Breite bzw. Höhe, sondern nur die x- oder y-Koordinate. Diesen Feldeintrag gibt es doch dann gar nicht, sondern nur ein Rechteck, das diese x- und y-Koordinate enthält...


----------



## Marco13 (30. Sep 2007)

Jo  :roll: Deswegen ja teilen.

Wenn du 5 Felder hast, und die sind jeweils 10 Pixel breit, und man klickt bei x-Koordinate 23, dann hast du
int feldX = event.getX() / feldBreite
= 23 / 10
= 2
D.h. wenn man bei x=23 klickt, dann liegt das im Feld mit Index 2. Hm. Sooo schwer ist das doch jetzt nicht.


----------



## Neolity (30. Sep 2007)

Marco13 hat gesagt.:
			
		

> Jo  :roll: Deswegen ja teilen.
> 
> Wenn du 5 Felder hast, und die sind jeweils 10 Pixel breit, und man klickt bei x-Koordinate 23, dann hast du
> int feldX = event.getX() / feldBreite
> ...



Sorry, mein Fehler, hab das "/ feldBreite" fälschlicherweise als Kommentar gesehen...

So ist das natürlich verständlich! 
Spontan dachte ich jetzt man würde in Feld 3 landen, aber das ist bei den Java Indizes ja 2...



EDIT:

Das funktioniert und sieht auch deutlich runder aus als die Sache mit dem contains. Aber an der scheinbar verschobenen Darstellung ändert das nix...


----------



## Neolity (2. Okt 2007)

So richtig weiter bin ich damit noch nicht...

Die einzige Idee, die ich noch hätte wäre das einfach rauszurechnen, aber das ist mir ein bißchen zu ungenau...


----------



## LoN_Nemesis (2. Okt 2007)

Zunächst mal würde ich dir raten, die Zahl 41 als Konstante zu definieren, dann musst du nicht den Code an 200 Stellen anpassen wenn du das mal ändern willst.
Was mich zu der Frage bringt, was diese 41 überhaupt ist? Die Breite und Länge eines Feldes?

Wie groß ist denn das gesamte Spielfbrett und wie groß ist ein Feld (in Pixeln)? Vielleicht bleiben da ein paar Pixel übrig, weil die Rechnung nicht glatt aufgeht. Bei Java muss man z.B. immer bedenken, dass der Bereich unter dem oberen Fensterrahmen auch mitgerechnet wird, obwohl man ihn nicht nutzen kann.


----------



## Neolity (2. Okt 2007)

41 ist die Höhe und Breite der kleinen Quadrate aus denen ich das Spielfeld aufbaue.
Das kann natürlich sein, dass der obere Rand das Problem darstellt. Aber das ließe sich dann wirklich nur rausrechnen, oder?


----------



## LoN_Nemesis (2. Okt 2007)

Marco13 hat gesagt.:
			
		

> Wenn z.B. ein MouseListener an der Component hängt, in der (NUR) die Rechtecke gezeichnet werden:



Marco13 hat es schon indirekt angedeutet, es wäre eventuell sinnvoll eine Component (JPanel oder was auch immer) extra nur für Feld mit den Quadraten einzurichten. Also zum Beispiel 360x360 und dann jedes Feld genau 40x40 Pixel groß, dann kannst du auf den Pixel genau einfach ausrechnen wo dein Mauszeiger gerade hinklickt.

Rausrechnen ginge natürlich auch, aber so fände ich es "ordentlicher".


----------



## Neolity (2. Okt 2007)

Ganz genau das waren auch meine Bedenken beim einfachen Rausrechnen. Da stehen dann irgendeine Formel und in 3 Wochen weiß ich sowieso nicht mehr warum und wieso.
Werde mir das morgen mal anschauen!


----------



## Neolity (3. Okt 2007)

hmm, ich hab da jetzt mal was gebastelt, das aber nicht funktioniert.

Ich habe eine innere Klasse Zeichenflaeche geschrieben, die eine x und eine y Koordinate übergeben bekommt und eigentlich ab dieser Stelle 10 x 10 Quadrate mit Seitenlänge 41 zeichnen soll.
Die Klasse sieht so aus:

```
private class Zeichenflaeche extends JPanel
	{
		private int x;
		private int y;
		
		Zeichenflaeche(int x, int y)
		{
			this.x = x;
			this.y = y;
		}
		
		public void paintComponent(Graphics g)
		{
			super.paintComponent(g);
			
			/* Zeichnen der Rechtecke */
			int k = x;
			int l = y;
			for (int i = 0; i < 10; i++)
			{
				l = y + i * 41;
				for (int j = 0; j < 10; j++)
				{
					k += 41;
					g.drawRect(k, l, 41, 41);
				}
				k = x;
			}
		}
	}
```
Jetzt habe ich mir einfach 2 Objekte dieser Klasse erstellt:

```
Zeichenflaeche z = new Zeichenflaeche(600, 200);
	Zeichenflaeche z2 = new Zeichenflaeche(100, 200);
```
und füge die meinem Fenster hinzu:

```
add(z);
	add(z2);
```
Es wird aber nur z dargestellt bzw. wenn ich z auskommentiere z2. Das wird wahrscheinlich an den 2 paint Methoden liegen, die sich da gegenseitig ins Gehege kommen. Wie kann ich das Problem denn umgehen?


----------



## Marco13 (3. Okt 2007)

Nee, eigentlich passt das schon. Natürlich braucht jede Component ihre eigene paintComponent Methode. Was das (x,y) ist, was da übergeben wird, ist mir aber nicht ganz klar.

Nur die Sache mit der 41 ist nicht so schön. Wenn's wenigstens 42 wäre, aber nein... :? 
Du kannst die aktuelle Größe einer Zelle ja ausrechen: Die Breite des Panels durch die Anzahl der Zellen.

However, das Problem ist vermutlich ein falscher LayoutManager, in der Component, wo du die beiden Panels mit "add" hinzufügst. Ein GridLayout(1,2) sollte es da tun...

```
class Hauptpanel extends JPanel
{
    public Hauptpanel()
    {
         super(new BorderLayout());
         add(panelMitButtonsUndSo, BorderLayout.NORTH);

         //--->--- relevanter Teil
         Zeichenflaeche z = new Zeichenflaeche(600, 200);
         Zeichenflaeche z2 = new Zeichenflaeche(100, 200);

         JPanel spielfelderPanel = new JPanel(new GridLayout(1,2));
         spielfelderPanel.add(z);
         spielfelderPanel.add(z2);
         //---<--- relevanter Teil

         add(spielfelderPanel, BorderLayout.CENTER);
    }
}
```


----------



## Neolity (3. Okt 2007)

Also die 41 Pixel kommen von 40 Pixeln Breite und Höhe plus 1 Pixel für die Linie.

x und y geben mehr oder weniger die Koordinaten an, ab der die jeweiligen Kästchen gezeichnet werden.
100, 200 für das linke Gitternetz und 600, 200 für das rechte.


----------



## Neolity (9. Okt 2007)

Hallo,

das ganze funktioniert noch nicht wirklich wie gewollt....

So sieht die Klasse jetzt aus:


Klassenvariablen und Konstruktor:

```
Ki cpu = new Ki();
	Zeichenflaeche z = new Zeichenflaeche(10, 200);
	Zeichenflaeche z2 = new Zeichenflaeche(600, 200);
	JPanel spielerfelderPanel = new JPanel(new GridLayout(1, 2));
        
	Test()
	{
		super("Test zur Maus");
		
		cpu.setzeSchiffe();
		
		setSize(1024, 768);
	
                spielerfelderPanel.add(z);
		spielerfelderPanel.add(z2);
                spielerfelderPanel.setBackground(Color.green);
                add(spielerfelderPanel);
		
		addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent we)
			{
				System.exit(0);
			}
		});
			
		setVisible(true);
	}
```

innere, private Klasse Zeichenflaeche mit MouseListener:

```
private class Zeichenflaeche extends JPanel
	{
		private int x;
		private int y;
		
		Zeichenflaeche(int x, int y)
		{
			this.x = x;
			this.y = y;
                     
                        /* MouseListener, der auf die Mausklicks reagiert. Liegt ein Klick innerhalb eines Rechtecks, werden
                        die Koordinaten und der String "Drin!!!" auf Konsolenebene ausgegeben */
                        addMouseListener(new MouseAdapter()
                        {
                            public void mouseClicked(MouseEvent me)
                            {
                        	System.out.println((me.getX() - 600) / 41 + " / " + (me.getY() - 200) / 41);
                            }
                	});		
                }
		
		public void paintComponent(Graphics g)
		{
			super.paintComponent(g);
			
			((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			
			/* Zeichnen der Rechtecke */
			int k = x;
			int l = y;
			for (int i = 0; i < 10; i++)
			{
				l = y + i * 41;
				for (int j = 0; j < 10; j++)
				{
					k += 41;
					g.drawRect(k, l, 41, 41);
				}
				k = x;
			}
		}
	}
```

- Wenn man das kompiliert und startet, dann wird nur z auf dem Bildschirm gezeichnet. Die 2. Zeichenflaeche z2 wird
   nicht gezeichnet. 
- Kommentiert man z und das Hinzufügen von z aus, so wird z2 gezeichnet.
- Fügt man zunächst z2 zum Panel hinzu und danach z, so wird nur z2 gezeichnet.

Hat das nicht evt. doch was mit der paintComponent zu tun?

Außerdem habe ich mir vorgestellt, dass man jetzt nur noch im Panel klicken kann und nicht mehr im ganzen Fenster. Dem ist aber leider nicht so... 

Vielen Dank für die Hilfe!


----------



## Marco13 (9. Okt 2007)

```
Test()
	{
                ...
                spielerfelderPanel.setLayout(new GridLayout(1,2)); // <--- !!!
                spielerfelderPanel.add(z);
		spielerfelderPanel.add(z2);
                ....
	}
```



			
				Neolity hat gesagt.:
			
		

> Außerdem habe ich mir vorgestellt, dass man jetzt nur noch im Panel klicken kann und nicht mehr im ganzen Fenster.


Wie sollte sich das äußern? Soll der Mauscursor im Panel "gefangen" sein? :lol:


----------



## Neolity (9. Okt 2007)

Das hilft leider auch nicht! Immer noch gleiches Problem...

Beim Mauszeiger habe ich eher daran gedacht, dass Mausklicks außerhalb des Panels nicht registriert werden, da man die ja für das Spiel nicht braucht....


----------



## Marco13 (9. Okt 2007)

Was machst du innerhalb der Zeichenfläche mit den übergebenen x,y-Koordinaten?


----------



## Neolity (9. Okt 2007)

```
int k = x;
			int l = y;
			for (int i = 0; i < 10; i++)
			{
				l = y + i * 41;
				for (int j = 0; j < 10; j++)
				{
					k += 41;
					g.drawRect(k, l, 41, 41);
				}
				k = x;
			}
```

In diesem Teil berechne ich die Postionen der einzelnen Rechtecke. Da es 2 Instanzen der Klasse Zeichenflaeche gibt, sollte das doch eigentlich kein Problem sein, oder?


----------



## Marco13 (9. Okt 2007)

Ja doch. Das rechte Panel liegt vielleicht an der Position (600,200). Aber wenn man in diesem Panel zeichnet, liegt die linke obere Ecke immernoch bei (0,0). Ansonsten würdest du auch mit der Abfrage der Mauskoordinaten ein Problem kriegen. Wie schon in einem meiner ersten Beiträge gesagt: Das Panel sollte NUR das Spielfeld enthalten (und keinen Offset, Rand oder sonstwas). Damit machst du dir das Leben VIEL einfacher. 

```
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class SchiffeVersenken extends JFrame
{
    public static void main(String args[])
    {
        new SchiffeVersenken();
    }

    //Ki cpu = new Ki();
    Zeichenflaeche z = new Zeichenflaeche(10, 200);
    Zeichenflaeche z2 = new Zeichenflaeche(10, 200);
    JPanel spielerfelderPanel = new JPanel(new GridLayout(1, 2, 20, 20));

    SchiffeVersenken()
    {
        super("Test zur Maus");

        //cpu.setzeSchiffe();

        setSize(1024, 768);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        spielerfelderPanel.add(z);
        spielerfelderPanel.add(z2);
        spielerfelderPanel.setBackground(Color.green);
        add(spielerfelderPanel);

        setVisible(true);
    }


    private class Zeichenflaeche extends JPanel
    {
        Zeichenflaeche(int x, int y)
        {
            addMouseListener(new MouseAdapter()
            {
                public void mouseClicked(MouseEvent me)
                {
                    int x = me.getX()/ 41;
                    int y = me.getY()/ 41;
                    System.out.println(x + " / " + y);
                }
            });
        }

        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);

            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            /* Zeichnen der Rechtecke */
            for(int i = 0; i < 10; i++)
            {
                for(int j = 0; j < 10; j++)
                {
                    g.drawRect(i*41, j*41, 41, 41);
                }
            }
        }
    }
}
```

Wenn dir jetzt nicht gefällt, dass die Felder direkt oben links in der Ecke kleben (wovon ich ausgehe :wink: ) dann kannst du das durch ein anderes (geeignetes) Layout ändern, zum Beispiel(!) so

```
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class SchiffeVersenken extends JFrame
{
    public static void main(String args[])
    {
        new SchiffeVersenken();
    }

    //Ki cpu = new Ki();
    Zeichenflaeche z = new Zeichenflaeche(10, 200);
    Zeichenflaeche z2 = new Zeichenflaeche(10, 200);
    JPanel spielerfelderPanel = new JPanel(new FlowLayout());

    SchiffeVersenken()
    {
        super("Test zur Maus");

        //cpu.setzeSchiffe();

        setSize(1024, 768);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        spielerfelderPanel.add(z);
        z.setPreferredSize(new Dimension(410,410));
        spielerfelderPanel.add(z2);
        z2.setPreferredSize(new Dimension(410,410));
        spielerfelderPanel.setBackground(Color.green);
        add(spielerfelderPanel);

        setVisible(true);
    }


    private class Zeichenflaeche extends JPanel
    {
        Zeichenflaeche(int x, int y)
        {
            addMouseListener(new MouseAdapter()
            {
                public void mouseClicked(MouseEvent me)
                {
                    int x = me.getX()/ 41;
                    int y = me.getY()/ 41;
                    System.out.println(x + " / " + y);
                }
            });
        }

        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);

            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            /* Zeichnen der Rechtecke */
            for(int i = 0; i < 10; i++)
            {
                for(int j = 0; j < 10; j++)
                {
                    g.drawRect(i*41, j*41, 41, 41);
                }
            }
        }
    }
}
```

Aber an der Zeichenflaeche sollte sich nicht mehr so viel ändern.... Vor allem eben keine x/y-Offsets und so...


----------



## Neolity (9. Okt 2007)

Vielen Dank, das funktioniert jetzt! die Dimension habe ich noch auf (420, 420) erweitert, weil sonst die beiden letzten Linien verschluckt wurden, aber das war ja kein großes Ding. 

Diese Variante die Kästchen zu zeichnen war eigentlich wieder typisch für mich! Mir fehlt da noch etwas der Blick für "das Einfache". 

Nun wollte ich das noch wirklich in die Mitte des Fensters platzieren. Dazu habe ich dem Fenster mit setLayout(new BorderLayout()); ein BorderLayout zugewiesen und das spielerfelderPanel mit add(spielerfelderPanel, BorderLayout.CENTER); eigentlich auch der Mitte zugewiesen. Aber es tut sich leider nichts....


----------



## Marco13 (9. Okt 2007)

Solange im CENTER die einzige Component liegt, tut sich da auch nichts. Man kann mit dem Layout i.a. nur eine "relative lage" der Components zueinander beschreiben. Man könnte jetzt einen LayoutManager schreiben, der die Components immer in der Mitte platziert, oder so... aber ... ob sich das lohnt? Wichtig ist ja eigentlich erstmal, dass die Spielfelder immer die gewünschte Größe haben - wenn du die Lage wirklich pixelgenau angeben willst, kannst du statt des FlowLayout() im spielfelderPanel auch ein 'null' verwenden, und die Spielfelder dann einzeln mit "setBounds()" platzieren, aber sobald dann noch weitere Components (Buttons etc.) dazukommen oder die Fenstergröße sich ändert, verschiebt sich auch das spielfelderPanel wieder.... Im Idealfall sollten sich die Spielfelder auch eher der verfügbaren Größe anpassen (fallst du nicht irgendwelche Images reinmalen willst) ... dann würde auch die vielfach kritisierte "41" verschwinden....


----------



## BlinderOpa (26. Nov 2007)

also ich hab das Problem mit Mouseevent nur innerhalb des Panels so gelöst:


```
public void mouseClicked(MouseEvent m)
	{
	
		if( m.getSource() instanceof SpielfeldPanelModule) {
			SpielfeldPanelModule sfm = (SpielfeldPanelModule)m.getSource();

			neuX= m.getX();
			neuY = m.getY();
			neuX -= sfm.getInsets().left;
			neuX -= 20;
			neuY -= sfm.getInsets().top;
			neuY -= 20;
			neuX = (int)Math.floor(neuX / 20d)+1;
			neuY = (int)Math.floor(neuY / 20d)+1;
			
//			setneuX(neuX);
//			setneuY(neuY);
//			sfm.getSpielfeld();
			click=true;
		}	
		//Objekt ist jetzt richtig. aber der wartet nicht auf den input...-.-
		PvE.setneuX(neuX);
		PvE.setneuY(neuY);
		System.out.println(" Die Maus ist bei ( "+neuX+" | "+neuY+" )");
		}
```

hänge aber Momentan wie in einem anderen Thread schon erfragt daran, dass mein Hauptprogramm an der notwendigen Stelle nicht auf die Eingabe durch die Maus wartet...-.-


----------

