/*******************************************************************************
* 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.tests;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.tests.utils.GdxTest;
import com.badlogic.gdx.tests.utils.OrthoCamController;
public class ParallaxTest extends GdxTest {
class ParallaxCamera extends OrthographicCamera {
Matrix4 parallaxView = new Matrix4();
Matrix4 parallaxCombined = new Matrix4();
Vector3 tmp = new Vector3();
Vector3 tmp2 = new Vector3();
public ParallaxCamera (float viewportWidth, float viewportHeight) {
super(viewportWidth, viewportHeight);
}
public Matrix4 calculateParallaxMatrix (float parallaxX, float parallaxY) {
update();
tmp.set(position);
tmp.x *= parallaxX;
tmp.y *= parallaxY;
parallaxView.setToLookAt(tmp, tmp2.set(tmp).add(direction), up);
parallaxCombined.set(projection);
Matrix4.mul(parallaxCombined.val, parallaxView.val);
return parallaxCombined;
}
}
TextureRegion[] layers;
ParallaxCamera camera;
OrthoCamController controller;
SpriteBatch batch;
BitmapFont font;
@Override
public void create () {
Texture texture = new Texture(Gdx.files.internal("data/layers.png"));
layers = new TextureRegion[3];
layers[0] = new TextureRegion(texture, 0, 0, 542, 363);
layers[1] = new TextureRegion(texture, 0, 363, 1024, 149);
layers[2] = new TextureRegion(texture, 547, 0, 224, 51);
camera = new ParallaxCamera(480, 320);
controller = new OrthoCamController(camera);
Gdx.input.setInputProcessor(controller);
batch = new SpriteBatch();
font = new BitmapFont(Gdx.files.internal("data/arial-15.fnt"), false);
}
@Override
public void dispose () {
layers[0].getTexture().dispose();
batch.dispose();
font.dispose();
}
@Override
public void render () {
Gdx.gl.glClearColor(242 / 255.0f, 210 / 255.0f, 111 / 255.0f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// keep camera in foreground layer bounds
boolean updateCamera = false;
if (camera.position.x < -1024 + camera.viewportWidth / 2) {
camera.position.x = -1024 + (int)(camera.viewportWidth / 2);
updateCamera = true;
}
if (camera.position.x > 1024 - camera.viewportWidth / 2) {
camera.position.x = 1024 - (int)(camera.viewportWidth / 2);
updateCamera = true;
}
if (camera.position.y < 0) {
camera.position.y = 0;
updateCamera = true;
}
// arbitrary height of scene
if (camera.position.y > 400 - camera.viewportHeight / 2) {
camera.position.y = 400 - (int)(camera.viewportHeight / 2);
updateCamera = true;
}
// background layer, no parallax, centered around origin
batch.setProjectionMatrix(camera.calculateParallaxMatrix(0, 0));
batch.disableBlending();
batch.begin();
batch.draw(layers[0], -(int)(layers[0].getRegionWidth() / 2), -(int)(layers[0].getRegionHeight() / 2));
batch.end();
batch.enableBlending();
// midground layer, 0.5 parallax (move at half speed on x, full speed on y)
// layer is 1024x320
batch.setProjectionMatrix(camera.calculateParallaxMatrix(0.5f, 1));
batch.begin();
batch.draw(layers[1], -512, -160);
batch.end();
// foreground layer, 1.0 parallax (move at full speed)
// layer is 2048x320
batch.setProjectionMatrix(camera.calculateParallaxMatrix(1f, 1));
batch.begin();
for (int i = 0; i < 9; i++) {
batch.draw(layers[2], i * layers[2].getRegionWidth() - 1024, -160);
}
batch.end();
// draw fps
batch.getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.begin();
font.draw(batch, "fps: " + Gdx.graphics.getFramesPerSecond(), 0, 30);
batch.end();
}
}