How to make a smooth camera follow algorithm? - java

I am making a game with LibGDX (Java).
I need the camera to follow a fast moving character. The easiest way to do it is to just write this:
this.getCamera().position.set(obj.x, obj.y, 0);
But, is there any algorithm to make this more smooth? Like when camera is not that strict, and is always a bit late: character goes quick right, camera follows with slight delay, or if you suddenly appeared somewhere far, camera doesn't teleport instantly but travels at a top speed to you when it comes closer it slows down a bit and finds you again.
Is there any libgdx libs that do that or anyone had this experience?

Try something simple like lerping a tenth of the distance. It works surprisingly well.
float lerp = 0.1f;
Vector3 position = this.getCamera().position;
position.x += (Obj.x - position.x) * lerp * deltaTime;
position.y += (Obj.y - position.y) * lerp * deltaTime;

Take a look at Aurelion Ribon's Java Universal Tween Engine. This performs interpolation and has several easing equations that I think would get you what you are looking for. It also has other advanced features like waypointing and chaining certain actions together for other interesting effects.
Your game logic could check to see if the character is moving quickly or has a step change in terms of position. In response to this, turn your current camera position over to the tween engine and let it take over -- smoothly zooming to the character's current position.

Related

Box2D - Controlled Movement with Physics

I am creating a Java desktop 2D Game using LibGDX.
I need to be able to move objects (controlled by the player with W/A/S/D).
The movement speed is always the same (read out from a field of the moving object).
While they are moving, they should still be affected by physics.
This means that when moving away from a magnet would make you move slower, moving towards it makes you faster and moving past it would cause you to move a curve. (see blue part of image)
Also a single impulse in while moving would knock you away but you keep moving (see red part of image)
You should also be able to change direction or stop, only stopping your own movement, so you will still be affected by physics.
So I need to apply constant forces that will still be accessible (and removable) after the next step.
Can I do this with Box2D?
-If yes, how?
-If no, any other libraries that can do this? I don't really need density and stuff like that, the use cases in the image is pretty much all I need (+ Collision Detection).
*A magnet would be a body constantly pulling other bodies in a certain range to itself
*Kockback would just be a simple impulse or the collision of a projectile with the object.
EDIT: If you know The Binding of Isaac, thats the kinda physics I'm aiming for.
Set the distance where the magnet has his influence:
float magnetRadius = 30;
Set the attractive force of the magnet:
float magnetForce = 400;
Get the position of the player and of the magnet:
Vector2 magnetPos = magnet.getWorldCenter();
Vector2 playerPos = player.getWorldCenter();
Now calculate the distance between the player and the magnet:
Vector2 magnetDist = new Vector2((playerPos.x - magnetPos.x), (playerPos.y - magnetPos.y));
float distance = (float) Math.sqrt((magnetPos.x) * (magnetPos.x) + (magnetPos.y) * (magnetPos.y));
Then, if the player is inside the magnet's radius, you must apply a force to him that depends on the distance of the player from the magnet:
if (distance <= magnetRadius) {
float vecSum = Math.abs(magnetDist.x)+Math.abs(magnetDist.y);
Vector2 force = new Vector2((magnetForce*magnetDist.x * ((1/vecSum)*magnetRadius/distance)), (magnetForce*magnetDist.y * ((1/vecSum)*planetRadius/distance)));
player.applyForceToCenter(force, true);
}

Calculating collisions, taking into account velocity

I'm making a platformer game. The jumping and movement are working, and now I want to program the collisions. I have a sort of idea as to how this will work:
I wasn't sure whether this question should be here or in the game dev site.
I have two Vector2's - velo and momentum (velo is the velocity). Both are (0, 0). The momentum is what's added to the velocity each frame.
Each frame, I first get the input. Momentum is increased and/or increased based on the keys pressed (e.g: if (Gdx.input.isKeyPressed(Keys.A)) { momentum.x -= speed; })
I then multiply the momentum by 0.15. This is so that it slows down.
After this, I multiply the velocity by 0.8.
Then, I add the momentum to the velocity, to increase the velocity, as
this is what actually moves the player.
I then add the velocity to the position of the player.
To apply the gravity, I add a gravity vector (0, -10) to the position of the player.
So I need to find a way to move the player, but not allowing it to overlap any part of the world. The world is made up of lots of Rectangle instances. The player's body is also an instance of Rectangle. Would it be easier to rewrite the collisions using Box2D? What I've tried is checking if the player overlaps any rectangles when it's moved, and if it will, not moving it. But this doesn't seem to take everything into account - sometimes it works, but other times, it stops before touching the world.
TL;DR: I want to make collisions of my player with a world which is stored as a grid of rectangles. How would I do this, as my player is also a Rectangle. Would it be easier to use Box2D?
This answer gives a good overview about the details of collision detection:
https://gamedev.stackexchange.com/a/26506
However, that might be a bit overwhelming if you just want to get a simple game going. Does your game loop happen in fixed interval or is it dependent on the framerate? Maybe you could solve a part of your issue by simply dividing the collision detection into more steps. Instead of moving the full way during one update, you could make 10 little updates that each move you only a 10th of the distance. Then you do a collision check after each step, so it's less likely that you stop too early or move through thin objects.
That would of course be more taxing on the performance, but it's a naive and easy to implement approach to a solution.
EDIT:
Just wrap the position update in a for loop. I don't know how your code for collision checking and updating, but the general structure would be something like
for (int i = 0; i < 10; i++) {
newPosX += deltaX * 0.1; // 1/10th of the usual update
newPosY += deltaY * 0.1; // 1/10th of the usual update
if (checkCollision(newPosX, newPosY))
{
posX = newPosX;
posY = newPosY;
}
else
{
break; // We hit something, no more mini-updates necessary.
}
}

LibGDX 3D Camera spasm when player looks directly up or down

My circumstance
I am making a 3D LibGDX game. I am using a custom camera controller, based off of the one over here. It takes out the use of delta Y, when determining where to move the player, so that they can stay on the same level whether they are looking up or down.
My problem
My problem is that whenever the player looks too far up, or down, the camera kinda starts spazing out. I believe that it is trying to look either strait up, or down. My problem is that I don't want that. In previous projects I have tried to set a limit like so:
if(camera.direction.y + deltaY >= 0.9){
return;
}
(Code might not be exactly correct), but when that happens, the player usually cannot see enough.
My code
There is a link to my code here.
I got my code fixed with the help of one of the fine fellows over at Github. Here is my new FirstPersonCameraController#touchDragged:
float deltaX = -Gdx.input.getDeltaX() * degreesPerPixel;
float deltaY = -Gdx.input.getDeltaY() * degreesPerPixel;
camera.direction.rotate(camera.up, deltaX);
Vector3 oldPitchAxis = tmp.set(camera.direction).crs(camera.up).nor();
Vector3 newDirection = tmp2.set(camera.direction).rotate(tmp, deltaY);
Vector3 newPitchAxis = tmp3.set(tmp2).crs(camera.up);
if (!newPitchAxis.hasOppositeDirection(oldPitchAxis))
camera.direction.set(newDirection);
(I removed a couple of parts that are specific to my game)

Free-flight camera with vectors - how to rotate properly?

I have this camera that is set up with vecmath.lookatMatrix(eye, center, up).
The movement works fine, forwards, backwards, right, left, these work fine.
What does not seem to work fine is the rotation.
I am not really good at math, so I assume I may be missing some logic here, but I thought the rotation would work like this:
On rotation around the Y-axis I add/sub a value to the X value of the center vector.
On rotation around the X-axis I add/sub a value to the Y value of the center vector.
For example here is rotation to the right: center = center.add(vecmath.vector(turnSpeed, 0, 0))
This actually works, but with some strange behaviour. It looks like the higher the x/y of the center vector value gets, the slower the rotation. I guess it's because through the addition/substraction to the center vector it moves too far away or something similar, I would really like to know what is actually happening.
Actually while writing this, I just realized this can't work like this, because once I have moved around and rotated a bit, and for example I'm in "mid air", the rotation would be wrong....
I really hope someone can help me here.
Rotating a vector for OpenGL should be done using matrices. Linear movement can be executed by simply adding vectors together, but for rotation it is not enough just to change one of the coordinates... if that was the case, how'd you get from (X,0,0) direction to (0,X,0)?
Here is another tutorial, which is C++, but there are Java samples too.
There is a bit of math behind all this - you seem to be familiar with vectors, and probably have a 'feel' of them, which helps.
EDIT - if you are to use matrices in OpenGL properly, you'll need to familiarize yourself with the MVP concepts. You have something to display (the model) which is placed somewhere in your world (view) at which you are looking through a camera (projection).
A working solution to working with a free-flight camera with eye, center, up vectors was posted here:
Free Flight Camera - strange rotation around X-axis

Box2d helicopter physics

I am developing java game using box2d for my physics, I have got helicopter, ex:
I reduced gravity by setting:
body.setGravityScale(0.03f);
So it acts bit realistic (is affected by gravity only little bit, floating in the air)
To move it, down/up left/right I have controller, thats how I control my helicopter:
body.applyLinearImpulse(new Vector2(pValueX * 3, pValueY * 3), mainBody.getWorldCenter());
Where pValueX and pValueY are 1 or -1 (directions up/down left or right)
It works good, but now I am trying to achieve more realistic effect, when moving helicopter left/right I wanted to tilt it little bit so it works like real helicopter, but could not find proper way how to do it, I have tried applying force in different part of the body, but it makes my helicopter rotating 360 degrees if keep pressing left or right.
This question is old, but in case it's still relevant, I created a helicopter using JBox2D (which pretty much maps directly to Box2D). For tilting left/right (i.e. forwards/backwards relative to the pilot):-
heli.applyTorque(TURN_TORQUE);
or
heli.applyTorque(-TURN_TORQUE);
This rotates the heli, and then if the player wants lift:
Vec2 force = new Vec2();
force.y = (float)Math.cos(chopper.getAngle()) * -1;
force.x = (float)Math.sin(chopper.getAngle());
force.mulLocal(ROTOR_FORCE);
heli.applyForceToCenter(force);
What you can do is, just define two constants as maxForceLeft and maxForceRight. When you press left apply some force on the cockpit part of the helicopter and keep comparing it with the maxForceLeft,once it reaches that value stop applying the force.Do the same for the right button by applying the force on the tail rotor part of the helicopter.In this way you can avoid rotating it 360 degrees.Depending upon the kind of effect you want for your helicopter you can apply the forces in either upward or downward direction.
http://www.iforce2d.net/b2dtut/rotate-to-angle
What you need is rotating the body to a desired angle..
This is a great tutorial to achieve this.
I hope this would help.

Categories