My bullet(missile,magic) doesn't want to go to mouse x,y!? [solved]

I asked this question before but i had particles on my missile and i thougth that it was working, and it’s not! :emo:

Well i get this:

before i changed static x,y to not static:

after:

GitHub for the code
Look in the src/Entity for the player(shooting from the player)
and missile, camera is in the control

I don’t know why is it doing this? I want it to go at any angle! Why it doesn’t ?

Here is how you calculate rotation between player and mouse:


float rot = Math.atan2(xmouse - xplayer, ymouse - yplayer);

And from that how can i calculate the velocity for x,y?

Simple Pythagoras? Or what do you need?

To calculate the x & y velocity you need to use this code:


float x = xMouse - xPlayer;
float y = yMouse - yPlayer;
float length = Math.sqrt((x * x) + (y* y));
xVelocity = x / length * speed;
yVelocity = y / length * speed;

Sorry if it doesn’t work I am very tired and I didn’t test it.

Here are a couple of utility methods I wrote that work like a charm:


	public static vec2 point(vec2 pivot, vec2 point, float rotation) {
		
		float rot = (float)(1f / 180 * rotation * Math.PI);
		
		float x = point.x - pivot.x;
		float y = point.y - pivot.y;
		
		float newx = (float)(x * Math.cos(rot) - y * Math.sin(rot));
		float newy = (float)(x * Math.sin(rot) + y * Math.cos(rot));
		
		
		newx += pivot.x;
		newy += pivot.y;
		
		return new vec2(newx, newy);
	}

	public static int angle(vec2 pivot, vec2 point) {

		float xdiff = pivot.x - point.x;
		float ydiff = pivot.y - point.y;
		
		float angle = (float) ((Math.atan2(xdiff, ydiff)) * 180 / Math.PI);
		
		return -(int)angle;
	}


Here is vec2 class.



public class vec2 {

	public float x, y;

	public vec2(float x, float y) {
		this.x = x;
		this.y = y;
	}

	public int getX() {
		return (int) x;
	}

	public int getY() {
		return (int) y;
	}

}

Now, to get velocities, you do something like this:


float rot = angle(new vec2(player.x, player.y), new vec2(mouse.x, mouse.y));

vec2 velocity = point(new vec2(0, 0), new vec2(0, -speed), rot);

To get x and y velocities, do velocity.x for x velocity and velocity.y for y velocity.

So why exactly did you open this thread when you already have one for the exact same purpose?

By the way NegativeZero’s way of doing it is correct (the only mistake is that you have to cast Math.sqrt’s result to be a float).
Basically you create a vector that points from your player’s position to your mouse’s position, normalize the vector (that’s the part when you divide the components by the length of the vector) and then multiply it by the projectile speed. Ta da. :smiley:

@trollwarrior1: There’s no need to involve angles in this, that just unnecessarily makes the code more complex.

Its called abstractions, and while it adds more complexity to the code, the code is easier to read, if you don’t need to understand what is happening behind the scenes. 2 lines of very simple code to get the velocities is very small simple to me at least. Besides, you will probably want to render the sprites rotated, in which case you will need to calculated rotation anyway, so whatever.

Patronising much?

Anyway, for somebody with such attitude, you’d at least think the suggested code was flawless. Your atan2(x, y) must be atan2(y, x). Last but not least, I agree with NegativeZero: his code is faster, simpler, easier to grasp.

People calculating an angle using atan2, then passing that to sin and cos, should be brushing up on their vector math. The spurious casts to int are equally a red flag.

Guess I will go do that, because I can’t argue with someone who has 10 times more experience in programming than me.

Abstraction is not about adding levels of unnecessary code to the project. It’s about providing a higher-level interface for easier development.
Even if you would like to render the sprites rotated, calculating the rotation (normally) has nothing to do with the mouse position.
The sad part is that you didn’t even stop to think about my (or rather NegativeZero’s) solution instead you continued to argue and only stopped because someone who has ‘10 times as much programming experience as you’ proved you wrong. :frowning:

I just want to ask something as this is relevant to the asked question :persecutioncomplex:

Panda, you helped me understand vector math with finding positions and normalizing them using the built in function that comes with LibGDX. As I understand, normalizing a vector gives it a unit length of 1 as we only care about the direction and not the length of the vector. However, i’m struggling to understand how the vector still knows which direction to go when it has a length of 1? If that makes sense. Sorry for the noob question, my math is poor :point:

@panda

Sorry, but in my world, objects are not moving from point a to point b, they are moving in the direction they are rotated to.

The vector still retains it’s (i, j) for 2D or (i, j, k) if you’re in 3D. You might be more familiar with (x, y) and (x, y, z). For example take a vector:

(2, 2)

It’s magnitude is found using Pythagoras Theorem:

sqrt(2 * 2 + 2 * 2) = 2.828427125

Then to make it a unit vector multiply each component by the reciprocal of the magnitude:

(1 / 2.828427125 * 2, 1 / 2.828427125 * 2)

Gets you:

(0.707106781, 0.707106781)

Which if you find the magnitude of again:

sqrt(0.707106781 * 0.707106781 + 0.707106781 * 0.707106781) = 1

So you can see it still retains the direction but has unit magnitude?

I use the code like NegativeZero said but i get the effect shown on the screen and i want it to go in a straight line, i tried with vec2 same effect,Is it possible or should I leave it as it is?
http://www.mediafire.com/download/sunoh7d6ctwalf1/game.jar
here you can see what is happening!

My guess would be that you’re using integer positions instead of float positions somewhere.

It’s a bit ironic… but… maybe there?

The angles are snapped to multiples of 15 degrees. This is usually not what truncation to integers results into.

Then how can i make it not snapp to 15 degrees?


public class vec2 {

@@	public float x, y; // there is a reason these are public



	public int getX() {
		return (int) x;
	}

	public int getY() {
		return (int) y;
	}

}