com.bladecoder.engine.ui.SceneExtendViewport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of blade-engine Show documentation
Show all versions of blade-engine Show documentation
Classic point and click adventure game engine
/*******************************************************************************
* Copyright 2014 Rafael Garcia Moreno.
*
* 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.bladecoder.engine.ui;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.HdpiUtils;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Scaling;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.bladecoder.engine.util.EngineLogger;
/**
* This is a Custom ExtendViewport:
*
* - The camera uses screen coordinates. This is used to draw fonts and UI 1:1
* - The world dimensions is used only to calculate the dimensions of the viewport
* - The dimensions of the viewport is calculated to extend the world between 4:3 and 16:9
*
* @author rgarcia
*/
public class SceneExtendViewport extends Viewport {
private float minWorldWidth, minWorldHeight;
private float maxWorldWidth, maxWorldHeight;
/** Creates a new viewport using a new {@link OrthographicCamera}. */
public SceneExtendViewport() {
setCamera(new OrthographicCamera());
}
@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);
}
super.setWorldSize(worldWidth, worldHeight);
// Center.
setScreenBounds((screenWidth - viewportWidth) / 2, (screenHeight - viewportHeight) / 2, viewportWidth, viewportHeight);
apply(centerCamera);
EngineLogger.debug("SCREEN VIEWPORT: " + getScreenWidth() + "x" + getScreenHeight());
EngineLogger.debug("SCREEN WORLD: " + getWorldWidth() + "x" + getWorldHeight());
}
@Override
public void apply(boolean centerCamera) {
HdpiUtils.glViewport(getScreenX(), getScreenY(), getScreenWidth(), getScreenHeight());
getCamera().viewportWidth = getScreenWidth();
getCamera().viewportHeight = getScreenHeight();
if (centerCamera)
getCamera().position.set(getScreenWidth() / 2, getScreenHeight() / 2, 0);
getCamera().update();
}
@Override
public void setWorldSize(float worldWidth, float worldHeight) {
super.setWorldSize(worldWidth, worldHeight);
// The minimum height aspect is 4:3, the maximum is the world aspect
minWorldWidth = Math.min(worldHeight * 4f / 3f, worldWidth);
// The minimum width aspect is 16:9, the maximum is the world aspect
minWorldHeight = Math.min(worldWidth * 9f / 16f, worldHeight);
maxWorldWidth = worldWidth;
maxWorldHeight = worldHeight;
}
@Override
public Vector2 unproject(Vector2 out) {
super.unproject(out);
out.x = MathUtils.clamp(out.x, 0, getScreenWidth() - 1);
out.y = MathUtils.clamp(out.y, 0, getScreenHeight() - 1);
return out;
}
@Override
public Vector3 unproject(Vector3 out) {
super.unproject(out);
out.x = MathUtils.clamp(out.x, 0, getScreenWidth() - 1);
out.y = MathUtils.clamp(out.y, 0, getScreenHeight() - 1);
return out;
}
}