
-----------------------------------
kingghaffari
Mon Nov 07, 2011 3:51 pm

Java animation help.
-----------------------------------
Hey guys,
I am making a simple program that involves having a circle move towards the mouse when the user holds 'w' it's the equivalent  of moving "forwards" relative to there the "player" is facing.
I have two classes

GameFrame.class

[code]
import javax.swing.*;

public class GameFrame extends JFrame {
	public static void main( String[] args ) {
		JFrame f = new JFrame( "Sina and Tristan Shooter" );
		f.setSize( 1000, 500 );
		f.setResizable( false );
		f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		Game g = new Game();
		f.add( g );
		f.setVisible( true );
	}
}
[/code]

and Game.class

[code]
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.applet.*;
import javax.swing.*;

public class Game extends JComponent implements MouseListener, MouseMotionListener, KeyListener {

	private Image dbImage;
	private Graphics dbg;
	private int MouseX, MouseY;
	private double PX=200;
	private double PY=200;
	private double angle;
	private double Velocity;
	private double Distance;
	
	public Game() {
		angleChange();
		addMouseMotionListener(this);
        addMouseListener(this);
        addKeyListener(this);
	}

	public void angleChange() {
		Thread t = new Thread(new Runnable() {

			public void run() {
				while(true)
				{
					angle =  Math.toDegrees(Math.atan2((PY - MouseY),(PX - MouseX)));
					if ( angle < 0 )
						angle = (180 - (Math.abs(angle)) + 180);
					PX += Velocity * Math.toDegrees(Math.cos( angle ));
					PY += Velocity * Math.toDegrees(Math.sin( angle ));
					Distance = Math.sqrt((Math.pow((PX - MouseX), 2)) + (Math.pow((PY - MouseY), 2)));
					try {
						Thread.sleep(3);
					} catch (InterruptedException e) {
					}
			        repaint();
				}
			}
		});
		t.start();
	}

	
	public void paint( Graphics g ) {
		Graphics2D g2 = ( Graphics2D )g;
		this.grabFocus();
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		setSize( 1000, 500 );
		this.setBackground( Color.white );
		g2.setPaint(Color.blue);
		g2.fill( new Ellipse2D.Double(PX - 10, PY - 10, 20, 20));
		g.drawString("Angle = " + angle, 40, 40);
		g.drawString("MouseX = " + MouseX, 40, 50);
		g.drawString("MouseY = " + MouseY, 40, 60);
		g.drawString("PX = " + Velocity, 40, 200);
		g.drawString("PY = " + Distance, 40, 220);

	}

	public void keyPressed( KeyEvent k ) {
		if (k.getKeyCode() == KeyEvent.VK_D )  PX+=3;
        if (k.getKeyCode() == KeyEvent.VK_A )  PX-=3;
        if (k.getKeyCode() == KeyEvent.VK_W )
        {
        	Velocity = 0.01;
        }
        if (k.getKeyCode() == KeyEvent.VK_S ) PY+=3;
	}

	public void keyReleased( KeyEvent k ) {
		Velocity = 0;
	}

	public void keyTyped( KeyEvent k ) {

	}

	public void mouseDragged( MouseEvent e ) {

	}

	public void mouseMoved( MouseEvent e ) {
		MouseX = e.getX();
		MouseY = e.getY();
	}

	public void mouseClicked( MouseEvent e ) {

	}

	public void mouseEntered( MouseEvent e ) {

	}

	public void mouseExited( MouseEvent e ) {

	}

	public void mousePressed( MouseEvent e ) {

	}
	public void mouseReleased( MouseEvent e ) {

	}

}
[/code]

It seems to work fine, unless the user moves the mouse constantly as the circle is moving.
I don't understand WHY the circle moves so spastic-like, as the formula shouldn't even allow for that kind of movement.

And help would be greatly appreciated.

Thanks,
Sina Ghaffari

-----------------------------------
Zren
Mon Nov 07, 2011 5:33 pm

RE:Java animation help.
-----------------------------------
fucked messed up your understanding of conversion from degrees to radians, and how trig functions work in general (don't worry, you're not the first, nor are you the last).

The variable angle seems to be a the angle calculated in degrees. However the parameter for [url=http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html]Math.cos(double radians) uses radians.

Math.toDegrees(Math.sin( angle ))

Converting the result of those trig functions to degrees means nothing as the result is not even an angle.

So:
You need to pass an angle in radians into trig functions.

Solutions:
- Have your angle variable be represented in radians (radians are cool!)
- Look into [url=http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html]Math.toRadians(double angleDegrees)

Further:
Look into what sine() and cosine() actually do, along with vector math in general. Post here if you'd like us to expand on this subject.

-----------------------------------
kingghaffari
Mon Nov 07, 2011 6:04 pm

Re: Java animation help.
-----------------------------------
YES!

You have succeeded where many others have failed!

Everything works fine, but for some reason i have to change PX += and PY += to PX -= and PY -=. Works like a charm now!

-----------------------------------
Zren
Mon Nov 07, 2011 9:53 pm

Re: Java animation help.
-----------------------------------
For some reason i have to change PX += and PY += to PX -= and PY -=. Works like a charm now!
That's because you are calculating displacement incorrectly on this line:

angle =  Math.toDegrees(Math.atan2((PY - MouseY),(PX - MouseX))); 

Displacement is as follows: dx = x2 - x1

The logic is that dx will be the distance from x1 to x2. It will be positive if x1 < x2. It will be negative if x1 > x2.

It's the displacement from x1 to x2.

Basically you had it backwards as your having the displacement from mouse to point. That would make it negative if the mouse was below-right of the point, when the coordinates of the mouse are actually greater than those of the point. So all the while you wanted the displacement of point to mouse. The error there flowed into the calculation for Math.atan2() to get the angle, which flowed down to your vector addition. The same logic can be used for the y-axis.
