All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bladecoder.engine.model.SceneCamera Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * 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.model;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.Json.Serializable;
import com.badlogic.gdx.utils.JsonValue;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.bladecoder.engine.actions.ActionCallback;
import com.bladecoder.engine.anim.CameraTween;
import com.bladecoder.engine.anim.Tween;
import com.bladecoder.engine.assets.EngineAssetManager;
import com.bladecoder.engine.util.InterpolationMode;

public class SceneCamera extends OrthographicCamera implements Serializable {

	private static final float START_SCROLLX = 0.1f;
	private static final float START_SCROLLY = 0.15f;

	// to avoid create new vector when calling getPosition
	private final static Vector2 tmpPos = new Vector2();

	private float startScrollDistanceX;
	private float startScrollDistanceY;

	private float scrollingWidth, scrollingHeight;

	private CameraTween cameraTween;

	private Matrix4 parallaxView = new Matrix4();
	private Matrix4 parallaxCombined = new Matrix4();
	private Vector3 tmp = new Vector3();
	private Vector3 tmp2 = new Vector3();

	public SceneCamera() {
	}

	public void create(float worldWidth, float worldHeight) {
		scrollingWidth = worldWidth;
		scrollingHeight = worldHeight;

		zoom = 1.0f;

		setToOrtho(false, worldWidth, worldHeight);
		update();

		startScrollDistanceX = worldWidth * START_SCROLLX;
		startScrollDistanceY = worldHeight * START_SCROLLY;
	}

	public float getScrollingWidth() {
		return scrollingWidth;
	}

	public float getScrollingHeight() {
		return scrollingHeight;
	}

	public void setScrollingDimensions(float w, float h) {
		scrollingWidth = Math.max(w, viewportWidth);
		scrollingHeight = Math.max(h, viewportHeight);
	}

	public void update(float delta) {
		if (cameraTween != null) {
			cameraTween.update(delta);
			if (cameraTween != null && cameraTween.isComplete()) {
				cameraTween = null;
			}
		}
	}

	public void setPosition(float x, float y) {

		float maxleft = viewportWidth / 2 * zoom;
		float maxright = (scrollingWidth - viewportWidth / 2 * zoom);

		float maxbottom = viewportHeight / 2 * zoom;
		float maxtop = (scrollingHeight - viewportHeight / 2 * zoom);

		x = MathUtils.clamp(x, maxleft, maxright);
		y = MathUtils.clamp(y, maxbottom, maxtop);

		position.set(x, y, 0);

		update();
	}

	public void setZoom(float zoom) {
		this.zoom = zoom;
		update();
	}

	public Vector2 getPosition() {
		Vector3 p = position;
		return tmpPos.set(p.x, p.y);
	}

	public float getZoom() {
		return zoom;
	}

	public void stopAnim() {
		cameraTween = null;
	}

	/**
	 * Create camera animation.
	 */
	public void startAnimation(float destX, float destY, float zoom, float duration, InterpolationMode interpolation,
			ActionCallback cb) {
		cameraTween = new CameraTween();

		cameraTween.start(this, Tween.Type.NO_REPEAT, 1, destX, destY, zoom, duration, interpolation, cb);
	}

	public void getInputUnProject(Viewport viewport, Vector3 out) {

		out.set(Gdx.input.getX(), Gdx.input.getY(), 0);

		unproject(out, viewport.getScreenX(), viewport.getScreenY(), viewport.getScreenWidth(),
				viewport.getScreenHeight());

		out.x = MathUtils.clamp(out.x, 0, scrollingWidth - 1);
		out.y = MathUtils.clamp(out.y, 0, scrollingHeight - 1);
	}

	public void updatePos(SpriteActor followActor) {
		float cx = position.x;
		float posx = followActor.getX();
		float cy = position.y;
		float posy = followActor.getY();

		boolean translate = false;

		if (cx - posx > startScrollDistanceX * zoom) {
			cx = cx - (cx - posx - startScrollDistanceX * zoom);
			translate = true;
		} else if (posx - cx > startScrollDistanceX * zoom) {
			cx = cx + (posx - cx - startScrollDistanceX * zoom);
			translate = true;
		}

		if (cy - posy + followActor.getHeight() > startScrollDistanceY * zoom) {
			cy = cy - (cy - posy - startScrollDistanceY * zoom);
			translate = true;
		} else if (posy - cy > startScrollDistanceY * zoom) {
			cy = cy + (posy - cy - startScrollDistanceY * zoom);
			translate = true;
		}

		if (translate) {
			setPosition(cx, cy);
		}
	}

	public void scene2screen(Viewport viewport, Vector3 out) {
		project(out, 0, 0, viewport.getScreenWidth(), viewport.getScreenHeight());
	}

	public Matrix4 calculateParallaxMatrix(float parallaxX, float parallaxY) {
		update();
		tmp.set(position);
//		tmp.x *= parallaxX;
		tmp.y *= parallaxY;

		tmp.x = (tmp.x - scrollingWidth / 2) * parallaxX + scrollingWidth / 2;

		parallaxView.setToLookAt(tmp, tmp2.set(tmp).add(direction), up);
		parallaxCombined.set(projection);
		Matrix4.mul(parallaxCombined.val, parallaxView.val);
		return parallaxCombined;
	}

	@Override
	public void write(Json json) {
		float worldScale = EngineAssetManager.getInstance().getScale();

		json.writeValue("width", viewportWidth / worldScale);
		json.writeValue("height", viewportHeight / worldScale);
		json.writeValue("scrollingWidth", scrollingWidth / worldScale);
		json.writeValue("scrollingHeight", scrollingHeight / worldScale);

		Vector2 p = getPosition();
		p.x = p.x / worldScale;
		p.y = p.y / worldScale;
		json.writeValue("pos", p);
		json.writeValue("zoom", getZoom());

		if (cameraTween != null)
			json.writeValue("cameraTween", cameraTween);
	}

	@Override
	public void read(Json json, JsonValue jsonData) {
		float worldScale = EngineAssetManager.getInstance().getScale();

		viewportWidth = json.readValue("width", Float.class, jsonData) * worldScale;
		viewportHeight = json.readValue("height", Float.class, jsonData) * worldScale;
		scrollingWidth = json.readValue("scrollingWidth", Float.class, jsonData) * worldScale;
		scrollingHeight = json.readValue("scrollingHeight", Float.class, jsonData) * worldScale;
		Vector2 pos = json.readValue("pos", Vector2.class, jsonData);
		pos.x *= worldScale;
		pos.y *= worldScale;
		float z = json.readValue("zoom", Float.class, jsonData);

		create(viewportWidth, viewportHeight);
		this.zoom = z;
		position.set(pos.x, pos.y, 0);
		update();

		cameraTween = json.readValue("cameraTween", CameraTween.class, jsonData);
		if (cameraTween != null) {
			cameraTween.setTarget(this);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy