Java libgdx 1.20版本纹理bug

问题描述 投票:0回答:3

在我的游戏中,我一直在努力修复与fickering和distored纹理相关的bug。我在互联网上搜索,我尝试了一些像使用scene2d的解决方案,但它没有用。我该怎么办 ?

此屏幕截图显示了问题:当角色移动时,一只眼睛有时比另一只眼睛大:

编辑:

当我使用sprite.setPosition((int)sprite.getX(),(int)sprite.getY())时,我仍然遇到问题widthdistored eye;每次我渲染我的角色之前。

当我从答案中使用自定义视口时,我在游戏窗口中看不到我做错了什么?

package com.mygdx.redHoodie;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.viewport.StretchViewport;

public class GameScreen implements Screen {
    public static final int GAME_WIDTH = 800;
    public static final int GAME_HEIGHT= 480 ;

    SpriteBatch batch;
    Background background;
    public Hoodie hoodie;

    public PixelMultipleViewport viewport;
       OrthographicCamera camera;
    public int gameMode; // 0 normalna gra, 1 level up, 2 end game

    public GameScreen(){
         camera= new OrthographicCamera(GAME_WIDTH,GAME_HEIGHT);


         viewport = new PixelMultipleViewport(GAME_WIDTH, GAME_HEIGHT, camera);
         viewport.update();
         camera.setToOrtho(false, GAME_WIDTH, GAME_HEIGHT);
        batch = new SpriteBatch();

        //klasy wyswietlane
        background= new Background(this);
        hoodie = new Hoodie(this);

        startNewGame();
    }

    @Override
    public void render(float delta) {
        // TODO Auto-generated method stu

         Gdx.gl.glClearColor(1, 1, 0, 1);

         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
         batch.setProjectionMatrix(camera.projection);
            batch.setTransformMatrix(camera.view);

         camera.update();
         //batch.setProjectionMatrix(camera.combined);
         this.update(delta);
         this.batch.begin();
            toRender(delta);
         this.batch.end();



    }

    public void update(float delta){
        hoodie.update(delta);
    }

    public void toRender(float delta){
        background.render();
        hoodie.render();

    }

    public void startNewGame(){

    }
    public void startNevLevel(){

    }

    @Override
    public void resize(int width, int height) {
        // TODO Auto-generated method stub
        viewport.update(width, height,false);
    }

    @Override
    public void show() {
        // TODO Auto-generated method stub

    }

    @Override
    public void hide() {
        // TODO Auto-generated method stub

    }

    @Override
    public void pause() {
        // TODO Auto-generated method stub

    }

    @Override
    public void resume() {
        // TODO Auto-generated method stub

    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub

    }

}
libgdx textures
3个回答
2
投票

加载纹理时,请使用线性过滤和mip-mapping。默认过滤器是最近/最近,这将导致您看到的问题。

Texture myTexture = new Texture("textureFilename", true); //must enable mip-mapping in constructor
myTexture.setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Linear);

编辑:

我现在意识到,你看截图,你在一个更大的窗口中做像素化图形。为了做到这一点,是的,你需要保持最近/最近的过滤,而不是我建议的。

为避免某些像素的大小不同,您必须将角色移动和相机移动四舍五入到最近的世界单位。当角色位于像素之间时,精灵像素的大小会有所不同,因为它们不与屏幕像素对齐。

你缩放了世界,所以一个单位等于你的一个大像素。因此,无论何时绘制任何东西,都需要先将其位置四舍五入到x和y中最接近的整数,以及相机位置。所以移动相机或精灵后,你必须做这样的事情:

sprite.position.set((int)sprite.position.x,(int)sprite.position.y,sprite.position.z);

就你的视口而言,如果你不想要任何黑条,你可能需要一个自定义的视口类,试图尽可能地匹配你想要的分辨率,然后向外扩展它以避免失真。 ExtendViewport做了类似的事情,但与像素化图形的不同之处在于,您需要将世界分辨率设置为屏幕分辨率的整数倍,这样像素的边缘看起来就像是清晰而不是模糊。

我想这会做你想要的。它采用您所需的屏幕分辨率并将其缩小到适合屏幕像素中每个像素大小为整数的位置。然后它将视图扩展到所需的分辨率以避免失真和黑条。这个类假设所有屏幕尺寸总是4的倍数。我认为这是真的。如果你想获得花哨,你可以使用OpenGL剪裁将视口大小向下舍入到最接近的4的倍数,这是安全的。最多你会有2个像素的黑条,我认为这不会引人注意。

public class PixelMultipleViewport extends Viewport {

    private int minWorldWidth, minWorldHeight;

    public PixelMultipleViewport (int minWorldWidth, int minWorldHeight, Camera camera) {
        this.minWorldHeight = minWorldHeight;
        this.minWorldWidth = minWorldWidth;
        this.camera = camera;
    }

    @Override
    public void update (int screenWidth, int screenHeight, boolean centerCamera) {

        viewportWidth = screenWidth;
        viewportHeight = screenHeight;

        int maxHorizontalMultiple = screenWidth / minWorldWidth;
        int maxVerticalMultiple = screenHeight / minWorldHeight;

        int pixelSize = Math.min(maxHorizontalMultiple, maxVerticalMultiple);

        worldWidth = (float)screenWidth/(float)pixelSize;
        worldHeight = (float)screenHeight/(float)pixelSize;

        super.update(screenWidth, screenHeight, centerCamera);
    }
}

0
投票

这是我遇到的另一种选择。这是一种以任何分辨率在没有黑条的情况下以您喜欢的比例绘制场景的方法。

视觉质量将比我的其他答案(您以所需场景比例的整数倍绘制)略差,但明显优于使用截图中的直接最近过滤。

基本思想是以您想要的比例将所有内容绘制到一个小的FrameBuffer,然后使用一个升级着色器将FrameBuffer的颜色纹理绘制到屏幕上(与线性过滤不同)仅沿着精灵像素的边缘插入像素颜色。

is here的解释。我没有把它移植到Libgdx或测试它。而且我不确定这个着色器在移动设备上的效果如何。它涉及每个屏幕片段运行四个相关的纹理查找。


0
投票

我知道这个话题已经过时了但是我的搜索引导了我,未来可能会有更多人关注。我有同样的像素撕裂问题,但仅限于我的iOS 9 iPhone 4S。它在我的Android 9 Pixel 2上渲染得很好。试过很多东西(特别是四舍五入到全像素)但是即使使用一个未经过校准的全屏正交相机,也会受到人工制品的影响。

强迫我的纹理是POT(2的力量)解决了问题!

© www.soinside.com 2019 - 2024. All rights reserved.