简体   繁体   中英

LibGDX - setProjectionMatrix() "hiding" a Sprite

I am trying to draw a Sprite but it just appears for a frame when I first run my program, and then immediately disappears. I am working with a Stage , a Tiled map and two Batches , which I hope is not a problem.

It pretty much looked like the sprite was hiding behind something else, but I made completely sure that nothing was being drawn after it. So after a long time messing around, I found out that deleting the setProjectionMatrix() method "solved" my problem, since the sprite showed perfectly somehow.

I don't understand the reason why this happened at all, and I don't want to just delete the method and have sprites following the camera around, so:

Why or how would a setProjectionMatrix() method "hide" a Sprite? Is it altering the order in which my sprites are drawing? And most importantly, how do I fix it?

Here's my render method:

public void render(float delta) {
    Render.cleanScreen(); //Render is a class i made with useful static stuff, like the Batch i am using.
                          //This method is pretty much just a Gdx.gl.glClearColor() method.
    
    tmr.setView(camera); // tileMapRenderer
    tmr.render();
    b2dr.render(world, camera.combined); // Box2DDebugRenderer
    stage.act();
    stage.draw();
    
    Render.batch.begin(); 
    sprite2.draw(Render.batch); //The sprite i want to draw
    Render.batch.end();

    hudBatch.begin();
    sprite1.draw(hudBatch); //This works fine
    hudBatch.end();

    Render.batch.setProjectionMatrix(camera.combined);
    Gdx.input.setInputProcessor(stage);
}

Edit: Someone asked for extra info, so:

This is what my game looks like with the setProjectionMatrix (after the first frame when the Sprite dissapears) and this is what it looks when i delete it. You can clearly see the red square(the Sprite).

• I am currently using a FitViewport.

Stage.draw() calls apply() on the Stage's Viewport, but never restores the OpenGL Viewport to what it was before. I'm guessing that your stage uses FitViewport, so it is cropping part of the screen. If you want different viewport behavior for stuff you draw outside your stage, you should create a separate viewport for that, and call viewport.apply() before you start rendering the other stuff.

Side note: if you are lazy loading anything that uses native memory (like SpriteBatch and Texture, things implementing Disposable) and storing a reference in a static variable (your Render class), make sure you dispose all of it and null it out in your game's destroy() method. Otherwise, on Android you will be leaking that stuff and it will fail to work when you reopen your game.

Another side note: In my opinion, the Sprite class should not be used unless you have hundreds of them and they aren't moving much (in which case it might have slightly better performance). Sprite is a weird conflation of an asset (a TextureRegion) and game state data. As a result, it can create design issues that you have to work around, such as when you want to animate it or flip it. It is better to create your own GameObject class that references a TextureRegion (a single instance of which can be shared by many elements), and has its own variables for position, color, rotation, etc. Then draw it with the appropriate SpriteBatch.draw method using those properties. In my game, I have a wrapper interface around TextureRegion that can alternately wrap Animation<TextureRegion> so my GameObject class can use either and it can be swapped easily. This makes the code more flexible to change.

So... I just realized my coworker accidentally deleted the viewport.update() method.

@Override
public void resize(int width, int height) {
    viewport.update(width, height);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM