8

libgdx no motion smooth screen resolution small

 3 years ago
source link: https://www.codesd.com/item/libgdx-no-motion-smooth-screen-resolution-small.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

libgdx no motion smooth screen resolution small

advertisements

I am developing a simple game and faced with a problem. On devices with screen resolution that is lower, than game world resolution, movement is not smooth and looks very disgusting.

My code:

public float LAST_GROUND_LEVEL, CURRENT_GROUND_LEVEL, LAST_GROUND_LEVEL_PLANKS;
public int CURRENT_GROUND_INDEX, COUNTER_TO_NEXT_PLANK = 0;

private Ball ball;
private Array<Plank> planks;
private Array<GroundPlank> groundPlanks;

private Random random;

public PlayState(GameStateManager gsm) {
    super(gsm);
    orthographicCamera.setToOrtho(false, JumpingBall.WIDTH, JumpingBall.HEIGHT);
    ball = new Ball(JumpingBall.WIDTH / 2, JumpingBall.HEIGHT / 2, gameStateManager);

    planks = new Array<Plank>();

    random = new Random();
    groundPlanks = new Array<GroundPlank>();
    for (int i = 0; i < 3; i++) {
        if (i != 2) {
            groundPlanks.add(new GroundPlank(i * orthographicCamera.viewportWidth / 2, 600 * JumpingBall.RATIO, orthographicCamera));
            CURRENT_GROUND_INDEX = i;
            CURRENT_GROUND_LEVEL = 600 * JumpingBall.RATIO;
        } else {
            boolean side = random.nextBoolean();
            if (side == true) {
                groundPlanks.add(new GroundPlank(i * orthographicCamera.viewportWidth / 2, 800 * JumpingBall.RATIO, orthographicCamera));
                LAST_GROUND_LEVEL = 800 * JumpingBall.RATIO;
            } else {
                groundPlanks.add(new GroundPlank(i * orthographicCamera.viewportWidth / 2, 400 * JumpingBall.RATIO, orthographicCamera));
                LAST_GROUND_LEVEL = 400 * JumpingBall.RATIO;
            }
        }
        LAST_GROUND_LEVEL_PLANKS = LAST_GROUND_LEVEL;
        COUNTER_TO_NEXT_PLANK++;
    }
}

@Override
public void handleInput() {
    if (Gdx.input.justTouched()) {
        ball.jump();
    }
}

@Override
public void update(float delta) {
    if (delta > 0f) {
        handleInput();
        for (int i = 0; i < groundPlanks.size; i++) {
            if ((ball.getPosition().x + ball.getBall().getWidth() / 30 * JumpingBall.RATIO / 2 > groundPlanks.get(i).getPosition().x) &(ball.getPosition().x + ball.getBall().getWidth() / 30 * JumpingBall.RATIO / 2 < groundPlanks.get(i).getPosition().x + orthographicCamera.viewportWidth / 2))
            {
                ball.update(delta, CURRENT_GROUND_LEVEL + groundPlanks.get(0).getGroundPlankTexture().getHeight() / 4 * JumpingBall.RATIO, groundPlanks.get(i).getPosition().x + orthographicCamera.viewportWidth / 2, CURRENT_GROUND_LEVEL + groundPlanks.get(0).getGroundPlankTexture().getHeight() / 4 * JumpingBall.RATIO, LAST_GROUND_LEVEL + groundPlanks.get(0).getGroundPlankTexture().getHeight() / 4 * JumpingBall.RATIO);
            }
        }
        orthographicCamera.position.x = ball.getPosition().x + ball.getBall().getWidth() / 30 * JumpingBall.RATIO / 2;

        boolean foundPlank = false;
        for (int i = 0; i < groundPlanks.size; i++) {
            if (foundPlank == false) {
                GroundPlank groundPlank = groundPlanks.get(i);
                GroundPlank RepositionPlank;

                if ((orthographicCamera.position.x > groundPlank.getPosition().x) & ((groundPlank.getPosition().x + orthographicCamera.viewportWidth / 2) > orthographicCamera.position.x)) {
                    CURRENT_GROUND_LEVEL = groundPlank.getPosition().y;
                    if (i > 1) {
                        RepositionPlank = groundPlanks.get(0);
                    } else if (i == 1) {
                        RepositionPlank = groundPlanks.get(2);
                    } else {
                        RepositionPlank = groundPlanks.get(1);
                    }
                    if (i != CURRENT_GROUND_INDEX) {
                        boolean side = random.nextBoolean();
                        if (side == true) {
                            if (LAST_GROUND_LEVEL < GroundPlank.HIGHEST_OPENING) {
                                RepositionPlank.Reposition(groundPlank.getPosition().x + orthographicCamera.viewportWidth / 2, LAST_GROUND_LEVEL + 200 * JumpingBall.RATIO);
                                LAST_GROUND_LEVEL = LAST_GROUND_LEVEL + 200 * JumpingBall.RATIO;
                            } else {
                                RepositionPlank.Reposition(groundPlank.getPosition().x + orthographicCamera.viewportWidth / 2, LAST_GROUND_LEVEL - 200 * JumpingBall.RATIO);
                                LAST_GROUND_LEVEL = LAST_GROUND_LEVEL - 200 * JumpingBall.RATIO;
                            }
                        } else {
                            if (LAST_GROUND_LEVEL > GroundPlank.LOWEST_OPENING) {
                                RepositionPlank.Reposition(groundPlank.getPosition().x + orthographicCamera.viewportWidth / 2, LAST_GROUND_LEVEL - 200 * JumpingBall.RATIO);
                                LAST_GROUND_LEVEL = LAST_GROUND_LEVEL - 200 * JumpingBall.RATIO;
                            } else {
                                RepositionPlank.Reposition(groundPlank.getPosition().x + orthographicCamera.viewportWidth / 2, LAST_GROUND_LEVEL + 200 * JumpingBall.RATIO);
                                LAST_GROUND_LEVEL = LAST_GROUND_LEVEL + 200 * JumpingBall.RATIO;
                            }
                        }
                        CURRENT_GROUND_INDEX = i;

                        for (int j = 0; j < groundPlanks.size; j++) {
                            if (orthographicCamera.position.x < groundPlanks.get(j).getPosition().x) {
                                LAST_GROUND_LEVEL_PLANKS = groundPlanks.get(j).getPosition().y;
                            }
                        }

                        COUNTER_TO_NEXT_PLANK++;
                        if (COUNTER_TO_NEXT_PLANK == 4) {
                            if (planks.size != 0) {
                                Plank plank = planks.get(0);
                                plank.reposition(RepositionPlank.getPosition().x, LAST_GROUND_LEVEL_PLANKS + 20 * JumpingBall.RATIO + RepositionPlank.getGroundPlankTexture().getHeight() / 4 * JumpingBall.RATIO, RepositionPlank.getGroundPlankTexture().getHeight() / 4 * JumpingBall.RATIO + LAST_GROUND_LEVEL_PLANKS + 150 * JumpingBall.RATIO);
                            } else {
                                planks.add(new Plank(RepositionPlank.getPosition().x, LAST_GROUND_LEVEL_PLANKS + 20 * JumpingBall.RATIO + RepositionPlank.getGroundPlankTexture().getHeight() / 4 * JumpingBall.RATIO, RepositionPlank.getGroundPlankTexture().getHeight() / 4 * JumpingBall.RATIO + LAST_GROUND_LEVEL_PLANKS + 150 * JumpingBall.RATIO));
                            }
                            COUNTER_TO_NEXT_PLANK = 0;
                        }
                    }
                    foundPlank = true;
                }
            }
        }

        if (planks.size != 0){
            if (planks.get(0).Collides(ball.getBounds())){
                gameStateManager.set(new MenuState(gameStateManager));
            }
        }
    }
    orthographicCamera.update();
}

@Override
public void render(SpriteBatch spriteBatch) {
    spriteBatch.setProjectionMatrix(orthographicCamera.combined);
    spriteBatch.begin();
    spriteBatch.draw(ball.getBall(), ball.getPosition().x, ball.getPosition().y, ball.getBall().getWidth() / 30 * JumpingBall.RATIO, ball.getBall().getHeight() / 30 * JumpingBall.RATIO);
    for (Plank plank : planks) {
        spriteBatch.draw(plank.getPlank(), plank.getPosTopPlank().x, plank.getPosTopPlank().y, plank.getPlank().getWidth() * JumpingBall.RATIO / 4, plank.getPlank().getHeight() * JumpingBall.RATIO);
        spriteBatch.draw(plank.getPlank(), plank.getPosBotPlank().x, plank.getPosBotPlank().y, plank.getPlank().getWidth() * JumpingBall.RATIO / 4, plank.getPlank().getHeight() * JumpingBall.RATIO);
    }
    for (GroundPlank groundPlank : groundPlanks) {
        spriteBatch.draw(groundPlank.getGroundPlankTexture(), groundPlank.getPosition().x, groundPlank.getPosition().y, orthographicCamera.viewportWidth / 2, groundPlank.getGroundPlankTexture().getHeight() * JumpingBall.RATIO / 4);
    }
    spriteBatch.end();
}

@Override
public void dispose() {
    for (Plank plank : planks) {
        plank.dispose();
    }
    ball.getBall().dispose();
    for (GroundPlank groundPlank : groundPlanks) {
        groundPlank.getGroundPlankTexture().dispose();
    }
}

EDITED:

public void update(float delta, float groundlevel, float cur_x_end, float cur_y, float next_y){
    GROUND_LEVEL = groundlevel;
    if (position.y > GROUND_LEVEL){
        velocity.add(0, GRAVITY, 0);
    }
    velocity.scl(delta);
    position.add(MOVEMENT * delta, velocity.y, 0);
    if ((position.y <= GROUND_LEVEL) & (position.x + getBall().getWidth() / 30 * JumpingBall.RATIO < cur_x_end)){
        if (Down == false) {
            position.y = GROUND_LEVEL;
        }
    } else if (position.x + getBall().getWidth() / 30 * JumpingBall.RATIO > cur_x_end){
        if (next_y > cur_y){
            if (position.y < next_y){
                Down = true;
            }
        }
    }
    if (position.y + getBall().getHeight() / 30 * JumpingBall.RATIO < 0){
        gameStateManager.set(new MenuState(gameStateManager));
    }
    if (position.y >= JumpingBall.WORLD_HEIGHT * JumpingBall.RATIO - BallTexture.getHeight() / 30 * JumpingBall.RATIO){
        position.y = JumpingBall.WORLD_HEIGHT * JumpingBall.RATIO - BallTexture.getHeight() / 30 * JumpingBall.RATIO;
    }
    velocity.scl(1/delta);
    bounds.setPosition(position.x, position.y);
}


It could be that you are moving the ball at an average of uneven pixels. If you move at a average speed of 1.6 pixels pr. frame, the ball will move 1 pixel some frames and 2 pixels other frames. This will result in stuttering.

There are no half pixels so you should make sure your speed makes the ball move the same number of pixel each frame.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK