Java Projekt Schiffe-versenken: Komme nicht weiter

I-Bot18

Lt. Junior Grade
Registriert
Nov. 2010
Beiträge
291
Hey,

ich habe mir nun in den Kopf gesetzt nach 2 Jahren Programmierungerfahrung und meinem Studium Wirtschaftsinformatik, mal ein größeres Projekt zu machen. Wie im Titel erwähnt will ich ein einfaches Schiffe versenken programmieren.

Nun zu meinem Problem bei dem ich im Moment häng:

Ich erzeuge ein Frame und füge diesem ein Panel hinzu, das aus lauter 35*35 Px-Feldern besteht, die als Raster für später dienen sollen.
Darüber lege ich ein Button[][]Array, das gefüllt mit, wer hätte es gedacht, JButtons.

Nun soll der Button der Angeklickt wird unsichtbar werden (das klappt auch problemlos) und anschließend eine Methode aufgerufen wird, die an entsprechender Stelle ein X oder einen Kreis zeichnet.

Und hier hänge ich. Ich kann nicht einfach ein DrawLine()machen, da ja stets nur ein Panel dargestellt werden kann, und ich somit mein Raster darunter nicht sichbar machen würde => CardLayout fällt weg.

Ich bin im Moment relativ Ideen los wie ich es hinbekommen kann ein Raster und eine entsprechende Markierung zu setzen (Muss nich mal ein X oder ein Kreis sein)...

Vielleicht könnt ihr mir ja weiter helfen ?

Mit freundlichem Gruß,
Tobi
 
Wie sieht es aus, wenn du Bilder auf die Buttons legst? BZW bin gerade nicht sicher ob ich das Problem verstanden habe
 
Du meinst 2 Bilder drau (einen für getroffen und einen für gewassert) und dann jenachdem eins davon sichtbar machen ?
 
Mahlzeit,

du könntest dir ne neue Klasse bauen, die von JButton erbt und die paint-Methode überschreibt.
Wenn alles "normal" ist, wird die paint-methode von JButton aufgerufen (parent, super oder wie das in Java heißt)
ansonsten nen Kreis gemalt. Alternativ onClick das Icon wechseln ;-)

Gruß
 
KP sollte ja klappen, aber ich kenn mich mit Swing nicht so aus. Frag mich auch ob Buttons in deinem Fall sinnvoll sind
 
Ich würde das überhaupt nicht mit Buttons machen, sondern den zustand z.b. in einem 2D Array mit Objekten einer eigenen Klasse speichern, die den Status eines einzelnen Feldes repräsentiert, und das dann in festen Intervallen auf ein JComponent malen. Damit hast du model und view gleich sauber getrennt.
Dann müsstest du auch nicht gleich die endgültige GUI implementieren, sondern könntest das ganze erst mal prototypisch machen, z.B. als Text Ein/Ausgabe, und dich um die Spiellogik kümmern.
 
Imho sind diese Standard-Komponenten nur bedingt für Spiele geeignet. Das einzige was sie ersparen, ist das Feststellen des angeklickten "Feldes". Dafür schleppen sie haufenweise Ballast mit sich herum, den du nicht brauchst.

Eine Alternative wäre die paintComponent-Methode des Panels zu überschreiben und sämtliches Rendering selbst zu übernehmen. Da kannst du dann auch drawLine und solche Späße machen, wobei du vermutlich besser dran bist, das Spielfeld als Grafik zu erstellen, denn dann ist es mit einem einzigen drawImage getan. Dann musst du nur noch ein bisschen Logik schreiben um zum Klickzeitpunkt festzustellen, wo der Mauszeiger ist und welches Feld sich darunter befindet. Da alle Felder gleich groß sind, ist das leicht zu berechnen. Brauchst ja nur den offset zu dem Punkt berechnen, an dem du das Spielfeld gezeichnet hast.

Wenn du schon dabei bist, würde ich alles als Images rendern. Performt gut und sieht wesentlich besser aus.
 
Also erstmal danke für die vielen Antworten =)
Wenn ich so überlege sagt mir die Methode von Tumbleweed am meisten zu:

Um mal kurz zu rekapitulieren ob ich das richtig verstanden hab:

- Ich erzeuge ein Image als Spielfeld (z.B. in PS), und lade das dann mit ner g.drawImage() in meiner Panel-Klasse und füge wiederrum ein Objekt dieser Klasse in mein Frame hinzu
- Dann überprüfe ich wo geklickt wurde (nehm mal an da gibts so was wie ne mouse.getposition() oder so) und überprüfe auf welchem "Feld" der Mauszeiger ist und führe dementsprechend eine drawLine() durch

So richtig?
 
Arbeite dich doch in Slick2D ein, dann übernimmt der Gameloop das updaten des Frames.
Mittels der GameState Klasse, glaube so heißt sie, kannst du die einzelnen Game Situationen abbilden und musst diese dann nur noch aufrufen.
So kannst du dich mehr der Game Logic widmen.
Ist nur ein allgemeiner Tipp, habe lange nicht mehr mit Slick2D gearbeitet
 
I-Bot18 schrieb:
- Ich erzeuge ein Image als Spielfeld (z.B. in PS), und lade das dann mit ner g.drawImage() in meiner Panel-Klasse und füge wiederrum ein Objekt dieser Klasse in mein Frame hinzu
Da dein Spielfeld ja aus mehreren Elementen besteht die unterschiedliche Zustände haben können, malst du nicht nur ein Image, sondern für jedes Feld eins (oder mehrere überlagernde). Du kannst natürlich auch ein festes Hintergrundbild haben um das Gitternetz darzustellen, aber wenn du auch das aus einzelnen Bildern zusammensetzt, dann kannst du sogar die Spielfeldgröße wählbar machen.
I-Bot18 schrieb:
- Dann überprüfe ich wo geklickt wurde (nehm mal an da gibts so was wie ne mouse.getposition() oder so) und überprüfe auf welchem "Feld" der Mauszeiger ist und führe dementsprechend eine drawLine() durch

Du registrierst bei dem JComponent (oder JPanel, oder einer anderen Unterklasse die in deinem Fall sinnvoll sein könnte) einen Mouselistener. Wenn der Benutzer klickt, dann bekommt der von dir implementierte Listener ein MouseEvent, welches Methoden hat um dir die Position des Mausklicks relativ zum Nullpunkt des JComponent liefert.

Ich empfehle dir mal die Tutorials für Swing Eventlistener und Java2D zu lesen.
 
Um es dir etwas leichter zu machen:

Baue nicht ein Feld aus JButtons, sondern aus JCompontent.

Wenn ein Button gedrückt ist, so weißt du (kann man implementieren), wo dieser im Array liegt.

Nun erstetzt du den JButtons mit einem JLabel, das mit nichts oder einem X - also Treffer gefüllt ist.

Wenn du es noch ein wenig geschickter anstellen willst, bau dir einen Adapter für JButton/JLabel. Also erbe von JComponent, und füge halt noch die Funktionen makeX, makeO (für kein Treffer) hinzu. So könntest du diesen Zustand darstellen.

Noch ein kleiner Tipp am Rande: Man benötigt auch kein JButton um MouseListener auszuführen, auch Labels haben diese ;-), d.h. du kannst dir das obere Sparen ;). Dafür kannst du dann sogar ein BoxLayout wählen ;).

Die Position des Feldes kannst du auch in den Namen reincodieren (Nicht in den Text - dieser wird ja angezeigt), so ist evtl. deine Datenhaltung leichter ;)
 
DjNDB schrieb:
Da dein Spielfeld ja aus mehreren Elementen besteht die unterschiedliche Zustände haben können, malst du nicht nur ein Image, sondern für jedes Feld eins (oder mehrere überlagernde). Du kannst natürlich auch ein festes Hintergrundbild haben um das Gitternetz darzustellen, aber wenn du auch das aus einzelnen Bildern zusammensetzt, dann kannst du sogar die Spielfeldgröße wählbar machen.


Du registrierst bei dem JComponent (oder JPanel, oder einer anderen Unterklasse die in deinem Fall sinnvoll sein könnte) einen Mouselistener. Wenn der Benutzer klickt, dann bekommt der von dir implementierte Listener ein MouseEvent, welches Methoden hat um dir die Position des Mausklicks relativ zum Nullpunkt des JComponent liefert.

Ich empfehle dir mal die Tutorials für Swing Eventlistener und Java2D zu lesen.

Also ich bin nochmal alles durchgegangen.
Es ist doch bestimmt möglich 3 Felder übereinander zu machen oder?
Denn dann würde ich als oberstes das leere und dann darunter eins mit nem X als Image und eins mit nem O als Image und je nachdem welcher Zustand ist (z.B.: int 1,2 oder 3) soll das Feld sichtbar gemacht werden...
Ist das so möglich ?
 
Ich würde nicht alle Übereinander malen, sondern nur jeweils das was zutrifft. Dabei muss das Bild natürlich einen Alphakanal für Transparenz haben.
Du iterierst über dein 2D Array, und malst für jedes Feld das Hintergrundbild (Teil des Gitternetzes), und darüber das X oder O, je nach Wert im Array.

Ich hab mal einen alten Prototypen von mir herausgekramt und aktualisiert. Darin kannst du sehen wie das funktionieren könnte. Unten findest du ein .zip mit Quellcode und Ausführbarem .jar.
Das gewinnt sicher keinen Schönheitspreis, aber genügt u es zu verdeutlichen. Außerdem sind noch ein paar Benchmarking Ausgaben enthalten. Das war damals (2006) ein Prototyp für die GUI meines Boulderdash remakes. Da gab es noch Performanceprobleme in Java2D, da man für Hardwarebeschleunigung noch Tricks anwenden musste, die ich darin getestet habe. Die habe ich nun aber alle aus dem Code entfernt, da es auch einfacher geht.
Wenn du dich wunderst, dass alles Zittert: Es ging damals um Animation, deswegen wollte ich sehen können, dass neu gemalt wird.

paintcrap.png
 

Anhänge

Zuletzt bearbeitet:
Super danke =)

Werd ich mir demnächst mal reinziehen, etz muss ich mit dem projekt eh mal 2 wochen lang pausieren, weil wir ne projektarbeit von der Uni ham...aber des is wenigstens was leichtes im Vergleich hierzu :D
 
Zurück
Oben