Java-Gaming.org Hi !
 Featured games (90) games approved by the League of Dukes Games in Showcase (736) Games in Android Showcase (223) games submitted by our members Games in WIP (813) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 How to send projectile over a vector path ?  (Read 3195 times) 0 Members and 1 Guest are viewing this topic.
Norakomi
 « Posted 2014-05-08 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 2014-05-08 10:24:21 »

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

 1  2  3 `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:

 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

JGO Kernel

Medals: 173

 « Reply #2 - Posted 2014-05-08 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!
hwinwuzhere
 « Reply #3 - Posted 2014-05-08 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

JGO Kernel

Medals: 173

 « Reply #4 - Posted 2014-05-08 10:47:51 »

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.

Mathias - I Know What [you] Did Last Summer!
hwinwuzhere
 « Reply #5 - Posted 2014-05-08 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

JGO Kernel

Medals: 173

 « Reply #6 - Posted 2014-05-08 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 2014-05-08 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 2014-05-08 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 2014-05-08 13:52:04 »

 1  2  3 `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);`

 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;//// 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:

 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

hwinwuzhere
 « Reply #10 - Posted 2014-05-08 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.

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 2014-05-08 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??

Norakomi
 « Reply #12 - Posted 2014-05-08 14:21:34 »

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

hwinwuzhere
 « Reply #13 - Posted 2014-05-08 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 2014-05-08 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 2014-05-08 14:40:26 »

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 :
 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 `// 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));

Norakomi
 « Reply #16 - Posted 2014-05-08 14:59:55 »

(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 2014-05-08 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 2014-05-08 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 2014-05-08 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.

Pages: [1]
 ignore  |  Print

You cannot reply to this message, because it is very, very old.

 cybrmynd (124 views) 2017-08-02 12:28:51 cybrmynd (147 views) 2017-08-02 12:19:43 cybrmynd (142 views) 2017-08-02 12:18:09 Sralse (158 views) 2017-07-25 17:13:48 Archive (629 views) 2017-04-27 17:45:51 buddyBro (737 views) 2017-04-05 03:38:00 CopyableCougar4 (1266 views) 2017-03-24 15:39:42 theagentd (1246 views) 2017-03-24 15:32:08 Rule (1221 views) 2017-03-19 12:43:22 Rule (1274 views) 2017-03-19 12:42:17
 List of Learning Resourcesby elect2017-03-13 14:05:44List of Learning Resourcesby elect2017-03-13 14:04:45SF/X Librariesby philfrei2017-03-02 08:45:19SF/X Librariesby philfrei2017-03-02 08:44:05SF/X Librariesby SkyAphid2017-03-02 06:38:56SF/X Librariesby SkyAphid2017-03-02 06:38:32SF/X Librariesby SkyAphid2017-03-02 06:38:05SF/X Librariesby SkyAphid2017-03-02 06:37:51
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org