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

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

There is a newer version: 4.3.1
Show 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 getWidth() {
		return viewportWidth;
	}
	
	public float getHeight() {
		return viewportHeight;
	}
	
	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.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;
	}

	/**
	 * 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