Search code examples
javalibgdxinitialization

Why do i have to initialize the ball in Resize() method? - Libgdx


I'm making a simple Bouncing Ball game, even if i call the init() method via BouncingBall class constructor in Show() method of the BallScreen class, the ball isn't created. So to create a ball, i should call BouncingBall's init() method in Resize() method. Why? Isn't it supposed to be created in Show() method ?

Here is the code for Bouncing Ball

public class BouncingBall {

public static final float RADIUS_RATIO = 0.04f;
public static final float START_KICK = 500.0f;
private static final float KICK_INTERVAL = 3f;
private static final float DRAG = 1f;


private Vector2 position;
private Vector2 velocity;
float radius;
float lastKick;

public BouncingBall(Viewport viewport) {
    init(viewport);
}

public void init(Viewport viewport) {
    position = new Vector2();
    position.x = viewport.getWorldWidth() / 2;
    position.y = viewport.getWorldHeight() / 2;

    velocity = new Vector2(0,0);

    radius = RADIUS_RATIO * Math.min(viewport.getScreenWidth(), viewport.getScreenHeight());
    startKick();
}

public void update(float delta, Viewport viewport) {

    float elapsedSeconds = MathUtils.nanoToSec * (TimeUtils.nanoTime() - lastKick);

    if (elapsedSeconds > KICK_INTERVAL) {
        lastKick = TimeUtils.nanoTime();
        startKick();
    }

    velocity.x -= delta * DRAG * velocity.x;
    velocity.y -= delta * DRAG * velocity.y;

    position.x += velocity.x * delta;
    position.y += velocity.y * delta;
    collision(radius,viewport);
}


public void collision(float radius, Viewport viewport) {
    if (position.x + radius > viewport.getWorldWidth()) {
        position.x = viewport.getWorldWidth() - radius;
        velocity.x = -velocity.x;
    }

    if (position.x - radius < 0) {
        position.x = radius;
        velocity.x = -velocity.x;
    }

    if (position.y + radius > viewport.getScreenHeight()) {
        position.y = viewport.getWorldHeight() - radius;
        velocity.y = -velocity.y;
    }

    if (position.y - radius < 0) {
        position.y = radius;
        velocity.y = -velocity.y;
    }
}

public void startKick() {
    Random random = new Random();
    float angle = random.nextFloat() * MathUtils.PI2;
    velocity.x = START_KICK * MathUtils.cos(angle);
    velocity.y = START_KICK * MathUtils.sin(angle);
}

public void render(ShapeRenderer renderer) {
    renderer.setColor(Color.RED);
    renderer.circle(position.x, position.y, radius);
}
}

Here is the Screen Class for Bouncing Ball

public class BallScreen extends ScreenAdapter {


private static final float WORLD_SIZE = 480f;
private static final String TAG = BallScreen.class.getSimpleName();

private BouncingBall ball;
private Viewport viewport;
private ShapeRenderer renderer;


@Override
public void show() {
    Gdx.app.log(TAG, "Show");
    viewport = new FitViewport(WORLD_SIZE, WORLD_SIZE);
    renderer = new ShapeRenderer();
    ball = new BouncingBall(viewport);
}

@Override
public void resize(int width, int height) {
    Gdx.app.log(TAG, "resize" + width + " " + height);
    viewport.update(width,height,true);
    ball.init(viewport);
}

@Override
public void dispose() {
    Gdx.app.log(TAG, "dispose");
    renderer.dispose();
}

@Override
public void render(float delta) {
    viewport.apply();
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);

    renderer.setProjectionMatrix(viewport.getCamera().combined);
    renderer.begin(ShapeType.Filled);

    ball.update(delta, viewport);
    ball.render(renderer);

    renderer.end();

}
}

Solution

  • Problem is in this line :

    radius = RADIUS_RATIO * Math.min(viewport.getScreenWidth(), viewport.getScreenHeight());
    

    When you create FitViewPort and pass to BouncingBall, at that time viewport having only worldWidth and worldHeight that is what you set 480. At that time screenwidth and screenheight of viewport is zero so your radius initialise with zero value.

    But After update() method if I call init() method :

    viewport.update(width,height,true);  // this method set value to screenwidth/height
    

    when you call update method on viewport after that screenwidth and screenheight of viewport having some value according to what type of ViewPort you're using.

    After update() if I call ball.init(viewport); then radius is not zero value so that ball is visible on screen.