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 */ AbstractCinematicEvent()70 public AbstractCinematicEvent() { 71 } 72 73 /** 74 * contruct a cinematic event wwith the given initial duration 75 * @param initialDuration 76 */ AbstractCinematicEvent(float initialDuration)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 */ AbstractCinematicEvent(LoopMode loopMode)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 */ AbstractCinematicEvent(float initialDuration, LoopMode loopMode)94 public AbstractCinematicEvent(float initialDuration, LoopMode loopMode) { 95 this.initialDuration = initialDuration; 96 this.loopMode = loopMode; 97 } 98 99 /** 100 * Play this event 101 */ play()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 */ onPlay()116 protected abstract void onPlay(); 117 118 /** 119 * should be used internally only 120 * @param tpf time per frame 121 */ internalUpdate(float tpf)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 */ onUpdate(float tpf)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 */ stop()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 */ onStop()159 protected abstract void onStop(); 160 161 /** 162 * pause this event 163 */ pause()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 */ onPause()178 public abstract void onPause(); 179 180 /** 181 * returns the actual duration of the animtion (initialDuration/speed) 182 * @return 183 */ getDuration()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 */ setSpeed(float speed)194 public void setSpeed(float speed) { 195 this.speed = speed; 196 } 197 198 /** 199 * returns the speed of the animation. 200 * @return 201 */ getSpeed()202 public float getSpeed() { 203 return speed; 204 } 205 206 /** 207 * Returns the current playstate of the animation 208 * @return 209 */ getPlayState()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 */ getInitialDuration()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 */ setInitialDuration(float initialDuration)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 */ getLoopMode()235 public LoopMode getLoopMode() { 236 return loopMode; 237 } 238 239 /** 240 * Sets the loopMode of the animation 241 * @see LoopMode 242 * @param loopMode 243 */ setLoopMode(LoopMode loopMode)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 */ write(JmeExporter ex)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 */ read(JmeImporter im)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 */ initEvent(Application app, Cinematic cinematic)279 public void initEvent(Application app, Cinematic cinematic) { 280 } 281 282 /** 283 * return a list of CinematicEventListener added on this event 284 * @return 285 */ getListeners()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 */ addListener(CinematicEventListener listener)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 */ removeListener(CinematicEventListener listener)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 */ setTime(float time)313 public void setTime(float time) { 314 this.time = time / speed; 315 } 316 getTime()317 public float getTime() { 318 return time; 319 } 320 } 321