# Einfache Physik (Beschleunigung)



## Dagobert (24. Apr 2008)

Ich hab da mal wieder ein mehr oder weniger kleines Problem.
Diesmal aber er weniger Programmiert orientiert. Sondern mehr ein Logisches Problem.
Ich habe ein Mobieles Flakgeschütz in mein kleines Spiel eingebaut. 
Dieses bewegt sich jetzt mit einer konstanten Geschwindigkeit von seinem Erschaffungspunkt zu einem Startpunkt und patrolliert zwischen dem Start- und Zielpunkt hin und her.
Nun möchte ich aber nicht, das sich dieses immer mit gleicher Geschwindigkeit bewegt, sondern nach dem wenden bis zu einer max. Geschwingikeit beschleunigt und auch wieder vor dem Zielpunkt wieder abgebremst.
Nur leider habe ich keine große Idee mehr wie ich das anstellen soll.
Wenn das irgendwie gehen sollte am besten nur die Startgeschwindigkeit, die maxGeschwindigkeit und die Strecke auf die beschleunigt werden soll oder die Beschleunigung selber. Ich weis nicht was da mehr Sinn machen würde.
Ich hab es bereits mit den Formeln:
s=a/2*t^2 
versucht.

Mein Ansatz (den ich nicht zufireden stellen fand):
Also ich hatte die länge der Strecke auf der beschleunigt werden sollte, die maxGeschwindikeit, die aktuelle Geschwindigkeit und die Beschleunigung a.
Ich habe dann s=a/2t^2 nach t umgestellt damit ich die Zeit der Beschleunigung erhalte. Dann habe ich ein Timer mit t erstellt, der das Geschütz um a beschleunigt hatte bis zur maxGeschwindigkeit.
Doch war die Zeit die für t raus kam immer höher als es eigentlich sein dürfte für die maxGeschwindigkeit. Ich weis, dass das an der Strecke liegt das ich die vorgegeben hatte. Doch weis ich leider nicht wie ichs anders machen sollte.
Desweiteren war das immer er eine "ruckartige" beschleunigung (falls ihr versteht was ich meine), das hat mich auch genervt und da fällt mir auch keine andere möglichkeit ein.

Zum bremsen fällt mir überhaut nichts Sinvolles ein. Ich habe da keine bezugsgrößen was einigermaßen Realistisch wäre. Reicht es wenn ich da iwie die Formel verwende die ich mal in der Fahrschule gelernt habe? Oder sollte ich da eine komplexere Formel nehmen?
Ich denke das die doch für meine Ansprüche erstmal reichen sollte, da das beschleunigen und bremsen des Geschützes nur ein "netter Nebeneffekt" ist und nicht mehr sein soll.

Habt ihr eine bessere Iddee wie ich das anstellen kann? Vielleicht schon einen ganz anderen oder besseren Ansatz für mich?

Würde mich sehr freuen

Ich hab da noch eine Frage zu meinem Code:
Warum werden meine Geschosse schnelle desto steiler sie abgeschossen werden.

Hier nochmal meine Flakklasse:

```
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.Timer;
/*
 * Diese Klasse ist ein bewegliches Mobiles Flak geschütz, das den Feind beschießt.
 * Es besitzt ein primitieves Feuerleitsystem. Die Geschwindigkeit ist Felxibel und die Patrulien Art auch. 
 * Desweitern kann die Feuergeschwindigkeit nach belieben geändert werden
 */

public class Flak extends Sprite implements ActionListener {
	 ///////////////////////////////////
	// Bewegungen und Beschleunigung //
   ///////////////////////////////////
	
	double movefrom;			// Die Position von der das Flak Geschütz startet
	double moveto;				// bis zu Position zu der es fahren soll
	Timer accelerationTimer;	// Timer für die Beschleunigung
	boolean acceleration;		// Wert ob eine Beschleunigung stattfindet
	boolean breaking;			// Wert ob gebremst wird
	int a;						// Wert um den Beschleunigt wird
	int aktSpeed;				// Die aktuelle Geschwindigkeit
	int maxSpeed;				// Die maximale Geschwindigkeit die erreicht werden kann
	int accelerationTime;		// Die Zeit die für die Beschleunigung benötigt wird
	int currentAccelerationTime;// Zeit die bereits beschleunigt wurde
	int accelerationDistance;	// Strecke auf der beschleunigt werden soll
	
	 ////////////////////////////////
	// Zielerfassung und Beschuss //
   ////////////////////////////////
	
	boolean targetLocked;		// Gibt an ob ein Ziel erfasst wurde
	boolean fire;				// Gibt an ob Geschossen wird
	Timer bulletTimer;			// Timer in welchem Zeitabstand die Kugeln verschossen werden
	int firespeed;				// Geschwindigkeit in der Geschossen werden soll
	Sprite target;				// Das Zielobjekt
	int targetHeight;			// Die Höhe bis die das Flakgeschütz zielen kann
	int targetWidth;			// Die Weiter des Zielsystems
	Polygon aim;				// Das Polygon (Geo. Form) die als Zielerfassung dient
	
	/**
	 * @param i, das Bild des Sprits
	 * @param x, X-Pos des Sprits
	 * @param y, Y-Pos des Sprites
	 * @param delay, Bildwechselgeschwindigkeit
	 * @param movefrom, von wo
	 * @param moveto, bis wo sich das Geschütz hin-und herbewegen sollen
	 * @param startSpeed, die Startgeschwindigkeit des Geschütz
	 * @param acceleration, die beschleunigung
	 * @param accelerationDistance, die Strecke auf der beschleunigt wird
	 * @param maxSpeed, maximale Geschwindigkeit
	 * @param firespeed, Feuergeschwindigkeit
	 * @param p, Gamepanel
	 */
	
	public Flak(BufferedImage[] i, double x, double y, long delay,
			double movefrom, double moveto, int startSpeed, int acceleration, int accelerationDistance, int maxSpeed,
			int firespeed, int targetHeight, int targetWidth, GamePanel p) {
		super(i, x, y, delay, p);
		 ///////////////////////////////////////////////
		// Bewegung und Beschleunigung initalisieren //
	   ///////////////////////////////////////////////
		this.aktSpeed = startSpeed;
		this.a = acceleration;
		this.maxSpeed = maxSpeed;
		this.accelerationDistance = accelerationDistance;
		this.firespeed = firespeed;
		this.targetHeight = targetHeight;
		this.targetWidth = targetWidth;
		setPoints(maxSpeed); 						// Punkte die der Spieler bei der Zerstörung erhält
		aim = new Polygon();						// Neues Polygon, das als Zielerfassungssystem dient
		bulletTimer = new Timer(firespeed, this);	// bulletTimer wird der Feuergeschwindigkeit angepasst	
		targetLocked = false;						// wahr wenn ein Ziel erfasst wird								
		if (getX() >= parent.getWidth()-getWidth()){// Wenn das Flakgeschütz rechts auserhalb des Fensters starten soll,
			this.x = parent.getWidth() - getWidth();	// wird es automatisch in den sichtbaren rechten Bereich gesetzt
		}											
		if (getX() <= parent.getX()) {				// Wenn das Flakgeschütz links auserhalb des Fenster starten soll,
			this.x = parent.getX();						// wird es automatisch in den sichtbraren linken Bereich gesetzt
		}
		if (movefrom > moveto) {					// wenn der Startpunkt größer ist als der Zielpunkt
			double ram;									// werden die beiden einfach vertauscht
			ram = movefrom;					
			this.movefrom = moveto;			
			this.moveto = ram;						
		} else {
			this.movefrom = movefrom;
			this.moveto = moveto;
		}
		if (this.movefrom <= parent.getX()) {		// Wenn der Startpunkt auserhalb des Fensters liegt, wird er
			this.movefrom = parent.getX();				// automatisch auf die X-Pos 0 gesetzt			
		}
		if (this.moveto > parent.getWidth()) {		// wenn der Zeilpunkt rechts auserhalb des Fenster liegt,
			this.moveto = parent.getWidth();			// wird er Endpunkt dem Fensterende angepast
		}
		/*
		 * Wenn die Startposition des Objektes kleiner ist als der Startpunkt,
		 * muss das Flakgeschütz sich nach rechts bewegen, desweitern wird das Zielsystem erstellt, dies setzt sich
		 * aus einem Dreieck zusammen (Polygon). Dieses Dreieck wird nach vorne gezeichnet.
		 * Wenn die Startposition des Objektes größer ist als der Startpunkt,
		 * wird nach links beschleunigt, bementsprechend wird auch das Zieldreieck zur anderen Seite ausgerichtet.
		 * Desweitern werden auch die Animationen auch bestimmt
		 */
		if (getX() <= movefrom) {	
			setHorizontalSpeed(aktSpeed);
			aim.addPoint((int) (getX() + getWidth()), (int) getY());
			aim.addPoint((int) (getX() + getWidth() + this.targetWidth), (int)getY() - this.targetHeight);
			aim.addPoint((int) (getX() + getWidth() + this.targetWidth + this.targetHeight), (int)getY() - 	this.targetHeight);
			setLoop(0, 0);
		} else if (getX() > movefrom) {
			setHorizontalSpeed(-aktSpeed);
			aim.addPoint((int) (getX()), (int) getY());
			aim.addPoint((int) (getX() - this.targetWidth), (int)getY() - this.targetHeight);
			aim.addPoint((int) (getX() - this.targetWidth - this.targetHeight), (int)getY() - this.targetHeight);
			setLoop(1, 1);
		}
		System.out.println("Start bei: " + getX());
		System.out.println("von " + this.movefrom + " nach " + this.moveto);
	}
	/*
	 * (non-Javadoc)
	 * @see Sprite#doLogic(long)
	 * Methode, die die gesamte Logik des Objktes übernimmt	
	 */
	public void doLogic(long delta) {
		super.doLogic(delta);
		if (this.aktSpeed != 0) {					// Wenn die Geschwindigkeit nicht 0 ist:
			if (getX()+getWidth() >= this.moveto) { // Gleiches Prinziep wie beim Konstruktor
				setHorizontalSpeed(-this.aktSpeed);
				setLoop(1, 1);
			} else if (getX() <= this.movefrom) {
				setHorizontalSpeed(this.aktSpeed);
				setLoop(0, 0);
			}
			if (getHorizontalSpeed() < 0) {			// Wenn die Geschwindigkeit kleiner ist als 0,
				aim.reset();						// wird das Zielsystem resetet
				aim.addPoint((int) (getX()), (int) getY());
				aim.addPoint((int) (getX() - 300), (int)getY()+this.targetHeight);
				aim.addPoint((int) (getX() - this.targetWidth), (int)getY()+this.targetHeight);
			} else if (getHorizontalSpeed() > 0) {	// wenn die Geschwindigkeit größer ist als 0,
				aim.reset();						// wird das Zielsystem resetet und zur anderen Richtung neu berechnet
				aim.addPoint((int) (getX() + getWidth()), (int) getY());
				aim.addPoint((int) (getX() + getWidth() + this.targetWidth), (int)getY()+this.targetHeight);
				aim.addPoint((int) (getX() + getWidth() + this.targetWidth), (int)getY()+this.targetHeight);
			}
		}
		if (target == null) {						// wenn kein Ziel vorhanden ist:
			for (Sprite s : parent.actorscopy) {	// 	alle vorhandenen Sprits durchgehen
				if (s instanceof Heli) {			// 	wenn das Zielsprite ein Instanz vom Hubtschrauber ist
					if (aim.intersects(s)) {		// 	und wenn sich das Zielsystem und der Hubschrauber überschreiben
						target = s;					// 	makiere den Hubtschrauber als Ziel
						if (!getZielerfasst()) {	// 	Wenn kein Ziel erfasst ist
							bulletTimer.start();	// 	Starte den Kugeltimer der die Schüsse auslöst
							setZielerfasst(true);	// 	Zielerfast wird auf wahr gesetzt
						}
					}
				}
			}
		} else {									// sonst:
			if (target.isRemove()) {				//	wenn das Ziel zerstört wurde wir das Ziel wieder auf Null gesetzt,
				target = null;						//	damit der beschuss eingestellt wird
				return;
			}
			if (!(aim.intersects(target))) {		//	wenn das Ziel sich nicht mit der Zielvorrichtung überschneidet:
				target = null;						//		wird das Ziel auf Null gesetzt,
				if (getZielerfasst()) {				//		wenn ein Ziel erfasst ist  
					bulletTimer.stop();				//			wird deswiteren wird der Schusstimer gestoppt
					setZielerfasst(false);			// 			und die Zielerfassung wird aufgehoben
				}
			}
		}
		if (isRemove()) {							// wenn das Flakgeschütz zerstört wird							
			bulletTimer.stop();						// dann wird der Timer gestoppt, damit das Flakgeschütz nicht weiter feuert
		}
	}

	@Override
	public boolean collidedWith(Sprite s) {			
		if (this.intersects(s)) {
			if (s instanceof Rocket) {
				if (this.checkOpaqueColorCollision(s)) {
					parent.creatExplosion((int) getX(), (int) getY());
					parent.creatExplosion((int) s.getX(), (int) s.getY());
					parent.actors.elementAt(parent.actorscopy.indexOf(this))
							.setRemove(true);
					parent.actors.elementAt(parent.actorscopy.indexOf(s))
							.setRemove(true);
					return true;
				}
			}
			if (s instanceof Heli) {
				if (this.checkOpaqueColorCollision(s)) {
					parent.creatExplosion((int) getX(), (int) getY());
					parent.creatExplosion((int) s.getX(), (int) s.getY());
					parent.actors.elementAt(parent.actorscopy.indexOf(this))
							.setRemove(true);
					parent.actors.elementAt(parent.actorscopy.indexOf(s))
							.setRemove(true);
					return true;
				}
			}
		}
		return false;
	}

	public void drawObjects(Graphics g) {
		super.drawObjects(g);
		g.drawPolygon(aim);
	}

	public void actionPerformed(ActionEvent e) {
		if (parent.isStarted() && e.getSource().equals(bulletTimer)) {
			Bullet b = new Bullet(parent.imgBullet, aim.xpoints[0],
					aim.ypoints[0], 0, parent, this.target, 150);
			parent.actors.add(b);
		}
	}

	public void setZielerfasst(boolean zielerfasst) {
		this.targetLocked = zielerfasst;
	}

	public boolean getZielerfasst() {
		return this.targetLocked;
	}
}
```

und hier nochmal miene Bullet Klasse:

```
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;

public class Bullet extends Sprite {
	double m;

	double b;

	double erg;

	int speed;

	Sprite target;

	public Bullet(BufferedImage[] i, double x, double y, long delay,
			GamePanel p, Sprite target, int speed) {
		super(i, x, y, delay, p);
		this.target = target;
		this.speed = speed;
		this.m = ((this.target.getY() + this.target.getHeight() / 2) - (getY() + getHeight() / 2))
				/ ((this.target.getX() + this.target.getWidth() / 2) - (getX() + getWidth() / 2));
		this.b = -m * getX() + getY();
		if (getX() > target.getX()) {
			setHorizontalSpeed(-this.speed);
		} else if (getX() < target.getX()) {
			setHorizontalSpeed(this.speed);
		} else {
			setVerticalSpeed(-this.speed);
		}
	}

	public void doLogic(long delta) {
		super.doLogic(delta);
		if (getX() != target.getX()) {
			setY(m * getX() + b);
		} else {
			setVerticalSpeed(-speed);
		}
		if (getX() > parent.getWidth() || getX() + getWidth() < parent.getX()
				|| getY() + getHeight() < 0) {
			parent.actors.elementAt(parent.actorscopy.indexOf(this)).setRemove(
					true);
		}
	}

	@Override
	public boolean collidedWith(Sprite s) {
		if (this.intersects(s)) {
			if (s instanceof Heli) {
				if (this.checkOpaqueColorCollision(s)) {
					parent.creatExplosion((int) s.getX(), (int) s.getY());
					parent.actors.elementAt(parent.actorscopy.indexOf(this))
							.setRemove(true);
					parent.actors.elementAt(parent.actorscopy.indexOf(s))
							.setRemove(true);
					return true;
				}
			}
			if (s instanceof Rocket) {
				if (this.checkOpaqueColorCollision(s)) {
					parent.creatExplosion((int) s.getX(), (int) s.getY());
					parent.actors.elementAt(parent.actorscopy.indexOf(this)).setRemove(true);
					parent.actors.elementAt(parent.actorscopy.indexOf(s)).setRemove(true);
					return true;
				}
			}
			if (s instanceof Bullet) {
				if (this.checkOpaqueColorCollision(s)) {
					parent.actors.elementAt(parent.actorscopy.indexOf(this)).setRemove(true);
					parent.actors.elementAt(parent.actorscopy.indexOf(s)).setRemove(true);
					return true;
				}
			}
		}
		return false;
	}

	public void drawObjects(Graphics g) {
		super.drawObjects(g);
		g.drawLine((int) (getX() + getHeight() / 2),
				(int) (getY() + getHeight() / 2), (int) (target.getX() + target
						.getWidth() / 2), (int) (target.getY() + target
						.getHeight() / 2));
	}
}
```


mit freundlichen Grüßen Dagobert Dokate


----------



## Marco13 (24. Apr 2008)

Hmja ist ohne ein KSKB jetzt schwer nachzuvollziehen. Das Abbremesen ist eigentlich auch nur ein Beschleunigen. Nur dass die Beschleunigung negativ ist.

Hm. Ggf. schau' ich morgen nochmal drüber, hab nur grad zum testen sowas zusammengestümpert... (echt nur zum testen gehackt)

```
import java.awt.*;
import javax.swing.*;


class Position
{
    float x;
}

class Thing extends Position
{
    float v;
    float a = 100;
    float maxV = 200;
    boolean accelerate = true;
}

class ThingPanel extends JPanel
{
    Thing thing;

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.fillOval((int)thing.x, 100, 8,8);
    }
}

class AccelerationTest extends JFrame
{
    public static void main(String args[])
    {
        new AccelerationTest();
    }

    Thing thing = new Thing();
    Position target = new Position();
    ThingPanel panel = new ThingPanel();

    public AccelerationTest()
    {
        setSize(800,300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        panel.thing = thing;

        getContentPane().add(panel);
        setVisible(true);

        startMoving();
    }

    void startMoving()
    {
        target.x = 700;
        thing.x = 100;

        Thread t = new Thread(new Runnable()
        {
            public void run()
            {
                long prevTime = System.nanoTime();
                while (true)
                {
                    doit(System.nanoTime()-prevTime);
                    prevTime = System.nanoTime();
                    panel.repaint();
                    try
                    {
                        Thread.sleep(20);
                    }
                    catch (Exception e){}
                }
            }
        });
        t.start();

    }


    void doit(long delta)
    {
        float dt = delta / 1000000000.0f;
        float timeToStop = thing.v / thing.a;
        float distanceForStop = 0.5f * thing.a * timeToStop * timeToStop;
        float distanceToEnd = target.x - thing.x;

        if (Math.abs(distanceToEnd) < 1) // Am ende angekommen? Rumdrehen und beschleunigung AN
        {
            target.x = 800 - target.x;
            thing.accelerate = true;
        }
 

        // Kurz vorm Ziel? Abbremsen!
        if (distanceForStop >= Math.abs(distanceToEnd))
        {
            thing.accelerate = false;
        }

        // Abbremsen oder Beschleunigen
        if (thing.accelerate)
        {
            thing.v += dt * thing.a;
        }
        else
        {
            thing.v -= dt * thing.a;
        }

        thing.v = Math.min(Math.max(0, thing.v), thing.maxV);

        // Wenn man steht, auf jeden Fall beschleunigen
        if (thing.v == 0)
        {
            thing.accelerate = true;
        }

        // Nach recths oder links bewegen
        if (distanceToEnd > 0)
        {
            thing.x += thing.v * dt;
        }
        else
        {
            thing.x -= thing.v * dt;
        }
    }



}
```


----------



## filth (25. Apr 2008)

Dagobert:

arbeitest du mit GAGE? (wegen *public class Flak extends Sprite*)


----------



## Quaxli (25. Apr 2008)

Nein, tut er nicht, den Methodennamen nach hat er da so ein tolles Tutorial gelesen    

Ich habe jetzt den Code nur überfolgen, aber muß es denn eine physikalisch korrekte Beschleunigung sein? Wir reden ja schließlch "nur" von einem kleinen Ballerspiel.
Mein Vorschlag wäre, in der Methode setSpeed() nur einen boolean zu setzen und in der doLogic-Methode die aktuelle Geschwindigkeit bis zu einem Maximalwert zu erhöhen.


----------



## Dagobert (25. Apr 2008)

Nein es muss nicht umbeding eine physikalisch korrekte Beschleunigung sein. Hauptsache ich kann sie verändern, sie läuft lüssig und es gibt eine Beschleunigung bis maxV und kurz vor dem Ziel eine Bremsphase.
Ich werde mal an beiden hier vorgestellen Lösungen drüber nachdenken und mal rumprobieren.

mfg. Dagobert


----------



## Dagobert (6. Mai 2008)

So ich habe jetzt nach dem obrigen Beispiel versucht eine Beschleunigung einzubauen. Leider nur mit mäßigen bis schlechten Erfolg.
Mein Flak geschleunigt unglaublich schnell (viel zu schnell) ... und bremmst dann sofort langsam runter bis zum Zielpunkt. Wobei es auch nicht konstant bremst, sondern immer Gas gibt und bremst.
Ich glaube ich brauche da nochmal ganz dringend hilfe :bahnhof: 
Ich habe hier mal eine Beispielausgabe die ich mir zu Hilfe gemacht habe...


> Start bei: 0.0
> von 0.0 nach 800.0
> Zeit zum Stoppen: 0.0
> Entfernung zum Stoppen: 0.0
> ...


Ich finde das läuft offentsichtlich etwas falsch XD ich hab nur leider keine Große ahnung mehr was, aber ich glaube es wird auch was mit der Zeile zu tun haben:
	
	
	
	





```
if(Math.min(this.v, this.maxV) < this.maxV && distanceToEnd >= distanceForStop){
				this.v += this.a;
			} else {
				this.v -= this.a;
			}
```
Ich weis nur nicht wie ich das anders machen soll.

Hier nochmal meine ganze Klasse so wie sie aktuell aussieht:

```
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.Timer;
/*
 * Diese Klasse ist ein bewegliches Mobiles Flak geschütz, das den Feind beschießt.
 * Es besitzt ein primitieves Feuerleitsystem. Die Geschwindigkeit ist Felxibel und die Patrulien Art auch. 
 * Desweitern kann die Feuergeschwindigkeit nach belieben geändert werden
 */

public class Flak extends Sprite implements ActionListener {
	 ///////////////////////////////////
	// Bewegungen und Beschleunigung //
   ///////////////////////////////////
	
	double movefrom;			// Die Position von der das Flak Geschütz startet
	double moveto;				// bis zu Position zu der es fahren soll
	Timer accelerationTimer;	// Timer für die Beschleunigung
	boolean acceleration;		// Wert ob eine Beschleunigung stattfindet
	int a;						// Wert um den Beschleunigt wird
	int v;						// Die aktuelle Geschwindigkeit
	int maxV;					// Die maximale Geschwindigkeit die erreicht werden kann
	int accelerationTime;		// Die Zeit die für die Beschleunigung benötigt wird
	int currentAccelerationTime;// Zeit die bereits beschleunigt wurde
	
	 ////////////////////////////////
	// Zielerfassung und Beschuss //
   ////////////////////////////////
	
	boolean targetLocked;		// Gibt an ob ein Ziel erfasst wurde
	boolean fire;				// Gibt an ob Geschossen wird
	Timer bulletTimer;			// Timer in welchem Zeitabstand die Kugeln verschossen werden
	int firespeed;				// Geschwindigkeit in der Geschossen werden soll
	Sprite target;				// Das Zielobjekt
	int targetHeight;			// Die Höhe bis die das Flakgeschütz zielen kann
	int targetWidth;			// Die Weiter des Zielsystems
	Polygon aim;				// Das Polygon (Geo. Form) die als Zielerfassung dient
	
	/**
	 * @param i, das Bild des Sprits
	 * @param x, X-Pos des Sprits
	 * @param y, Y-Pos des Sprites
	 * @param delay, Bildwechselgeschwindigkeit
	 * @param movefrom, von wo
	 * @param moveto, bis wo sich das Geschütz hin-und herbewegen sollen
	 * @param startSpeed, die Startgeschwindigkeit des Geschütz
	 * @param acceleration, die beschleunigung
	 * @param accelerationDistance, die Strecke auf der beschleunigt wird
	 * @param maxSpeed, maximale Geschwindigkeit
	 * @param firespeed, Feuergeschwindigkeit
	 * @param p, Gamepanel
	 */
	
	public Flak(BufferedImage[] i, double x, double y, long delay,
			double movefrom, double moveto, int startSpeed, int acceleration, int maxSpeed,
			int firespeed, int targetHeight, int targetWidth, GamePanel p) {
		super(i, x, y, delay, p);
		 ///////////////////////////////////////////////
		// Bewegung und Beschleunigung initalisieren //
	   ///////////////////////////////////////////////
		this.v = startSpeed;
		this.a = acceleration;
		this.maxV = maxSpeed;
		 //////////////////////////////////////
		// Feuereinstellungen initalisieren //
	   //////////////////////////////////////
		this.firespeed = firespeed;
		this.targetHeight = targetHeight;
		this.targetWidth = targetWidth;
		setPoints(maxSpeed); 						// Punkte die der Spieler bei der Zerstörung erhält
		aim = new Polygon();						// Neues Polygon, das als Zielerfassungssystem dient
		bulletTimer = new Timer(firespeed, this);	// bulletTimer wird der Feuergeschwindigkeit angepasst	
		targetLocked = false;						// wahr wenn ein Ziel erfasst wird
		 ///////////////////////////////////////////////
		//Korrekturen der Startpositionen fals nötig //
	   ///////////////////////////////////////////////
		if (getX() >= parent.getWidth()-getWidth()){// Wenn das Flakgeschütz rechts auserhalb des Fensters starten soll,
			this.x = parent.getWidth() - getWidth();	// wird es automatisch in den sichtbaren rechten Bereich gesetzt
		}											
		if (getX() <= parent.getX()) {				// Wenn das Flakgeschütz links auserhalb des Fenster starten soll,
			this.x = parent.getX();						// wird es automatisch in den sichtbraren linken Bereich gesetzt
		}
		 //////////////////////////////////////////////
		// Korrektur der Bewegungspunkt falls nötig //
	   //////////////////////////////////////////////
		if (movefrom > moveto) {					// wenn der Startpunkt größer ist als der Zielpunkt
			double ram;									// werden die beiden einfach vertauscht
			ram = movefrom;					
			this.movefrom = moveto;			
			this.moveto = ram;						
		} else {
			this.movefrom = movefrom;
			this.moveto = moveto;
		}
		if (this.movefrom <= parent.getX()) {		// Wenn der Startpunkt auserhalb des Fensters liegt, wird er
			this.movefrom = parent.getX();				// automatisch auf die X-Pos 0 gesetzt			
		}
		if (this.moveto > parent.getWidth()) {		// wenn der Zeilpunkt rechts auserhalb des Fenster liegt,
			this.moveto = parent.getWidth()-getWidth();			// wird er Endpunkt dem Fensterende angepast
		}
		/*
		 * Wenn die Startposition des Objektes kleiner ist als der Startpunkt,
		 * muss das Flakgeschütz sich nach rechts bewegen, desweitern wird das Zielsystem erstellt, dies setzt sich
		 * aus einem Dreieck zusammen (Polygon). Dieses Dreieck wird nach vorne gezeichnet.
		 * Wenn die Startposition des Objektes größer ist als der Startpunkt,
		 * wird nach links beschleunigt, bementsprechend wird auch das Zieldreieck zur anderen Seite ausgerichtet.
		 * Desweitern werden auch die Animationen auch bestimmt
		 */
		if (getX() <= this.movefrom) {	
			aim.addPoint((int) (getX() + getWidth()), (int) getY());
			aim.addPoint((int) (getX() + getWidth() + 100), (int)getY() - this.targetHeight);
			aim.addPoint((int) (getX() + getWidth() + 100 + this.targetWidth), (int)getY() - this.targetHeight);
			setLoop(0, 0);
		} else if (getX() > this.movefrom) {
			aim.addPoint((int) (getX()), (int) getY());
			aim.addPoint((int) (getX() - 100), (int)getY() - this.targetHeight);
			aim.addPoint((int) (getX() - 100 - this.targetWidth), (int)getY() - this.targetHeight);
			setLoop(1, 1);
		}
		System.out.println("Start bei: " + getX());
		System.out.println("von " + this.movefrom + " nach " + this.moveto);
	}
	 ///////////////////////////////////////////////////////////
	// Methode, die die gesamte Logik des Objktes übernimmt	 //
   ///////////////////////////////////////////////////////////
	public void doLogic(long delta) {
		super.doLogic(delta);
		float timeToStop;
		double distanceForStop;
		if(this.v >= 0){
			timeToStop = this.v/this.a;
			distanceForStop = (0.5 * this.a * timeToStop * timeToStop);
		}else{
			timeToStop = 0;
			distanceForStop = 0;
		}
			double distanceToEnd = this.moveto - getX()-getWidth();
			System.out.println("Zeit zum Stoppen: " + timeToStop);
			System.out.println("Entfernung zum Stoppen: "+ distanceForStop);
			System.out.println("Entfernung zum Ende: " + distanceToEnd);
			System.out.println("Geschwindigkeit: " + this.v);
			
			if(Math.min(this.v, this.maxV) < this.maxV && distanceToEnd >= distanceForStop){
				this.v += this.a;
			} else {
				this.v -= this.a;
			}
			
			setHorizontalSpeed(v);
			
			if (getHorizontalSpeed() < 0) {			// Wenn die Geschwindigkeit kleiner ist als 0,
				aim.reset();							// wird das Zielsystem resetet
				aim.addPoint((int) (getX()), (int) getY());
				aim.addPoint((int) (getX() - 100), (int)getY() - this.targetHeight);
				aim.addPoint((int) (getX() - 100 - this.targetWidth), (int)getY() - this.targetHeight);
			} else if (getHorizontalSpeed() > 0) {	// wenn die Geschwindigkeit größer ist als 0,
				aim.reset();							// wird das Zielsystem resetet und zur anderen Richtung neu berechnet
				aim.addPoint((int) (getX() + getWidth()), (int) getY());
				aim.addPoint((int) (getX() + getWidth() + 100), (int)getY() - this.targetHeight);
				aim.addPoint((int) (getX() + getWidth() + 100 + this.targetWidth), (int)getY() - this.targetHeight);
			}
		if (target == null) {						// wenn kein Ziel vorhanden ist:
			for (Sprite s : parent.actorscopy) {	// 	alle vorhandenen Sprits durchgehen
				if (s instanceof Heli) {			// 	wenn das Zielsprite ein Instanz vom Hubtschrauber ist
					if (aim.intersects(s)) {		// 	und wenn sich das Zielsystem und der Hubschrauber überschreiben
						target = s;					// 	makiere den Hubtschrauber als Ziel
						if (!getZielerfasst()) {	// 	Wenn kein Ziel erfasst ist
							bulletTimer.start();	// 	Starte den Kugeltimer der die Schüsse auslöst
							setZielerfasst(true);	// 	Zielerfast wird auf wahr gesetzt
						}
					}
				}
			}
		} else {									// sonst:
			if (target.isRemove()) {				//	wenn das Ziel zerstört wurde wir das Ziel wieder auf Null gesetzt,
				target = null;						//	damit der beschuss eingestellt wird
				return;
			}
			if (!(aim.intersects(target))) {		//	wenn das Ziel sich nicht mit der Zielvorrichtung überschneidet:
				target = null;						//		wird das Ziel auf Null gesetzt,
				if (getZielerfasst()) {				//		wenn ein Ziel erfasst ist  
					bulletTimer.stop();				//			wird deswiteren wird der Schusstimer gestoppt
					setZielerfasst(false);			// 			und die Zielerfassung wird aufgehoben
				}
			}
		}
		if (isRemove()) {							// wenn das Flakgeschütz zerstört wird							
			bulletTimer.stop();						// dann wird der Timer gestoppt, damit das Flakgeschütz nicht weiter feuert
		}
	}

	@Override
	public boolean collidedWith(Sprite s) {			
		if (this.intersects(s)) {
			if (s instanceof Rocket) {
				if (this.checkOpaqueColorCollision(s)) {
					parent.creatExplosion((int) getX(), (int) getY());
					parent.creatExplosion((int) s.getX(), (int) s.getY());
					parent.actors.elementAt(parent.actorscopy.indexOf(this))
							.setRemove(true);
					parent.actors.elementAt(parent.actorscopy.indexOf(s))
							.setRemove(true);
					return true;
				}
			}
			if (s instanceof Heli) {
				if (this.checkOpaqueColorCollision(s)) {
					parent.creatExplosion((int) getX(), (int) getY());
					parent.creatExplosion((int) s.getX(), (int) s.getY());
					parent.actors.elementAt(parent.actorscopy.indexOf(this))
							.setRemove(true);
					parent.actors.elementAt(parent.actorscopy.indexOf(s))
							.setRemove(true);
					return true;
				}
			}
		}
		return false;
	}

	public void drawObjects(Graphics g) {
		super.drawObjects(g);
		g.drawPolygon(aim);
	}

	public void actionPerformed(ActionEvent e) {
		if (parent.isStarted() && e.getSource().equals(bulletTimer)) {
			Bullet b = new Bullet(parent.imgBullet, aim.xpoints[0],
					aim.ypoints[0], 0, parent, this.target, 150);
			parent.actors.add(b);
		}
	}

	public void setZielerfasst(boolean zielerfasst) {
		this.targetLocked = zielerfasst;
	}

	public boolean getZielerfasst() {
		return this.targetLocked;
	}
}
```

Nochmals vielen Dank für eure Hilfe


----------



## Quaxli (7. Mai 2008)

Mal ehrlich, wer soll sich durch den ganzen Code wühlen?  ???:L  Auch hier gilt die Forderung nach kleinen Programmen, die möglichst sogar direkt ausgeführt werden können.
Ich hab' mir das Ding da oben mal kopiert und alles unnötige rausgeworfen, was für das Beschleunigungsproblem nicht notwendig ist. Außerdem habe ich keine physikalischen Formeln verwendet, sondern feste Werte, wie von mir schon mal vorgeschlagen. 

<edit>
  Ach ja, und ich hab' nur den "Hinweg" realisiert, da es rein um Demozwecke geht. 
</edit>




```
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import tutorial.game.GamePanel;
import tutorial.sprite.Sprite;

public class Flak extends Sprite implements ActionListener {
   
   double a;                  // Wert um den Beschleunigt wird
   double v;                  // Die aktuelle Geschwindigkeit
   int maxV;               // Die maximale Geschwindigkeit die erreicht werden kann
   int minV;
   
   public Flak(BufferedImage[] i, double x, double y, long delay, GamePanel p) {
      super(i, x, y, delay, p);
     
      v = 0;
      a = 0.5;
      maxV = 100;
      minV = 10;
   }

   
   public void doLogic(long delta) {
      super.doLogic(delta);
      
      //Beschleunigung > 0 = Bewegung nach rechts
      if(a>0){
      	System.out.println(v + " vs. " + a);
        if(getX()>=0 && getX()<=100){
        	v += a;
        	if(v>=maxV){
        		v=maxV;
        	}
        }
        
        if(getX()>=parent.getWidth()-getWidth()-100 && getX()<=parent.getWidth()-getWidth()){
          v -= a;
          if(v<minV){
          	v=minV;
          }
        }
      }
      
      if(getX()+getWidth()>=parent.getWidth()){
      	v = 0;
      	a = 0;
      }
         
      setHorizontalSpeed(v);
         
   }

   @Override
   public boolean collidedWith(Sprite s) {         

  	 return false;
   }

   public void drawObjects(Graphics g) {
      super.drawObjects(g);

   }

   public void actionPerformed(ActionEvent e) {

   }

}
```


----------

