/******************************************************************************* * Copyright 2011 See AUTHORS file. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.badlogic.gdx.utils.viewport; import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Scaling; /** A viewport that keeps the world aspect ratio by extending the world in one direction. The world is first scaled to fit within * the viewport, then the shorter dimension is lengthened to fill the viewport. A maximum size can be specified to limit how much * the world is extended and black bars (letterboxing) are used for any remaining space. * @author Nathan Sweet */ public class ExtendViewport extends Viewport { private float minWorldWidth, minWorldHeight; private float maxWorldWidth, maxWorldHeight; /** Creates a new viewport using a new {@link OrthographicCamera} with no maximum world size. */ public ExtendViewport (float minWorldWidth, float minWorldHeight) { this(minWorldWidth, minWorldHeight, 0, 0, new OrthographicCamera()); } /** Creates a new viewport with no maximum world size. */ public ExtendViewport (float minWorldWidth, float minWorldHeight, Camera camera) { this(minWorldWidth, minWorldHeight, 0, 0, camera); } /** Creates a new viewport using a new {@link OrthographicCamera} and a maximum world size. * @see ExtendViewport#ExtendViewport(float, float, float, float, Camera) */ public ExtendViewport (float minWorldWidth, float minWorldHeight, float maxWorldWidth, float maxWorldHeight) { this(minWorldWidth, minWorldHeight, maxWorldWidth, maxWorldHeight, new OrthographicCamera()); } /** Creates a new viewport with a maximum world size. * @param maxWorldWidth User 0 for no maximum width. * @param maxWorldHeight User 0 for no maximum height. */ public ExtendViewport (float minWorldWidth, float minWorldHeight, float maxWorldWidth, float maxWorldHeight, Camera camera) { this.minWorldWidth = minWorldWidth; this.minWorldHeight = minWorldHeight; this.maxWorldWidth = maxWorldWidth; this.maxWorldHeight = maxWorldHeight; setCamera(camera); } @Override public void update (int screenWidth, int screenHeight, boolean centerCamera) { // Fit min size to the screen. float worldWidth = minWorldWidth; float worldHeight = minWorldHeight; Vector2 scaled = Scaling.fit.apply(worldWidth, worldHeight, screenWidth, screenHeight); // Extend in the short direction. int viewportWidth = Math.round(scaled.x); int viewportHeight = Math.round(scaled.y); if (viewportWidth < screenWidth) { float toViewportSpace = viewportHeight / worldHeight; float toWorldSpace = worldHeight / viewportHeight; float lengthen = (screenWidth - viewportWidth) * toWorldSpace; if (maxWorldWidth > 0) lengthen = Math.min(lengthen, maxWorldWidth - minWorldWidth); worldWidth += lengthen; viewportWidth += Math.round(lengthen * toViewportSpace); } else if (viewportHeight < screenHeight) { float toViewportSpace = viewportWidth / worldWidth; float toWorldSpace = worldWidth / viewportWidth; float lengthen = (screenHeight - viewportHeight) * toWorldSpace; if (maxWorldHeight > 0) lengthen = Math.min(lengthen, maxWorldHeight - minWorldHeight); worldHeight += lengthen; viewportHeight += Math.round(lengthen * toViewportSpace); } setWorldSize(worldWidth, worldHeight); // Center. setScreenBounds((screenWidth - viewportWidth) / 2, (screenHeight - viewportHeight) / 2, viewportWidth, viewportHeight); apply(centerCamera); } public float getMinWorldWidth () { return minWorldWidth; } public void setMinWorldWidth (float minWorldWidth) { this.minWorldWidth = minWorldWidth; } public float getMinWorldHeight () { return minWorldHeight; } public void setMinWorldHeight (float minWorldHeight) { this.minWorldHeight = minWorldHeight; } public float getMaxWorldWidth () { return maxWorldWidth; } public void setMaxWorldWidth (float maxWorldWidth) { this.maxWorldWidth = maxWorldWidth; } public float getMaxWorldHeight () { return maxWorldHeight; } public void setMaxWorldHeight (float maxWorldHeight) { this.maxWorldHeight = maxWorldHeight; } }