Schachbrettdarstellung

Tach zusammen,
wo ich schon mal dabei bin… :smile:

Ist hier jemand, der schon mal ein Schachbrett programmiert hat? Mich interessiert vor allem, wie das Brett am sinnvollsten und natürlich auch einfachsten dargestellt wird, so dass es beim Skalieren und Figurenbewegungen „vernünftig“ aussieht. Eignet sich da eher ein 8x8 (GridBag-)Layout, um das geklickte Feld einfacher identifizieren zu können? Oder doch eine große Grafik? Oder gibt es noch eine andere, bessere Möglichkeit? Und wie kann das Figurenziehen umgesetzt werden, ohne dass grafische Lücken entstehen oder die Brettanzeige verschwindet?

Hmm…kann jemand helfen?

Moin

Ist hier jemand, der schon mal ein Schachbrett programmiert
hat? Mich interessiert vor allem, wie das Brett am
sinnvollsten und natürlich auch einfachsten dargestellt wird,
so dass es beim Skalieren und Figurenbewegungen „vernünftig“
aussieht. Eignet sich da eher ein 8x8 (GridBag-)Layout, um das
geklickte Feld einfacher identifizieren zu können? Oder doch
eine große Grafik? Oder gibt es noch eine andere, bessere
Möglichkeit? Und wie kann das Figurenziehen umgesetzt werden,
ohne dass grafische Lücken entstehen oder die Brettanzeige
verschwindet?

Schachbretter hab ich noch nicht programmiert, hab aber länger an einer iso-Darstellung gearbeitet:

Wenn die Graphic nicht ganz flüssig sein muss, sprich die Figuren von einem Feld zum anderen springen, kann man mit JButton und Gridbag arbeiten.

Man erzeugt ein Gridbag, füllt es mit JButtons und reg. die entsprechenden ActionListener. Dadurch wird die klickdetection SEHR einfach. Die JButton können Icons darstellen. Die Icons kann man im Vorraus erzeugen (alle Figuren auf den 2 Feldern). Man sieht dann nur die Icons und die Ränder um die Buttons.

ABER:

Bei resize müssen neue Icone her. Beliebige „Zoom-stufen“ sind also schwierig.

Figuren können sich nicht in einer Animation von einem Feld zu einem anderen bewegen, sie springen immer.

Animationen von Figuren (der King krazt sich am Ohr…) sind auch tabu. Ist theo. möglich, aber dafür ist das paint-swing-awt-…etc. System von java zu langsam.

Die 2. Möglichkeit ist ein costum-System. Du schreibst dir eine Klasse die von Canvas erbt und zeichnest alles selbst. Dabei kann man Vector-graphiken einsetzen (Zoom frei einstellbar !), das java pendant zum Framebuffer (BufferedImage) einsetzen und Animationen basteln (java.awt.Component.getGraphics()). Die Maus kann dabei relativ einfach per MouseListener (Mousemotion- und Mouse-Listener) kontrollieren. Der Motionlistener sollte allerdings schnell und kurz sein, da er oft aufgerufen wird.

Dabei sollte man:

  1. Auf den Typ der BufferedImage aufpassen. Lass die JVM entscheiden was für sie am günstigen ist.

  2. den Repaintmanager für das Canvas „ausschalten“.

  3. Im vorraus BufferedImages in der aktuellen Zoom-stufe erzeugen, falls Animationen/Bewegungen anstehen.

  4. Die Mehtode paint(Graphics g) der Canvas als letzten Rettungsanker betrachten und nur benutzen (lassen) wenn’s wirklich nicht anderes geht.

4.2. repaint() ist Tabu, weil sehr langsam.

Die JVM kann auch mit vielen BufferedImages umgehen, der Speicherverbrauch ist relativ gering, und gc macht ab Version 1.4.0 auch keine Probleme mehr.

Die Buttons und Spielkontrollen würd ich aber in jedem Fall mit normalen java-swing Elementen erzeugen. Die Funkionalität der Buttons ist schon klasse.

ich hoffe ich konnte helfen.

Moin

Wenn die Graphic nicht ganz flüssig sein muss, sprich die
Figuren von einem Feld zum anderen springen, kann man mit
JButton und Gridbag arbeiten.

Das reicht wohl auf jeden Fall.

Man erzeugt ein Gridbag, füllt es mit JButtons und reg. die
entsprechenden ActionListener. Dadurch wird die klickdetection
SEHR einfach. Die JButton können Icons darstellen. Die Icons
kann man im Vorraus erzeugen (alle Figuren auf den 2 Feldern).
Man sieht dann nur die Icons und die Ränder um die Buttons.

ABER:

Bei resize müssen neue Icone her. Beliebige „Zoom-stufen“ sind
also schwierig.

Hmm. Ich denke, das GBL ist doch gerade für resize/zooming besonders geeignet. Und wenn die einzenen Felder=Buttons die Zelle ausfüllen, sollte das beim zoomen keine Probleme bereiten. Vielleicht ist der Begriff Zoom an dieser Stelle auch falsch, ich meinte eher skalieren.

Figuren können sich nicht in einer Animation von einem Feld zu
einem anderen bewegen, sie springen immer.

Animiert sollen sie auch nicht werden, also kein laufender Bauer oder so. Triviale Möglichkeit ist klar, das ist Anklicken des Startfeldes und dann Anklicken des Zielfeldes, woraufhin die beiden Felder mit den aktualisierten Grafiken neu angezeigt werden. Die elegantere Möglichkeit ist das „Schleppen“ der Figuren. Hierbei wird beim Klick auf das Ausgangsfeld die Figur angefasst, wandert mit der Maus mit - schwebt also förmlich über dem Brett - und wird dann auf dem Zielfeld wieder losgelassen. Hmm, kann man für sowas den Mauszeiger temporär ändern, so dass er für die Zeit während des Mausziehens aussieht wie die entsprechende Figur?

Animationen von Figuren (der King krazt sich am Ohr…) sind
auch tabu. Ist theo. möglich, aber dafür ist das
paint-swing-awt-…etc. System von java zu langsam.

S.o., für mich uninteressant. Sowas soll Eidos mit Battlechess XP oder so ähhnlich übernehmen. :wink:

Die 2. Möglichkeit ist ein costum-System. Du schreibst dir
eine Klasse die von Canvas erbt und zeichnest alles selbst.
Dabei kann man Vector-graphiken einsetzen (Zoom frei
einstellbar !), das java pendant zum Framebuffer
(BufferedImage) einsetzen und Animationen basteln
(java.awt.Component.getGraphics()). Die Maus kann dabei
relativ einfach per MouseListener (Mousemotion- und
Mouse-Listener) kontrollieren. Der Motionlistener sollte
allerdings schnell und kurz sein, da er oft aufgerufen wird.

Dabei sollte man:

  1. Auf den Typ der BufferedImage aufpassen. Lass die JVM
    entscheiden was für sie am günstigen ist.

  2. den Repaintmanager für das Canvas „ausschalten“.

Mal schauen, wie das überhaupt geht…

  1. Im vorraus BufferedImages in der aktuellen Zoom-stufe
    erzeugen, falls Animationen/Bewegungen anstehen.

S.o., eher skalieren als zoomen. Ist deshalb vermutlich auch nicht nötig.

  1. Die Mehtode paint(Graphics g) der Canvas als letzten
    Rettungsanker betrachten und nur benutzen (lassen) wenn’s
    wirklich nicht anderes geht.

4.2. repaint() ist Tabu, weil sehr langsam.

Das verstehe ich nicht so ganz. AFAIK ist paint(Graphics g) doch DIE Methode, mit der man wirklich selbst zeichnen kann. Wenn sie nicht zu verwenden ist, wie soll es dann umgesetzt werden?

Die Buttons und Spielkontrollen würd ich aber in jedem Fall
mit normalen java-swing Elementen erzeugen. Die Funkionalität
der Buttons ist schon klasse.

Ja, das ist klar, da sehe ich auch weniger das Problem. Ich hadere immer noch mit dem Brett, tendiere aber zum GBL… :smile:

ich hoffe ich konnte helfen.

Thx, auf jeden Fall!
BTW kennst Du (oder ein anderer Leser hier) ein deutschsprachiges Forum o.ä., wo sich Experten etwas intensiver (oder gar ausschliesslich) mit Java-Schachprogrammierung beschäftigen? Aufgrund der Geschwindigkeit, die ja das A und O für Schachprogramme sind, ist Java nicht gerade sonderlich geeignet für ein (starkes) Schachprogramm, aber zumindest ein bisschen Datenbank-ähnliche Anwendung mit Nachspielen und Abspeichern usw. solle ja wohl mit Java möglich sein. Lässt sich eigentlich auch ggf. eine C++ oder Assembler-dll in Java einbinden? Läuft dann wohl nur auf Window$-Rechnern, aber man hätte dafür wenigstens einen flottere Motor für das rechnende Schachprogramm („engine“).

Danke schon mal!
Harald

Moin

Hmm. Ich denke, das GBL ist doch gerade für resize/zooming
besonders geeignet. Und wenn die einzenen Felder=Buttons die
Zelle ausfüllen, sollte das beim zoomen keine Probleme
bereiten. Vielleicht ist der Begriff Zoom an dieser Stelle
auch falsch, ich meinte eher skalieren.

Das Problem sind die Icone. Wenn das Icon den gesamten Button ausfüllen soll muss es immer genau so gross sein wei der Button. Wird der Button durch das resize grösser so sieht man den Button an sich, also einen grauen Rand. Wird der Button kleiner sieht man nur noch einen Teil der Figur, nämlich die obere linke Ecke.

Das meinte ich mit Zoom.

Figuren können sich nicht in einer Animation von einem Feld zu
einem anderen bewegen, sie springen immer.

Die elegantere Möglichkeit ist das
„Schleppen“ der Figuren. Hierbei wird beim Klick auf das
Ausgangsfeld die Figur angefasst, wandert mit der Maus mit -
schwebt also förmlich über dem Brett - und wird dann auf dem
Zielfeld wieder losgelassen. Hmm, kann man für sowas den
Mauszeiger temporär ändern, so dass er für die Zeit während
des Mausziehens aussieht wie die entsprechende Figur?

Theo. ja, aber X (also fast alle Unix-systeme) machen da nicht mit. Ausserdem ist die Grösse des Mauszeigers begrenzt auf etwa 100x100 Pixel.

  1. Die Mehtode paint(Graphics g) der Canvas als letzten
    Rettungsanker betrachten und nur benutzen (lassen) wenn’s
    wirklich nicht anderes geht.

4.2. repaint() ist Tabu, weil sehr langsam.

Das verstehe ich nicht so ganz. AFAIK ist paint(Graphics g)
doch DIE Methode, mit der man wirklich selbst zeichnen kann.
Wenn sie nicht zu verwenden ist, wie soll es dann umgesetzt
werden?

Das Problem ist nur die Geschwindigkeit:

paint wird aufgerufen wenn:

  1. Etwas sichtbar wird was verdeckt war

  2. repaint aufgerufen wurde

  3. Ist kein Problem. Wenn das Fenster im Hintergrund war sollte man eh alle Animationen stoppen.

  4. Ist SEHR langsam. zwischen dem repaint()-call und dazu passenden paint() vergehen min. 100 ms. Typ. sind 250 ms bei Applets, 200 ma bei Programmen. Das ist für Animationen tötlich, das beschränkt die fps schonmal auf 4 und man hat noch nichts gezeichnet.

Man umgeht die Wartezeit in dem man sich die Graphics einfach selbst besorgt mit getGraphics. Das Graphics-Object entspricht den Graphics-Object aus paint() und die gezeichneten Linen, Punkte werden direkt sichtbar. Nur Bilder können noch etwas mehr Zeit (