Libgdx之Viewport 螢幕適配

來源:互聯網
上載者:User

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

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

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.