Asteroid unschöne Bewegung

Status
Nicht offen für weitere Antworten.

raven

Bekanntes Mitglied
Hallo...
Ich habe mal wieder eine Frage an euch. Ich versuche mich gerade an einem Asteroid-Clone, jedoch sieht die Bewegung meines Raumschiff so unschön aus...
Und zwar beim beschleunigen ist alles OK, nachdem ich das Raumschiff gedreht habe und erneut beschleunige will. Fährt es gleich in die Richtung. Ist es im Weltraum nicht so, das das Raumschiff erstmal Gegenschub(hoffe ihr wisst was ich meine) ausübt und auch ein wenig von der eigentlich geplanten Flugbahn abkommt...

Die Bewegung habe ich Moment so gelöst
Code:
public void move() {
		if(forward) {
			if(v < vMax)
				v = v + a;
		}

		if(backward) {
			if(v > -vMax)
				v = v - a;
		}

		if(!forward && !backward) {
			if(v < 0)
				v = v + 0.01F;
			if(v > 0)
				v = v - 0.01F;
		}

		if(right) {
			alpha = alpha + rv;
		}
		if(left) {
			alpha = alpha - rv;
		}

		impuls();
	}

	public void impuls() {
		if(!right && !left) {
			vx = (float)(Math.cos(Math.toRadians(alpha)) * v);
			vy = (float)(Math.sin(Math.toRadians(alpha)) * v);
		}
		x = x + vx;
		y = y + vy;
	}

Hoffe ihr wisst wie ich es meine...

mfg raven
 

0x7F800000

Top Contributor
nichts für ungut, aber in einem solchen spiel Koordinaten in Polardarstellung abzuspeichern ist krank^^ :autsch:
Schreib das alles in normale Kartesische rechteckige Koordinaten um, dann läuft's von selbst...
(Den Winkel für die Orientierung des schiffes mitzuspeichern ist zwar unnötig, aber hier grad noch so akzeptabel. Für die Position, geschwindigkeit und beschleunigung solltest du mit einer normalen "Vector2D"-Klasse rechnen, ob aus irgendeinem package oder selbstgeschrieben ist egal)
 

Developer_X

Top Contributor
ich glaub die wissen net was du meinst, das gibts doch auch als Online Game,
stell hier mal den Link rein, damit die Sehen was du und ich meinen....
 

Marco13

Top Contributor
Polarkoordinaten sehe ich da auch nicht - dieses sin/cos-Gedengel ist wohl nur, um die Geschwindikeitsänderung in die entsprechende (Blick)Richtung hinzukriegen (ob man den Drehwinkel speichert oder die Blickrichtung ist ja wurscht ...). Allerdings scheint dort nur die Position verändert zu werden, und nicht die Geschwindigkeit (bzw. der Impuls).
 

raven

Bekanntes Mitglied
Ja genau so was, halt also 360 Grad Drehung usw... wenn ich das jetzt richtig verstanden habe, soll ich mein Schiff nicht einfach so drehen, sonder die Drehung über Vektoren berechnen...

EDIT:
Hat jemand von euch ne Seite wo die Berechnung erklärt wird, oder zum Beispiel wie es anhand so eines Spiels erläutert wird... ich kann mir bis jetzt noch nichts darunter vorstellen... wie ich das Schiff anders drehen soll...
 
Zuletzt bearbeitet:

0x7F800000

Top Contributor
1) Position als p=(px,py) abspeichern
2) Geschwindigkeit als v=(vx,vy) abspeichern
3) Meinetwegen drehung als alpha aus [0,2PI] abspeichern. Bitte, tue der Welt eine gefallen, und lasse diesen ganzen
Code:
toDegrees(fromDegrees(toRadians(myAngleInSomeFuckedUpFormat))))
-Mist weg, und speichere direkt alles im schönen vorfaktor unbehafteten Bogenmaß.
4) Betrag der beschleunigung irgendwo als konstante definieren
Code:
public static double ACCELERATION=123.456;
5) Rictungsänderung des schiffes auch als konstante abspeichern
Code:
public static double ROTATION=0.01;
6) Reaktion auf tasten:
Rechts: alpha-=ROTATION
Links: alpha+=ROTATION
Oben: :
Code:
//Beschleunigung berechnen
a=(ax,ay)=ACCELERATION*(Math.cos(alpha),Math.sin(alpha))

...

//geschwindigkeit ändern
v+=a*dt //wobei "dt" entweder die zeit des letzten durchlaufs des gameloops oder einfach kleine konstante ist
//bewegen
x+=v*dt
Beim Druck des pfeilchens nach unten zeigt der beschleunigungsvektor einfach in die entgegengesetzte richtung:
Code:
//Beschleunigung berechnen
a=(ax,ay)=-ACCELERATION*(Math.cos(alpha),Math.sin(alpha))

...
//geschwindigkeit ändern
v+=a*dt //wobei "dt" entweder die zeit des letzten durchlaufs des gameloops oder einfach kleine konstante ist
//bewegen
x+=v*dt
Sonst noch Fragen...?
 

raven

Bekanntes Mitglied
Ok danke erstmal... aber ich verstehe folgende Zeilen noch nicht

a=(ax,ay)=ACCELERATION*(Math.cos(alpha),Math.sin(alpha))

mfg raven
 

0x7F800000

Top Contributor
das ist kein javacode, sondern einfach nur als "pfeilchenrechung" hingeschrieben.
sinus ist sinus
kosinus ist kosinus
* ist die multiplikation
(x,y) ist ein tupel mit 2 koordinaten, dafür solltest du dir eine Vector2d-Klasse basteln...
 

raven

Bekanntes Mitglied
Code:
if(forward) {
			a.setLocation(ACCELERATION*Math.cos(alpha), ACCELERATION*Math.sin(alpha));
			
			if(v.getX()+v.getY() < vMax)
				v.setLocation(v.getX()+a.getX()*1.00F, v.getY()+a.getY()*1.00F);
			
			p.setLocation(p.getX()+v.getX()*0.05F, p.getY()+v.getY()*0.05F);
			
		}

hab das jetzt so hin gebaut, aber der Flieger fliegt nicht in die gewünschte Richtung...
wie ne vectort2d klasse... warum brauch ich dafür ne extra klasse...
 

Marco13

Top Contributor
4) Betrag der beschleunigung irgendwo als konstante definieren
...
5) Rictungsänderung des schiffes auch als konstante abspeichern

... vorrausgesetzt, sie SIND wirklich konstant (und es gibt nicht irgendwelche "booster", die die Beschleunigung erhöhen) dann sollten sie auch final sein. Final oder nicht public static.

wie ne vectort2d klasse... warum brauch ich dafür ne extra klasse...

Man braucht die natürlich nicht - aber es ist viel bequemer und sauberer. Die Klasse könnte dann praktische Methoden anbieten (add, scale, normalize, rotate...), damit man solches Gewurste
Code:
a.setLocation(ACCELERATION*Math.cos(alpha), ACCELERATION*Math.sin(alpha));
			
			if(v.getX()+v.getY() < vMax)
				v.setLocation(v.getX()+a.getX()*1.00F, v.getY()+a.getY()*1.00F);
			
			p.setLocation(p.getX()+v.getX()*0.05F, p.getY()+v.getY()*0.05F);
vx = (float)(Math.cos(Math.toRadians(alpha)) * v);
			vy = (float)(Math.sin(Math.toRadians(alpha)) * v);
hübscher schreiben kann, z.B. als
Code:
direction.rotate(alpha);
a.scaleAdd(speed, direction);
p.scaleAdd(0.05f, v);
usw.

Das macht es viiieel einfacher und sauberer, den zeitlichen Verlauf von
position
geschwindigkeit
beschleunigung
(was ja alles 2D-Vektoren SIND) in der Form hinzuschreiben, die "näher" an dem ist, was du hoffentlich schon als Bleistifgekritzel auf einem Blatt Papier vor dir liegen hast....
 

raven

Bekanntes Mitglied
Könntet ihr mir noch ein aller letztes mal helfen... Mein Schiff fliegt hin wo es will ohne ersehbaren Grund... Ich habe auch schon die Werte der Beschleunigung und des Drehwinkels geändert. Ohne Erfolg... Könnt ihr mir sagen was ich falsch mache?

Hier die die Klasse des Schiffes...
Code:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.Graphics;

public class Ship implements KeyListener {

	private Main main;

	private boolean forward;
	private boolean backward;
	private boolean right;
	private boolean left;

	private Point p;
	private Point v;
	private Point a;

	private double ACCELERATION = 1.00F;
	private double ROTATION = 2.00F;

	private int w = 24;
	private int h = 20;
	private int vMax = 1000;
	private int alpha;

	public Ship(Main main, int x, int y) {
		this.main = main;
		this.p = new Point(x, y);
		this.v = new Point(0, 0);
		this.a = new Point(0, 0);
		main.frame.addKeyListener(this);
	}

	protected void paint(Graphics2D g2d) {
		double x = p.getX();
		double y = p.getY();
		AffineTransform rotation = new AffineTransform();
		rotation.rotate(Math.toRadians(alpha), x, y);
		g2d.setTransform(rotation);

		g2d.setColor(Color.white);
		g2d.draw(new Line2D.Double(x+w/2, y, x-w/2, y-h/2));
		g2d.draw(new Line2D.Double(x-w/2, y-h/2, x-w/2, y+h/2));
		g2d.draw(new Line2D.Double(x-w/2, y+h/2, x+w/2, y));

	}

	public void move() {
		if(right) {
			alpha += ROTATION;
		}
		if(left) {
			alpha -= ROTATION;
		}

		if(forward) {
				a.setLocation(ACCELERATION*Math.cos(alpha), ACCELERATION*Math.sin(alpha));

				v.setLocation(v.getX()+a.getX()*0.60F, v.getY()+a.getY()*0.60F);
			System.out.println(v.getX()+"/"+v.getY());
			p.setLocation(p.getX()+v.getX()*0.05F, p.getY()+v.getY()*0.05F);
			
		}

		if(!forward && !backward) {
			if(v.getX()+v.getY() < 0)
				v.setLocation(v.getX()+100.00F, v.getY()+100.00F);
			if(v.getX()+v.getY() > 0)
				v.setLocation(v.getX()-1000.00F, v.getY()-1000.00F);
		}

		
	}

	public void keyPressed (KeyEvent k) {
		int key = k.getKeyCode();
		switch(key) {
			case KeyEvent.VK_NUMPAD8:
				forward = true;
				break;
			case KeyEvent.VK_NUMPAD5:
				backward = true;
				break;
			case KeyEvent.VK_NUMPAD6:
				right = true;
				break;
			case KeyEvent.VK_NUMPAD4:
				left = true;
				break;
		}
	}

	public void keyReleased (KeyEvent k) {
		int key = k.getKeyCode();
		switch(key) {
			case KeyEvent.VK_NUMPAD8:
				forward = false;
				break;
			case KeyEvent.VK_NUMPAD5:
				backward = false;
				break;
			case KeyEvent.VK_NUMPAD6:
				right = false;
				break;
			case KeyEvent.VK_NUMPAD4:
				left = false;
				break;
		}
	}

	public void keyTyped(KeyEvent e) {  }
}

Ich wäre sehr dankbar, wenn ihr mir helfen könntet... ich weiß echt nicht mehr weiter...
mfg raven
 

Marco13

Top Contributor
Was auch immer mit
Code:
			if(v.getX()+v.getY() < 0)
				v.setLocation(v.getX()+100.00F, v.getY()+100.00F);
			if(v.getX()+v.getY() > 0)
				v.setLocation(v.getX()-1000.00F, v.getY()-1000.00F);
Erreicht werden soll: Es sieht komisch aus...
 

raven

Bekanntes Mitglied
das war nur von einem Test, was ich noch nicht auskommentiert hatte.... wie auch immer habe durch Zufall das Problem gefunden...
hab gemerkt das sin() bzw. cos() ein wert in Bogenmaß erwarten... und ich hatte einfach nur den Winkel alpha rein geschrieben...
funktioniert alles perfekt.. danke an euch noch mal alle...

mfg raven
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben