Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (538)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (600)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Accelerate and slow down a camera move  (Read 1878 times)
0 Members and 1 Guest are viewing this topic.
Offline martin

Senior Newbie





« Posted 2011-06-08 00:39:34 »

Hi folks,
I have a 2d scene, and do camera moves between two given points by simply defining N equal intermediate steps along the line formed by the start and stop point.
I'd like to accelerate at the beginning and slow down at the end. Do you have any suggestions to do that smartly?
Cheers,
Martin
Online ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #1 - Posted 2011-06-08 03:17:57 »

Have an acceleration vector or variable and add it to the velocity until you reach your maximum velocity. Then (velocity/acceleration) ticks before you reach the other point, subtract that acceleration from the velocity until you reach 0.

Offline loom_weaver

JGO Coder


Medals: 17



« Reply #2 - Posted 2011-06-08 04:40:48 »

Heh, I was just working on almost exactly the same problem.  In my game one can move the camera with the keys but I want the motion to accelerate at first.  (Think StarCraft RTS camera panning control)

Here's how you calculate the distance with initial acceleration and then constant velocity movement.  I'll leave the deceleration portion as an exercise for the reader.

From physics class you learn:
distance = velocity * time
distance = 0.5 * acceleration * time^2

Thus if you know at what point your camera was when you first started panning, then this is how you calculate the distance that the camera should have moved:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
elapsed_sec = (System.currentTimeMillis - start_ms) / 1000.0

velocity = 7.0  // units per sec
accel = 9.0  // units per sec^2

accel_dur_sec = 1.0  // acceleration happens for the first second, then speed is constant after that

distance = 0.0
if (elapsed_sec < accel_dur_sec) {
    distance = 0.5 * accel * elapsed_sec * elapsed_sec
} else {
    distance = 0.5 * accel * accel_dur_sec * accel_dur_sec + velocity * (elapsed_sec - accel_dur_sec)
}


Or you can do it in stepwise intervals as ra4king described.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #3 - Posted 2011-06-08 06:20:06 »

That works too Smiley

Offline martin

Senior Newbie





« Reply #4 - Posted 2011-06-08 13:26:09 »

Hi,

Thanks for these suggestions. One thing I forgot to tell: I want to control the LENGTH of each animation. Up to now I check the frame rate before starting any animation, to determine the number of necessary key points required to have the choosen duration. Unless I misunderstood your suggestion, it seems to me that your solutions requires little thinking to determine acceleration and other parameters to control the number of steps.

I was thinking about using a function to shifts linear steps:
 
(1) compute the linear interpolation of the n intermediate steps. First and last point make distance D.
(2) convert each point to polar, to have a distance information from start.
(3) then each point Pi should be at distance= D*i/n from start.

(4) For this next step, the best is to normalize in [0;1], so consider distance=i/n. We will update each polar point with:
      P.radius = f(P.radius)
I thus need a function y=f(x) that gives y=0 for x=0 and y=1 for x=1, and that let me "stretch" the animation timing easily:
      f(x)=x^2 makes a simple accelerating move, x^3,4,5 will be more "sharp": slower at the beginning and faster at the end.
      f(x)=-(x-1)^2+1 makes the contrary acceleration: fast at the beginning, slow at the end. One must have an even pow value.

so I better need a normalized sigmoïd function. I will tell you if I find a good candidate for this method Smiley

It is a little mangled, but allows to customize speed variation easily! Maybe there are some other more straightforward methods.

Cheers,
Martin
Offline krasse
« Reply #5 - Posted 2011-06-08 13:54:15 »

Edit: This was probably not helpful at all after I read the last post by martin Smiley

Here is a very simple filter for smooth movement. Just set the factor between 0 and 1 and call the update() method with the target position. For 2D, just use two DoubleSmoothers, one for x and the other for y. You can also use it for any smooth transition like zoom, angle etc.
A smaller factor gives a slower movement until you reach 0 (no movement at all).

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
public class DoubleSmoother {

   private double factor;
   private double current;

   public DoubleSmoother(double factor, double start) {
      this.factor = factor;
      this.current = start;
   }

   public DoubleSmoother(double factor) {
      this(factor, 0.0);
   }

   public double getValue() {
      return current;
   }

   public double update(double value) {
      current = factor * value + (1.0 - factor) * current;
      return current;
   }
   
   public void setValue(double value) {
      current = value;
   }

}


If you know some filter theory, then it might help you that this is simply a single pole, linear, discrete filter.

Offline martin

Senior Newbie





« Reply #6 - Posted 2011-06-10 08:44:17 »

Thanks for the piece of code!

After some more thought, I came out with the following idea: a "standard" sigmoïd method works, but it is not easy to control tune it. Actually I just would like to build a function that looks like a smoothed stair:

1       /-        slow stop
|   /-/
0-/      1       slow start


satisfying f(0)=0, f(0.5)=0.5 and f(1)=1, and any other constraint letting me say "at T I want the cam to have done distance D". Finally, it seems the best is to "build" the function using an interpolation (I will use bernstein, that works well), where each keypoint represent a D=f(T) constraint. One can really "model" the camera behaviour with details.

Cheers,
Martin
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (29 views)
2014-12-15 09:26:44

Mr.CodeIt (20 views)
2014-12-14 19:50:38

BurntPizza (40 views)
2014-12-09 22:41:13

BurntPizza (76 views)
2014-12-08 04:46:31

JscottyBieshaar (37 views)
2014-12-05 12:39:02

SHC (50 views)
2014-12-03 16:27:13

CopyableCougar4 (47 views)
2014-11-29 21:32:03

toopeicgaming1999 (114 views)
2014-11-26 15:22:04

toopeicgaming1999 (102 views)
2014-11-26 15:20:36

toopeicgaming1999 (30 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!