Grafik zu Mausklick-Koordinate bewegen

Maxim6394

Bekanntes Mitglied
also ich hab eine grafik, von da aus soll bei einem mausklick ein geschoss in richtung der mausklick position abgefeuert werden.
dafür muss ich wohl lineare funktionen verwenden, aber es klappt irgendwie nicht.
hier der code für das bewegen:

cX ist die position des mausklicks, pX die position des spielers. beide verändern ihren wert nicht nachdem das geschoss abgefeuert wurde.
Code:
	public void move2()
	{
		
		if(cX==pX)
		{
			if(cY==pY)
			{
				
			}
			else
			{
				if(cY<pX)
				{
					y--;
					 x=(int) ((y-n)/m);
				}
				else 
				{
					y++;
					 x=(int) ((y-n)/m);
				}
			}
		}
		
	
		else 
		{
			if(cY==pY)
			{
				if(cX<pX)
				{
					x--;
				}
				else
				{
					x++;
				}
			}

				//da oben wird nur überprüft ob das geschoss nur gerade auf einer achse bewegt werden muss
			else
			{
				
				 m=(float)deltaY/(float)deltaX; //die steigung(deltax und y werden im konstruktor des geschoss objektes erstellt)
				 n=pY -m*pX;                 //y-achsenabschnitt
				 
				 if(m>1)
				 {
					 if(cY>pY)
					 {
						y++;
						
						 x=(int) ((y-n)/m);
						 System.out.println("asdf");
					 }
					 else
					 {
						 y--;
						 x=(int) ((y-n)/m);
					 }
						 
				 }
				 else
				 {
					 if(m<-1)
					 {
						 if(cY>pY)
						 {
							 y++;
							 x=(int) ((y-n)/m);
						 }
						 else
						 {
							 y--;
							 x=(int) ((y-n)/m);
						 }
					 }
					 else 
					 {
						 if(m>-1)
						 {
							 if(m<0)
							 {
								 if(cX>pX)
								 {
									 x++;
									 y=(int) (m*x+n);
								 }
								 else 
								 {
									 x--;
									 y=(int) (m*x+n);
								 }
							 }
							 else
							 {
								 if(cX>pX)
								 {
									 x++;
									 y=(int) (m*x+n);
								 }
								 else 
								 {
									 x--;
									 y=(int) (m*x+n);
								 }
							 }
						 }
					 }
				 }
				
			}
		}

	}

die drecksdinger fliegen irgendwie immer falsch, scheint mir fast so als wären sie teilweise spiegelverkehrt.
die move2 methode hab ich übrigens schritt für schritt nach einem flussdiagramm erstellt dass ich vorher entworfen hab.
also kann irgendwer helfen?
 
G

Gast2

Gast
cX, pX, cY, pY, y, x, n, m ... :rtfm:
Wer soll denn da bitteschön durchblicken?

Hast du dir schonmal sysouts reingesetzt und die Rechnungen kontrolliert?
 

Maxim6394

Bekanntes Mitglied
m ist die steigung, n der y achsenabschnitt. x und y position des projektils und der rest wurde schon erklärt.
wie würde denn einer von hier an sowas rangehen, wenn einfach ein objekt zu einem beliebigen punkt bewegt werden soll?
 
G

Gast2

Gast
Ich würde das so machen:
Das Objekt dass sich bewegen soll hat nen Geschwindigkeitsvektor. Der gibt die Richtung sowie die Geschwindigkeit an mit der das Objekt pro Zeiteinheit fliegt. Klickst du mit der Maus irgendwo hin wird der Vektor berechnet und dem Objekt gesetzt. Irgendwo anders hast du dann ne art gameloop laufen die in Regelmäßigen Abständen die Position des Objekts neu berechnet:
Code:
pos = pos + vVec;

Wenn du damit nicht weiterkommst sag bescheid, ich hab hier noch nen Codeschnipsel liegen der genau sowas macht.
 

Maxim6394

Bekanntes Mitglied
Ich würde das so machen:
Das Objekt dass sich bewegen soll hat nen Geschwindigkeitsvektor. Der gibt die Richtung sowie die Geschwindigkeit an mit der das Objekt pro Zeiteinheit fliegt. Klickst du mit der Maus irgendwo hin wird der Vektor berechnet und dem Objekt gesetzt. Irgendwo anders hast du dann ne art gameloop laufen die in Regelmäßigen Abständen die Position des Objekts neu berechnet:
Code:
pos = pos + vVec;

Wenn du damit nicht weiterkommst sag bescheid, ich hab hier noch nen Codeschnipsel liegen der genau sowas macht.

ich wüsste nicht wie ich das machen soll. nach norden, süden, nordosten etc etwas zu bewegen wäre ja kein problem, aber zu einem beliebigen punkt klappt es einfach nicht.
es kommt mir fast so vor als wär die flugbahn auf jeder achse ziemlich spiegelverkehrt.
es könnte also daran liegen: x=(int) ((y-n)/m);
wenn x vergrößert wird sollte y=(int) (m*x+n); sein.
 
Zuletzt bearbeitet:

Michael...

Top Contributor
ich wüsste nicht wie ich das machen soll. nach norden, süden, nordosten etc etwas zu bewegen wäre ja kein problem, aber zu einem beliebigen punkt klappt es einfach nicht.
es kommt mir fast so vor als wär die flugbahn auf jeder achse ziemlich spiegelverkehrt.
es könnte also daran liegen: x=(int) ((y-n)/m);
wenn x vergrößert wird sollte y=(int) (m*x+n); sein.
Das ist "simple" Vektorrechnung:
- gegeben ist ein startpunkt A und ein Zielpunkt B
- damit ergibt sich ein Vektor v = (B.x-A.x , B.y-A.y)
- diesen könnte man ein einen Einheitsverktor oder eine beliebe Länge normieren n = v / |v|
- wenn man annimmt, das sich das Objekt O sich pro Spielrunde um x Einheiten bewegt, ergibt sich die jeweils neue Position Oneu = Oakt + x*n

P.S: Hier gibt's auch ein Matheforum für solche Themen

Wichtig: Da das ganze sicherlich graphisch dargestellt wird, ist es wichtig sich mit Threads auseinander zu setzen.
 

Maxim6394

Bekanntes Mitglied
versteh ich nicht. Ich soll also delta aus jeweils x und y koordinate von ziel uns start in einen vector speichern. was dann? was bedeutet n = v / |v|? welcher datentyp soll das sein? und was bedeuten die || beim zweiten v?
 

Michael...

Top Contributor
versteh ich nicht. Ich soll also delta aus jeweils x und y koordinate von ziel uns start in einen vector speichern.
Ich spreche hier von einem math. Vektor nicht zu verwechseln mit der Klasse Vector. Den Richtungsvektor von einem 2D Punkt zu einem anderen 2D Punkt ermittelt man ja durch die jeweilige Differenz der x bzw. y-Werte.
was bedeutet n = v / |v|? welcher datentyp soll das sein? und was bedeuten die || beim zweiten v?
Das ist wieder ein math. Vektor. Leider gibt es hier keinen Formeleditor. Sollte nur die Berechnung des Einheitvektors darstellen - als Vektor dividiert durch seinen Betrag/Länge
 

Maxim6394

Bekanntes Mitglied
ich hab nirgendwo irgendeine lösung gefunden, könnte also bitte jemand nen funktionsfähigen code posten für das bewegen eines objekts zu einem punkt? ich sitz da seit tagen dran und es geht nicht.
 
Zuletzt bearbeitet:

Michael...

Top Contributor
ich hab nirgendwo irgendeine lösung gefunden
die kunst des programmierens besteht darin lösungen zu entwickeln, wenn man keine passenden findet ;-)
Ist nicht böse gemeint, ich denke Dir fehlen dazu einmal die passenden Grundlagen und scheinbar ein bisschen das mathematische Verständnis.
könnte also bitte jemand nen funktionsfähigen code posten für das bewegen eines objekts zu einem punkt?
Es gibt hier auch Jobbörse, in der man gegen Bezahlung Code entwickeln lassen kann.

Da es allerdings kein großartiger Aufwand war und heute Freitag ist:
Java:
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

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

public class MouseFollowDemo2 extends JFrame {
	private volatile Point m, target;

	public MouseFollowDemo2() {
		m = new Point(200, 200);
		final JPanel panel = new JPanel() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				g.drawRect(m.x - 5, m.y - 5, 10, 10);
			}
		};
		panel.addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseMoved(MouseEvent e) {
				target = e.getPoint();
			}
		});
		add(panel);

		new Thread(new Runnable() {
			public void run() {
				while (true) {
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if (target!=null) {
						int x = target.x - m.x;
						int y = target.y - m.y;
						if (Math.abs(x)<=2 && Math.abs(y)<=2)
							target = null;
						else {
							double len = Math.sqrt(x*x +y*y);
							m.x += (int)(2*x/len);
							m.y += (int)(2*y/len);
							panel.repaint();
						}
					}
				}
			}
		}).start();
	}

	public static void main(String[] args) {
		JFrame frame = new MouseFollowDemo2();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
 

Michael...

Top Contributor
Ist jetzt nur eine Demo und nicht unbedingt praktikabel einzusetzen, zeigt aber zumindest wie man ein Objekt von A nach B bewegen kann.
Um soetwas in einer "produktiven" Anwendunge einzusetzen, sollte man sich genauer mit Threads bzw. Multithreading in Java auseinandersetzen, um das ganze effizienter zu gestalten.
 
G

Gast2

Gast
ich wüsste nicht wie ich das machen soll. nach norden, süden, nordosten etc etwas zu bewegen wäre ja kein problem, aber zu einem beliebigen punkt klappt es einfach nicht.
es kommt mir fast so vor als wär die flugbahn auf jeder achse ziemlich spiegelverkehrt.
es könnte also daran liegen: x=(int) ((y-n)/m);
wenn x vergrößert wird sollte y=(int) (m*x+n); sein.
Wenn ich später zuhause bin, dann poste ich dir mal noch meinen Beispielcode. Die eigentliche Logik sind nur nen ganz paar Zeilen.
 
G

Gast2

Gast
Hier wie versprochen noch die kleine Demo:
Java:
public class Main {

	public static final int TEST = 99;

	public static void main(final String[] args) {
		JFrame frame = new JFrame("Bullet Demo");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		BulletPanel bulletPanel = new BulletPanel();
		bulletPanel.setPreferredSize(new Dimension(800, 600));

		frame.add(bulletPanel);
		frame.pack();
		frame.setVisible(true);
	}
}

Java:
public class Bullet {
	private Point2D position;
	private Point2D direction;

	public Bullet(final Point2D position, final Point2D direction) {
		this.position = position;
		this.direction = direction;
	}

	public Point2D getPosition() {
		return position;
	}

	public void setPosition(final Point2D position) {
		this.position = position;
	}

	public Point2D getDirection() {
		return direction;
	}
}
Die Variable direction gibt an in welche Richtung und wie schnell (länge des Vektors) die Kugel fliegt. position ist die aktuelle Position.

Java:
public class BulletPanel extends JPanel implements ActionListener {

	private List<Bullet> bullets;
	private static final int SPEED_MULTIPLIER = 1;

	private Timer timer;
	private static final int TIMER_DELAY = 25;


	public BulletPanel() {
		bullets = new ArrayList<Bullet>();

		// attach mouse listener
		addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(final MouseEvent e) {
				createNewBullet(e);
			}
		});

		// create the timer
		timer = new Timer(TIMER_DELAY, this);
		timer.setRepeats(true);
	}

	@Override
	public void actionPerformed(final ActionEvent e) {
		Iterator<Bullet> bulletIterator = bullets.iterator();

		// move the bullets
		while (bulletIterator.hasNext()) {
			Bullet bullet = bulletIterator.next();

			Point2D position = bullet.getPosition();
			Point2D direction = bullet.getDirection();

			double newX = position.getX() + SPEED_MULTIPLIER * direction.getX();
			double newY = position.getY() + SPEED_MULTIPLIER * direction.getY();
			Point2D newPosition = new Point2D.Double(newX, newY);

			// remove bullet?
			if (newX < 0 || newX > getWidth() || newY < 0 || newY > getHeight()) {
				bulletIterator.remove();
			}

			bullet.setPosition(newPosition);
		}

		if (bullets.size() == 0) {
			timer.stop();
		}

		repaint();
	}

	@Override
	protected void paintComponent(final Graphics g) {
		super.paintComponent(g);

		// draw the "cannon"
		g.fillOval(-10, -10, 20, 20);

		// draw the bullets
		for (Bullet bullet : bullets) {
			Point2D pos = bullet.getPosition();
			g.fillOval((int)pos.getX(), (int)pos.getY(), 4, 4);
		}
	}

	private void createNewBullet(final MouseEvent evt) {
		int cannonX = 0;
		int cannonY = 0;

		// calculate direction vector and reduce its length
		double vecX = (evt.getX() - cannonX) / 50.0;
		double vecY = (evt.getY() - cannonY) / 50.0;

		Point2D direction = new Point2D.Double(vecX, vecY);
		Point2D position = new Point2D.Double(cannonX, cannonY);

		bullets.add(new Bullet(position, direction));
		repaint();

		if (!timer.isRunning()) {
			timer.start();
		}
	}
}
In der Methode createNewBullet steckt die ganze Logik um die Flugbahn der Kugel zu berechnen, hier wird auch ein neues Bullet Objekt erstellt. In der actionPerformed Methode wird dann die Bewegung der Kugeln berechnet. Die Methode wird vom Timer alle x ms aufgerufen. Die neue Position wird per
Code:
position + speedVector
berechnet. Der SPEED_MULTIPLIER kann ignoriert werden.
 

Maxim6394

Bekanntes Mitglied
danke, das sieht ziemlich gut aus. aber wieso wird die geschwindigkeit der kugel geringer je näher der mausklick an der cannon position war?
 
G

Gast2

Gast
Weil dann der Vektor zwischen "Kanone" und Mauszeiger kürzer ist. Und die Länge des Vektors gibt die Geschwindigkeit der Kugel an.
Das kannst du aber relativ einfach ändern indem du den Vektor normierst. Dann fliegen alle Kugel gleich schnell.
 

Maxim6394

Bekanntes Mitglied
ich hab nicht die leiseste ahnung wie ich das machen soll. ich hab versucht mich über vektoren zu informieren aber ich kann das alles immernoch nicht verstehen.
 

Maxim6394

Bekanntes Mitglied
hab endlich die verdammte lösung rausgefunden. ich musste nur vom steigungsdreieck die hypothenusenlänge ausrechnen. satz des pytagoras wär das richtige stichwort gewesen.
dann noch delta x und delta y jeweils durch die hypothenusenlänge teilen und danach jeweils das ergebnis mit der gewünschten bewegungsgeschwindigkeit multiplizieren. schon hat man die werte, wie weit der punkt auf x und auf y bewegt werden soll.
 

Michael...

Top Contributor
hab endlich die verdammte lösung rausgefunden. ich musste nur vom steigungsdreieck die hypothenusenlänge ausrechnen. satz des pytagoras wär das richtige stichwort gewesen.
dann noch delta x und delta y jeweils durch die hypothenusenlänge teilen
Oder mathematisch kurz: den Einheitsvektor bestimmen.

######Edit######
die Lösung stand übrigens schon weider oben:
[JAVA=36] int x = target.x - m.x;
int y = target.y - m.y;
...
...
else {
double len = Math.sqrt(x*x +y*y);
m.x += (int)(2*x/len);
m.y += (int)(2*y/len);[/code]
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
I 2D-Grafik Vektor-Grafik über die Zwischenablage nach Adobe Illustrator transferieren Allgemeine Java-Themen 8
N 3d Grafik Kamera Allgemeine Java-Themen 2
N 3D Grafik erstellt Allgemeine Java-Themen 5
N 3D-Grafik 3D Grafik selber bauen Allgemeine Java-Themen 0
I Wie Vektor-Grafik in die Zwischenablage kopieren? Allgemeine Java-Themen 2
P Probleme mit Grafik (Java) Allgemeine Java-Themen 6
E 2D-Grafik nicht-rechteckige Grafik anzeigen Allgemeine Java-Themen 3
vladimir Welche API für Grafik und Drag&Drop Allgemeine Java-Themen 3
R Texterkennung - Text aus einem/r Bild/Grafik auslesen Allgemeine Java-Themen 2
N grafik rotieren und zentrieren Allgemeine Java-Themen 4
L Grafik lesen Allgemeine Java-Themen 2
S 3D Grafik Library? Allgemeine Java-Themen 5
hdi Auslesen der Farbwerte einer Grafik-Datei Allgemeine Java-Themen 4
B Grafik erzeugen in java Allgemeine Java-Themen 2
G Messen in einer Grafik Allgemeine Java-Themen 7
W Java verursacht Grafik-Fehler? Allgemeine Java-Themen 3
P Grafik Bibliothek Allgemeine Java-Themen 4
S Konverter Postscript -> Grafik gesucht Allgemeine Java-Themen 2
C Grafik Editor in Java Allgemeine Java-Themen 2
P dxf-Daten aus Grafik erstellen Allgemeine Java-Themen 3
S Generellen MausKlick am PC erkennen Allgemeine Java-Themen 1
K Farbe erkannt = agieren, per Mausklick etc. Allgemeine Java-Themen 47
M Input/Output Mausklick außerhalb des Frames registrieren Allgemeine Java-Themen 2
S per Mausklick Position ermitteln Allgemeine Java-Themen 8
M JTree aktualisieren nach Mausklick Allgemeine Java-Themen 12
L Mausklick simulieren Allgemeine Java-Themen 4
D JTable -> ArrayIndexOutOfBoundsException bei Mausklick Allgemeine Java-Themen 2
M JTextPane Mausklick auf bestimmte Wörter startet Aktion Allgemeine Java-Themen 8
S Mausklick außerhalb des Programms erzeugen? Allgemeine Java-Themen 23
M datei über rechten mausklick aus explorer in programm laden Allgemeine Java-Themen 4
N JList mit Mausklick auf einen JButton scrollen Allgemeine Java-Themen 28

Ähnliche Java Themen

Neue Themen


Oben