为什么我必须在Resize()方法中初始化球? --Libgdx

问题描述:

即使我通过BallScreen类的Show()方法中的BouncingBall类构造函数调用init()方法,我也正在制作一个简单的Bouncing Ball游戏,但并未创建球。所以要创建一个球,我应该在Resize()方法中调用BouncingBall的init()方法。为什么?它不是应该在Show()方法中创建的吗?为什么我必须在Resize()方法中初始化球? --Libgdx

这里是一个弹跳球

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); 
} 
} 

下面的代码为弹跳球Screen类

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(); 

} 
} 
+0

你是什么意思是由球没有创建或不显示在屏幕上? – Aryan

+0

@AbhishekAryan是的,它在视口上不可见。 –

问题是在这一行:

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

当您创建FitViewPort并传递给BouncingBall,那时视口只有wo rldWidth和worldHeight就是你设置的480.那时候视口的screenwidth和screenheight是零,所以你的半径初始化为零值。

但经过update()方法如果我叫init()方法:

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

,当你调用视口更新方法屏幕宽度,并根据你使用什么类型的视口有一些价值视窗的screenheight后。

update()之后如果我打电话ball.init(viewport);那么半径不是零值,以便球在屏幕上可见。

+0

非常感谢!我想我错过了screenWidth和worldWidth之间的区别... –