gdx-studio

#libgdx#java#desktop

git clone https://git.pyrossh.dev/gdx-studio

An IDE for creating Games using libgdx and Java supported on all platforms Android, iOS, Desktop


src/scene2d/Camera.java
a9b2a64 1
package scene2d;
a9b2a64 2
import com.badlogic.gdx.Gdx;
a9b2a64 3
import com.badlogic.gdx.graphics.OrthographicCamera;
a9b2a64 4
import com.badlogic.gdx.math.Interpolation;
a9b2a64 5
import com.badlogic.gdx.math.Vector3;
a9b2a64 6
import com.badlogic.gdx.scenes.scene2d.Actor;
a9b2a64 7
import com.badlogic.gdx.utils.Array;
a9b2a64 8
import com.badlogic.gdx.math.Rectangle;
a9b2a64 9
a9b2a64 10
public class Camera extends OrthographicCamera {
a9b2a64 11
	private static Camera instance;
a9b2a64 12
	private static float duration;
a9b2a64 13
	private static float time;
a9b2a64 14
	private static Interpolation interpolation;
a9b2a64 15
	private static boolean moveCompleted;
a9b2a64 16
	private static float lastPercent;
a9b2a64 17
	private static float percentDelta;
a9b2a64 18
	private static float panSpeedX, panSpeedY;
a9b2a64 19
	private static final Array<Actor> hudActors = new Array<Actor>();
a9b2a64 20
	
a9b2a64 21
	
a9b2a64 22
	private static Actor followedActor = null;
a9b2a64 23
	private static float followSpeed = 1f;
a9b2a64 24
	/*
a9b2a64 25
	 *  This is to set the offsets of camera position when following the actor
a9b2a64 26
	 *  When the camera follows the actor its (x,y) position is set to actor's (x,y) position
a9b2a64 27
	 *  based on followSpeed. The offsets are used to position the camera in such a way that the actor
a9b2a64 28
	 *  doesn't need to be at the center of the camera always
a9b2a64 29
	 */
a9b2a64 30
	public static Rectangle followOffset = new Rectangle(10,70,10,60);
a9b2a64 31
	private static boolean followContinous = false;
a9b2a64 32
a9b2a64 33
	
a9b2a64 34
	public static boolean usePan = false;
a9b2a64 35
    public static boolean useDrag = false;
a9b2a64 36
	/*
a9b2a64 37
	 * Sets the speed at which the camera pans. By default it moves 1px for a duration a 1f
a9b2a64 38
	 * so its speed is 1px/f. So reduce the duration to increase its speed.
a9b2a64 39
	 * ex: setPanSpeed(0.5) will change its speed to 2px/f
a9b2a64 40
	 * Here: f can/maybe also indicate seconds 
a9b2a64 41
	 */
a9b2a64 42
	public static float panSpeed = 5f;
a9b2a64 43
	public static Rectangle panSize;
a9b2a64 44
	
a9b2a64 45
	/*
a9b2a64 46
	 *  This sets the boundary of the camera till what position can it move or pan in the
a9b2a64 47
	 *  directions left, right, top, down. This is to prevent is from panning overboard the game area.
a9b2a64 48
	 *  Usually the bounds of the camera is like a rectangle. This must be calculated carefully
a9b2a64 49
	 *  as the camera's position is based on its center.
a9b2a64 50
	*/
a9b2a64 51
	public static Rectangle bounds = new Rectangle(0,0,999,999);
a9b2a64 52
a9b2a64 53
a9b2a64 54
	Camera(){
a9b2a64 55
		setToOrtho(false, Scene.targetWidth, Scene.targetHeight);
a9b2a64 56
		position.set(Scene.targetWidth/2, Scene.targetHeight/2, 0);
a9b2a64 57
		instance = this;
a9b2a64 58
		panSize = new Rectangle(10, 10, Scene.targetWidth-10, Scene.targetHeight - 10);
a9b2a64 59
	}
a9b2a64 60
a9b2a64 61
	/*
a9b2a64 62
	 * Moves the camera to x,y over a time duration
a9b2a64 63
	 */
a9b2a64 64
	public void moveTo(float x, float y, float duration) {
a9b2a64 65
		moveBy(x-position.x, y-position.y, duration);
a9b2a64 66
	}
a9b2a64 67
a9b2a64 68
	/*
a9b2a64 69
	 * Moves the camera by amountX, amountY over a time duration
a9b2a64 70
	 */
a9b2a64 71
	public static void moveBy (float amountX, float amountY, float duration) {
a9b2a64 72
		moveBy(amountX, amountY, duration, null);
a9b2a64 73
	}
a9b2a64 74
a9b2a64 75
	/*
a9b2a64 76
	 * Moves the camera by amountX, amountY over a time duration and interpolation interp
a9b2a64 77
	 */
a9b2a64 78
	public static void moveBy (float amountX, float amountY, float dur, Interpolation interp) {
a9b2a64 79
		duration = dur;
a9b2a64 80
		interpolation = interp;
a9b2a64 81
		panSpeedX = amountX;
a9b2a64 82
		panSpeedY = amountY;
a9b2a64 83
		lastPercent = 0;
a9b2a64 84
		time = 0;
a9b2a64 85
		moveCompleted = false;
a9b2a64 86
	}
a9b2a64 87
a9b2a64 88
	private static Rectangle cullRect = new Rectangle();
a9b2a64 89
	private void moveByAction(float delta){
a9b2a64 90
		time += delta;
a9b2a64 91
		moveCompleted = time >= duration;
a9b2a64 92
		float percent;
a9b2a64 93
		if (moveCompleted)
a9b2a64 94
			percent = 1;
a9b2a64 95
		else {
a9b2a64 96
			percent = time / duration;
a9b2a64 97
			if (interpolation != null) percent = interpolation.apply(percent);
a9b2a64 98
		}
a9b2a64 99
		percentDelta = percent - lastPercent;
a9b2a64 100
		if(Scene.cullingEnabled){
a9b2a64 101
			cullRect.set(getXLeft(), getYBot(), Scene.targetWidth, Scene.targetHeight);
a9b2a64 102
			Scene.getCurrentScene().setCullingArea(cullRect);
a9b2a64 103
		}
a9b2a64 104
		translate(panSpeedX * percentDelta, panSpeedY * percentDelta, 0);
a9b2a64 105
		for(Actor actor: hudActors) 
a9b2a64 106
			actor.setPosition(actor.getX()+panSpeedX * percentDelta, actor.getY()+panSpeedY * percentDelta);
a9b2a64 107
		lastPercent = percent;
a9b2a64 108
		if (moveCompleted) interpolation = null;
a9b2a64 109
	}
a9b2a64 110
a9b2a64 111
	public void resetCamera(){
a9b2a64 112
		position.set(Scene.targetWidth/2, Scene.targetHeight/2, 0);
a9b2a64 113
	}
a9b2a64 114
a9b2a64 115
	/*
a9b2a64 116
	 * This makes the camera follow the actor once and only once. Once the camera reaches its
a9b2a64 117
	 * target, it stops following the actor.
a9b2a64 118
	 */
a9b2a64 119
	public static void followActor(Actor actor){
a9b2a64 120
		followedActor = actor;
a9b2a64 121
		followContinous = false;
a9b2a64 122
	}
a9b2a64 123
a9b2a64 124
	/*
a9b2a64 125
	 * This makes the camera follow the actor continuously, even after the camera reaches its
a9b2a64 126
	 * target, it keeps following the if the actor changes its position.
a9b2a64 127
	 */
a9b2a64 128
	public static void followActorContinuously(Actor actor){
a9b2a64 129
		followedActor = actor;
a9b2a64 130
		followContinous = true;
a9b2a64 131
	}
a9b2a64 132
a9b2a64 133
a9b2a64 134
a9b2a64 135
	/*
a9b2a64 136
	 * Sets the speed at which the camera follows the actor. By default it moves 1px for a duration of 1f
a9b2a64 137
	 * so its speed is 1px/f. So reduce the duration to increase its speed.
a9b2a64 138
	 * ex: setPanSpeed(0.5) will change its speed to 2px/f
a9b2a64 139
	 * Here: f can/maybe also indicate seconds
a9b2a64 140
	 */
a9b2a64 141
	public static void setFollowSpeed(float duration){
a9b2a64 142
		followSpeed = duration;
a9b2a64 143
	}
a9b2a64 144
a9b2a64 145
	private void follow(){
a9b2a64 146
		//if(camera.position.x == followedActor.getX()+followLeftOffset &&
a9b2a64 147
		//	camera.position.y == followedActor.getY()+followTopOffset)
a9b2a64 148
		//return;
a9b2a64 149
		//moveTo(followedActor.getX()+followLeftOffset, followedActor.getY()+followTopOffset, 100f);
a9b2a64 150
		if(position.x < followedActor.getX() - followOffset.x) moveBy(1f, 0, followSpeed);
a9b2a64 151
		else if(position.x > followedActor.getX() + followOffset.width) moveBy(-1f, 0, followSpeed);
a9b2a64 152
		else if(position.y < followedActor.getY() - followOffset.y) moveBy(0, 1f, followSpeed);
a9b2a64 153
		else if(position.y > followedActor.getY() - followOffset.height) moveBy(0, -1f, followSpeed);
a9b2a64 154
		else {
a9b2a64 155
			if(!followContinous)
a9b2a64 156
				followedActor = null;
a9b2a64 157
		}
a9b2a64 158
	}
a9b2a64 159
a9b2a64 160
	@Override
a9b2a64 161
	public void update(){
a9b2a64 162
		super.update();
a9b2a64 163
		Scene.mouse.x = Gdx.input.getX();
a9b2a64 164
		Scene.mouse.y = Gdx.graphics.getHeight() - Gdx.input.getY();
a9b2a64 165
		if(!moveCompleted)
a9b2a64 166
			moveByAction(Scene.stateTime);//FIXME
a9b2a64 167
		if(usePan) 
a9b2a64 168
			panCameraWithMouse();
a9b2a64 169
		if(followedActor != null)
a9b2a64 170
			follow();
a9b2a64 171
	}
a9b2a64 172
a9b2a64 173
	private void panCameraWithMouse(){
a9b2a64 174
		 if(Scene.mouse.x > panSize.width && getXLeft() < bounds.width) moveBy(1f, 0, panSpeed);
a9b2a64 175
		 else if(Scene.mouse.x < panSize.x  && getXLeft() > bounds.x)  moveBy(-1f, 0, panSpeed);
a9b2a64 176
		 else if(Scene.mouse.y < panSize.y && getYBot() > bounds.y) moveBy(0, -1f, panSpeed);
a9b2a64 177
		 else if(Scene.mouse.y > panSize.height && getYBot() < bounds.height) moveBy(0, 1f, panSpeed);
a9b2a64 178
	}
a9b2a64 179
	
a9b2a64 180
	private final static Vector3 curr = new Vector3();
a9b2a64 181
	private final static Vector3 last = new Vector3(-1, -1, -1);
a9b2a64 182
	private final static Vector3 deltaDrag = new Vector3();
a9b2a64 183
	private static float deltaCamX = 0;
a9b2a64 184
	private static float deltaCamY = 0;
a9b2a64 185
	public static void dragCam(int x, int y){
a9b2a64 186
		instance.unproject(curr.set(x, y, 0));
a9b2a64 187
    	if (!(last.x == -1 && last.y == -1 && last.z == -1)) {
a9b2a64 188
    		instance.unproject(deltaDrag.set(last.x, last.y, 0));
a9b2a64 189
    		deltaDrag.sub(curr);
a9b2a64 190
    		deltaCamX = deltaDrag.x + instance.position.x;
a9b2a64 191
    		deltaCamY = deltaDrag.y + instance.position.y;
a9b2a64 192
    		if(deltaCamX > bounds.x && deltaCamX < bounds.x+bounds.width)
a9b2a64 193
    			moveBy(deltaDrag.x, 0f, 0f);
a9b2a64 194
    		if(deltaCamY > bounds.y && deltaCamY < bounds.y+bounds.height)
a9b2a64 195
    			moveBy(0f, deltaDrag.y, 0f);		
a9b2a64 196
    	}
a9b2a64 197
    	last.set(x, y, 0);
a9b2a64 198
    }
a9b2a64 199
	
a9b2a64 200
	public static void resetDrag(){
a9b2a64 201
		last.set(-1, -1, -1);
a9b2a64 202
	}
a9b2a64 203
	
a9b2a64 204
	public static void reset(){
a9b2a64 205
		usePan = false;
a9b2a64 206
		followActor(null);
a9b2a64 207
		clearAllHud();
a9b2a64 208
		instance.position.set(Scene.targetWidth/2, Scene.targetHeight/2, 0);
a9b2a64 209
	}
a9b2a64 210
a9b2a64 211
	/* If you want to make any elements/actors to move along with the camera 
a9b2a64 212
	 * like HUD's add them using this method */
a9b2a64 213
	public static void addHud(Actor actor){
a9b2a64 214
		if(actor != null){
a9b2a64 215
			Scene.getCurrentScene().addActor(actor);
a9b2a64 216
			hudActors.add(actor);
a9b2a64 217
		}
a9b2a64 218
	}
a9b2a64 219
	
a9b2a64 220
	/* If you want to make any elements/actors to move along with the camera 
a9b2a64 221
	 * like HUD's add them using this method */
a9b2a64 222
	public static void addHud(String actorName){
a9b2a64 223
		if(actorName != null && !actorName.isEmpty()){
a9b2a64 224
			Actor actor = Scene.getCurrentScene().findActor(actorName);
a9b2a64 225
			Scene.getCurrentScene().addActor(actor);
a9b2a64 226
			hudActors.add(actor);
a9b2a64 227
		}
a9b2a64 228
	}
a9b2a64 229
a9b2a64 230
a9b2a64 231
	/* If you want to any elements/actors which was a Hud the use this */
a9b2a64 232
	public static void removeHud(Actor actor){
a9b2a64 233
		Scene.getCurrentScene().removeActor(actor);
a9b2a64 234
		hudActors.removeValue(actor, true);
a9b2a64 235
	}
a9b2a64 236
	
a9b2a64 237
	/* If you want to any elements/actors which was a Hud the use this */
a9b2a64 238
	public static void removeHud(String actorName){
a9b2a64 239
		if(actorName != null && !actorName.isEmpty()){
a9b2a64 240
			Actor actor = Scene.getCurrentScene().findActor(actorName);
a9b2a64 241
			Scene.getCurrentScene().removeActor(actor);
a9b2a64 242
			hudActors.removeValue(actor, true);
a9b2a64 243
		}
a9b2a64 244
	}
a9b2a64 245
	
a9b2a64 246
	
a9b2a64 247
a9b2a64 248
	/*
a9b2a64 249
	 * Clears all hud's registered with the camera
a9b2a64 250
	 */
a9b2a64 251
	public static void clearAllHud(){
a9b2a64 252
		hudActors.clear();
a9b2a64 253
	}
a9b2a64 254
	
a9b2a64 255
	/*
a9b2a64 256
	 * Returns the x position of the camera
a9b2a64 257
	 */
a9b2a64 258
	public static float getX(){
a9b2a64 259
		return instance.position.x;
a9b2a64 260
	}
a9b2a64 261
	
a9b2a64 262
	/*
a9b2a64 263
	 * Returns the y position of the camera
a9b2a64 264
	 */
a9b2a64 265
	public static float getY(){
a9b2a64 266
		return instance.position.y;
a9b2a64 267
	}
a9b2a64 268
	
a9b2a64 269
	public static float getXLeft(){
a9b2a64 270
		return instance.position.x - Scene.targetWidth/2;
a9b2a64 271
	}
a9b2a64 272
	
a9b2a64 273
	public static float getYBot(){
a9b2a64 274
		return instance.position.y - Scene.targetHeight/2;
a9b2a64 275
	}
a9b2a64 276
	
a9b2a64 277
	public static float getWidth(){
a9b2a64 278
		return instance.viewportWidth;
a9b2a64 279
	}
a9b2a64 280
	
a9b2a64 281
	public static float getHeight(){
a9b2a64 282
		return instance.viewportHeight;
a9b2a64 283
	}
a9b2a64 284
}