"Städte raten" programmieren mit Java/Swing

X

xout

Hallo Java-Freunde,

ich bin Java Anfänger und habe an der FH gerade den ersten Java-Grundkurs. Als Studienarbeit möchte ich gerne ein kleines Spiel programmieren. Wahrscheinlich kennt Ihr die Sendung "Schlag den Raab". Dort gibt es immer ein kleines Spiel genannt "Städte raten".
Wer es nicht kennen sollte, kann sich unter dem folgenden Link ein Bild davon machen.

goto: http://www.lachecke.de/flash_view_125.html#

Das Spiel muss unter Java/Swing erstellt werden. Es sollte kein Problem sein, die einzelnen Städte auf der Karte zu platzieren, und die Interaktion des Users, den Mausklick, abzufragen. Auch eine Ausgabe, ob der User die Stadt gefunden hat oder nicht, sollte realisierbar sein. Aber wie stelle ich es an, dass eine Ausgabe erscheint, die dem User mitteilt, dass er z.B. 100km neben die zu findende Stadt geklickt hat?
Diese Frage stellt mich momentan vor ein Problem.

Habt Ihr hierzu den einen oder anderen Tip auf Lager?

Vielen Dank & Gruß,
xout
 
Zuletzt bearbeitet von einem Moderator:
edit: bitte hier nicht antworten, habe den thread ins falsche forum gepostet, und nun die mods um löschung gebeten!
Und wir Mods haben auch die Möglichkeit, einen Thread in einen anderen Forenbereich zu verschieben, also brauchst du dir nicht die Mühe zu machen, und ein Duplikat des Themas zu erstellen.
 
Moin,

Die Sache mit der Karte und den "angepinnten" Städten sollte wie Du selbst sagst kein Problem darstellen.

Für die Berechnung der Entfernung gibt es genau 2 Möglichkeiten, zumindest fallen mir keine weiteren ein:
  • Euklidische Distanz
  • Berechnung der Distanz nach Mittelbreite (navigatorisch) -> aufwändig, aber exakter

Damit berechnest Du die Distanz zwischen dem gewählten Punkt sowie dem Städtepunkt aus,
multiplizierst das ganze mit der Maßstabszahl und erhälst das reale Ergebnis.

Ich hoffe, das ist ein wenig verständlich.

Gruß,
Xan
 
Zuletzt bearbeitet:
Wie wäre es mit dem Satz des Pythagoras?
Du hast 2 Punkte mit jeweils x und y Koordinate, dann sollte das Berechnen der Entfernung nicht so schwer fallen.
 
Danke Euch! Werde mir diese drei Möglichkeiten einmal näher ansehen!
 
Zuletzt bearbeitet von einem Moderator:
Hallo Zusammen,

ich habe nun mit dem Projekt begonnen, aber anscheinend stellt sich selbst das Platzieren der Städte für mich als doch etwas schwierig heraus. Besser gesagt weiß ich nicht wie ich das genau angehen soll.
In den Sinn gekommen ist mir, die Deutschlandkarte mit einem Gridbag Layout zu unterteilen. Allerdings erscheint mir dieser Weg etwas umständlich, da das Grid ja relativ "fein", also hoch aufgelöst sein muss. Dadurch müsste ich das Bild ja zunächste per Photoshop "zerhacken", um dann die einzelnen Puzzleteile den Zellen des Grids zuweisen zu können.
Die zweite Möglichkeit an die ich denke ist, für jeweile eine Stadt einen unsichtbaren Button zu erstellen und diesen dann entsprechend auf der Karte zu platzieren...

Was denkt Ihr? Welche weiteren Möglichkeiten gibt es dafür? Mit dem Suchbegriff "image mapping" konnte ich nicht wirklich fündig werden.

Gruß,
xout

P.S. Die GUI sieht bisher folgendermaßen aus:
 

Anhänge

  • CjtyQujz.jpg
    CjtyQujz.jpg
    71,3 KB · Aufrufe: 230
Das ist nix mit Gridbag oder versteckten Buttons.
Was du brauchst, ist ein Mouselistener, den du deinem JFrame/JDialog/JPanel/Whatever zuweist. Über den kannst du dann das MouseClicked-Event abfangen und dir die aktuelle Mausposition holen.
 
Ok danke! Wenns spät am Abend wird, dann verschwimmt wohl etwas die Sicht! :)

Listeners werden hier recht schön beschrieben: http://java.sun.com/docs/books/tutorial/uiswing/events/mouselistener.html

Frage: Lässt sich das auf einem LayerdPanel anwenden? Vom Prinzip her habe ich mir das so gedacht, daß Klicks auf Ebene 0 als "false" gewertet werden, Bereiche die auf Ebene 1 definiert werden dann beim Klick als "true" gewertet werden.

Kleines Bild zur Verdeutlichung:
 

Anhänge

  • event.jpg
    event.jpg
    22,5 KB · Aufrufe: 1.633
Du machst dir das viel zu kompliziert - hab dir mal ein einfaches Beispiel vorbereitet:

Java:
package de.tutorials.mouselistener;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

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

public class MouseListenerDemo extends JFrame {
	
	private BackgroundPanel background = null;
	
	public MouseListenerDemo() {
		super();
		initialize();
	}
	
	private void initialize() {
		this.setLayout(new BorderLayout());
		this.setSize(350, 450);
		this.setTitle("Klick in die Mitte");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		ImageIcon icon = new ImageIcon("karte.png");
		background = new BackgroundPanel(icon);
		background.setSize(340, 425);
		this.add(background, BorderLayout.CENTER);
		setVisible(true);
	}
	
	public static void main(String args[]) {
		new MouseListenerDemo();
	}
	
	
	private class BackgroundPanel extends JPanel implements MouseListener {
  		ImageIcon icon;
  
  		public BackgroundPanel(ImageIcon icon) {
  			this.icon = icon;
  			this.addMouseListener(this);
  		}
  
  		protected void paintComponent(Graphics g) {
  			super.paintComponent(g);
  			if (this.icon != null) {
 				g.drawImage(icon.getImage(), 0, 0, this);
  			}
  		}
  
  		public Dimension getPreferredSize() {
  			if (icon != null) {
 			    return new Dimension(icon.getIconWidth(), icon.getIconHeight());
  			} else {
 				return super.getPreferredSize();
  			}
  		}

		@Override
		public void mouseClicked(MouseEvent e) {
			Point position = e.getLocationOnScreen();
			//Position des Mausklicks
			int xClicked = position.x;
			int yClicked = position.y;
			//Gesuchte Position
			int xMatch = icon.getIconWidth() / 2;
			int yMatch = icon.getIconHeight() / 2;
			// Abstandsberechnung
			double xDiff = (double) xClicked - xMatch;
			double yDiff = (double) yClicked - yMatch;
			double distance = Math.sqrt((xDiff * xDiff) + (yDiff * yDiff));
			System.out.println("Der Abstand beträgt: " + distance + " Pixel");
			
		}

		@Override
		public void mouseEntered(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mousePressed(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}
  	}

}

In Kürze: Der JFrame hat eine private Klasse names Backgroundpanel, die zum einen ein im Konstruktor übergebenes Icon als Hintergrund zeichnet, zum anderen einen Mouselistener implementiert und zugewiesen bekommt.
In der MouseClicked-Methode wird zuerst die Position des Mausklicks abgefragt. Danach wird der Abstand zum Mittelpunkt für die x- und y-Komponete der Mausklickposition berechntet. Der Abstand ergibt sich aus dem Satz des Pythagoras, wie Dunas schon erklärt hat. Der Umweg über irgendwelche LayeredPanes oder ähnliches ist also nich nötig.

Gruss,

Manuel
 
Zurück