Motion.java
上传用户:haobig99
上传日期:2022-06-15
资源大小:369k
文件大小:9k
源码类别:

J2ME

开发平台:

Java

  1. /*
  2.  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
  3.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4.  *
  5.  * This code is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License version 2 only, as
  7.  * published by the Free Software Foundation.  Sun designates this
  8.  * particular file as subject to the "Classpath" exception as provided
  9.  * by Sun in the LICENSE file that accompanied this code.
  10.  *
  11.  * This code is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * version 2 for more details (a copy is included in the LICENSE file that
  15.  * accompanied this code).
  16.  *
  17.  * You should have received a copy of the GNU General Public License version
  18.  * 2 along with this work; if not, write to the Free Software Foundation,
  19.  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22.  * CA 95054 USA or visit www.sun.com if you need additional information or
  23.  * have any questions.
  24.  */
  25. package com.sun.lwuit.animations;
  26. /**
  27.  * Abstracts the notion of physical motion over time from a numeric location to
  28.  * another. This class can be subclassed to implement any motion equation for
  29.  * appropriate physics effects.
  30.  * <p>This class relies on the System.currentTimeMillis() method to provide
  31.  * transitions between coordinates. The motion can be subclassed to provide every
  32.  * type of motion feel from parabolic motion to spline and linear motion. The default
  33.  * implementation provides a simple algorithm giving the feel of acceleration and
  34.  * deceleration.
  35.  *
  36.  * @author Shai Almog
  37.  */
  38. public class Motion {
  39.     private static final int LINEAR = 0;
  40.     private static final int SPLINE = 1;
  41.     private static final int FRICTION = 2;
  42.     
  43.     private int motionType;
  44.     private int sourceValue;
  45.     private int destinationValue;
  46.     private int duration;
  47.     private long startTime;
  48.     private float initVelocity,  friction;
  49.     
  50.     /**
  51.      * Construct a point/destination motion
  52.      * 
  53.      * @param sourceValue starting value
  54.      * @param destinationValue destination value
  55.      * @param duration motion duration
  56.      */
  57.     protected Motion(int sourceValue, int destinationValue, int duration) {
  58.         this.sourceValue = sourceValue;
  59.         this.destinationValue = destinationValue;
  60.         this.duration = duration;
  61.     }
  62.     /**
  63.      * Construct a velocity motion
  64.      * 
  65.      * @param sourceValue starting value
  66.      * @param initVelocity initial velocity
  67.      * @param friction degree of friction
  68.      */
  69.     protected Motion(int sourceValue, float initVelocity, float friction) {
  70.         this.sourceValue = sourceValue;
  71.         this.initVelocity = initVelocity;
  72.         this.friction = friction;
  73.         duration = (int) ((Math.abs(initVelocity)) / friction);
  74.     }
  75.     /**
  76.      * Creates a linear motion starting from source value all the way to destination value
  77.      * 
  78.      * @param sourceValue the number from which we are starting (usually indicating animation start position)
  79.      * @param destinationValue the number to which we are heading (usually indicating animation destination)
  80.      * @param duration the length in milliseconds of the motion (time it takes to get from sourceValue to
  81.      * destinationValue)
  82.      * @return new motion object
  83.      */
  84.     public static Motion createLinearMotion(int sourceValue, int destinationValue, int duration) {
  85.         Motion l = new Motion(sourceValue, destinationValue, duration);
  86.         l.motionType = LINEAR;
  87.         return l;
  88.     }
  89.     
  90.     /**
  91.      * Creates a spline motion starting from source value all the way to destination value
  92.      * 
  93.      * @param sourceValue the number from which we are starting (usually indicating animation start position)
  94.      * @param destinationValue the number to which we are heading (usually indicating animation destination)
  95.      * @param duration the length in milliseconds of the motion (time it takes to get from sourceValue to
  96.      * destinationValue)
  97.      * @return new motion object
  98.      */
  99.     public static Motion createSplineMotion(int sourceValue, int destinationValue, int duration) {
  100.         Motion spline = new Motion(sourceValue, destinationValue, duration);
  101.         spline.motionType = SPLINE;
  102.         return spline;
  103.     }
  104.     /**
  105.      * Creates a friction motion starting from source with initial speed and the friction
  106.      * 
  107.      * @param sourceValue the number from which we are starting (usually indicating animation start position)
  108.      * @param initVelocity the starting velocity
  109.      * @param friction the motion friction
  110.      * @return new motion object
  111.      */
  112.     public static Motion createFrictionMotion(int sourceValue, float initVelocity, float friction) {
  113.         Motion frictionMotion = new Motion(sourceValue, initVelocity, friction);
  114.         frictionMotion.motionType = FRICTION;
  115.         return frictionMotion;
  116.     }
  117.     
  118.     /**
  119.      * Sets the start time to the current time
  120.      */
  121.     public void start() {
  122.         startTime = System.currentTimeMillis();
  123.     }
  124.     /**
  125.      * Returns true if the motion has run its course and has finished meaning the current
  126.      * time is greater than startTime + duration.
  127.      * 
  128.      * @return true if System.currentTimeMillis() > duration + startTime
  129.      */
  130.     public boolean isFinished() {
  131.         return System.currentTimeMillis() > duration + startTime;
  132.     }
  133.     private int getSplineValue() {
  134.         //make sure we reach the destination value.
  135.         if(isFinished()){
  136.             return destinationValue;
  137.         }
  138.         float totalTime = duration;
  139.         float currentTime = (int) (System.currentTimeMillis() - startTime);
  140.         currentTime = Math.min(currentTime, totalTime);
  141.         int p = Math.abs(destinationValue - sourceValue);
  142.         float centerTime = totalTime / 2;
  143.         float l = p / (centerTime * centerTime);
  144.         int x;
  145.         if (sourceValue < destinationValue) {
  146.             if (currentTime > centerTime) {
  147.                 x = sourceValue + (int) (l * (-centerTime * centerTime + 2 * centerTime * currentTime -
  148.                         currentTime * currentTime / 2));
  149.             } else {
  150.                 x = sourceValue + (int) (l * currentTime * currentTime / 2);
  151.             }
  152.         } else {
  153.             currentTime = totalTime - currentTime;
  154.             if (currentTime > centerTime) {
  155.                 x = destinationValue + (int) (l * (-centerTime * centerTime + 2 * centerTime * currentTime -
  156.                         currentTime * currentTime / 2));
  157.             } else {
  158.                 x = destinationValue + (int) (l * currentTime * currentTime / 2);
  159.             }
  160.         }
  161.         return x;
  162.     }
  163.     
  164.     /**
  165.      * Returns the value for the motion for the current clock time. 
  166.      * The value is dependent on the Motion type.
  167.      * 
  168.      * @return a value that is relative to the source value
  169.      */
  170.     public int getValue() {
  171.         if (motionType == SPLINE) {
  172.             return getSplineValue();
  173.         }else if(motionType == FRICTION){
  174.             return getFriction();
  175.         }else{
  176.             return getLinear();
  177.         }
  178.     }
  179.     private int getLinear() {
  180.         //make sure we reach the destination value.
  181.         if(isFinished()){
  182.             return destinationValue;
  183.         }
  184.         float totalTime = duration;
  185.         float currentTime = (int) (System.currentTimeMillis() - startTime);
  186.         int dis = destinationValue - sourceValue;
  187.         int val = (int)(sourceValue + (currentTime / totalTime * dis));
  188.         
  189.         if(destinationValue < sourceValue) {
  190.             return Math.max(destinationValue, val);
  191.         } else {
  192.             return Math.min(destinationValue, val);
  193.         }
  194.     }
  195.     
  196.     private int getFriction() {
  197.         int time = (int) (System.currentTimeMillis() - startTime);
  198.         int retVal = 0;
  199.         retVal = (int)((Math.abs(initVelocity) * time) - (friction * (((float)time * time) / 2)));
  200.         if (initVelocity < 0) {
  201.             retVal *= -1;
  202.         }
  203.         retVal += (int) sourceValue;
  204.         return retVal;
  205.     }
  206.     /**
  207.      * The number from which we are starting (usually indicating animation start position)
  208.      * 
  209.      * @return the source value
  210.      */
  211.     public int getSourceValue() {
  212.         return sourceValue;
  213.     }
  214.     /**
  215.      * The number from which we are starting (usually indicating animation start position)
  216.      * 
  217.      * @param sourceValue  the source value
  218.      */
  219.     public void setSourceValue(int sourceValue) {
  220.         this.sourceValue = sourceValue;
  221.     }
  222.     /**
  223.      * The value of System.currentTimemillis() when motion was started
  224.      * 
  225.      * @return the start time
  226.      */
  227.     protected long getStartTime() {
  228.         return startTime;
  229.     }
  230. }