Auto in bestimmte Richtung fahren lassen

StrikeTom

Bekanntes Mitglied
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:)
 

StrikeTom

Bekanntes Mitglied
Danke, ich habe es mir mal angeguckt und ich habe eine Frage:
Was hast du für eine klasse hast du vererbt
(
Java:
this.getWidth()
)?
Also: wovon nimmst du die Breite?
 

TheChemist

Bekanntes Mitglied
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

Bekanntes Mitglied
Eclipse sagt mir, nachdem ich die Taste nach oben gedrückt habe, einen Fehler:
Code:
[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:
Java:
if (keyPressed[UP]) 
	 {
	       x -= translation.getTranslateX(); //<-Das ist zeile 116
	       y -= translation.getTranslateY();
	 }
 
G

Gast2

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

StrikeTom

Bekanntes Mitglied
Omg, ich bin ja so dumm:)))
Ich habe zwei globale variablen
(
Java:
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:D:D:D
 

StrikeTom

Bekanntes Mitglied
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:)
 
Zuletzt bearbeitet:

StrikeTom

Bekanntes Mitglied
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

Bekanntes Mitglied
Das ist der Unterschied zwischen Bogen- und Gradmaß. Zum Umrechnen:
Java:
Math.toDegrees(angrad)
Math.toRadians(angdeg)
 

TheChemist

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

StrikeTom

Bekanntes Mitglied
1. Die Funktion, die den Logischen Teil erledigen soll:
Java:
 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:
Java:
   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:
Java:
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:
Java:
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:
Java:
 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:D
 

Marco13

Top Contributor
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 :D )
 

TheChemist

Bekanntes Mitglied
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.
 

Marco13

Top Contributor
... 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

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

Java:
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

	}
	
	
}

:D:D:D
 

StrikeTom

Bekanntes Mitglied
Also der ganze Code:
Java:
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:
Java:
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

Top Contributor
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

Bekanntes Mitglied
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)
 

Hansdampf

Bekanntes Mitglied
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:
Code:
 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.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
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

Bekanntes Mitglied
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:eek::eek::eek:
Es tut mir ja so Leid:oops:
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:D
Wenn ich dann Probleme hab, dann melde ich mich hier noch mal, aber vorerst makiere ich das thema als erledigt:D
 

Neue Themen


Oben