Initaler Commit
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package de.blight.game.control;
|
||||
|
||||
import com.jme3.input.InputManager;
|
||||
import com.jme3.input.MouseInput;
|
||||
import com.jme3.input.controls.AnalogListener;
|
||||
import com.jme3.input.controls.MouseAxisTrigger;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.scene.Spatial;
|
||||
|
||||
/**
|
||||
* Third-Person-Kamera:
|
||||
* - Mausbewegung → Kamera um den Charakter drehen (immer, kein Klick nötig)
|
||||
* - Y-Achse invertiert → Maus hoch = Kamera runter (oldschool)
|
||||
* - Mausrad → Zoom (Abstand)
|
||||
*/
|
||||
public class ThirdPersonCamera {
|
||||
|
||||
private static final float MOUSE_SENSITIVITY = 1.8f;
|
||||
private static final float MIN_DISTANCE = 3f;
|
||||
private static final float MAX_DISTANCE = 20f;
|
||||
private static final float MIN_VERTICAL_ANGLE = -0.3f;
|
||||
private static final float MAX_VERTICAL_ANGLE = FastMath.HALF_PI - 0.1f;
|
||||
private static final float TARGET_HEIGHT = 1.6f;
|
||||
|
||||
private final Camera cam;
|
||||
private final InputManager inputManager;
|
||||
|
||||
private Spatial target;
|
||||
|
||||
private float yaw = 0f;
|
||||
private float pitch = 0.4f;
|
||||
private float distance = 10f;
|
||||
private boolean paused = false;
|
||||
|
||||
public ThirdPersonCamera(Camera cam, InputManager inputManager) {
|
||||
this.cam = cam;
|
||||
this.inputManager = inputManager;
|
||||
registerMappings();
|
||||
}
|
||||
|
||||
public void setTarget(Spatial target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public void setPaused(boolean paused) { this.paused = paused; }
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
private void registerMappings() {
|
||||
inputManager.addMapping("ZoomIn", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false));
|
||||
inputManager.addMapping("ZoomOut", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true));
|
||||
inputManager.addMapping("MouseX", new MouseAxisTrigger(MouseInput.AXIS_X, false));
|
||||
inputManager.addMapping("MouseXNeg", new MouseAxisTrigger(MouseInput.AXIS_X, true));
|
||||
inputManager.addMapping("MouseY", new MouseAxisTrigger(MouseInput.AXIS_Y, false));
|
||||
inputManager.addMapping("MouseYNeg", new MouseAxisTrigger(MouseInput.AXIS_Y, true));
|
||||
|
||||
AnalogListener analogListener = (name, value, tpf) -> {
|
||||
if (paused) return;
|
||||
switch (name) {
|
||||
// Horizontale Rotation
|
||||
case "MouseX" -> yaw -= value * MOUSE_SENSITIVITY;
|
||||
case "MouseXNeg" -> yaw += value * MOUSE_SENSITIVITY;
|
||||
// Vertikale Rotation — Y invertiert: Maus hoch → Kamera runter
|
||||
case "MouseY" -> pitch = FastMath.clamp(pitch - value * MOUSE_SENSITIVITY, MIN_VERTICAL_ANGLE, MAX_VERTICAL_ANGLE);
|
||||
case "MouseYNeg" -> pitch = FastMath.clamp(pitch + value * MOUSE_SENSITIVITY, MIN_VERTICAL_ANGLE, MAX_VERTICAL_ANGLE);
|
||||
// Zoom
|
||||
case "ZoomIn" -> distance = FastMath.clamp(distance - value * 20f, MIN_DISTANCE, MAX_DISTANCE);
|
||||
case "ZoomOut" -> distance = FastMath.clamp(distance + value * 20f, MIN_DISTANCE, MAX_DISTANCE);
|
||||
}
|
||||
};
|
||||
inputManager.addListener(analogListener,
|
||||
"MouseX", "MouseXNeg", "MouseY", "MouseYNeg", "ZoomIn", "ZoomOut");
|
||||
}
|
||||
|
||||
public void update(float tpf) {
|
||||
if (target == null) return;
|
||||
|
||||
Vector3f pivot = target.getWorldTranslation().add(0, TARGET_HEIGHT, 0);
|
||||
|
||||
// Sphärische Koordinaten → kartesisch
|
||||
float x = distance * FastMath.cos(pitch) * FastMath.sin(yaw);
|
||||
float y = distance * FastMath.sin(pitch);
|
||||
float z = distance * FastMath.cos(pitch) * FastMath.cos(yaw);
|
||||
|
||||
Vector3f camPos = pivot.add(x, y, z);
|
||||
cam.setLocation(camPos);
|
||||
cam.lookAt(pivot, Vector3f.UNIT_Y);
|
||||
}
|
||||
|
||||
/** Aktueller Yaw-Winkel (für CharacterControl nutzbar). */
|
||||
public float getYaw() { return yaw; }
|
||||
}
|
||||
Reference in New Issue
Block a user