How to send projectile over a vector path ?

Hi,

I’m want to have my enemies shoot projectiles at my main character.
The way I’m thinking of how to do that is to calculate a vector using the enemies & my main character’s position and then send a projectile over a straight line according to the calculated vector.

Thing is i have no idea how to do this. It’s been a while since I’ve done some vector math and I wouldn’t no what code to use.

Does anyone have any suggestions for me?

Links to examples, tutorials or explanation of how to code this?

To get the angle between the player and the enemy you can do:


double xx = targetX - shooterX; // Target would be the Mob that gets shot at, and shooter would be the mob that shoots.
double yy = targetY - shooterY; // Keep in mind that all these values give more accurate results when they are doubles.
double angle = Math.atan2(yy, xx);

To send a projectile over this angle you could do this for every update:


projectileX += projectileSpeed * Math.cos(angle);
projectileY += projectileSpeed * Math.sin(angle);

Always keep in mind: SohCahToa :slight_smile:

Nah, you dont need the angle. Just divide the deltas (xx, yy) by your locked fps and you can use them instead of cos(angle) and sin(angle) …

Could you give a code example?

Only have a phone right now, but look here: http://www.java-gaming.org/topics/how-to-make-a-bullet-shoot-towards-the-mouse/33010/view.html and also watch the embedded video there.

Great, thanks :slight_smile:

Both ways work, I guess you even have a choice which one you like to use.

Kind of, but i wouldnt use the angle here because of some downsides:

  • atan has continuity breaks with results switching from +infinity to -infinity
  • you have to check for division by zero if xx is 0
  • trig functions are less performant

Would I get problems with projectileX/Y not being integers but doubles?
Or can I just pass double values for x & y to my EnemyProjectile instances?
Like changing EnemyProjectile (int x, int y) to EnemyProjectile (double x, double y)?

well wait… g.drawImage requires integers?

So how do I solve that problem?

You should have the coordinates of all your entities in double values. You can work with more accurate coordinates that way.

You can easily convert these double values to an integer when drawing it:

g.drawLine((int)x1, (int)y1, (int)x2, (int)y2);

This is called ‘casting’. You can ‘cast’ a double to an integer by putting ‘(int)’ in front of it.

This looks pretty simple and i would have to mind about x being 0 because my enemies wouldnt ever fire projectiles when they’re at x or y=0.

But so far it isnt working.
I assume

double angle = Math.atan2(yy / xx);

needs to be

double angle = Math.atan2(yy, xx);

since atan2 requires 2 variables y,x.

This is what i added to my ProjectileEnemy class’ constructor:

	
	x = startX;
	y = startY;

//
// bunch of other variables here
	targetX = KnightmareGame.popolon.getCenterX();
		targetY = KnightmareGame.popolon.getCenterY();
		System.out.println("popolon x,y=" + targetX + "," + targetY );
		
		shooterX = startX;
		shooterY = startY;
		System.out.println("start x,y=" + shooterX + "," + shooterY );
		
		double xx = targetX - shooterX; // Target would be the Mob that gets shot at, and shooter would be the mob that shoots.
		double yy = targetY - shooterY; // Keep in mind that all these values give more accurate results when they are doubles.
		double angle = Math.atan2(yy , xx);
		System.out.println("angle= " + angle );

And in my update method:

		x += speedX * Math.cos(angle);
		y += speedY * Math.sin(angle);

but i just get projectiles with y = always 0 and every projectile slowly moving to the right with a speed of x=1 if i set speedX to 1 instead of speed

Target’s x/y and shooter’s x/y values are passed correctly and a different angle is calculated for different projectiles.

but math.sin(angle) is always close to 1 and math.cos(angle) always close to 0.
what’s going wrong?

I’ll also check & see if i can just solve the whole problem using cylab’s way

True. My bad :slight_smile:

What type of variables do you use for you mobs coordinates? (int? or double?)

targetX/y and shooterx/y are both integers.

But i thought


double xx = targetX - shooterX; 
double yy = targetY - shooterY;

would just make doubles out of the values??

btw. just found this on youtube &which might be an interesting vid. on this subject for other noobs like me:

-s5JgN20sK0

Well it shouldn’t really make a huge difference, but try to use doubles for your x and y coords. Or at least try to cast the targetX and shooterX to a double.

As for your problem, I don’t see how else I can help you… I’d have to see your full code for projectiles etc.

Well this is basically it:
http://pastebin.java-gaming.org/a101f122090

Math.sin(angle)= -0.99995954292494
But even when i cast y to an int with :

y += (int) Math.sin(angle);

the projectile doesnt wanna move up or down.

This is the code in my paint method in my gameclass:

// PAINT ENEMY PROJECTILES
			
			ArrayList projectilesEnemies = enemy.getProjectiles();
			//System.out.println("nr. getprojectiles(enemy) knightmaregame" + projectilesEnemies.size());
			for (int j = 0; j < projectilesEnemies.size(); j++) {
				ProjectileEnemy pe = (ProjectileEnemy) projectilesEnemies.get(j);
				g.setColor(Color.WHITE);			
				g.drawImage(arrow_knight, (int)pe.getX(), (int)pe.getY(), (this));
				}

I guess maybe i should just change y to a double and only cast it to an int in my paintmethod at g.drawImage(arrow_knight, (int)pe.getX(), (int)pe.getY(), (this));

(both of) You helped me a lot already! Tnx
Think with all this info i should be able to figure out how to get it done

You shouldn’t cast Math.sin(angle) to an integer, that makes it 1 and not the actual angle.

A double can hold decimal values that are past a comma e.g.:

0,98
1.273
3.1415926535897
etc.

And integer can only hold values without a decimal e.g.:

1
2
3
4
5

10000

So when you cast a decimal number to an integer you get:

double x = 3.14;
int y = (int)x;

y = 3; (you see? rounded.)

Do now you understand the difference between a double and an integer?

yeah understood it before, but what i didnt understand was whether or not the double -0.999etc got rounded to 0 (and why not -1 f.e.) and this was the problem or something else was going on.

I solved it and apperently I cant use double in front of the angle variable


double angle = Math.atan2(yy / xx);

If I do Eclipse tells me: “the value of the local variable is not used”

So i removed “double”, changed x & y variables of my ProjectileEnemy class from integers to doubles:

public ProjectileEnemy(double x2, double y2) {

		x = x2;
		y = y2;

& added a minus sign to my multipliers in the update method:

	x +=  projectileSpeed * -Math.cos(angle);
		y += projectileSpeed* -Math.sin(angle);

Cast my x&y variables to integers in my paint method &
Now my projectiles shoot straight at my hero.