程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Libgdx之Viewport 屏幕適配

Libgdx之Viewport 屏幕適配

編輯:JAVA綜合教程

Libgdx之Viewport 屏幕適配


在游戲開發的時候我們一般會設置一個世界的大小,這個大小是固定的,游戲的位置也是固定的。但是Android的各種分辨率,為了使游戲元素在不同的分辨率顯示在相同比例的位置上,我們需要為游戲做適配。不過好在Libgdx給我定義了Viewport。

Viewport的種類

這裡寫圖片描述

Viewport解釋

ScreenViewport:沒有確定的世界尺寸,世界尺寸是由屏幕尺寸來確定的。
 

/* Creates a new viewport using a new {@link OrthographicCamera}. / 
public ScreenViewport () { 
this(new OrthographicCamera()); 
} 
public ScreenViewport (Camera camera) { 
setCamera(camera); 
} 
@Override 
public void update (int screenWidth, int screenHeight, boolean centerCamera) { 
setScreenBounds(0, 0, screenWidth, screenHeight); 
setWorldSize(screenWidth * unitsPerPixel, screenHeight * unitsPerPixel); 
apply(centerCamera); 
} 

從上面可以看出初始化ScreenViewport的時候並沒有指定世界大小,當調用update時才會根據屏幕來計算。默認屏幕上一個像素對應一個世界尺寸單位,這個比例可以調用setUnitsPerPixel (float unitsPerPixel)修改。這種形式下不會縮放,各個游戲元素按其尺寸(size)繪畫,不會有黑框,屏幕尺寸越大,暴露的視野范圍越大。換句話說屏幕尺寸小,那麼有些游戲元素就不會顯示,一般是游戲上部元素不顯示

ExtendViewport: 先采取Scaling.fit再向右或者向上擴展屏幕尺寸。

update (int screenWidth, int screenHeight, boolean centerCamera)

但是如果采用了maxWorldWidth則可能會出現黑屏
3. FitViewport: 保持高寬比例不變,按比例縮放世界直到有一個方向(上下或者左右)到達屏幕尺寸,世界居於屏幕中央,上下或者左右會留有黑框
4. FillViewport: 保持高寬比例不變,按比例縮放直到不留黑框,可能世界尺寸會超出屏幕尺寸,即有些有些元素在屏幕之外

StretchViewport:不保持高寬比例,將世界尺寸縮放到屏幕尺寸,但是有時候游戲元素會變形

 

如果是做游戲開發一般使用StretchViewport視圖,懶人辦法
測試代碼:

    private static final float MIN_SCENE_WIDTH = 800.0f;
    private static final float MIN_SCENE_HEIGHT = 600.0f;
    private static final float MAX_SCENE_WIDTH = 1280.0f;
    private static final float MAX_SCENE_HEIGHT = 800.0f;

    Texture bg, sprite;
    SpriteBatch batch;
    Camera camera;
    BitmapFont font;

    private ArrayMap viewports; // 使用ViewPort相機已經在屏幕中央了
    private int currentViewport;
    private InputListenEvent inputListenEvent;

    @Override
    public void create() {
        bg = new Texture(Gdx.files.internal("background.jpg"));
        sprite = new Texture(Gdx.files.internal("badlogic.jpg"));
        batch = new SpriteBatch();
        camera = new OrthographicCamera();
        font = new BitmapFont();
        font.getData().setScale(2.0f);
        font.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);

        createViewports();
        selectNextViewport();

        inputListenEvent = new InputListenEvent(); // 初始化監聽事件
        Gdx.input.setInputProcessor(inputListenEvent); // Libgdx開始監聽inputListenEvent
    }

    @Override
    public void resize(int width, int height) {
        viewports.getValueAt(currentViewport).update(width, height, true); // centerCamera=true將camera設置在world的中央

        getTextLog("resize");
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0.39f, 0.58f, 0.92f, 1.0f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        batch.draw(bg, 0, 0, viewports.getValueAt(currentViewport)
                .getWorldWidth(), viewports.getValueAt(currentViewport)
                .getWorldHeight());
        batch.draw(sprite, 0, 0);
        font.draw(batch, viewports.getKeyAt(currentViewport), 10, 400);
        batch.end();
    }

    @Override
    public void dispose() {
        bg.dispose();
        sprite.dispose();
        batch.dispose();
        font.dispose();
    }

    private void createViewports() {
        viewports = new ArrayMap();
        viewports.put("StretchViewport", new StretchViewport(MIN_SCENE_WIDTH, MIN_SCENE_HEIGHT, camera));
//      上面初始化和下面效果一致
//      viewports.put("StretchViewport", new ScalingViewport(Scaling.stretch, MIN_SCENE_WIDTH, MIN_SCENE_HEIGHT, camera));
        viewports.put("FitViewport", new FitViewport(MIN_SCENE_WIDTH,MIN_SCENE_HEIGHT, camera));
//      上面初始化和下面效果一致
//      viewports.put("FitViewport", new ScalingViewport(Scaling.fit, MIN_SCENE_WIDTH,MIN_SCENE_HEIGHT, camera));
        viewports.put("FillViewport", new FillViewport(MIN_SCENE_WIDTH, MIN_SCENE_HEIGHT, camera));
//      上面初始化和下面效果一致
//      viewports.put("FillViewport", new ScalingViewport(Scaling.fill, MIN_SCENE_WIDTH, MIN_SCENE_HEIGHT, camera));
        viewports.put("ScreenViewport", new ScreenViewport(camera));
        viewports.put("ExtendViewport (no max)", new ExtendViewport(MIN_SCENE_WIDTH, MIN_SCENE_HEIGHT, camera));
        viewports.put("ExtendViewport (max)", new ExtendViewport(MIN_SCENE_WIDTH, MIN_SCENE_HEIGHT, MAX_SCENE_HEIGHT,
                MAX_SCENE_WIDTH, camera));

        currentViewport = -1;
    }

    private void selectNextViewport() {
        currentViewport = (currentViewport + 1) % viewports.size;
        viewports.getValueAt(currentViewport).apply(true);  // 將camera至於屏幕中央

        viewports.getValueAt(currentViewport).update(Gdx.graphics.getWidth(),
                Gdx.graphics.getHeight(), true);  // centerCamera=true將camera設置在world的中央

        getTextLog("selectNextViewport");
    }

    private void getTextLog(String flag) {
        Gdx.app.log(flag, "selcected " + viewports.getKeyAt(currentViewport));

        Gdx.app.log(flag, "screentWidth= " + viewports.getValueAt(currentViewport).getScreenWidth() +
                "  screentHeight= " + viewports.getValueAt(currentViewport).getScreenHeight());

        Gdx.app.log(flag, "wordWidth= " + viewports.getValueAt(currentViewport).getWorldWidth() +
                "  wordHeight= " + viewports.getValueAt(currentViewport).getWorldHeight());

        Gdx.app.log(flag, "camera.x=" + camera.position.x + " camera.y="
                + camera.position.y);

        Gdx.app.log(flag, "screen x="+ viewports.getValueAt(currentViewport).getScreenX() + " y="+ viewports.getValueAt(currentViewport).getScreenY());

    }

    class InputListenEvent extends InputAdapter {
        // 可以參考上一節將的內容
        // 點擊屏幕自動切換Viewport
        @Override
        public boolean touchDown(int screenX, int screenY, int pointer, int button) {
            selectNextViewport();
            return false;
        }

    }

測試效果圖:其實這張圖並不能看出具體效果,只是讓大家知道我用了怎樣的圖片來測試
這裡寫圖片描述

   

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved