LibGDX down is up and up is down Gdx.input.getY() - java

I'm sure this is something very simple. I am having a major brain freeze. I have been inverting it, subtracting from it, multiplying to it, adding to it. No matter what up is down and down is up.
if (Gdx.input.isButtonPressed(Buttons.LEFT)) s.drawCirc(c, Gdx.input.getX(), Gdx.input.getY(), 100, 100);
The x axis is fine the culprit is the Gdx.input.getY(). When I move my finger up it goes down and down it goes up.
My circle lines up in the middle but when I go up it goes down and when I go down it goes up. I would like to understand what exactly is going on here and why it is happening.(& of course how to fix it please)
In case you need to know c is my camera and here is the code in case this is the culprit
c = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
and in my drawCirc method I am using
shapeRenderer.setProjectionMatrix(c.combined);

This is because the coordinate system used for input and the coordinate system used by the camera are opposite of each other on the y axis. Ideally when getting inputs, you want to unproject the input to the camera so that all of the coordinates are nicely aligned. You can do this using c.unproject(input). Here's a code example:
if (Gdx.input.isButtonPressed(Buttons.LEFT))
{
Vector3 input = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
cam.unproject(input);
//Now you can use input.x and input.y, as opposed to Gdx.input.getX() and
//Gdx.input.getY(), to draw the circle
s.drawCirc(c, input.x, input.y, 100, 100);
}

LibGDX uses OpenGL which uses another coordinate system.
It uses left to right, bottom to top.
So in OpenGL 0,0 means bottom left corner.
Use
c = new OrthographicCamera();
c.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
First parameter means Y-Down
More information here: http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/OrthographicCamera.html
Check this link for more information about using LibGDX with down-y.
https://github.com/libgdx/libgdx/blob/master/tests/gdx-tests/src/com/badlogic/gdx/tests/YDownTest.java

Related

How to create a proper ortographic camera in libgdx

So I am having a little hard time understanding how ortographic cameras work in libgdx.
what I want is to have a camera that will only render things within a square while having another camera set the bounds for my whole screen.
So here, I was able to do what I wanted on the whole screen for the game pad. But, the thing you see on the top right is the background map of the game and i want to render the parts only fall within the red square you see here. How do I achieve that?
Are cameras supposed to do that or do I need to figure out a way to do it manually? I am really confused as to how cameras and projection matrices work.
Here on this screen, The red square and the green pad on the left are being drawn using the projection matrix of my screen camera. The map(top right) is drawn using my map cam.
Map cam is a view port of 400x400 but as you can see , the tiles are rectangular and that isnt the aspect ration i want. If someone can briefly explain how cameras work , I'd greatly appreciate it.
The reason I am not posting my code here is because I feel like I need to understand how camera mechanics work to even code it properly so I want to address that issue first.
Following #Tenfour04's advice worked perfectly. In case anyone wonders what I wanted to achieve. Here's a picture.
A camera alone cannot crop off part of the screen. For that you need to use glViewport. There is already a Viewport class in Libgdx that can do that for you. You will need two orthographic cameras (one for the map and one for the GUI), but the viewport can create its own.
private Viewport viewport;
//in create:
viewport = new FitViewport(400, 400);
//in resize:
viewport.update(width, height);
//in render:
viewport.getCamera().position.set(/*...move your map camera as needed*/);
viewport.apply(); //viewport cropped to your red square
batch.setProjectionMatrix(viewport.getCamera().combined);
batch.begin();
//draw map
batch.end();
//return to full screen viewport
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.setProjectionMatrix(yourGUICamera.combined);
batch.begin();
//draw gui
batch.end();
What happens, is the camera will fit itself to the size of the screen. In order to change this, you would want to use a FrameBuffer. The frame buffer will constrain the camera into the desired size, then can be drawn as a texture.
Create the frame buffer with the dimensions being in pixels.
//Initialize the buffer
FrameBuffer fbo = new FrameBuffer(Format.RGB565, width, helght, false);
Render the world within the buffer.
fbo.begin();
//Draw the world here
fbo.end();
Draw the buffer to the screen with a batch.
batch.begin();
batch.draw(fbo.getColorBufferTexture(), x, y);
batch.end();

How can I move the camera under the terrain for a reflection?

I am attempting to render the reflection of some water.
To create the illusion of reflection, I need the camera to be below the water:
(Pictures not drawn by me)
Therefore, I need to move the camera under the water before rendering the scene. I need to move the camera downward by the distance from the camera to the water multiplied by two, and then I need to invert the cameras' pitch.
The problem is that I am currently limited to the fixed-function pipeline to do this, meaning that I must use glTranslatef() and glRotatef() calls to do this.
Here's my current implementation:
public void createReflectionTexture(){
EulerCamera c = Main.TerrainDemo.camera; //This is the camera
float amtDown = -(2f * (c.y() - 300)); //Amount to move the camera down by. 300 is the height of the water.
float amtPit = (-(c.pitch() * 2));//Pitch to invert the camera by
glRotatef(-amtPit, 0, 0, 1); //I have tried both negative and positive values here, neither seem to work.
glTranslatef(0, amtDown, 0);
bindArrays();
fbos.bindReflectionFrameBuffer();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Main.TerrainDemo.renderVBOTerrain();
fbos.unbindCurrentFrameBuffer();
unBindArrays();
glTranslatef(0, -amtDown, 0); /This puts things back to their original translation so I can keep on rendering other objects.
glRotatef(amtPit, 0, 0, 1);
}
Unfortunately, in my game, the code creates a completely messy image which definitely is obviously not the correct reflection:
If I crash my plane into the water and then position the cameras' pitch to 0, it does appear to render the correct objects.
The refraction texture renders perfectly fine.
How can I correctly move the camera below the water to create a scene that looks like reflection when viewed from above?

How do I get a touch coordinates in LibGdx using the same resolution in al devices?

So I was using this code to get the coordinates of the touch in the screen.
if(Gdx.input.justTouched()){
System.out.println("X= "+Gdx.input.getX()+"Y= "+Gdx.input.getY());
}
but if I have a device with a 1280x960 resolution and I have a 800x600 orthographic camera.
What can I do to obtain the coordinates inside the camera instead the device touch coordinates
"for example if I touch the limit of the screen on the x axis I want to get 800 instead of 1280"
The correct way to do it is to use the camera to give you the world coordinates from the screen coordinates.
For example...
Vector3 mousePos = new Vector3(Gdx.input.getX(), Gdx.input.getY());
camera.unproject(mousePos); // mousePos is now in world coordinates
That way, if you change the camera (zoom / rotate / whatever) then everything will still work.
If you're using a Viewport, then you should use the vieport's unproject method instead, as it may have additional issues to handle (e.g. allowing for the letterboxing in a FitViewport).
Note - In the example I gave, it'd be better to reuse a single Vector3 instance but I wanted the example to be as simple as possible.

Android, calling glRotatef based on geomagnetic sensor

I have an app that renders a cube. I'm kind of new to using openGL for 3d stuff, but essentially what I want is for a corner of my cube to point north at all times, but also orient itself according to the geomagnetic sensor.
That way, when the user has the phone parallel to the ground and faces north, the corner will point "up" on the screen, whereas if the user has the phone upright, the corner will point "away" from the user, toward the back of the phone.
I had no problem writing this in 2d on only one rotational axis so that it would point the corner north if the phone was parallel to the ground.
However, when I made this 3D, two of the axes seem to be working fine, but the axis I worked with the first time doesn't seem to behave the same way.
I use the following code to get the rotation for each:
gl.glPushMatrix();
gl.glTranslatef(0,0,-4);
//get target angle
targetAngle1 = rotationHandler.getRotation1();
targetAngle2 = rotationHandler.getRotation2();
targetAngle3 = rotationHandler.
if (Math.abs(getShortestAngle(targetAngle1, currentAngle)) > 5) //this is to create a 5 degree "dead zone" so the compass isnt shaky
currentAngle1 = (getShortestAngle(currentAngle, targetAngle1) > 0) ?
currentAngle+1f : currentAngle-1f; //increase or decrease the current angle to move it towards the target angle
if (Math.abs(getShortestAngle(targetAngle2, currentAngle2))>5)
currentAngle2 = (getShortestAngle(currentAngle2, targetAngle2) > 0) ?
currentAngle2 + 1f : currentAngle2-1f;
if (Math.abs(getShortestAngle(targetAngle3, currentAngle3))>5)
currentAngle3 = (getShortestAngle(currentAngle3, targetAngle3) > 0) ?
currentAngle3 + 1f : currentAngle3 - 1f;
gl.glRotatef(currentAngle, 0, 0, -4);
gl.glRotatef(currentAngle2, 0, -4, 0);
gl.glRotatef(currentAngle3, -4, 0, 0);
cube.draw(gl);
gl.glPopMatrix();
The calls to glRotatef that use currentAngle2 and currentAngle3 seem to rotate the cube on an axis relative to the cube, while the first call seems to rotate it on an axis relative to the screen. When I comment out any two of the rotation calls, the third works as intended. But I can't seem to figure out how to get them to work together.
---EDIT---
I found that I could get the cube to rotate to almost any position possible even after taking away the first call. So it seems like I'm going to have to come up with an algorithm that will calculate the rotation as appropriate. I honestly don't know if I can do it but I'll post it here if I figure it out.
This might not be the best solution, but it seems to work as long as the phone isn't completely flat.
After changing the model to a rectangular prism, I could approach the problem a little more clearly. I used only the first two axes, and didn't even touch the last axis. I treated the prism like a fighter jet - in order to turn it left or right, I rotated it on its side, then altered the pitch up or down. Then I "un-rotated" it, and altered the pitch again for to point it up or down as appropriate.
public void findTargetRotation(float rotationAngle, float pitchAngle, GL10 gl){
//first, enable rotation around a vertical axis by rotating on frontBack axis by -90 degrees
gl.glRotatef(-90, 0, -4, 0);
//rotate around the leftRight axis by the angle1 amount
gl.glRotatef(rotationAngle, 0,-4,0);
//then rotate on frontBack axis by 90 degrees again, to straighten out
gl.glRotatef(90, 0, -4, 0);
//lastly, rotate around the leftRight axis to point it up or down
gl.glRotatef(pitchAngle, -4, 0, 0);
}
This seems to work as long as pitchAngle isn't extremely close to or equal to 0. So I just added a little more code to treat it like a 2D object if the pitchAngle is really small.
There's probably a better solution but at least this works.

JAVA: 2D Game Adventure. Collision Detection problem

This is about animation in JAVA. I had success when using same dimension on all picture. But if i keep all picture dimension on same size(width and height) i get some bug which when player punch. Before player's hand touch enemy body, enemy died
But others with my case where idle, run, and punch has an different
dimension. Punching animation facing to the left became very strange.
Should his hand hit to the left but his body shifts to the right. This
is because I draw on the x & y are the same.
How can I fix it? Need instructions :D
I use png coz support transparent
I think this can fix with 2 option
1. Fix my collision detection
2. Fix of drawing position my image when some condition occur
Trying to picture your problem, hope this helps.
I am typeing directly from my head, so there are might errors in code
fixing coalision decection
i would try this
Image fist
Image enemy
//in paint
g2D.drawImage(fist,x,y,this);
g2D.drawImage(enemy,x1,y1,this);
Rectangle2D myFist = new Rectangle2D.Double(x,y,fist.getWidth(this),fist.getHeight(this));
Rectangle2D myEnemy = new Rectangle2D.Double(x1,y1,enemy.getWidth(this),enemy.getHeight(this));
if (myEnemy.contains(myFist){
//action u want to happend
}
I think something like this should fix coalision problems
I am seeing this as mario a game on sega
Fix of drawing position
//arm image can be the same image if u want
Image leftArm;
Image rightArm;
image headLegsAndTorsoLeft;
image headLegsAndTorsoRight;
//where am i looking in game if true i look to the leftside of user thats playing
boolean turnedLeft
//in paint
if(turnedLeft){
//this lets it look like he is turned to the left with his right arm in the visible behind his left.
//draw right arm
g2D.drawImage(rightArm,x,y,this);
//draw body moved a bit in x coor
g2D.drawImage(headLegsAndTorsoLeft,x-3,y,this);
// draw left arm a bit more in x coor
g2D.drawImage(leftArm,x-6,y,this);
}else{
//this lets it look like he is turned to the right with his left arm in the visible behind his right.
// draw left arm
g2D.drawImage(leftArm,x,y,this);
//draw body moved a bit in x coor
g2D.drawImage(headLegsAndTorsoRight,x-3,y,this);
//draw right arm a bit more in x coor
g2D.drawImage(rightArm,x-6,y,this);
}
same order for animation of arms, ultimatly i would use different methods animations for torso, leftarm, rightarm
something like keypressed leftarrow torso does walking animation left, hit left arm key moves left arm,hit right arm key moves right arm,thats 3 for lets say left arm, now u need another 3 for when ur char is moved to the right.
Thats how i would try to do things.

Categories