Land aus einer Weltkarte selektieren

  • Themenstarter Themenstarter Gast
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
G

Gast

Gast
Hey,

ich bin neu hier und ich hoffe, dass ihr mir helfen könnt.

Ich möchte das Brettspiel Risiko als Computerspiel umsetzen. Dazu muss ich es schaffen, dass ich auf der Weltkarte, mit der Maus über ein Land fahren kann und dabei das Land farblich hervorgehoben wird. Wenn ich dann auf das Land klicke, soll eine bestimmte Aktion geschehen.

Nun meine Frage: Wie geht so etwas? Ich bin totaler Anfänger auf dem Gebiet. Kann mir jemand ein Tipp geben unter was ich da zum Bsp. bei google suchen muss. Ich finde nichts zu dem Thema bzw. weiß nicht so richtig unter was ich suchen soll?

Ich hab schon mal was von BufferedImage oder so gehört. Damit soll wohl so einiges möglich sein.

Meine Idee: Jedes Land ist zum Bsp. mit einer schwarzen Linie umrandet. Kann man dann einen Bereich, der vollkommen von einer solchen schwarzen Linie umrandet ist auswählen? Praktisch die Pixel auf die Farbe schwarz überprüfen. Wenn man dann alle Pixel gefunden hat (von einer Umrandung) dann kann man den Bereich zwischen diesen Pixeln auswählen.

Ist diese Idee umsetzbar oder totaler Quatsch?

Wäre echt nett, wenn mir jemand einen Tipp geben könnte.
 
Ach, "umsetzbar" ist vieles. Sind ja nur Bits. Also, man könnte das theoreitsch so machen: Man "füllt" den Bereich, über dem sich die Maus befindet, bis man an schwarze Pixel stößt. Aber das wäre ziemlich murksig und ineffizient. Besser wäre es, wenn du die Umrisse der Länder als Polygon hättest.... Wo gedenkst du denn die Karte herzubekommen?
 
Zum Weiterlesen empfehle ich dir, daß du dir mal die Klasse GeneralPath anguckst - mit der kannst du ein Polygon anhand eines Pfades (also deinen Linien) konstruieren.

Hier mal eine Beispiel-Methode:
Code:
private GeneralPath makePolygon(int sides, double[] x, double[] y,
			boolean closed) {
		GeneralPath polygon = new GeneralPath(Path2D.WIND_EVEN_ODD, sides);
		polygon.moveTo(x[0], y[0]);
		for (int i = 1; i < sides; i++)
			polygon.lineTo(x[i], y[i]);
		if (closed)
			polygon.closePath();
		return polygon;
	}
 
Erst mal danke für eure schnelle Antwort. Also wegen dem Bild: Entweder ich "male " das Bild mit einem Grafikprogramm selbst oder halt ein Bild bei Google suchen, oder das Spielbrett von Risiko abscannen. Macht das irgendwie einen Unterschied? Oder sollte ich eine Variante bevorzugen?
 
Das kannst Du machen, wie Du willst. 😉 Selber malen ist individueller 😉

Zum Thema Landerkennung noch eine andere Lösungsmöglichkeit: hier
 
Hi,

ich habe dazu mal in folgendem Post was geschrieben:
http://www.java-forum.org/de/viewtopic.php?t=70810&postdays=0&postorder=asc&start=0
Der Kram von mir beginnt auf Seite 2.

Das hilft dir vielleicht auch weiter.


Hab mal nen kleines Beispielprogramm geschrieben damit du siehst was ich meine.
Das gezeichnete Polygon könntest du dann über deine Grafik legen.
Ich hab die Transparenz auch direkt eingebaut.
Die Linie ist nicht transparent, der Füllbereich schon.

Ich finde diese Methode halt am sinnvollsten. Du musst halt nur schauen, dass das Polygon grob zu deinen Ländern passt. Voila dann gehts. 🙂

Viel Spaß damit.

Achso noch was. Das hier ist natürlich nur ein Beispielprogramm. Du solltest bei deinem Spiel halt schon mit MVC oder so arbeiten und das hier dann passend einfügen.


Code:
package polygon;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class PolygonTest 
extends JPanel 
implements MouseMotionListener {
	public static void main(String[] args) {
		JFrame frm = new JFrame();
		frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel pnl = new PolygonTest();
		frm.getContentPane().add(pnl);
		
		frm.setLocation(50, 50);
		frm.setSize(200, 200);
		frm.setVisible(true);
	}
	
	private Polygon poly;
	private boolean mouseInPoly = false;
	
	public PolygonTest() {
		int[] x = {20, 40, 70, 50, 10};
		int[] y = {10, 10, 30, 50, 40};
		int n = 5;
		poly = new Polygon(x, y, n);
		addMouseMotionListener(this);
	}
	
	

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		
	    Graphics2D g2d = (Graphics2D)g;
	    
	    //Composite dient dazu die durchsichtige Fläche zu zeichnen	    
	    //Alter Composite zum Zeichnen der Linie merken
	    Composite oldComposite = g2d.getComposite();
	    
	    //Durchsichtiger gefüllter Bereich, falls Maus drinnen ist
	    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2F));
	    
	    g2d.setColor(Color.BLUE);
	    if(mouseInPoly) {
	    	g2d.fill(poly);
	    }
	    
	    //Undurchsichtiger Rand
	    g2d.setComposite(oldComposite);
	    g2d.draw(poly);		
	}



	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void mouseMoved(MouseEvent arg0) {
		int x = arg0.getX();
		int y = arg0.getY();
		
		if(poly.contains(x, y)) {
			mouseInPoly = true;
		}else {
			mouseInPoly = false;
		}
		
		repaint();
	}


	
	
}

Übrigens wollte ich auch mal nen Risiko schreiben und diese Idee kam mir genau dabei. 😉
Leider hatte ich nie genug Zeit das ganze fertig zu machen 😉

Falls du noch Probleme mit dem Java2D Kram haben solltest empfehle ich dir:
http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html#Java2D-Tutorial-Paint-Transparency
 
Also ich glaube ich habe jetzt eine Lösung für mein Problem gefunden.

Das gesamte Problem lässt sich über die sogenannte "Schattenkarte" lösen, die in dem einem Link beschrieben wurde.
Im Vordergrund habe ich meine Originalkarte, in der nicht jedes Land eine eigene Farbe hat. Im Hintergrund (Benutzer sieht sie nicht) gibt es eine Schattenkarte, in der jedes Land eine eigene eindeutige Farbe hat.

Bewegt der Benutzer nun, die Maus über ein Land, wird die Position der Maus im Bild bestimmt. Diese Pixel werden im Schattenbild bzgl. der Farbe analysiert. Dann lasse ich überprüfen welche Pixel im Schattenbild noch diesen Farbwert haben, und speichere die Pixelpositionen ab. Im Anschluss, verändere ich die Pixelfarbe an den Positionen, die ich gespeichert habe. Gleichzeitig kann ich über die Schattenkarte jeder Farbe den Namen des Landes speichern und somit weiß ich, wenn der Benutzer auf ein Land klickt, um welches Land es sich handelt.

Nun meine Frage an euch: Was sagt ihr zu dieser Lsg? Ist sie vielleicht zu rechenintensiv?

Das mit dem Polygon ist geeignet, wenn man die Postionen der Pixel kennt, die zu einem Land gehören bzw. zu der Umrandung. Aber diese über ein Grafikprogramm auszulesen, ist mir zu mühsam.
 
Anonymous hat gesagt.:
Nun meine Frage an euch: Was sagt ihr zu dieser Lsg? Ist sie vielleicht zu rechenintensiv?
Rechenintensiv ist sie nicht - im Vergleich zur Lösung mit den Polygonen sogar wesentlich schneller, da immer nur ein "lookup" gemacht wird: Es braucht ja praktisch nichts gerechnet zu werden. Man schaut einfach nach der Farbe, und hat sofort die Antwort. Die Lösung benötigt zwar ggf. mehr Speicher, aber was sind schon 2 oder 3 MB :roll: Auf jeden Fall ist es wohl eine der einfachsten denkbaren Lösungen, wenn man die Karte erstmal als Bild (mit eindeutigen Länderfarben) vorliegen hat.
 
Also ich hab in verschiedenen Klassen nach einer Farbe getColor() gesucht, sowas gabs aber nicht. Methoden wie: (MouseEvent.getColor(), MouseEvent.getPoint.getColor(), Image.getColor(Point p)) hätte ich erwartet, aber sowas gibt es nicht zur Verfügung.
Nun lautet die Frage: Was machen?
Soll ich Polygone zeichnen, sie mit einer eindeutigen Farbe füllen, um danach ermitteln zu müssen, welchem Polygon der Mausklick gewidmet ist, um dann die Füllfarbe zurückzugeben? Das wäre ja noch umständlicher.
Mit Image.getGraphics().getColor() kann ich auch nix anfangen, ich will ja die Farbe des angeklickten Pixels...

Könnt ihr mir helfen?

Okay, ich hab grade was gefunden: java.awt.Robot;
ich versuch mich mal damit zurechtzufinden!
Wenn ichs nich schaffe, meld ich mich wieder.
So long 🙂
 
Zuletzt bearbeitet:
Wow. Mehr als ein Jahr. Man kann ein Bild mit ImageIO als BufferedImage laden, und dann mit
int rgb = bufferedImage.getRGB(x,y);
die Farbe eines Pixels abfragen - und das RGB notfalls noch mit
Color c = new Color(rgb);
in ein Color-Objekt verwandeln...
 
Um die einzelnen Farbwerte bekomman muss man den RGB-Wert aber noch wie folgt auseinanderhacken:

[Java]int argb = image.getRGB( x, y );
int alpha = (argb >> 24) & 0xff;
int red = (argb >> 16) & 0xff;
int green = (argb >> 8) & 0xff;
int blue = (argb) & 0xff;[/Java]
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben