summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2014-01-15 15:48:14 +0100
committerPeter Wu <lekensteyn@gmail.com>2014-01-15 15:48:14 +0100
commit4c3b53a48464afc46eb5d71870a105165e4f8498 (patch)
tree2e918eed27a5a39b8a7bfa635eb0233b048e1a48 /src
parentf6d14f13fb4342353512d4cf6e72798867d41230 (diff)
download2iv60-robots-4c3b53a48464afc46eb5d71870a105165e4f8498.tar.gz
Smoother camera transition
Transitions will now move to target with an animation of 500ms.
Diffstat (limited to 'src')
-rw-r--r--src/Camera.java103
1 files changed, 99 insertions, 4 deletions
diff --git a/src/Camera.java b/src/Camera.java
index 24ebbc9..fde3d80 100644
--- a/src/Camera.java
+++ b/src/Camera.java
@@ -18,7 +18,7 @@ class Camera {
public Vector up = Vector.Z;
/** Race track used. */
- private RaceTrack track;
+ private final RaceTrack track;
/**
* A reference to the global game state from RobotRace.
@@ -105,7 +105,7 @@ class Camera {
* In the Helicopter view, the camera (eye point) is located above the
* robots.
*/
- Robot focus = getFocusedRobot();
+ FocusPosition focus = smoothFocusTo(getFocusedRobot());
// center at the chosen robot.
center = track.getPointForLane(focus.getTimePos(), focus.getLane());
@@ -133,7 +133,7 @@ class Camera {
* In the Motor Cycle view, the camera is at the side of a track,
* following the robots.
*/
- Robot focus = getFocusedRobot();
+ FocusPosition focus = smoothFocusTo(getFocusedRobot());
// Center at the focused robot.
center = track.getPointForLane(focus.getTimePos(), focus.getLane());
@@ -155,7 +155,7 @@ class Camera {
/**
* First person mode: look from the slowest robot forward.
*/
- Robot focus = getSlowestRobot();
+ FocusPosition focus = smoothFocusTo(getSlowestRobot());
// trivial: looks from the robot POV.
eye = track.getPointForLane(focus.getTimePos(), focus.getLane());
@@ -221,4 +221,99 @@ class Camera {
}
return slowest;
}
+
+ /**
+ * Time when the transition started;
+ */
+ private long transition_start_ms;
+ private Robot old_target, moving_to_target;
+ /**
+ * Time that a transition takes to move from one to another target in ms.
+ */
+ private static final long TRANSITION_PERIOD = 500;
+
+ /**
+ * Determine the time position for the track position, using the specified
+ * robot parameter as new focus target. If the new focus target is different
+ * from the old one, then a smooth transition will be made between the old
+ * and new one.
+ */
+ private FocusPosition smoothFocusTo(Robot target) {
+ // target: goal
+ // moving target: new goal (after complete, set target to this)
+ // old target: previous goal (set to moving target when done)
+ // states:
+ // 1. same target
+ // 2. moving to new target (post-condition: moving != null)
+ long now = System.currentTimeMillis();
+
+ if (moving_to_target == null) { // state 1
+ // transition 1 -> 2 if old != new
+ if (target != old_target) {
+ old_target = target;
+ moving_to_target = target;
+ transition_start_ms = now;
+ } else {
+ // transition 1 -> 1 if old == new
+ // "no transition in progress" or "transition is still complete"
+ }
+ } else if (moving_to_target != null) { // state 2
+ // transition 2 -> 2 if the aimed target has changed
+ if (moving_to_target != target) {
+ // pretend that the camera moved from the current moving target
+ old_target = moving_to_target;
+ moving_to_target = target;
+ System.err.println("target changed at " + transition_start_ms);
+ // XXX: this does not work well if the transition has just
+ // started and the target is changed to something far away. It
+ // results in a non-fluent switch to the new target.
+ transition_start_ms = now;
+ } else {
+ // transition 2 -> 2 if target is still the same
+ // "transition progresses as time is increased"
+ }
+
+ // transition complete 2 -> 1: set new old target
+ if (now - transition_start_ms >= TRANSITION_PERIOD) {
+ old_target = target;
+ moving_to_target = null;
+ }
+ }
+
+ if (moving_to_target != null) { // in move state
+ double n = (now - transition_start_ms) / (double) TRANSITION_PERIOD;
+ // time is distributied from TC% target and the remaining old target
+ double time = n * target.getTimePos();
+ time += (1 - n) * old_target.getTimePos();
+
+ double lane = n * target.getLane();
+ lane += (1 - n) * old_target.getLane();
+
+ return new FocusPosition(lane, time);
+ } else { // not moving
+ return new FocusPosition(target.getLane(), target.getTimePos());
+ }
+ }
+
+ /**
+ * Represents the target on the track to focus the camera on.
+ */
+ class FocusPosition {
+
+ private final double lane;
+ private final double time;
+
+ FocusPosition(double lane, double time) {
+ this.lane = lane;
+ this.time = time;
+ }
+
+ double getTimePos() {
+ return time;
+ }
+
+ double getLane() {
+ return lane;
+ }
+ }
}