【发布时间】:2019-01-06 08:15:46
【问题描述】:
我正在为 android 开发我的开源 LibGDX 游戏,我正在尝试从使用像素坐标更改为世界坐标。 但是,我无法通过使用正交相机和视口来获得所需的结果,因为显示器仍以像素坐标呈现。
例如:我将世界的相机配置为 100 x 100 单位,但显示器在任何设备上都呈现 100 x 100 像素。
我已尝试更改视口,但我怀疑问题与它有什么关系。在我使用 Gdx.graphics.getHeight[/getWidth]
的任何地方,我也使用过 cam.viewport.height[/width]这是我的游戏状态类:
public class PlayState extends State {
private Stork stork;
private CollectibleOrbs orbs;
Array<Texture> textures = new Array<Texture>();
private ShapeRenderer shapeRenderer;
private BitmapFont font;
private Texture lifeTex;
private int score = 0;
private int lives = 5;
public PlayState(GameStateManager gsm, OrthographicCamera cam, Viewport viewport,Stage stage) {
super(gsm,cam,viewport,stage);
Gdx.app.debug("Display",Gdx.graphics.getWidth() + " : " + Gdx.graphics.getHeight());
Gdx.app.debug("CamViewport",cam.viewportWidth + " : " + cam.viewportHeight);
stork = new Stork(0, 50);
lifeTex = new Texture(Gdx.files.internal("lifes.png"));
orbs = new CollectibleOrbs(cam);
font = new BitmapFont(Gdx.files.internal("fonts/abel.fnt"),Gdx.files.internal("fonts/abel.png"),false);
textures.add(new Texture("n0.png"));
textures.get(textures.size - 1).setWrap(Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.ClampToEdge);
for(int i = 1; i <=4;i++) {
textures.add(new Texture(i + ".png"));
textures.get(textures.size - 1).setWrap(Texture.TextureWrap.MirroredRepeat, Texture.TextureWrap.MirroredRepeat);
}
ParallaxBackground parallaxBackground = new ParallaxBackground(textures,cam);
parallaxBackground.setSize(cam.viewportWidth,cam.viewportHeight);
parallaxBackground.setSpeed(1);
stage.addActor(parallaxBackground);
}
@Override
protected void handleInput() {
if(Gdx.input.isTouched()){
stork.fly();
}
}
@Override
public void update(float dt) {
cam.update();
handleInput();
stork.update(dt);
orbs.update(dt);
CollisionCheckMain();
}
@Override
public void render(SpriteBatch sb) {
Gdx.app.debug("Stork", stork.getBoundingRectangle() + "");
sb.setProjectionMatrix(cam.combined);
stage.draw();
sb.begin();
sb.draw(stork.getTextureRegion(),stork.getPosition().x,stork.getPosition().y);
orbs.render(sb);
sb.end();
sb.begin();
font.draw(sb,"Score : "+ getScore(), 84 , 90 );
sb.end();
sb.begin();
for(int i =1; i <= lives; i++){
sb.draw(lifeTex, lifeTex.getWidth()*i - lifeTex.getWidth() + 20 , 100 - lifeTex.getHeight() - Gdx.graphics.getHeight()/10,lifeTex.getWidth(),lifeTex.getHeight());
}
sb.end();
}
@Override
public void dispose() {
stage.dispose();
orbs.dispose();
font.dispose();
}
public void CollisionCheckMain(){
int temp;
temp = orbs.checkCollision(stork.getBoundingRectangle());
if(temp==1){
score +=temp;
if (score%20==0){
lives+=1;
}
}
else
if(temp == -1){
lives -=1;
}
checkKillCondition();
}
public void checkKillCondition(){
if (lives == 0){
//Killed, Restart
gsm.set(new MenuState(gsm, cam, viewport,stage));
dispose();
}
}
public int getScore(){
return score;
}
}
这是我的游戏类:
public class StorkLightGameClass extends ApplicationAdapter {
public static final int HEIGHT = 100;
public static final int WIDTH = 100;
public static final float SPEED = 0.1f;
public static final String TITLE="Stork Light";
private GameStateManager gsm;
private SpriteBatch batch;
OrthographicCamera cam;
Viewport viewport;
Stage stage;
@Override
public void create () {
Gdx.app.setLogLevel(Application.LOG_DEBUG);
batch = new SpriteBatch();
stage = new Stage();
float aspectRatio = (float)Gdx.graphics.getHeight()/(float)Gdx.graphics.getWidth();
cam = new OrthographicCamera();
viewport = new StretchViewport(100 * aspectRatio,100,cam);
viewport.apply();
cam.position.set(cam.viewportWidth/2,cam.viewportHeight/2,0);
batch.getProjectionMatrix().setToOrtho2D(0, 0, cam.viewportWidth,cam.viewportHeight);
gsm = new GameStateManager();
gsm.push(new MenuState(gsm,cam, viewport,stage));
}
@Override
public void render () {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
gsm.update(Gdx.graphics.getDeltaTime());
gsm.render(batch);
}
@Override
public void dispose () {
batch.dispose();
}
@Override
public void resize(int width, int height){
Gdx.app.debug("GameClass", "resize called " + width + ":" + height);
viewport.update(width,height);
cam.position.set(cam.viewportWidth/2,cam.viewportHeight/2,0);
batch.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
stage.getViewport().update(width, height);
stage.getCamera().viewportWidth = WIDTH;
stage.getCamera().viewportHeight = HEIGHT * height / width;
stage.getCamera().position.set(stage.getCamera().viewportWidth/2, stage.getCamera().viewportHeight/2, 0);
stage.getCamera().update();
}
}
这是在 1920 x 1080 分辨率的 Android 设备上的屏幕截图:
期望的结果:
其余代码可在此处获得:https://github.com/sanjeev309/storklight/tree/world_units
【问题讨论】:
-
您必须可以在您的 resize() 方法中对视口进行 update()。
-
@Tenfour04 我做到了。我仍然得到相同的结果。由于我的游戏类扩展了 ApplicationAdapter,我将 cam 和 viewport 作为我的 playState 的可传递参数。现在 resize 被更新调用,但游戏大小仍然是 100 x 100 像素。
-
你能展示你的调整大小的方法吗?
-
您需要将您的视口传递给舞台构造函数。
-
使用其中一种传入宽度和高度参数的 batch.draw 方法。