Java-Gaming.org Hi !
 Featured games (91) games approved by the League of Dukes Games in Showcase (755) Games in Android Showcase (229) games submitted by our members Games in WIP (842) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Angle of slope for mouse movement.  (Read 11306 times) 0 Members and 1 Guest are viewing this topic.
SkyAphid
 « Posted 2012-05-07 01:14:49 »

So, I'm wanting smooth mouse movement, so I'm going to have the player move in directions (0-360).

I click the screen, and I have the slope. Which, is (y2-y1) / (x2-x1)

Now, I need to use trig to get the angle. I'm just stuck right there. Any help? I'm a freshie, so I'm just finishing geometry. So, I know about the whole SohCahToa thing, I'm just not very skilled in its use seeing as we messed with it for like a week out of the whole year.

Thanks.

EDIT/P.S:
I'm also going to need means of moving the players X/Y towards the direction we get from this, so advice on that too is appreciated.

it just werks
theagentd
 « Reply #1 - Posted 2012-05-07 02:06:18 »

 1 `Math.atan2(mouseY - playerY, mouseX - playerX); //Both are in world coordinates`

Myomyomyo.
DavidW

Junior Devvie

Medals: 3
Exp: 7 years

 « Reply #2 - Posted 2012-05-07 15:08:03 »

What theagentd said is correct, but ultimately you don't really want that angle since it will have to be transformed back into Cartesian coordinates to move your player.  Here is how you would achieve what you want.  Have three variables, dx, dy, and speed. The variables dx and dy represent the change in the players X and Y coordinate per game loop.  In case you are curious, they are named this way with the d because of calculus.  Not really important actually, you could name them "changeInX, changeInY" if you prefer.  Each game loop, you calculate what dx and dy are:
 1  2 `dx = mouseX - playerXdy = mouseY - playerY`

So now you have the proper direction, but not the proper speed.  If you add dx and dy to your players location now they will instantly teleport to the mouse location, which isn't what you want.  To fix this, we scale the values of dx and dy.  Think of dx and dy as the sides of a right triangle, and the hypotenuse is the direction you are going to travel.  We want this hypotenuse to be the same length no matter which direction the player is heading.   We can use the Pythagorean Theorem to figure out that what we want is
 1 `dx^2 + dy^2 = speed^2`

So what we will do is normalize the d variables: scale the triangle they currently make to have hypotenuse of length one.  We do this by calculating the distance using the Pythagorean theorem and then dividing both variables by that distance.  Finally, we multiply dx and dy by speed, which will give us the result we want!  Here it all is:
 1  2  3  4  5  6  7  8  9  10 `double hypotenuse = Math.sqrt(dx*dx + dy*dy);dx /= hypotenuse;dy /= hypotenuse;dx *= speed;dy *= speed;// now we have the correct dx and dy, so add those to the players position!playerX += dx;playerY += dy;`

You can of course do a slight optimization here by dividing speed by hypotenuse and multiplying dx and dy by that.  If you are heart set on using trigonometry, then the code would look like this:
 1  2  3  4  5  6 `double theta = Math.atan2(mouseY - playerY, mouseX - playerX);dx = speed*Math.cos(theta);dy = speed*Math.sin(theta);playerX += dx;playerY += dy; `

This will work just fine as well and basically does the same thing, however, it involves these trig functions which are slow.  In a small game it probably won't matter though.  If I were you, I would avoid using math that you haven't learned about yet since you will not be able to fix any bugs that show up.  Hope this helps!

Hello!
DruLeeParsec
 « Reply #3 - Posted 2012-05-07 15:18:13 »

I just wrote very similar code for a game I'm working on.  In this code example I have a gun turret in a stationary object which I want to point at my tank.  My tank is the playerEntity.  The getX and getY are returning the X and Y of THIS object (My gun turret).

Notice that the atan and atan2 return a positive or negative number depending on which quadrant you're in so you have to adjust for that.

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31 `   public void doUpdate(int delta){      Entity playerEntity = gameLevel.getPlayer();      float px = playerEntity.getX();      float py = playerEntity.getY();            float diffX = px - getX();      float diffY = getY() - py;      float angle = 0;            // Protect against a divide by zero error      if(diffY != 0){         angle = (float) Math.toDegrees(Math.atan(diffX/diffY));      }      if(diffX >0 && diffY >0){         // do nothing      }      if(diffX <0 && diffY <0){         angle = 180 + angle;      }      if(diffX >0 && diffY <0){         // Note, angle is negative so I'm actually subtracting from 180         angle = 180 + angle;      }      if(diffX <0 && diffY >0){         // Note, angle is negative so I'm actually subtracting from 360         angle = 360 + angle;      }      turretGun.setRotation((float) angle );   }`

At turretGun.setRotation((float) angle ); my angle is the proper angle in degrees.  So now my turret's gun is pointing at my tank.
ra4king

JGO Kernel

Medals: 508
Projects: 3
Exp: 5 years

I'm the King!

 « Reply #4 - Posted 2012-05-07 18:22:55 »

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31 `   public void doUpdate(int delta){      Entity playerEntity = gameLevel.getPlayer();      float px = playerEntity.getX();      float py = playerEntity.getY();            float diffX = px - getX();      float diffY = getY() - py;      float angle = 0;      -      // Protect against a divide by zero error-      if(diffY != 0){+         angle = (float) Math.atan2(diffY,diffX);-      }-      if(diffX >0 && diffY >0){-         // do nothing-      }-      if(diffX <0 && diffY <0){-         angle = 180 + angle;-      }-      if(diffX >0 && diffY <0){-         // Note, angle is negative so I'm actually subtracting from 180-         angle = 180 + angle;-      }-      if(diffX <0 && diffY >0){-         // Note, angle is negative so I'm actually subtracting from 360-         angle = 360 + angle;-      }      turretGun.setRotation((float) angle );   }`

FTFY: atan2 takes care of all that.

EDIT: @Riven, looks like your +/- feature is a bit buggy :/

Roquen

JGO Kernel

Medals: 517

 « Reply #5 - Posted 2012-05-07 19:32:34 »

Do the sqrt.  Do the divide once and multiply by the recip.  Forget about atan2 in this instance as you don't care about the angle.  Degrees are for little kids and scripting...radians are your friend.
pitbuller
 « Reply #6 - Posted 2012-05-07 20:56:43 »

 1 `vec2 direction = normalize(pos - pos2);`

Vectors, just learn those.
theagentd
 « Reply #7 - Posted 2012-05-08 02:20:30 »

What if he wants a cannon aimed at the mouse? atan2 has its uses. xd

Myomyomyo.
DruLeeParsec
 « Reply #8 - Posted 2012-05-08 02:44:04 »

Quote
FTFY: atan2 takes care of all that.

Math.toDegrees(Math.atan2(diffX,diffY)) gives positive degrees if the target is to the right of the source and negative degrees if you're to the left.

But it turns out that the Slick2D rotate command understands that so now the code is:

 1  2  3  4  5  6  7  8  9  10 `   public void doUpdate(int delta){      Entity playerEntity = gameLevel.getPlayer();      float px = playerEntity.getX();      float py = playerEntity.getY();            float diffX = px - getX();      float diffY = getY() - py;      turretGun.setRotation((float) Math.toDegrees(Math.atan2(diffX,diffY)));   }`
ra4king

JGO Kernel

Medals: 508
Projects: 3
Exp: 5 years

I'm the King!

 « Reply #9 - Posted 2012-05-08 02:57:18 »

You shouldn't be using degrees at all here. Everything works with radians.

Riven

« JGO Overlord »

Medals: 1340
Projects: 4
Exp: 16 years

 « Reply #10 - Posted 2012-05-08 03:00:28 »

 1  2 `      float diffX = px - getX();      float diffY = getY() - py;`

Didn't the alarm bells ring when you wrote that?

Hi, appreciate more people! Î£ â™¥ = Â¾
Learn how to award medals... and work your way up the social rankings!
ra4king

JGO Kernel

Medals: 508
Projects: 3
Exp: 5 years

I'm the King!

 « Reply #11 - Posted 2012-05-08 03:03:41 »

Looks fine to me if Y increases downwards.

UprightPath
 « Reply #12 - Posted 2012-05-08 03:06:49 »

Yeah, it depends on where your origin is!

Remember, that most GUI software places the origin (0,0) at the top left corner. Slick does this. If you're using LIBGDX then it's the bottom left corner.

Riven

« JGO Overlord »

Medals: 1340
Projects: 4
Exp: 16 years

 « Reply #13 - Posted 2012-05-08 03:08:08 »

Yeah, it depends on where your origin is!

Looks fine to me if Y increases downwards.

Never correct for the projection matrix in your vecmath

Your cannon will be affected by the same projection matrix, so you'd have to 'flip' your angle again if you'd want to aim your cannon in model space. If you do it in screen space, you're going to create a mess in your code.

Keep all your logic/math in model space!

Hi, appreciate more people! Î£ â™¥ = Â¾
Learn how to award medals... and work your way up the social rankings!
DruLeeParsec
 « Reply #14 - Posted 2012-05-08 03:23:16 »

You shouldn't be using degrees at all here. Everything works with radians.

I understand that.  But the rotate method in SLick2D which I'm using requires degrees.

 1  2  3  4  5 `rotatepublic void rotate(float angle)    Add the angle provided to the current rotation. The angle will be normalized to be 0 <= angle < 360. The image will be rotated around its center.`

That's why I'm not using radians.

Also, while it says we're actually adding an angle to the existing angle it appears to work by simply feeding it the angle we calculated.  Although when I was coding the rotation of my tank turret I did have to get the current angle and subtract it from the calculated angle.  I'm reviewing my code now to see why it worked one way in one part of my code and another in a different part of my code.

I'm not asking for help, I'm just pointing out that it's interesting.

Roquen

JGO Kernel

Medals: 517

 « Reply #15 - Posted 2012-05-08 03:53:24 »

What if he wants a cannon aimed at the mouse? atan2 has its uses. xd
Sure atan2 is handy.  But you don't need it in this example either.
theagentd
 « Reply #16 - Posted 2012-05-08 04:03:42 »

What if he wants a cannon aimed at the mouse? atan2 has its uses. xd
Sure atan2 is handy.  But you don't need it in this example either.
I claim wall hack and aimbot. Why not?

Myomyomyo.
Roquen

JGO Kernel

Medals: 517

 « Reply #17 - Posted 2012-05-11 14:33:23 »

Opps I missed this...quick write up: HERE
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #18 - Posted 2012-05-11 18:40:34 »

Yes, I agree with Riven. Logic / positioning should always be completely and totally separate from rendering. In other words, code the logic in whatever way makes sense to you. Meters, perhaps, where +Y is actually up? Then just do a conversion on these values when you draw. And do that conversion in one common place (a Camera class, perchance?).

Doing this also makes it very easy to zoom in and out, rotate the view, shake the screen, blah blah blah.

See my work:
OTC Software
Pages: [1]
 ignore  |  Print

 DesertCoockie (52 views) 2018-05-13 18:23:11 nelsongames (83 views) 2018-04-24 18:15:36 nelsongames (74 views) 2018-04-24 18:14:32 ivj94 (759 views) 2018-03-24 14:47:39 ivj94 (87 views) 2018-03-24 14:46:31 ivj94 (643 views) 2018-03-24 14:43:53 Solater (102 views) 2018-03-17 05:04:08 nelsongames (184 views) 2018-03-05 17:56:34 Gornova (426 views) 2018-03-02 22:15:33 buddyBro (1086 views) 2018-02-28 16:59:18
 Java Gaming Resourcesby philfrei2017-12-05 19:38:37Java Gaming Resourcesby philfrei2017-12-05 19:37:39Java Gaming Resourcesby philfrei2017-12-05 19:36:10Java Gaming Resourcesby philfrei2017-12-05 19:33:10List 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:05
 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