# Auto in bestimmte Richtung fahren lassen



## StrikeTom (21. Mai 2010)

Hall Leute,
ich versuche gerade ein Spiel wie dieses zu
programmieren. Ich bin noch nicht so weit und habe das problem, das ich, wenn ich die Pfeiltaste geradeaus drücke, nicht nach oben fahren möchte, sondern in die Richtung in die das Auto steht.
Weiß jemand wie? Ich habe noch keine Idee gehabt, wie ich das anstellen könnte.
Danke schonmal im vorraus


----------



## TheChemist (21. Mai 2010)

Hey, ich hab vor Kurzem genau dieses Problem auch gehabt und erfolgreich gelöst. Schau mal hier in den Thread http://www.java-forum.org/spiele-multimedia-programmierung/99804-java2d-rotation-translation.html

Frag einfach nach, wenn du was nicht verstehst^^


----------



## StrikeTom (21. Mai 2010)

Danke, ich gucke es mir gleich mal an


----------



## StrikeTom (21. Mai 2010)

Danke, ich habe es mir mal angeguckt und ich habe eine Frage:
Was hast du für eine klasse hast du vererbt
(

```
this.getWidth()
```
)?
Also: wovon nimmst du die Breite?


----------



## TheChemist (21. Mai 2010)

Oh ja sorry, das wär vielleicht noch ganz hilfreich. Das ganze baut auf Quaxlis Tutorial auf, also hab ich von Rectangle2D.Double geerbt.


----------



## StrikeTom (21. Mai 2010)

Danke, ich versuche es gleich mal.
Hoffendlich funktioniert esD)


----------



## StrikeTom (21. Mai 2010)

Eclipse sagt mir, nachdem ich die Taste nach oben gedrückt habe, einen Fehler:

```
[COLOR="Red"]Exception in thread "Thread-2"[/COLOR][COLOR="Navy"][U]java.lang.NullPointerException[/U] [/COLOR][COLOR="Red"]
at NFS2D.Auto$Game$2.run([COLOR="Navy"][U]Auto.java:116[/U][/COLOR])
[/COLOR]
```
Zeile 116:

```
if (keyPressed[UP]) 
	 {
	       x -= translation.getTranslateX(); //<-Das ist zeile 116
	       y -= translation.getTranslateY();
	 }
```


----------



## StrikeTom (22. Mai 2010)

Weiß denn keiner Rat;(;(;(


----------



## Gast2 (22. Mai 2010)

NPE... ergo ist translation null.
Wieso das so ist kann man bei den paar Zeilen leider nicht sagen


----------



## Hansdampf (22. Mai 2010)

poste doch mal mehr code


----------



## StrikeTom (22. Mai 2010)

Omg, ich bin ja so dumm))
Ich habe zwei globale variablen
(

```
static AffineTransform rotation;
	static AffineTransform translation;
```
)
gemacht, aber in der funktion in der ich die berechnungen anstelle noch mal die
gleichen variablen erstellt. und als dann die if-bedingung getestet wurde, habe ich die globalen variablen genutzt: Diese waren natürlich null.
Es funktioniert


----------



## StrikeTom (22. Mai 2010)

Mist, es funktioniert doch noch nicht so ganz()
wenn ich das Auto nach rechts drehe und dann die Pfeiltaste nach oben drücke, dann fährt das auto nur nach oben(nicht in die gedrehte richtung).
Wenn ich das Auto immer mehr drehe, dann fährt es immer weniger in die gedrehte richtung.(bei 90° fährt es nur schräg nach links)


Ps: Danke für die vielen Antworten


----------



## StrikeTom (22. Mai 2010)

Könnte es daran liegen, das degree ein komisches verhältnis zu der normalen gradzahl hat?
Denn wenn degree den wert 6.26 hat, dann entspricht das einer ganzen drehung(360°)


----------



## Hansdampf (22. Mai 2010)

Das ist der Unterschied zwischen Bogen- und Gradmaß. Zum Umrechnen:

```
Math.toDegrees(angrad)
Math.toRadians(angdeg)
```


----------



## StrikeTom (23. Mai 2010)

Danke
Weiß noch jemand wo der Fehler liegt?


----------



## StrikeTom (24. Mai 2010)

Hat keiner eine Idee?
Ich überlege die ganze Zeit aber komme einfach nicht auf den Fehler;(


----------



## StrikeTom (25. Mai 2010)

Ich glaub, ich gebs auf:rtfm:


----------



## Marco13 (25. Mai 2010)

Schwach  Beschreib' halt mal dein Problem (so, dass man auch antworten kann  )


----------



## TheChemist (25. Mai 2010)

Poste mal den Code kompletten deiner Klasse, die die Bewegung durchführen soll, dann wird sich der Fehler doch ausfindig machen lassen...


----------



## StrikeTom (25. Mai 2010)

1. Die Funktion, die den Logischen Teil erledigen soll:

```
public void moveLocic()
            {
            	if(degree >= 6.26 || degree <= -6.26)
            	{
            		degree = 0;
            	}
            	double dx;
                double dy;
                dx = Math.sin(Math.toRadians(-degree));
                dy = Math.cos(Math.toRadians(-degree));
                translation = AffineTransform.getTranslateInstance(dx, dy);
            }
```
Dann die Funktion fürs Updaten der Key-sachen:

```
public void update(KeyEvent e, boolean pressed) 
            {
                if (e.getKeyCode() == KeyEvent.VK_UP)
                {
                	keyPressed[UP] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_RIGHT)
                {
                    keyPressed[RIGHT] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_LEFT)
                {
                    keyPressed[LEFT] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_DOWN)
                {
                    keyPressed[DOWN] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
                {
                	 System.exit(0);
                }
            	moveLocic();

            	}
```
Das dürfte dann zusammen so aussehen:

```
public static class Game extends JFrame
	{
		public Game(String s)
		{
			super(s);
			this.setDefaultCloseOperation(Game.EXIT_ON_CLOSE);
			this.setSize(500, 500);
		addKeyListener(new KeyAdapter()
        {
            public void keyPressed(KeyEvent e) 
            {
                update(e, true);
            }
 
            public void keyReleased(KeyEvent e)
            {
                update(e, false);
            }
            public void moveLocic()
            {
            	if(degree >= 6.26 || degree <= -6.26)
            	{
            		degree = 0;
            	}
            	double dx;
                double dy;
                dx = Math.sin(Math.toRadians(-degree));
                dy = Math.cos(Math.toRadians(-degree));
                rotation = AffineTransform.getRotateInstance(Math.toRadians(degree), x +          
                car.getWidth(map) / 2, y + car.getHeight(map) / 2);
                translation = AffineTransform.getTranslateInstance(dx, dy);
            }
            public void update(KeyEvent e, boolean pressed) 
            {
                if (e.getKeyCode() == KeyEvent.VK_UP)
                {
                	keyPressed[UP] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_RIGHT)
                {
                    keyPressed[RIGHT] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_LEFT)
                {
                    keyPressed[LEFT] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_DOWN)
                {
                    keyPressed[DOWN] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
                {
                	 System.exit(0);
                }
            	moveLocic();
            }
        });
```
und dann noch die Methode zum drehen des Bildes:

```
public static void rot(final Graphics g, int xPos, int yPos)
{
    Graphics2D g2d = (Graphics2D) g;
    int w = car.getWidth(null);
    int h = car.getHeight(null);
    xPos = x;
    yPos = y;
    int xRot = x + w / 2;
    int yRot = y + h / 2;
    AffineTransform rotation = g2d.getTransform();
    rotation.rotate(degree, xRot, yRot);
    g2d.setTransform(rotation);
    g2d.drawImage(car, xPos, yPos, w, h, (ImageObserver)map);
    g2d.dispose();
}
```
Und der Thread zum Bewegen:

```
new Thread()
	        {
	            public void run() 
	            {
	                while (true) 
	                {
//	                    y -= (keyPressed[UP] ? maxKmh/10 : 0);
	                	if (keyPressed[UP]) 
	                    {
	                        x -= translation.getTranslateX();
	                        y -= translation.getTranslateY();
	                    }
	                	if (keyPressed[DOWN]) 
	                    {
	                        x += translation.getTranslateX();
	                        y += translation.getTranslateY();
	                    }
	                    degree += (keyPressed[RIGHT] ? 0.1 : 0);
	                    degree -= (keyPressed[LEFT] ? 0.1 : 0);
	                    

	                   repaint();
	                    try 
	                    {
	                        Thread.sleep(100);
	                    } 
	                    catch (InterruptedException e) 
	                    {
	                        e.printStackTrace();
	                    }
	                }
	            }
	        }.start();
	}
```
Ich hoffe, dass das reicht


----------



## Marco13 (25. Mai 2010)

Was heißt "reicht"... Wenn man es nicht 1:1 am Stück mit Copy&Paste in TextPad einfügen und sofort compilieren und starten kann, ist es mit Arbeit verbunden... (Wenn ich für jedes mal, wo ich 
[c]public static void main(String args[])[/c]
geschrieben habe, einen €-cent bekommen hätte, wäre ich jetzt reich  )


----------



## TheChemist (25. Mai 2010)

Was mir auf jeden Fall auffällt, dass du scheinbar alles in Klasse berechnest und das ganze sehr schnell ziemlich unübersichtlich wird. Ich weiß nicht ob du Quaxlis Tutorial dir schon angeschaut hast, aber das bietet für den Anfang auf jeden Fall einen sehr guten Aufbau. Mein Codebeispiel vom Anfang hat ja auch darauf aufgebaut.


----------



## StrikeTom (26. Mai 2010)

> Was heißt "reicht"... Wenn man es nicht 1:1 am Stück mit Copy&Paste in TextPad einfügen und sofort compilieren und starten kann, ist es mit Arbeit verbunden...


Soll heißen?


----------



## Marco13 (26. Mai 2010)

... dass man die geposteten Codestücke erst so zusammenkopieren müßte, wie man vermutet, dass sie bei dir sind, um dann vielleicht erahnen zu können, worin die Frage genau besteht... (wo und wann wird "rot" aufgerufen, wo und wann der Thread erstellt, was ist das gewünschte und was das beobachtete Verhalten...)


----------



## Quaxli (26. Mai 2010)

Was Marco meint: Kopieren, Ausführen, Angucken.
Also zum Beispiel sowas:


```
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferStrategy;


public class RecMove extends JPanel implements Runnable, KeyListener{

	private static final long	serialVersionUID	= 1L;
  JFrame frame;
  Rec rectangle;
  boolean left = false;
  boolean right = false;
	
	public static void main (String[] args){
		new RecMove();
	}
	
	public RecMove(){
    setPreferredSize(new Dimension(400,400));
    
		rectangle = new Rec(200,390,10,10,this);
    frame = new JFrame("RecMove");
		frame.setSize(400,400);
		frame.setLocation(100,100);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(this);
		frame.addKeyListener(this);
		frame.pack();
		frame.setVisible(true);
		
		Thread t = new Thread(this);
		t.start();
		
	}

	public void paintComponent(Graphics g){
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		rectangle.paintRect(g2);
	}
	
	
	public void run() {
		
		while(frame.isVisible()){
			
			if(left){
				rectangle.increaseAngle();
			}
			
			if(right){
				rectangle.decreaseAngle();
			}
			
			rectangle.doLogic();
			rectangle.move();
			
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {}
      
			frame.repaint();			
		}
		
	}

	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode()==KeyEvent.VK_LEFT){
			left = true;
		}
		if(e.getKeyCode()==KeyEvent.VK_RIGHT){
			right = true;
		}
	}

	public void keyReleased(KeyEvent e) {
		if(e.getKeyCode()==KeyEvent.VK_LEFT){
			left = false;
		}
		if(e.getKeyCode()==KeyEvent.VK_RIGHT){
			right = false;
		}
	}

	public void keyTyped(KeyEvent e) {
		
	}


}


class Rec extends Rectangle2D.Double{
	
	private static final long	serialVersionUID	= 1L;
	double dx = 0;
	double dy = 0;
  JPanel parent;
  long last = 0;
	int angle = 0;
	int speed = 60;
  
	public Rec(int x, int y, int w, int h,JPanel p){
		super(x,y,w,h);
		parent = p;
		last = System.nanoTime();
		setAngleSpeed(angle,speed);
	}
	
  public void setAngleSpeed(int degree, double speed) {
    
    double rad = Math.toRadians(degree);
    
    dx = Math.sin(rad) * speed;
    dy = Math.cos(rad) * speed;
  }

  public void increaseAngle(){
  	angle++;
  	if(angle==360){
  		angle =0 ;
  	}
  	setAngleSpeed(angle,speed);
  }

  public void decreaseAngle(){
  	angle--;
  	if(angle==-1){
  		angle =359 ;
  	}
  	setAngleSpeed(angle,speed);
  }
	
	public void paintRect(Graphics g){
		g.setColor(Color.RED);
		g.drawRect((int)x,(int)y,(int)width,(int)height);
		//temporärer Code
		Point p = new Point((int)(x+width/2),(int)(y+height/2));
		g.drawLine(p.x,p.y,(int)(p.x+dx/10),(int)(p.y+dy/10));
	}
	
	public void move(){
		long delta = last - System.nanoTime();
    x += (dx*(delta/1e9));
    y += (dy*(delta/1e9));
    last = System.nanoTime();
	}
	
	public void doLogic(){ 
    //erst mal nix

	}
	
	
}
```


----------



## StrikeTom (27. Mai 2010)

Also der ganze Code:

```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Auto
{
	private static boolean fahren;
	static double dx;
	static double dy;
	static AffineTransform rotation;
	static AffineTransform translation;
	private static boolean[] keyPressed = new boolean[4];
    private static int UP = 0, RIGHT = 1, DOWN = 2, LEFT = 3;
	private static int maxKmh;
	private static int saveKmh;
	private int kg;
	private int beschleunigung;
	private static Image car;
	private final static String load = "C:\\Dokumente und Einstellungen\\Karl\\Desktop\\Suchen\\NFS2D\\";
	private static String name;
	private static int x;
	private static int y;
	private static JPanel map = null;
	private static double degree = 0;
	public Auto(int max, int kg, int besch, String name, CarPanel karte, int x, int y,boolean fahr)
	{
		this.maxKmh = max;
		this.kg = kg;
		this.beschleunigung = besch;
		this.name = name;
		this.map = karte;
		this.x = x;
		this.y = y;
		this.saveKmh = this.maxKmh;
		this.fahren = fahr;
	}
	public static class Game extends JFrame
	{
		public Game(String s)
		{
			super(s);
			this.setDefaultCloseOperation(Game.EXIT_ON_CLOSE);
			this.setSize(500, 500);
		addKeyListener(new KeyAdapter()
        {
            public void keyPressed(KeyEvent e) 
            {
                update(e, true);
            }
 
            public void keyReleased(KeyEvent e)
            {
                update(e, false);
            }
            public void moveLocic()
            {
            	if(degree >= 6.26 || degree <= -6.26)
            	{
            		degree = 0;
            	}
            	double dx;
                double dy;
                dx = Math.sin(Math.toRadians(-degree));
                dy = Math.cos(Math.toRadians(-degree));
                rotation = AffineTransform.getRotateInstance(Math.toRadians(degree), x + car.getWidth(map) / 2, y + car.getHeight(map) / 2);
                translation = AffineTransform.getTranslateInstance(dx, dy);
                System.out.println(degree);
            }
            public void update(KeyEvent e, boolean pressed) 
            {
            	if(fahren)
            	{
                if (e.getKeyCode() == KeyEvent.VK_UP)
                {
                	maxKmh = saveKmh;
                	keyPressed[UP] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_RIGHT)
                {
                    keyPressed[RIGHT] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_LEFT)
                {
                    keyPressed[LEFT] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_DOWN)
                {
                    keyPressed[DOWN] = pressed;
                }
                if (e.isShiftDown() && e.getKeyCode() == KeyEvent.VK_UP)
                {
                    maxKmh = 300;
                    keyPressed[UP] = pressed;
                }
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
                {
                	 System.exit(0);
                }
            	moveLocic();

            	}
            }
        });
		 new Thread()
	        {
	            public void run() 
	            {
	                while (true) 
	                {
//	                    y -= (keyPressed[UP] ? maxKmh/10 : 0);
	                	if (keyPressed[UP]) 
	                    {
	                        x -= translation.getTranslateX();
	                        y -= translation.getTranslateY();
	                    }
	                	if (keyPressed[DOWN]) 
	                    {
	                        x += translation.getTranslateX();
	                        y += translation.getTranslateY();
	                    }
	                    degree += (keyPressed[RIGHT] ? 0.1 : 0);
//	                    x += (keyPressed[RIGHT] ? 5 : 0);
//	                    y += (keyPressed[DOWN] ? 5 : 0);
//	                    x -= (keyPressed[LEFT] ? 5 : 0);
	                    degree -= (keyPressed[LEFT] ? 0.1 : 0);
	                    

	                   repaint();
	                    try 
	                    {
	                        Thread.sleep(100);
	                    } 
	                    catch (InterruptedException e) 
	                    {
	                        e.printStackTrace();
	                    }
	                }
	            }
	        }.start();
	}
	}
	public static class CarPanel extends JPanel
	{
		public CarPanel()
		{
		}
		public void paintComponent(Graphics g) 
		{
			super.paintComponent(g);
			map.setBackground(Color.white);
			File f = new File(load + name + ".gif");
			try
			{
				car = ImageIO.read(f);
			} 
			catch (IOException e)
			{
				e.printStackTrace();
			}
		    rot(g.create(),x,y);
		}
	}
public static void rot(final Graphics g, int xPos, int yPos)
{
    Graphics2D g2d = (Graphics2D) g;
    int w = car.getWidth(null);
    int h = car.getHeight(null);
    xPos = x;
    yPos = y;
    //center of rotation is center of the Image:
    int xRot = x + w / 2;
    int yRot = y + h / 2;
    //rotate:
    AffineTransform rotation = g2d.getTransform();
    rotation.rotate(degree, xRot, yRot);
    //draw Image with rotation:
    g2d.setTransform(rotation);
    g2d.drawImage(car, xPos, yPos, w, h, (ImageObserver)map);
    g2d.dispose();
}

}
```
Und die main Klasse:

```
import NFS2D.Auto.CarPanel;
import NFS2D.Auto.Game;

public class Main
{

	public static void main(String[] args)
	{
		Game f = new Game("NFS2D");
		CarPanel p = new CarPanel();
		Auto a = new Auto(150,3,3,"Corvette",p,100,200, true);
		f.add(p);
		f.setVisible(true);
	}

}
```


----------



## Marco13 (27. Mai 2010)

Strukturfrei. Ich würde dir empfehlen, dir mal das anzusehen, was Quaxli gepostet hat, und schauen, ob du dort das Bild von deinem Auto reinbringst. Aber nicht bei jedem neuzeichnen das Bild neu laden...


----------



## Hansdampf (27. Mai 2010)

Ich habs mal angeschaut und den Fehler gesucht... aber der Aufbau ist so ungewöhnlich, dass neu schreiben schneller wäre. 
Schließe mich Marco13 an, nimm Quaxlis Beispiel. 
(Und fang gar nicht erst mit den statics an)


----------



## StrikeTom (27. Mai 2010)

Ich werd mich mal reinarbeiten:rtfm:
Was war jetzt an meinem Code falsch?


----------



## Hansdampf (27. Mai 2010)

Habe ich nicht rausgefunden, sind wahrscheinlich mehrere Dinge...
oben rechnest Du z.B. Math.toRadians(-degree)); aus, obwohl der Wert schon im Bogenmaß ist.
Außerdem kommt das Minus-Vorzeichen nicht in die Klammer, sondern so:

```
dx = Math.sin(degree);
 dy = -Math.cos(degree);
```
Deine moveLocic() wird nur bei Tastendruck aufgerufen, was die keypressed[] unsinnig macht.
Und da alles static ist und ein zusätzlicher (unnötiger) Thread läuft, ist es schwer nachzuvollziehen.

edit: deine x und y sind int!
edit: hat mir keine Ruhe gelassen. Ersetze alle int durch double, nimm das Math.toRadians() oben raus, dann gehts.
unten beim Zeichnen nach (int)xPos, (int)yPos casten.


----------



## StrikeTom (27. Mai 2010)

> Deine moveLocic() wird nur bei Tastendruck aufgerufen, was die keypressed[] unsinnig macht.


Wann sonst?


> deine x und y sind int!


Das weiß ich. Und?


----------



## Hansdampf (27. Mai 2010)

Habe eben meinen letzten Post noch editiert.
Wenn  int x=5 hast und addierst z.B. 100 mal hintereinander 0.4, dann ist x immer noch 5.


----------



## Marco13 (27. Mai 2010)

Die moveLogic sollte vermutlich (zumindest später) in einem eigenen Thread ständig aufgerufen werden, je nachdem, welches Verhalten du willst: Wenn sich das Auto NUR bei gedrückter Taste bewegen soll, könnte man es auch "von Hand" (d.h. bei KeyPressed) aufrufen, aber ... vermutlich soll ja nicht "die Welt anhalten" wenn man die Taste losläßt....


----------



## StrikeTom (28. Mai 2010)

> Habe eben meinen letzten Post noch editiert.
> Wenn int x=5 hast und addierst z.B. 100 mal hintereinander 0.4, dann ist x immer noch 5.


Achso
omg
Es tut mir ja so Leid
Ich habe den Codeaufbau(mit diesem unsinnigem thread usw...)  von einem anderem Quelltext, der nicht von mir stammt. Tschuldigung.
Ich werde den ganzen Code neu schreiben
Wenn ich dann Probleme hab, dann melde ich mich hier noch mal, aber vorerst makiere ich das thema als erledigt


----------



## Vaymiki (12. Jul 2016)




----------



## VfL_Freak (12. Jul 2016)

@Vaymiki 
Warum um alles in der Welt pusht Du diesen Uralt-Thread ???


----------



## Vaymiki (3. Okt 2016)

http://******.de/netent/piggy-riches  Sag mir, wie Sie das Skript dieses Spiel herunterladen kann?


----------



## Viktim (4. Okt 2016)

Vaymiki hat gesagt.:


> http://*******.de/netent/piggy-riches Sag mir, wie Sie das Skript dieses Spiel herunterladen kann?


was willst du?


----------

