Norakomi


«
Posted
20140508 09:34:14 » 

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?




hwinwuzhere


«
Reply #1  Posted
20140508 10:24:21 » 

To get the angle between the player and the enemy you can do: 1 2 3
 double xx = targetX  shooterX; double yy = targetY  shooterY; double angle = Math.atan2(yy, xx); 
To send a projectile over this angle you could do this for every update: 1 2
 projectileX += projectileSpeed * Math.cos(angle); projectileY += projectileSpeed * Math.sin(angle); 
Always keep in mind: SohCahToa

There are two kinds of people in this world: Those who can extrapolate from incomplete data,



cylab


«
Reply #2  Posted
20140508 10:38:45 » 

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) ...

Mathias  I Know What [you] Did Last Summer!



Games published by our own members! Check 'em out!


hwinwuzhere


«
Reply #3  Posted
20140508 10:40:23 » 

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?

There are two kinds of people in this world: Those who can extrapolate from incomplete data,



cylab


«
Reply #4  Posted
20140508 10:47:51 » 


Mathias  I Know What [you] Did Last Summer!



hwinwuzhere


«
Reply #5  Posted
20140508 11:00:04 » 

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

There are two kinds of people in this world: Those who can extrapolate from incomplete data,



cylab


«
Reply #6  Posted
20140508 12:45:10 » 

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

Mathias  I Know What [you] Did Last Summer!



Norakomi


«
Reply #7  Posted
20140508 13:07:16 » 

1 2
 projectileX += projectileSpeed * Math.cos(angle); projectileY += projectileSpeed * Math.sin(angle); 
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?




hwinwuzhere


«
Reply #8  Posted
20140508 13:38:34 » 

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: 1
 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.

There are two kinds of people in this world: Those who can extrapolate from incomplete data,



Norakomi


«
Reply #9  Posted
20140508 13:52:04 » 

1 2 3
 double xx = targetX  shooterX; double yy = targetY  shooterY; double angle = Math.atan2(yy / xx); 
1 2
 projectileX += projectileSpeed * Math.cos(angle); projectileY += projectileSpeed * Math.sin(angle); 
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 1
 double angle = Math.atan2(yy / xx); 
needs to be 1
 double angle = Math.atan2(yy, xx); 
since atan2 requires 2 variables y,x. This is what i added to my ProjectileEnemy class' constructor: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 x = startX; y = startY;
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; double yy = targetY  shooterY; double angle = Math.atan2(yy , xx); System.out.println("angle= " + angle ); 
And in my update method: 1 2
 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




Games published by our own members! Check 'em out!


hwinwuzhere


«
Reply #10  Posted
20140508 14:00:51 » 

I assume 1
 double angle = Math.atan2(yy / xx); 
needs to be 1
 double angle = Math.atan2(yy, xx); 
since atan2 requires 2 variables y,x. True. My bad What type of variables do you use for you mobs coordinates? (int? or double?)

There are two kinds of people in this world: Those who can extrapolate from incomplete data,



Norakomi


«
Reply #11  Posted
20140508 14:03:33 » 

targetX/y and shooterx/y are both integers. But i thought 1 2
 double xx = targetX  shooterX; double yy = targetY  shooterY; 
would just make doubles out of the values??





hwinwuzhere


«
Reply #13  Posted
20140508 14:26:35 » 

targetX/y and shooterx/y are both integers. But i thought 1 2
 double xx = targetX  shooterX; double yy = targetY  shooterY; 
would just make doubles out of the values?? 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.

There are two kinds of people in this world: Those who can extrapolate from incomplete data,



hwinwuzhere


«
Reply #14  Posted
20140508 14:27:47 » 

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.

There are two kinds of people in this world: Those who can extrapolate from incomplete data,



Norakomi


«
Reply #15  Posted
20140508 14:40:26 » 

Well this is basically it: http://pastebin.javagaming.org/a101f122090Math.sin(angle)= 0.99995954292494 But even when i cast y to an int with : 1
 y += (int) Math.sin(angle); 
the projectile doesnt wanna move up or down. This is the code in my paint method in my gameclass: 1 2 3 4 5 6 7 8 9
 ArrayList projectilesEnemies = enemy.getProjectiles(); 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));




Norakomi


«
Reply #16  Posted
20140508 14:59:55 » 

..., I don't see how else I can help you..
(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




hwinwuzhere


«
Reply #17  Posted
20140508 15:31:48 » 

Math.sin(angle)= 0.99995954292494 But even when i cast y to an int with : 1
 y += (int) Math.sin(angle); 
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: 1 2
 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?

There are two kinds of people in this world: Those who can extrapolate from incomplete data,



Norakomi


«
Reply #18  Posted
20140508 15:34:52 » 

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.




Norakomi


«
Reply #19  Posted
20140508 18:14:59 » 

I solved it and apperently I cant use double in front of the angle variable 1
 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: 1 2 3 4
 public ProjectileEnemy(double x2, double y2) {
x = x2; y = y2; 
& added a minus sign to my multipliers in the update method: 1 2
 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.




