com.android.ringfly.common.CameraHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.android.ringfly.common.CameraHelper.java

Source

/*
 * Copyright 2011 Rod Hyde (rod@badlydrawngames.com)
 * 
 * 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.android.ringfly.common;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Vector2;

public final class CameraHelper {

    private CameraHelper() {
    }

    /** Creates an orthographic camera where the "play area" has the given viewport size. The viewport will either be stretched to
     * fill the entire window, or it will be scaled to maintain the aspect ratio.
     * 
     * @param isStretched true if the "play area" is stretched to fill the entire window.
     * @param virtualWidth the width of the game screen in virtual pixels.
     * @param virtualHeight the height of the game screen in virtual pixels.
     * @return the new camera. */
    public static OrthographicCamera createCamera(boolean isStretched, float virtualWidth, float virtualHeight) {
        // Get the viewport size.
        Vector2 viewportSize = viewportSize(isStretched, virtualWidth, virtualHeight);
        float viewportWidth = viewportSize.x;
        float viewportHeight = viewportSize.y;

        // Create the camera, placing the origin at the bottom left of the viewport.
        OrthographicCamera camera = new OrthographicCamera(viewportWidth, viewportHeight);
        float xOrg = (viewportWidth - virtualWidth) / 2;
        float yOrg = (viewportHeight - virtualHeight) / 2;
        camera.position.set(viewportWidth / 2 - xOrg, viewportHeight / 2 - yOrg, 0);
        camera.update();
        return camera;
    }

    /** Calculates the dimensions of the viewport required to support the given virtual coordinates.
     * 
     * @param isStretched true if the viewport should be stretched to fill the entire window.
     * @param virtualWidth the width of the viewport in virtual units.
     * @param virtualHeight the height of the viewport in virtual units.
     * @return the viewport's dimensions. */
    public static Vector2 viewportSize(boolean isStretched, float virtualWidth, float virtualHeight) {
        float viewportWidth;
        float viewportHeight;
        if (isStretched) {
            // Stretch the camera to fill the entire screen.
            viewportWidth = virtualWidth;
            viewportHeight = virtualHeight;
        } else {
            // Maintain the aspect ratio by letterboxing.
            float aspect = virtualWidth / virtualHeight;
            float physicalWidth = Gdx.graphics.getWidth();
            float physicalHeight = Gdx.graphics.getHeight();
            if (physicalWidth / physicalHeight >= aspect) {
                // Letterbox left and right.
                viewportHeight = virtualHeight;
                viewportWidth = viewportHeight * physicalWidth / physicalHeight;
            } else {
                // Letterbox above and below.
                viewportWidth = virtualWidth;
                viewportHeight = viewportWidth * physicalHeight / physicalWidth;
            }
        }
        return new Vector2(viewportWidth, viewportHeight);
    }

    public static enum ViewportMode {
        PIXEL_PERFECT, STRETCH_TO_ASPECT, STRETCH_TO_SCREEN
    }

    public static OrthographicCamera createCamera2(ViewportMode viewportMode, float virtualWidth,
            float virtualHeight, float density) {
        // Get the viewport size.
        Vector2 viewportSize = sizeToDensity(viewportMode, virtualWidth, virtualHeight, density);
        float viewportWidth = viewportSize.x;
        float viewportHeight = viewportSize.y;

        // Create the camera, placing the origin at the bottom left of the viewport.
        OrthographicCamera camera = new OrthographicCamera(viewportWidth, viewportHeight);
        float xOrg = (viewportWidth - virtualWidth) / 2;
        float yOrg = (viewportHeight - virtualHeight) / 2;
        camera.position.set(viewportWidth / 2 - xOrg, viewportHeight / 2 - yOrg, 0);
        camera.update();
        return camera;
    }

    public static Vector2 sizeToDensity(ViewportMode viewportMode, float virtualWidth, float virtualHeight,
            float density) {
        float viewportWidth = virtualWidth;
        float viewportHeight = virtualHeight;
        float physicalWidth = Gdx.graphics.getWidth();
        float physicalHeight = Gdx.graphics.getHeight();
        if (viewportMode == ViewportMode.PIXEL_PERFECT) {
            float widthAtDensity = viewportWidth * density;
            float heightAtDensity = viewportHeight * density;
            viewportWidth *= (physicalWidth / widthAtDensity);
            viewportHeight *= (physicalHeight / heightAtDensity);
        } else if (viewportMode == ViewportMode.STRETCH_TO_ASPECT) {
            float aspect = virtualWidth / virtualHeight;
            if (physicalWidth / physicalHeight >= aspect) {
                // Letterbox left and right.
                viewportHeight = virtualHeight;
                viewportWidth = viewportHeight * physicalWidth / physicalHeight;
            } else {
                // Letterbox above and below.
                viewportWidth = virtualWidth;
                viewportHeight = viewportWidth * physicalHeight / physicalWidth;
            }
        }
        return new Vector2(viewportWidth, viewportHeight);
    }

    public static float bestDensity(float virtualWidth, float virtualHeight, float[] densities) {
        // TODO: Spell out that densities is assumed to be in ascending order.
        float bestDensity = densities[0];
        float physicalWidth = Gdx.graphics.getWidth();
        float physicalHeight = Gdx.graphics.getHeight();
        for (int i = 1; i < densities.length; i++) {
            float density = densities[i];
            float widthAtDensity = density * virtualWidth;
            float heightAtDensity = density * virtualHeight;
            if (widthAtDensity > physicalWidth || heightAtDensity > physicalHeight) {
                break;
            }
            bestDensity = density;
        }
        return bestDensity;
    }
}