com.bladecoder.engine.model.SceneCamera 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.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);
}
}
}