JOGL - moving the camera - java

Im building something in JOGL and im looking to make the camera move either through using the keyboard or mouse, it doesnt really matter, so long as the camera can pan around the object and possibly zoom in and out. If using the keyboard/mouse is difficult then I also dont mind using some buttons in the applications, e.g. arrows up, down, left and right and a plus and minus button for the zoom but basically whatevers easiest.
Im building something kind of like Lego but its proving to be quite difficult without being able to move the camera.

To move your "camera" you need to apply a glTranslate3f() transform at the beginning of your rendering function. If your camera's location is to be
cameraPos = <cx, cy, cz>
then you should use
glTranslate3f( -cx, -cy, -cz );
This will offset everything that is drawn by that vector.
In order to use the keyboard to make this happen, you will want to use a KeyListener implementation and define the functions specified by the interface.
public void keyPressed( KeyEvent ke ){ // put something intelligent here... }
public void keyReleased( KeyEvent ke ){}
public void keyTyped( KeyEvent ke ){}
Make sure to register this implementing class as a KeyListener to your GLJPanel (or whatever you're using). Then, inside the keyPressed(...) function, check which key is being pressed and increment the appropriate coordinate of the camera.
If you want to get really fancy and allow the mouse to enable you to look around, you can do a similar thing by creating a MouseMotionListener and registering it. The OpenGL transform that is needed to put this into play can vary based on what type of mouse behavior you are looking for. If you just want something simple that will allow you to look around, you can probably get away with tracking mouse motion in the x and y directions and allowing it to modify some offset angles. Moving the mouse in the x direction rotates about the y-axis. Movement in the y direction rotates about the x-axis. As an OpenGL call, as with the glTranslate3f(), you can use glRotatef() to rotate about each axis.
glRotatef( angleX, 1, 0, 0 ); // to rotate about the x-axis
glRotatef( angleY, 0, 1, 0 ); // to rotate about the y-axis
Again, this is just a quick and easy solution. It won't be beautiful, but it will work. If you want to implement something a bit fancier, you can look into computing an arbitrary axis rotation matrix.
http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/
(one of many resources on this topic)

You use a function called "gluLookAt( position of x , position of y , position of z , x of where the camera looks at, y of where the camera looks at, z of where the camera looks at, 0, 1, 0);"
As for the "0, 1, 0" part, leave them as they are as you are just panning around and zooming in. This just affects the tilt of the camera.

Related

Is there a way to track a rectangle on a JPanel (Like 3rd person)?

I've made a few 2D games using JPanels and the Graphics draw methods. For the game I'm currently working on, I'd like to be able track the player as they walk, from an aerial view (sort of like the earlier Pokemon games, where as you move the camera tracks you), but without having to hard code it (make it that when I walk, the x and y values of every other feature including the background moves the opposite direction). Is there another way to do this or will I have to hard code it?
Use Graphics.translate(x,y) where x and y positions are the positions of your camera or player. This will translate the origin of the graphics context to the point x, y.

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.

box2dlights set scale from box2d

I'm making a game in libGDX and I decided to use box2dlights to render the lights. I did not used cameras so much up to this point, because I already had most of the code done in pure LWJGL. There are two main operations that I need to do with the coordinates of everything.
The first is to translate the screen to the position of the map (the map is bigger than the screen, and the position of the player defines what portion of the map is visible). So for example, if the player is at (50, 30), I translate everything by (-50, -30), so that the player is in the middle.
The second thing is to multiply everything by a constant, that is the conversion from box2d meters to pixels on screen.
However, since I do not have access to box2dlights rendering, I need to pass these two information to the ray handler, and the only way to do that is via Camera. So I created an Orthographic Camera and translate it in deltaS every tick before drawing, instead of manually subtracting deltaS from every coordinate. That part works perfectly. On the other hand, the zoom thingy does not seem to work, because it zooms in and out based in the middle of the screen. For example, if I set zoom = 2, the screen is reduced twice, but it is centered on the screen. The coordinate (0,0) is not (0,0), as I would expect, but instead is screen.width/4.
Is there any way to set the camera so that it multiplies every coordinate by a number, you would assume zoom function should do OR is there any way to do it directly on box2dlights?
I don't know if my problem is very clear or common, but I can't find anything anywhere.
I finally figured it out! The problem was that I needed to set the zoom before I used
camera.setToOrtho(true, SCREEN_WIDTH, SCREEN_HEIGHT);
Because that method uses the current zoom to set its properties. Hope this helps!

Robot keep mouse in window

I have a fps "camera", and just recently managed to set up mouse movement to rotate the angle of viewing. The one problem with the camera is that the mouse can leave the window and the angles will not rotate anymore. I know I can use a robot method like mouseMove(), however, I've heard that it makes the camera rotation feel very jerky. Is there any other way to keep the mouse in the window, say like, Minecraft? I'm using Minecraft as an example because my program uses LWJGL too, and I was wondering how Notch does it. Any suggestions?
Mouse.setGrabbed(true) at a start-up moment,
and for every game-loop(frame):
catch mouse movement with Y_Angle += Mouse.getDX()*0.1f,
then rotate your view matrix around Y axis on Y_Angle degrees/radians.
For rotation around X and Z axes use Mouse.getDY() and think on your own how to implement right matrix rotation for those, but this is the main idea.

Mouse location in java

I am developing a first person shooter in Java and I want to implement controls in which movement of the mouse rotates the player. However in Java, I can only get mouse coordinates by using MouseListener events, so the coordinates will stop changing once the mouse cursor leaves the monitor edge and I will be unable to turn the player's view.
Any tips/suggestions on how to do that? Thanks.
I tried using a java.awt.Robot as AerandiR suggests, but there were a couple of problems I ran into, and it's possible other people will run into them as well, so I will elaborate.
If your goal is to keep the cursor in one position (preferably the center of the screen), then you will want to call something like robot.mouseMove(width/2, height/2); at the end of your mouseMoved() method. With this implementation, every time the mouse is moved off center, the Robot will move it back to the center.
However, when the Robot re-centers the mouse, the player will turn back to where it was. In effect, the player will stutter between the original position and a turned position.
To fix this, instead of defining how far your player turns on the difference between where the mouse is now and where it was, define it as the distance from the center.
Like so: turnAmountX += e.getX() - width/2;
Now, if the Robot re-centers the mouse, e.getX() - width/2 will always yield zero.
Recap:
void mouseMoved(MouseEvent e) {
turnAmountX += e.getX() - width/2;
turnAmountY += e.getY() - height/2;
robot.mouseMove(this.getLocationOnScreen().x + width/2,
this.getLocationOnScreen().y + height/2;
}
In some games, on every mouse movement event the cursor is moved back to the middle of the screen, and the view moves with the corresponding magnitude and direction of the mouse event. You can get that vector by calculating the offset of the cursor position to the center of the screen prior to centering the cursor. To move the cursor back to the center of the screen you can try using the java.awt.Robot class.
Since you're building a first person shooter, you'll probably want to hide the center locked cursor, and draw your own crosshair where the player is intending to aim. That will also involve keeping track of where the cursor should be based on the running total of previous mouse movement events.
If you want to achieve behaviour where the view will continue moving relative to the starting position of the mouse (even once the mouse has stopped moving), you could keep a moving sum of all the previous mouse movement vectors, and move the view correspondingly once every frame. However, this probably applies more to something like a flight simulator than a first person shooter.

Categories