Incorrect delta time caused by window movement - java

I'm creating a Minecraft clone menu, the yellow text on the logo is causing problems. It is a sprite and I'm using the scale methods to scale it up and down like in the actually menu of the game. This scaling uses Delta Time so it is runs smoothly. But whenever I seem to move the window it pauses my game momentarilly and creates an inaccurate Delta Time such as: 3.0482762
9.7077E-4
4.25514E-4
. These inaccuraces make my text scale more than I want, here is my code I am using LibGdx:
#Override
public void render(float delta) {
// Update
System.out.println(delta);
if(titleEnlargement)
{
if(title.getScaleX() < 1.1)
title.setScale(title.getScaleX() + (delta * 0.4f));
else
titleEnlargement = false;
}
else if(!titleEnlargement)
{
title.setScale(title.getScaleX() - (delta * 0.4f));
if(title.getScaleX() <= 1)
titleEnlargement = true;
}
// Render
batch.draw(background, 0, 0);
logo.draw(batch);
title.draw(batch);
}

You can clip the delta so that it never exceeds a certain value. This is what Stage does to prevent jitters with actions.
Place the following at the start of your render method:
delta = Math.min(delta, 1 / 30f);

Related

Box2D move bodies at same rate regardless of FPS

Sorry, I couldn't word my title properly but I will explain my problem with more clarity here.
I am using libgdx.
When I want to move a Texture so that it covers the same distance with all FPS I will do this:
//...define Player class with x property up here.
Player player = new Player();
int SPEED = 100
public void render() {
player.x += SPEED * Gdx.graphics.getDeltaTime();
}
Now I want to know how to do this to have the same affect on a body in box2d. Here is an example(the render method of a class that extends ApplicationAdapter):
public void render() {
//clear screen, ... do other stuff up here.
playerBody.applyForce(new Vector2(0.5f / PIXEL_PER_METER, 0.0f), playerBody.getWorldCenter(), true);
//PIXEL_PER_METER -> applied to scale everything down
//update all bodies
world.step(1/60f, 6, 2);
}
This applies a force on the playerBody so that it's acceleration increases. How do I make shore, just like with my first example, that how fast the body is travelling stays constant across at 30fps, 10fps, 60fps, etc. I know the timeStep parameter of the world.step is the amount of time to simulate but this value shouldn't vary.
Thankyou in advance.
You can update all bodies with delta (not 1/60 fixed delta)
world.step(Gdx.graphics.getDeltaTime(), 6, 2);
EDIT:
As #Tenfour04 mentioned, in order to prevent high delta values (causes huge jumps), we mostly set a cap for delta.
world.step(Math.min(Gdx.graphics.getDeltaTime(), 0.15f), 6, 2);
I wouldn't use a variable timestep - this is the approach I've used:
private float time = 0;
private final float timestep = 1 / 60f;
public void updateMethod(float delta) {
for(time += delta; time >= timestep; time -= timestep)
world.step(timestep, 6, 2);
}
Basically a variable-ish timestep, but uniformly updating.
If you run your game at very low FPS, or if you force it to with the application configuration (e.g. for testing) this will keep updating at roughly the same speed as a normal 60 FPS instance.
Take a look at Fix your timestep!

How to bounce a ball using libGdx project

I am trying to bounce a ball in an android project using the libGDX game engine.
ball = new Texture("football.jpg");
batch = new SpriteBatch();
sprite = new Sprite(ball);
render(float delta)
{
batch.begin();
sprite.draw(batch);
batch.end();
stage.draw();
jumpUp(); //here i call the jump function..
}
The jump function looks like this:
public void jumpUp()
{
sprite.setY(sprite.getY()+2);
dem=sprite.getY();
if(dem==100.0f)
{
jumpDown();
}
}
public void jumpDown()
{
sprite.setY(sprite.getY()-1);
}
The ball is actually moving upward but it's not coming down again.
Should I also call jumpDown() in the render() method?
The official wiki libgdx lifecycle states that game logic updates are also done in the render() function. So, yes you should also call jumpDown() there. I would however propose that you keep it simple and only use one function like this:
private Texture ballTexture;
private Sprite ballSprite;
private SpriteBatch batch;
private dirY = 2;
create(){
ballTexture = new Texture("football.jpg");
ballSprite = new Sprite(ballTexture);
batch = new SpriteBatch();
}
render(float delta){
recalculateBallPos(delta);
batch.begin();
sprite.draw(batch);
batch.end();
stage.draw();
}
private void recalculateBallPos(delta){
float curPos = ballSprite.getY();
if(curPos + dirY > 100 || curPos + dirY < 0){
dirY = dirY * -1 //Invert direction
}
ballSprite.setY(curPos+dirY)
}
This still might look a bit choppy but I hope it's a good way to start.
The problem is the following:
Your Ball goes up, until it's y-value is exactly 100.0f. If thats the case, you decrease it by 1, which results in an y-value of 99.0f.
In the next render you call jumpUp again, which results in a y-value of 101.
This time your condition is not met, the jumpDown() is not called.
Even if you change your condition to >= 100.0f, your Ball will always move up by 2 and down by 1, which results in an increasing y-value.
Instead you should call the method something like updateBallPos and store a boolean up.
In updateBallPos you can simply check the boolean up, if it is true, increase the y-value, if it is fales, decrease it.
Also you need to update this boolean up in the updateBallPos method:
if (up && sprite.getY() >= 100.0f)
up = false
else if (!up && sprite.getY() <= 0.0f)
up = true

Objects getting jerks when moving camera in downward direction

I have been making a game in which there is number of objects in negative 'y' for which I had taken the arrayList and I am moving the main character in downward direction.But when the camera move with the character the objects are not moving smooth, they are getting jerks after some interval of time.The code for that is following
#Override
public void create() {
camera = new OrthographicCamera(480, 720);
camera.position.set(480 / 2, 720 / 2, 0);
batch = new SpriteBatch();
int i;
this.baloonArrList = new ArrayList<Baloon>();
for (i = 0; i < 3000; i += 300) {
Baloon baloon = new Baloon(200, i);
baloonArrList.add(baloon);
System.out.println(baloon.balloon_y);
}
texture1 = new Texture(Gdx.files.internal("data/sheet_final.png"));
textureRegion1 = new TextureRegion(texture1, 561, 156, 115, 101);
}
#Override
public void render() {
GLCommon gl = Gdx.gl;
Gdx.gl.glClearColor(1, 1, 1, 1);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.position.y += 4;
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
int len = baloonArrList.size();
for (int i = 0; i < len; i++) {
batch.draw(textureRegion1, baloonArrList.get(i).balloon_x,
baloonArrList.get(i).balloon_y, 100, 100);
}
batch.end();
}
So, how can I make the motion of objects smooth.
I believe the source of your issue is the following line:
camera.position.y += 4;
You should instead change it to a smaller value, or better, make it based on the speed of the frame rate:
camera.position.y += 4 * Gdx.graphics.getDeltaTime();
This way your camera will move in the y direction 4 pixels every second, instead of 4 pixels every frame. (Of course you may need to increase the 4 to make it faster, but it will keep it quite smooth.)
If the rendering is jerky and inconsistent (use the builtin FPSLogger to find out what framerate you're getting), then something is taking more/variable amounts of time during rendering. You should use a profiler to figure out where time is going. The Android DDMS tools included with Eclipse are pretty good. Too-frequent garbage collection is often a source of variable runtimes, but its best to understand what is going on before trying to fix it.
That said, #Jyro117's suggestion to make your state updates frame-rate independent is always a good idea.

Creating "stick controls" for android game?

I'm trying to create a simple Android game, a 2D action shooter which has 2 control sticks (circles) on the screen, the left one is movement control and the right one weapon control. Direction is being controlled by the position of your thumb relative to the circle’s center.
I've been following a tutorial on this site: http://www.kilobolt.com/day-7-creating-an-android-game-from-start-to-finish.html but it only gave me the base to work on. I have no programming experience so I'm quite lost now.
I got the movement working only on TOUCH_DOWN event, the hero moves to about where it should but to change direction I have to lift my thumb and touch the circle again. TOUCH_DRAGGED (or ACTION_MOVE) is broken because if I drag my finger across the circle the character moves really fast. I guess the problem is too many touch events are being handled, but I have no idea how to fix it.
How can I change this so that I can drag my thumb around the circle and the hero will change its direction instantly, and keep its speed constant all the time? Also the speed should be the same no matter how close or far from the center of the circle you touch.
private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_DOWN || event.type == TouchEvent.TOUCH_DRAGGED) {
if (inBounds(event, 50, 300, 150, 150, 'c')) {
ctrl.setX(event.x);
ctrl.setY(event.y);
ctrl.direction();
hero.move(ctrl.getDirX(), ctrl.getDirY());
}
}
if (event.type == TouchEvent.TOUCH_UP) {
if (inBounds(event, 0, 0, 35, 35,'r')) {
pause();
}
hero.stopMove();
}
}
hero.update();
The movement: hero's speedX and speedY are added to hero's centerX and centerY on every hero.update() call.
public void move(float x, float y) {
speedX += x * MOVESPEED;
speedY += y * MOVESPEED;
}
This method that handles the x & y speed. Found it here at stackoverflow, and because touch_down event is working ok, I guess it's doing it's job. Although I feel it's not exactly how it's supposed to be. L_STICK_C is a constant with values of 100 and 350 (center of the circle).
public void direction() {
dir.x = x - L_STICK_C.x;
dir.y = y - L_STICK_C.y;
double hyp = Math.sqrt(dir.x * dir.x + dir.y * dir.y);
dir.x = (float) (dir.x / hyp);
dir.y = (float) (dir.y / hyp);
}
I suggest you look into some game programming tutorials. You usually would not move the character directly from the touch input. You'd set a game state variable once a game loop which would correspond to the position of your thumb inputs. Then you'd only update the hero once per game loop based on those inputs. This lets allows you to keep the game input control code, and hero code separate, and makes it re-usable for other parts of your game.
EDIT:
Based on your code, every time you drag your finger, you generate a bunch of dragged events. So you are adding onto your characters speed for each event. You should probably just be looking at the distance to center and x / y of the input on the last touch event, not all of them.

Java Timing Framework - triggering event at the end of an Animator animation

I'm using the Animator class from the Timing Framework to perform a simple animation (moving a JPanel), roughly based on examples in Filthy Rich Clients
I've overridden timingEvent() as follows
public void timingEvent(float arg0) {
float fraction = this.animator.getTimingFraction();
fraction = Math.min(1.0f, fraction);
if (fraction >= 1.0f) {
this.mainGUI.initiateSwitchToMainScreenTransition();
} else if (fraction < 0.5f) {
this.translateY = (int) (MAX_Y * (2 * fraction));
repaint();
}
}
I've overriden paint() to use the value in translateY to move the panel down.
The animation itself works perfectly.
My problem is the call to initiateSwitchToMainScreenTransition(), which I want to be performed when the animation is complete. Whilst this works, there is a sizeable delay between the animation ending and the call firing (debugging has confirmed that the problem isn't the length of the time taken by initiateSwitchToMainScreenTransition() - the delay occurs before the call).
Is there a better way to achieve this, i.e. without the delay?
If you are implementing org.jdesktop.animation.timing.TimingTarget then there is an end() method that should be called when your animation is complete - that seems to work for me when I have used it. I do not think you can guarantee that timingEvent will get called after the fraction has reached 1.0.
Your implementation does not seem to do anything for the second half of the timer (when fraction is between 0.5 and 1.0). If you want the animation to continue for the entire duration of the timer you could rearrange your code like this:
#Override
public void timingEvent(float fraction) {
translateY = (int) (MAX_Y * fraction);
repaint();
}
#Override
public void end() {
mainGUI.initiateSwitchToMainScreenTransition();
}

Categories