Home | History | Annotate | Download | only in events
      1 /*
      2  * Copyright (c) 2009-2010 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 package com.jme3.cinematic.events;
     33 
     34 import com.jme3.animation.LoopMode;
     35 import com.jme3.app.Application;
     36 import com.jme3.cinematic.Cinematic;
     37 import com.jme3.cinematic.PlayState;
     38 import com.jme3.export.InputCapsule;
     39 import com.jme3.export.JmeExporter;
     40 import com.jme3.export.JmeImporter;
     41 import com.jme3.export.OutputCapsule;
     42 import java.io.IOException;
     43 import java.util.ArrayList;
     44 import java.util.List;
     45 
     46 /**
     47  * This calls contains basic behavior of a cinematic event
     48  * every cinematic event must extend this class
     49  *
     50  * A cinematic event must be given an inital duration in seconds (duration of the event at speed = 1) (default is 10)
     51  * @author Nehon
     52  */
     53 public abstract class AbstractCinematicEvent implements CinematicEvent {
     54 
     55     protected PlayState playState = PlayState.Stopped;
     56     protected float speed = 1;
     57     protected float initialDuration = 10;
     58     protected LoopMode loopMode = LoopMode.DontLoop;
     59     protected float time = 0;
     60     protected boolean resuming = false;
     61 
     62     /**
     63      * the list of listeners
     64      */
     65     protected List<CinematicEventListener> listeners;
     66 
     67     /**
     68      * contruct a cinematic event
     69      */
     70     public AbstractCinematicEvent() {
     71     }
     72 
     73     /**
     74      * contruct a cinematic event wwith the given initial duration
     75      * @param initialDuration
     76      */
     77     public AbstractCinematicEvent(float initialDuration) {
     78         this.initialDuration = initialDuration;
     79     }
     80 
     81     /**
     82      * contruct a cinematic event with the given loopMode
     83      * @param loopMode
     84      */
     85     public AbstractCinematicEvent(LoopMode loopMode) {
     86         this.loopMode = loopMode;
     87     }
     88 
     89     /**
     90      * contruct a cinematic event with the given loopMode and the given initialDuration
     91      * @param initialDuration the duration of the event at speed = 1
     92      * @param loopMode the loop mode of the event
     93      */
     94     public AbstractCinematicEvent(float initialDuration, LoopMode loopMode) {
     95         this.initialDuration = initialDuration;
     96         this.loopMode = loopMode;
     97     }
     98 
     99     /**
    100      * Play this event
    101      */
    102     public void play() {
    103         onPlay();
    104         playState = PlayState.Playing;
    105         if (listeners != null) {
    106             for (int i = 0; i < listeners.size(); i++) {
    107                 CinematicEventListener cel = listeners.get(i);
    108                 cel.onPlay(this);
    109             }
    110         }
    111     }
    112 
    113     /**
    114      * Place here the code you want to execute when the event is started
    115      */
    116     protected abstract void onPlay();
    117 
    118     /**
    119      * should be used internally only
    120      * @param tpf time per frame
    121      */
    122     public void internalUpdate(float tpf) {
    123         if (playState == PlayState.Playing) {
    124             time = time + (tpf * speed);
    125             //time = elapsedTimePause + (timer.getTimeInSeconds() - start) * speed;
    126 
    127             onUpdate(tpf);
    128             if (time >= initialDuration && loopMode == loopMode.DontLoop) {
    129                 stop();
    130             }
    131         }
    132 
    133     }
    134 
    135     /**
    136      * Place here the code you want to execute on update (only called when the event is playing)
    137      * @param tpf time per frame
    138      */
    139     protected abstract void onUpdate(float tpf);
    140 
    141     /**
    142      * stops the animation, next time play() is called the animation will start from the begining.
    143      */
    144     public void stop() {
    145         onStop();
    146         time = 0;
    147         playState = PlayState.Stopped;
    148         if (listeners != null) {
    149             for (int i = 0; i < listeners.size(); i++) {
    150                 CinematicEventListener cel = listeners.get(i);
    151                 cel.onStop(this);
    152             }
    153         }
    154     }
    155 
    156     /**
    157      * Place here the code you want to execute when the event is stoped.
    158      */
    159     protected abstract void onStop();
    160 
    161     /**
    162      * pause this event
    163      */
    164     public void pause() {
    165         onPause();
    166         playState = PlayState.Paused;
    167         if (listeners != null) {
    168             for (int i = 0; i < listeners.size(); i++) {
    169                 CinematicEventListener cel = listeners.get(i);
    170                 cel.onPause(this);
    171             }
    172         }
    173     }
    174 
    175     /**
    176      * place here the code you want to execute when the event is paused
    177      */
    178     public abstract void onPause();
    179 
    180     /**
    181      * returns the actual duration of the animtion (initialDuration/speed)
    182      * @return
    183      */
    184     public float getDuration() {
    185         return initialDuration / speed;
    186     }
    187 
    188     /**
    189      * Sets the speed of the animation.
    190      * At speed = 1, the animation will last initialDuration seconds,
    191      * At speed = 2 the animation will last initialDuraiton/2...
    192      * @param speed
    193      */
    194     public void setSpeed(float speed) {
    195         this.speed = speed;
    196     }
    197 
    198     /**
    199      * returns the speed of the animation.
    200      * @return
    201      */
    202     public float getSpeed() {
    203         return speed;
    204     }
    205 
    206     /**
    207      * Returns the current playstate of the animation
    208      * @return
    209      */
    210     public PlayState getPlayState() {
    211         return playState;
    212     }
    213 
    214     /**
    215      * returns the initial duration of the animation at speed = 1 in seconds.
    216      * @return
    217      */
    218     public float getInitialDuration() {
    219         return initialDuration;
    220     }
    221 
    222     /**
    223      * Sets the duration of the antionamtion at speed = 1 in seconds
    224      * @param initialDuration
    225      */
    226     public void setInitialDuration(float initialDuration) {
    227         this.initialDuration = initialDuration;
    228     }
    229 
    230     /**
    231      * retursthe loopMode of the animation
    232      * @see LoopMode
    233      * @return
    234      */
    235     public LoopMode getLoopMode() {
    236         return loopMode;
    237     }
    238 
    239     /**
    240      * Sets the loopMode of the animation
    241      * @see LoopMode
    242      * @param loopMode
    243      */
    244     public void setLoopMode(LoopMode loopMode) {
    245         this.loopMode = loopMode;
    246     }
    247 
    248     /**
    249      * for serialization only
    250      * @param ex exporter
    251      * @throws IOException
    252      */
    253     public void write(JmeExporter ex) throws IOException {
    254         OutputCapsule oc = ex.getCapsule(this);
    255         oc.write(playState, "playState", PlayState.Stopped);
    256         oc.write(speed, "speed", 1);
    257         oc.write(initialDuration, "initalDuration", 10);
    258         oc.write(loopMode, "loopMode", LoopMode.DontLoop);
    259     }
    260 
    261     /**
    262      * for serialization only
    263      * @param im importer
    264      * @throws IOException
    265      */
    266     public void read(JmeImporter im) throws IOException {
    267         InputCapsule ic = im.getCapsule(this);
    268         playState = ic.readEnum("playState", PlayState.class, PlayState.Stopped);
    269         speed = ic.readFloat("speed", 1);
    270         initialDuration = ic.readFloat("initalDuration", 10);
    271         loopMode = ic.readEnum("loopMode", LoopMode.class, LoopMode.DontLoop);
    272     }
    273 
    274     /**
    275      * initialize this event (should be called internally only)
    276      * @param app
    277      * @param cinematic
    278      */
    279     public void initEvent(Application app, Cinematic cinematic) {
    280     }
    281 
    282     /**
    283      * return a list of CinematicEventListener added on this event
    284      * @return
    285      */
    286     private List<CinematicEventListener> getListeners() {
    287         if (listeners == null) {
    288             listeners = new ArrayList<CinematicEventListener>();
    289         }
    290         return listeners;
    291     }
    292 
    293     /**
    294      * Add a CinematicEventListener to this event
    295      * @param listener CinematicEventListener
    296      */
    297     public void addListener(CinematicEventListener listener) {
    298         getListeners().add(listener);
    299     }
    300 
    301     /**
    302      * remove a CinematicEventListener from this event
    303      * @param listener CinematicEventListener
    304      */
    305     public void removeListener(CinematicEventListener listener) {
    306         getListeners().remove(listener);
    307     }
    308 
    309     /**
    310      * When this method is invoked, the event should fast forward to the given time according tim 0 is the start of the event.
    311      * @param time the time to fast forward to
    312      */
    313     public void setTime(float time) {
    314         this.time = time / speed;
    315     }
    316 
    317     public float getTime() {
    318         return time;
    319     }
    320 }
    321