Portal > Foren > Java > Desktop-Applikationen und Grafik > awt.Canvas Spielfeld: Über welchem Feld ist die Maus?
Antwort
 
Themen-Optionen Thema durchsuchen
Alt 14.06.2005, 18:43 Nach oben    #1
matt
Gast
 
Beiträge: n/a
Standard awt.Canvas Spielfeld: Über welchem Feld ist die Maus?

Hallo alle mal!
Das ist vielleicht eine seltsame frage, aber:
Ich habe ein Spielfeld, welches aus Hexagonen besteht, die wie eine Bienenwabe angeordnet sind.
Das sieht ungefähr so aus wie auf diesem bild (auch wenn das aus google ist und nichts mit meinem programm zu tun hat)

nun ist es so, dass jede einzelne Zelle eine verbindung zu den sechs angrenzenden plus den nähesten beiden in der selben zeile hat. Das ganze funktioniert vom Prinzip her wie eine doppelt verlinkte Liste - aber eben mit 4 richtungen (eine von nord nach süd und umgekehrt, eine von ost nach west und umgekehrt, eine von Nordost nach Südwest und umgekehrt und schließlich eine von Nordwest nach Südost und zurück) Das ganze wird in einem Canvas dargestellt.

Das Problem ist nun das ich immer einen überblick darüber brauche, in welchem feld die Maus gerade ist. (ergänzend ist noch zu sagen, dass dieses Feld verdammt groß werden kann, also kann man nicht durch alle Felder gehen um zu gucken, ob die Maus gerade über diesem bestimmten ist)

Die frage ist nun: Gibt es eine möglichkeit, in Canvas oder etwas vergleichbarem, einen "Bereich" zu definieren, der einen Event auslöst, wenn die maus darüber fährt? (so etwa wie mit hyperlinks in html, die unterstrichen werden bzw. die farbe verändern, wenn man mit der maus darüberfährt)

Alternativ, wäre folgende Herangehensweise sinnvoll:
Zuerst: war die maus bei dem zeitpunkt der letzten bewegung in einem feld? Wenn ja: ist sie in dem selben feld, oder ist sie nun in einem angrenzenden feld?
Ansonten:
Das Feld wird in zwei bereiche geteilt: alle felder links der mitte und alle rechts der Mitte. Ist die maus links der Mitte wird auch dieses feld wieder gespalten wobei es jetzt in alle felder über bzw. unter der vertikalen mitte geteilt wird.

gibt es da eine bessere alternative, oder ist diese hier schon okay?
Ich bin auf eure antworten gespannt,
Liebe grüße schon mal im voraus, Matthias
 
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 23.06.2005, 15:29 Nach oben    #2
mr.no
Gast
 
Beiträge: n/a
Standard

Hi matt,
brauchst du überhautp Canvas? Ich habe auch schonmal eine Spieloberfläche geschrieben und habe alles auf "this" zeichnen lassen. Da kannste dann die ganz normalen events benutzen.
 
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 23.06.2005, 15:41 Nach oben    #3
Ben
Benjamin Klaile
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.512
Standard

Wie stellst Du denn eigentlich die Flächen dar? Also einfach nur, indem Du Linien zeichnest oder setzt Du da andere Komponenten oder sogar Bilder ein?
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 23.06.2005, 17:29 Nach oben    #4
matt
Gast
 
Beiträge: n/a
Standard

Hey danke für die antworten:

Also mal zuerst: von einem objekt welcher klasse redest du, wenn du dich auf "this" beziehst (ein JFrame?) Canvas bieten ja auch die Möglichkeit, event handler anzuhängen. Das problem ist ja nur, dass meine Felder sechseckig sind und ich daher keine "kleinen" GUI widgets nebeneinander packen kann (weil die eben alle viereckig sind und sich so vollkommen falsch überlappen würden) jetzt ist eben die frage, ob das nicht eventuell doch geht, bzw. ob man irgendwelche "Bereiche" definieren kann, die einen MouseListener bekommen (wobei diese Bereiche dann natürlich sechseckig sein müssten)

Als alternative habe ich folgenden algorithmus im Auge: Durch die Position der maus kann man ungefähr berechnen in welchem Hexagon sich die maus befindet (jedes hexagon hat eine höhe und eine breite) so würde es zwar zu unstimmigkeiten bei den schrägen kommen, nur man könnte ja sagen, dass man das errechnete Hexagon untersucht plus alle ankreuzenden (dann hätte man 7 hexagone zu untersuchen)
Das Hexagon, in dem die maus dann drinnen ist, wird gespeichert. Wird die maus wieder bewegt, untersucht man zuerst ob die maus das hexagon verlassen hat. Wenn ja untersucht man alle umliegenden, ob sie nun darin ist. Wenn dass auch nicht der fall ist, fängt man mit der berechnung von vorne an...

was haltet ihr davon?

So und zum zweiten Punkt: Die hexagone selbst werden durch eine Shape die mit einer AffiniateTransform skaliert wird derzeit über g.drawShape() gezeichnet. Der vorteil von Shapes ist natürlich dass sie eine methode haben, mit der man abfragen kann ob sich ein punkt in der form befindet.
Im anschluss will ich natürlich noch bilder da hineinpacken bzw. Vektorgrafiken aber das ist im ersten schritt noch nicht so wichtig.

Würde gerne mal euere Meinung hören.

Liebe grüße,
Matt
 
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.06.2005, 00:18 Nach oben    #5
mr.no
Gast
 
Beiträge: n/a
Standard

Um irgendwelche rechnungen, kommst du warscheinlich nicht herum. Es wäre warscheinlich auch die einfachste möglichkeite die Koordintaten des Mauszeigers auszulesen und dann durch eine formel zu berechnen in welchem Feld du dich gerade befindest. Da du diese linien zeichnen lässt, ist mir kein event für bestimmt gezeichnete Felder bekannt. (Zu dem this, meine oberfläche war auf einem applet. Deswegen hab ich es auf this zeichnen lassen).

mfg
mr.no
 
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.06.2005, 00:32 Nach oben    #6
matt
Gast
 
Beiträge: n/a
Standard

jepp, ich habe es inzwischen auch so gemacht. Es ist nur leider nicht möglich, wirklich zu berechnen, in welches feld die mausposition fällt, allerdings habe ich eine näherung hinbekommen, die 10 Felder, die in Frage kommen, fixieren kann. Da diese 10 felder je eine Shape haben, muss ich nur noch für 10 Shapes überprüfen, ob die mausposition darin ist. Das ganze läuft wunderbar schnell - selbst wenn man mit der maus darüberrast werden alle felder gefunden. (Und es ist um einiges besser, als alle felder zu durchsuchen bzw. die suche immer um die hälfte einzuschränken)

Wenn interesse herrscht, stelle ich die entsprechenden Teile hier online und erkläre kurz, wie es funktioniert. (Es ist eine überaus interessante Datenstruktur im hintergrund: eine beidseitig verlinkte Liste mit vier achsen und zusätzlich noch eine Matrix - also ein zweidimensionales Array)

Liebe grüße und danke für eure hilfe!

Matt
 
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.06.2005, 01:06 Nach oben    #7
Ben
Benjamin Klaile
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.512
Standard

Mich würde das interessieren!
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.06.2005, 02:07 Nach oben    #8
matt
Gast
 
Beiträge: n/a
Standard Mein Programm...

also mal eines vorweg: Mein Programm ist eigentlich kein "Spiel" im eigentlichen sinne, sondern soll ein "Landschaftsgenerator" werden. Diesen soll man (wenn er mal fertig wird) beispielsweise zum bauen von fantasy/Science Fiction Landschaften verwenden können.
Die Idee ist, dass die Karten in hexagone geteilt sind, weil das eine ziemlich gute form ist, die viel freiheit gibt, aber gleichzeitig auch nicht zu komplex ist.

Der Momentane entwicklungsstand ist folgender:


Ich habe den Quelltext des kompletten programms hochgeladen, allerdings will ich ihn nicht hier hineinstellen, weil ich das für zu unübersichtlich in diesem forum halte. unter: http://www.f4.fhtw-berlin.de/~s0511512/javafiles/
könnt ihr euch das gesamte ding ansehen (vieles ist noch in entwicklung und macht vielleicht noch keinen sinn also wundert euch nicht)
Was jedenfalls interessant ist, ist die Datenstruktur, in der die Karte gespeichert ist - um genau zu sein: die Datenstrukturen: Einerseits wird ein zweidimensionales Array verwendet, welches zeilen bzw. spaltenweise referenzen zu den terrainMaker.datastructure.Node ( http://www.f4.fhtw-berlin.de/~s0511512/javafiles/Node.java ) obj. hat. Das ist zwar für einen direkten zugriff sehr angenehm, allerdings hat es einen schweren Nachteil: da die einzelnen Elemente versetzt sind, ist es von gerader bzw. ungerader zeile abhängig, wo entsprechend angrenzende Elemente in den nächsten zeilen sind. Daher sind diese Nodes auch noch zusätzlich (bzw. vor allem!) in eine doppelt verlinkte Liste gepackt, diese hat allerdings nicht eine achse sondern vier (ich kann also von jedem node in 8 richtungen gehen: N, O, S, W, NO, SO, NW, NO) Diese liste berücksichtigt die verschiebung zwischen den zeilen bereits. Die Liste ist unter terrainMaker.dataStructure.TerrainMap ( http://www.f4.fhtw-berlin.de/~s0511512/javafiles/TerrainMap.java ) zu finden.

Bei dem initialisieren der Liste wird für jedes Element die Position errechnet und es bekommt eine "Form" zugewiesen (diese form ist das sechseck und wurde bereits an die stelle geschoben, an der es später sein soll)
Außerdem erhält jedes Element bei der Generierung noch ein TerrainBit Objekt, dass die Daten was auf dieser Fläche enthalten sein soll speichern kann.

Diese liste kann man nun durch einen TerrainMapIterator ablaufen und so jedes Element "besichtigen".
Genau das passiert auch, wenn die Elemente gezeichnet werden. Hierfür wird die Methode drawNode() von Node aufgerufen - diese zeichnet sich selbst auf ein gegebenes Spielfeld.

Was ich noch nicht erwähnt habe, ist dass die Klasse TerrainCanvas ( http://www.f4.fhtw-berlin.de/~s05115...ainCanvas.java ) die Hauptzeichenfläche ist. Diese hat einen MouseListener und einen MouseMotionListener, der in der Klasse TerrainMouseHandler ( http://www.f4.fhtw-berlin.de/~s05115...seHandler.java ) zu finden ist.

In dem TerrainMouseHandler steckt auch die Magie, die erkennt, über welcher Zelle sich die Maus befindet.
Das funktioniert folgendermaßen, dass ich davon ausgehe, dass, statistisch gesehen, jedes hexagon nur halb so hoch ist, wie es ist (weil die nächste zeile ja schon bei der halben höhe beginnt) allerdings 4/3 mal so breit ist (weil zwischen zwei hexagonen in einer zeile ja ein spalt ist) Dividiert man nun die mauskoordinaten durch diese werte, bekommt man einen ungefähren Wert eines Feldes, in dem die Maus sein könnte (genauer ist leider nicht auf diese art möglich, da die kanten ja schräg sind und die figuren überlappen)

Nun das macht allerdings nichts. Diese Position muss in der nähe der Maus sein. Durch eine Auswahlklasse terrainMaker.access.selections.AroundCellSelection - diese wählt eine Zelle und alle 8 umgebenden aus, wobei auch die beiden die in der selben spalte links und rechts von der mittigen zelle liegen ausgewählt werden obwohl diese die zelle nicht berühren.
Diese auswahl sieht grafisch dargestellt so aus:

Die Auswahl sind alle roten felder, das feld in der mitte ist die Errechnete mausposition. Diese stimmt allerdings rein garnicht, es ist sogar so, dass die maus immer irgendwo in dieser Auswahl ist. Die beiden äußersten Felder sind hierbei von großer Wichtigkeit, weil die Maus relativ oft in genau diesen beiden feldern ist.

Es macht allerdings nichts weiter, dass die Maus da irgendwo drinnen ist, denn sie ist immer da drinnen. Nun muss man nur noch alle Felder aus der Auswahl durchgehen (das ermöglicht die Auswahl selbst) und gucken, in welchem feld davon die Maus gerade ist. Dieses Feld ist dann die neue auswahl.
Übrigens wird die Auswahl in dem Canvas sofort überschrieben, sobald sie getroffen wird. Es wird kein repaint() erzwungen bzw. abgewartet. Da das Canvas vom typ CanvasJAI (aus dem Java Advanced Imaging framework) ist, funktioniert die getGraphics() methode immer und zuverlässig - man kann sich also jederzeit die Graphics holen und den gewünschten Bereich überschreiben.

Wird eine andere auswahl getroffen, wird die alte auswahl zuerst auf normal "zurücküberschrieben" und dann wird die neue Auswahl hervorgehoben.

Das Grundgerüst ist also vollständig fertig, jetzt müssen nur noch vieeele details kommen

bin auf eure kritik gespannt, Matt
 
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:16 Uhr.


Powered by vBulletin® Version 3.7.4 (Deutsch)
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45