Rotate player towards mouse - java

I want my player rotate towards mouse. Here's the code calculating the angle:
float angle = (float) Math.atan2(MouseInput.getMousePos().y - transform.position.y + transform.size.y / 2,
MouseInput.getMousePos().x - transform.position.x + transform.size.x / 2);
angle = (float) (angle * (180 / Math.PI));
if (angle < 0) {
angle = 360 + angle;
}
transform.rotation = 180 + angle;
And getMousePos() method (it just returns mouse pos relative to window):
public static Vector2 getMousePos() {
Point p = MouseInfo.getPointerInfo().getLocation();
return new Vector2(p.x - Game.w.getAccessToWindow(Acces.WINDOW_JFRAME_ACCES).getLocation().x,
p.y - Game.w.getAccessToWindow(Acces.WINDOW_JFRAME_ACCES).getLocation().y);
}
Can you tell me what's wrong with this code? Player isn't rotating properly.
I tried following this article: https://gamefromscratch.com/gamedev-math-recipes-rotating-to-face-a-point/
Update:
I found this post: Java 2d rotation in direction mouse point
Now I've updated my code to this:
int centerX = (int) (transform.size.x / 2);
int centerY = (int) (transform.size.x / 2);
int mouseX = (int) MouseInput.getMousePos().x;
int mouseY = (int) MouseInput.getMousePos().y;
double angle = Math.atan2(centerY - mouseY, centerX - mouseX) - Math.PI / 2;
transform.rotation = angle;
But still something is off. Try this code for yourself. Maybe I did something wrong somewhere else.

Related

How to repaint a specific area (e.g. circle) in java?

I am trying to make a simple game where you basically have to hit the circles to get a point. But i faced a tiny problem which i couldn't really solve on my own so here is my question how do I repaint a round surface.I used the repaint(Rectangle r) method but it doesn't workout.
public void objectHit(MouseEvent e) {
int distance = 0, deltaX = 0, deltaY = 0, RadiusSqaured = 0;
for (int i = 0; i < obj.length; i++) {
deltaX = e.getX() - obj[i].getPoint().x;
deltaY = e.getY() - obj[i].getPoint().y;
distance = deltaX * deltaX + deltaY * deltaY;
RadiusSqaured = obj[i].getRadius() * obj[i].getRadius();
if (distance <= RadiusSqaured) {
repaint(obj[i].repaintRect());
x = ThreadLocalRandom.current().nextInt(50 + radius / 2, 850 - radius / 2);
y = ThreadLocalRandom.current().nextInt(60 + radius / 2, 750 - radius / 2);
repaint(obj[i].repaintRect());
}
}
}
In JComponent, there is a method for repainting based on a box area. Does this satisfy your requirements?
https://docs.oracle.com/javase/8/docs/api/javax/swing/JComponent.html#repaint-long-int-int-int-int-

libgdx: Making a cross shape rotate

I am experimenting with libgdx trying to make my first simple game. I have managed to make a line rotate.
What I haven't accomplished is adding a perpendicular line, and making it a cross and then rotating this shape.
public void render(ShapeRenderer renderer) {
renderer.set(ShapeType.Line);
renderer.setColor(COLOR);
/**
* finding the angle
*/
float elapsedNanoseconds = TimeUtils.nanoTime() - initialTime;
float elapsedSeconds = MathUtils.nanoToSec * elapsedNanoseconds;
float elapsedPeriods = elapsedSeconds / 2.0f;
float cyclePosition = elapsedPeriods % 1;
float x = WORLD_SIZE / 2 + radius * MathUtils.cos(MathUtils.PI2 * cyclePosition);
float y = WORLD_SIZE / 2 + radius * MathUtils.sin(MathUtils.PI2 * cyclePosition);
//line rotates and moves at the same time.
renderer.line(position.x - x, position.y + y, position.x + x, position.y - y);
}
position is a Vector2() class object which is updated every delta seconds and holds the current center of the line.
I managed to find the solution. I will leave it here in case someone is having similar issues:
public void render(ShapeRenderer renderer) {
/**
* find the angle
*/
float elapsedNanoseconds = TimeUtils.nanoTime() - initialTime;
float elapsedSeconds = MathUtils.nanoToSec * elapsedNanoseconds;
float elapsedPeriods = elapsedSeconds / 2.0f;
float cyclePosition = elapsedPeriods % 1;
float x = WORLD_SIZE / 2 + radius * MathUtils.cos(MathUtils.PI2 * cyclePosition);
float y = WORLD_SIZE / 2 + radius * MathUtils.sin(MathUtils.PI2 * cyclePosition);
float x2 = WORLD_SIZE / 2 + radius * MathUtils.sin(MathUtils.PI2 * -cyclePosition);
float y2 = WORLD_SIZE / 2 + radius * MathUtils.cos(MathUtils.PI2 * -cyclePosition);
renderer.set(ShapeType.Line);
renderer.setColor(COLOR);
renderer.line(position.x - x, position.y + y, position.x + x, position.y - y);
renderer.line(position.x - x2, position.y + y2, position.x + x2, position.y - y2);
}

Zooming to Mouse position in LWJGL

I am trying to implement a zoom to an isometric map using LWJGL. Currently I have the functions
public static void setCameraPosition(float x, float y) {
x *= zoom;
y *= zoom;
cameraX = x;
cameraY = y;
x -= (Display.getWidth() / 2) * zoom;
y -= (Display.getHeight() / 2) * zoom;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLU.gluLookAt(x, y, 1f, x, y, 0, 0.0f, 1.0f, 0.0f);
}
which sets the camera center to a point (x, y),
public static Point getMouseCoordinates() {
float x = Mouse.getX() * getZoom() + getCameraLeft();
float y = (Display.getHeight() - Mouse.getY()) * getZoom() + getCameraTop();
return new Point((int) x, (int) y);
}
which returns the current mouse coordinates, and
public static void setZoom(int newZoom) {
if (newZoom >= 4) newZoom = 4;
else if (newZoom <= 1) newZoom = 1;
if (zoom == newZoom) return;
float x = ?; <-----
float y = ?; <-----
zoom = newZoom;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 0+Display.getWidth() * zoom , 0+Display.getHeight() * zoom, 0, 1, -1);
setCameraPosition((int) x, (int) y);
}
which is supposed to set the zoom to an integer value between 1 and 4. As you can see, I would like to set the camera position after changing the zoom to a certain point - and that point needs to be calculated so that the current mouse position does not change (aka zooming in to the mouse position, which is for example what Google Maps does). I have been trying for a good 2 days now, I've tried so many things, but I just couldn't figure out the equation to calculate x and y.
Please note that all points returned and entered are relative to the position of the map, specifically to the top piece of the map (whose top corner point is (0, 0)). The values getCameraLeft() and getCameraTop() in the getMouseCoordinates() function return
public static float getCameraLeft() {
return cameraX - zoom * (Display.getWidth() / 2);
}
and
public static float getCameraTop() {
return cameraY - zoom * (Display.getHeight() / 2);
}
.
Any help would be appreciated. I'm hoping, I did not express myself too complicated.
I finally found the correct equation:
float x = getMouseCoordinates().getX() + (getCameraX() - getMouseCoordinates().getX()) * (float) newZoom / (float) zoom;
float y = getMouseCoordinates().getY() + (getCameraY() - getMouseCoordinates().getY()) * (float) newZoom / (float) zoom;
Thank you anyways, I'm sure eventually someone would have given me the correct answer :)

Properly scaling x-axis in accordance with pixels (Java)

I am working on plotting a sin(x) graph for a school project. Currently I have everything working the way I want it to besides one thing: the scaling of the x axis.
Here is the code I am currently using:
int xStart = xShift;
int xEnd = xShift;
int yStart = getHeight() / 2;
int yEnd = getHeight() / 2;
int scale = getHeight() / 2;
double constraint = 0.80;
for (double i = Math.PI / 32; i <= Math.PI * 2; i+= Math.PI / 32){
xEnd += (getWidth() - (2 * xShift) / 64);
yEnd = (scale - ((int) Math.round(Math.sin(i) * scale * constraint))) ;
g.drawLine(xStart, yStart, xEnd, yEnd);
xStart = xEnd;
yStart = yEnd;
}
Which produces something that looks like this:
As you can see the red line indicating the sin graph ends short of where I need it to. For some reason I am unable to get the x coordinate of my 500x250 JFrame window to properly increment to the point where it will end at the proper position. I need it to stop where I have drawn the blue arrow, at the end of the gray line. What can I do to fix this? Thank you for your time and I appreciate any help offered.
The problem is,remove your Math.round() function,you see it is rounding of the values of the sin() function.This I know will generate error in the drawLine functionas it takes only integer arguments,to solve that type cast that to prevent lossy conversion.Like this:
g.drawLine((int) xStart,(int) yStart, (int) xEnd, (int) yEnd);

Bounding Joystick to a Circle

Here is a snippet of code that I have. I am trying to bound my object in a circle rather than a square, but there are things wrong with my code that I can't figure out. I have both the rectangle bounds which work and the circle bounds which don't work.
// get the pos
_touchingPoint.x = (int)event.getX();
_touchingPoint.y = (int)event.getY();
angle = Math.atan2(_touchingPoint.y , _touchingPoint.x);
// bound to a box
if( _touchingPoint.x < 75){
_touchingPoint.x = 75;
}
if ( _touchingPoint.x > 225){
_touchingPoint.x = 225;
}
if (_touchingPoint.y < 300){
_touchingPoint.y = 300;
}
if ( _touchingPoint.y > 450 ){
_touchingPoint.y = 450;
}
//bound to a circle
if( _touchingPoint.x < 75 * Math.cos(angle))
{
_touchingPoint.x = (int) (75 * Math.cos(angle));
}
if ( _touchingPoint.x > 225 * Math.cos(angle))
{
_touchingPoint.x = (int) (225 * Math.cos(angle));
}
if ( _touchingPoint.y < 300 * Math.sin(angle))
{
_touchingPoint.y = (int) (300 * Math.sin(angle));
}
if ( _touchingPoint.y > 450 * Math.sin(angle))
{
_touchingPoint.y = (int) (450 * Math.sin(angle));
}
_touchingPoint.x and _touchingPoint.y represent the object (Joystick) that I am trying to constrain. I figured I could try simple trig to constrain the Joystick to a circle, but I guess I was wrong.
What would be the best way to set up a circle constraint?
You seem to be trying to constrain the position to a circular disk, not a circle which is its boundary. I'd accomplish this by rescaling the offset vector from the center:
double dx = event.getX() - 150;
double dy = event.getY() - 375;
double len = Math.hypot(dx, dy);
if (len > 75) {
dx = dx*75/len;
dy = dy*75/len;
}
_touchingPoint.x = (int)dx + 150;
_touchingPoint.y = (int)dy + 375;
The code appears to have calculated the angle of your point from (0,0) then bounding it based on comparing its x with some function of that angle. For example, 75 * Math.cos(angle) varies between -75 and +75, whereas you want to be comparing the point with centre of a circle.
Set up variables for the centre of the circle (cx and cy) and the difference in the x and y ordinates (dx and dy).
You then want to test whether the distance from the centre exceeds your desired radius (usually this is done with the square of the distance as it avoids a sqrt operation - dx*dx+dy*dy>r*r).
If the distance is greater than the radius, project back to the circle, either using trig or by scaling the difference :
double dx = event.getX() - cx;
double dy = event.getY() - cy;
double d2 = dx*dx+dy*dy;
if(d2>r*r) {
double scale = r / Math.sqrt(d2);
dx*=scale;
dy*=scale;
}
then ( dx + cx, dy + cy ) will lie within the circle defined by cx,cy and r.
Unless I'm missing something, it would be along these lines:
===EDIT=== ONE THING I was missing, as pointed out by Pete, was how angle should be computed:
angle = atan2(y - 375, x - 150);
=== end of edit ===
a = _touchingPoint.x;
b = _touchingPoint.y;
if((a-150)*(a-150) + (b-375)*(b-375) > 75*75){
_touchingPoint.x = 150 + 75*cos(angle);
_touchingPoint.y = 375 + 75*sin(angle);
}

Categories