2
\$\begingroup\$

Before you give me a link to another post look first, just in case.

So I'm making a top down game where the person can shoot around, I want the bullets to move towards the mouse, I have tried this:

angle = (float) Math.atan2(pmx - x, pmy - y) * 180 / Math.PI;
x += this.getVelX() + (Math.cos(angle * Math.PI / 180) * 15);
y += this.getVelY() + (Math.sin(angle * Math.PI / 180) * 15);

The pmx means previous mouse position where I clicked, and the same for pmy. But this doesn't work properly look at this screenshot, the gun is pointed towards the mouse (the screenshot doesn't show the mouse) and the yellow squares are the bullets.

enter image description here

How it moves the bullets is the goes towards the mouse about 50 pixels then curls down to the left and inverted for the other side.


After looking at Theraot's post Section B:

int speed = 15;
int velocityX = pmx - x;
int velocityY = pmy - y;
length = Math.sqrt(velocityX * velocityX + velocityY * velocityY);
velocityX *= speed / length;
velocityY *= speed / length;

x += velocityX;
y += velocityY;

This has worked to move it the direction of the mouse, but a new issue has occurred whether this is my issue or not I don't know, as I'm not that good at maths, what it does is moves in the correct direction and when it gets to the mouses old position where it was clicked it stop moving:

enter image description here

If there is a way to stop this from that method can someone tell me if not which Section should I use instead?

\$\endgroup\$
  • \$\begingroup\$ This is not at all what I expected, I think would need to see more of your code. \$\endgroup\$ – Theraot Jul 28 at 10:46
  • \$\begingroup\$ It looks like you're using the wrong mouse position values. We can't see where you defined/set pmx & pmy, but they should be the mouse coordinates this frame, not a saved value from when the projectile was fired. \$\endgroup\$ – DMGregory Jul 28 at 12:05
  • \$\begingroup\$ @DMGregory I used the mouse position from where it was clicked because that is where I want the bullet to go to, pmx is defined when I click and so it doesn't move around after I move the mouse, this is what I wanted it's just the maths which is the issue for me \$\endgroup\$ – Webify Jul 28 at 13:47
2
\$\begingroup\$

First: you have your arguments to atan2 backwards. If you check the docs, you'll see it takes y first, then x

But why go to all the work to take the angle, convert it from radians to degrees, convert it back to degrees, then convert it back to a vector? This is a pile of extra trig you don't need.

instead, when you spawn the bullet, calculate its velocity like so:

dx = mouseX - x;
dy = mouseY - y;

length = Math.sqrt(dx*dx + dy*dy);

dx /= length;
dy /= length;

this.setVelX(dx * speed);
this.setVelY(dy * speed);

Do not repeat the above on every tick unless you want a homing bullet that can change direction in flight.

Instead, each frame, all you need to do is continue moving the bullet along the straight line of its velocity, using the same stored velocity rather than re-calculating it:

x += this.getVelX() * deltaTime;
y += this.getVelY() * deltaTime;

I've changed your velocity integration here, assuming you want to move straight at the mouse at some fixed speed, and adding a deltaTime adjustment so your speed stays consistent regardless of framerate.

\$\endgroup\$
  • \$\begingroup\$ I am not at all good at maths so I don't know what do from here on, all I need extra is just what to do to get the bullets moving from those variables just created \$\endgroup\$ – Webify Jul 27 at 16:08
  • \$\begingroup\$ What would i make the deltaTime to? \$\endgroup\$ – Webify Jul 27 at 18:54
  • \$\begingroup\$ The number of seconds since the last update. Search game-loop & timestep for info about incorporating this into your game. \$\endgroup\$ – DMGregory Jul 27 at 19:55
  • \$\begingroup\$ Based on your updates to your question, it sounds like you want to do the velocity calculation once when the bullet is launched, then continue moving in that straight line instead of following the mouse's movements with a homing bullet. I've edited the answer above to reflect this. \$\endgroup\$ – DMGregory Jul 28 at 15:15
0
\$\begingroup\$

Do you want bullets to be shot in the direction of the mouse?

When the player clicks (Version A)

  1. Compute the angle from the avatar position

    angle = Math.atan2(mouseY - avatarY, mouseX - avatarX);
    
  2. Compute the velocity vector

    speed = 15;
    velocityX = speed * cos(angle);
    velocityY = speed * sin(angle);
    
  3. Create the bullet with that velocity

When the player clicks (Version B)

DMGregory is right, we do not need trigonometry.

  1. Compute the velocity vector

    speed = 15;
    velocityX = mouseX - avatarX;
    velocityY = mouseY - avatarY;
    length = Math.sqrt(velocityX * velocityX + velocityY * velocityY);
    velocityX *= speed / length;
    velocityY *= speed / length;
    
  2. Create the bullet with that velocity

Addendum:

The idea is to compute the velocity vector (velocityX and velocityY) once before you create the bullet (thet is, on click), then create the bullet, and store the velocity in the bullet.


On update

For each bullet, move it according to velocity:

x += this.getVelX() * delta;
y += this.getVelY() * delta;

Where delta is the time from the last frame.


Do you want bullets to be chase the mouse?

On update, do it all

angle = Math.atan2(mouseY - y, mouseX - x); // x and y of the bullet
speed = 15;
velocityX = speed * cos(angle);
velocityY = speed * sin(angle);
x += velocityX * delta;
y += velocityY * delta;

speed = 15;
velocityX = mouseX - x; // x is of the bullet
velocityY = mouseY - y; // y is of the bullet
length = Math.sqrt(velocityX * velocityX + velocityY * velocityY);
velocityX *= speed / length;
velocityY *= speed / length;
x += velocityX * delta;
y += velocityY * delta;

Note: know that by changing velocity, technically the bullet has an acceleration. The code above ignores that fact.


Do you want to rotate the weapon towards the mouse?

On update, set the orientation to this angle

angle = Math.atan2(mouseY - avatarY, mouseX - avatarX);

Placing the bullets at the end of the gun

You might want to create the bullets at (avatarX, avatarY), however, it could be better to create at (avatarX + cos(angle) * r + offX, avatarY + sin(angle) * r + offY) and adjust r, offX and offY to make the bullet come out of the point of the gun.

\$\endgroup\$
  • \$\begingroup\$ What do you mean with delta being the time from the last frame, the previous mouse position? \$\endgroup\$ – Webify Jul 27 at 15:53
  • \$\begingroup\$ Note the order of arguments to atan2 \$\endgroup\$ – DMGregory Jul 27 at 16:03
  • \$\begingroup\$ @Webify delta is a measure of time between frames. You have a speed of 15 per frame, if you want per seconds, you need how many seconds passed from one frame to the other, if you do that then your game will not be frame rate dependent. No, I do not mean previous mouse position, you do not need that. \$\endgroup\$ – Theraot Jul 27 at 17:06
  • \$\begingroup\$ @Webify presumibly you have something like setVelX and setVelY and you can use that to store the velocity, however I haven't seen that part of your code. You could then get then with getVelX and getVelY. Perhaps it would work that way. Do you have all the code in the update or you have one part on the click? \$\endgroup\$ – Theraot Jul 28 at 10:48
  • \$\begingroup\$ I am assuming r means radius, if so how would I know that, just look where the gun rotates around and guess the pixel difference? \$\endgroup\$ – Webify Jul 29 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.