1 /*******************************************************************************
\r
2 * Copyright 2011 See AUTHORS file.
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
15 ******************************************************************************/
\r
17 package com.badlogic.gdx.graphics.g2d;
\r
19 import java.io.BufferedReader;
\r
20 import java.io.File;
\r
21 import java.io.FileWriter;
\r
22 import java.io.IOException;
\r
23 import java.io.InputStream;
\r
24 import java.io.InputStreamReader;
\r
25 import java.io.Writer;
\r
27 import com.badlogic.gdx.files.FileHandle;
\r
28 import com.badlogic.gdx.graphics.Texture;
\r
29 import com.badlogic.gdx.math.collision.BoundingBox;
\r
30 import com.badlogic.gdx.utils.Array;
\r
31 import com.badlogic.gdx.utils.Disposable;
\r
32 import com.badlogic.gdx.utils.GdxRuntimeException;
\r
34 /** See <a href="http://www.badlogicgames.com/wordpress/?p=1255">http://www.badlogicgames.com/wordpress/?p=1255</a>
\r
35 * @author mzechner */
\r
36 public class ParticleEffect implements Disposable {
\r
37 private final Array<ParticleEmitter> emitters;
\r
38 private BoundingBox bounds;
\r
40 public ParticleEffect () {
\r
41 emitters = new Array(8);
\r
44 public ParticleEffect (ParticleEffect effect) {
\r
45 emitters = new Array(true, effect.emitters.size);
\r
46 for (int i = 0, n = effect.emitters.size; i < n; i++)
\r
47 emitters.add(new ParticleEmitter(effect.emitters.get(i)));
\r
50 public void start () {
\r
51 for (int i = 0, n = emitters.size; i < n; i++)
\r
52 emitters.get(i).start();
\r
55 public void reset () {
\r
56 for (int i = 0, n = emitters.size; i < n; i++)
\r
57 emitters.get(i).reset();
\r
60 public void update (float delta) {
\r
61 for (int i = 0, n = emitters.size; i < n; i++)
\r
62 emitters.get(i).update(delta);
\r
65 public void draw (SpriteBatch spriteBatch) {
\r
66 for (int i = 0, n = emitters.size; i < n; i++)
\r
67 emitters.get(i).draw(spriteBatch);
\r
70 public void draw (SpriteBatch spriteBatch, float delta) {
\r
71 for (int i = 0, n = emitters.size; i < n; i++)
\r
72 emitters.get(i).draw(spriteBatch, delta);
\r
75 public void allowCompletion () {
\r
76 for (int i = 0, n = emitters.size; i < n; i++)
\r
77 emitters.get(i).allowCompletion();
\r
80 public boolean isComplete () {
\r
81 for (int i = 0, n = emitters.size; i < n; i++) {
\r
82 ParticleEmitter emitter = emitters.get(i);
\r
83 if (!emitter.isComplete()) return false;
\r
88 public void setDuration (int duration) {
\r
89 for (int i = 0, n = emitters.size; i < n; i++) {
\r
90 ParticleEmitter emitter = emitters.get(i);
\r
91 emitter.setContinuous(false);
\r
92 emitter.duration = duration;
\r
93 emitter.durationTimer = 0;
\r
97 public void setPosition (float x, float y) {
\r
98 for (int i = 0, n = emitters.size; i < n; i++)
\r
99 emitters.get(i).setPosition(x, y);
\r
102 public void setFlip (boolean flipX, boolean flipY) {
\r
103 for (int i = 0, n = emitters.size; i < n; i++)
\r
104 emitters.get(i).setFlip(flipX, flipY);
\r
107 public void flipY () {
\r
108 for (int i = 0, n = emitters.size; i < n; i++)
\r
109 emitters.get(i).flipY();
\r
112 public Array<ParticleEmitter> getEmitters () {
\r
116 /** Returns the emitter with the specified name, or null. */
\r
117 public ParticleEmitter findEmitter (String name) {
\r
118 for (int i = 0, n = emitters.size; i < n; i++) {
\r
119 ParticleEmitter emitter = emitters.get(i);
\r
120 if (emitter.getName().equals(name)) return emitter;
\r
125 public void save (File file) {
\r
126 Writer output = null;
\r
128 output = new FileWriter(file);
\r
130 for (int i = 0, n = emitters.size; i < n; i++) {
\r
131 ParticleEmitter emitter = emitters.get(i);
\r
132 if (index++ > 0) output.write("\n\n");
\r
133 emitter.save(output);
\r
134 output.write("- Image Path -\n");
\r
135 output.write(emitter.getImagePath() + "\n");
\r
137 } catch (IOException ex) {
\r
138 throw new GdxRuntimeException("Error saving effect: " + file, ex);
\r
141 if (output != null) output.close();
\r
142 } catch (IOException ex) {
\r
147 public void load (FileHandle effectFile, FileHandle imagesDir) {
\r
148 loadEmitters(effectFile);
\r
149 loadEmitterImages(imagesDir);
\r
152 public void load (FileHandle effectFile, TextureAtlas atlas) {
\r
153 loadEmitters(effectFile);
\r
154 loadEmitterImages(atlas);
\r
157 public void loadEmitters (FileHandle effectFile) {
\r
158 InputStream input = effectFile.read();
\r
160 BufferedReader reader = null;
\r
162 reader = new BufferedReader(new InputStreamReader(input), 512);
\r
164 ParticleEmitter emitter = new ParticleEmitter(reader);
\r
166 emitter.setImagePath(reader.readLine());
\r
167 emitters.add(emitter);
\r
168 if (reader.readLine() == null) break;
\r
169 if (reader.readLine() == null) break;
\r
171 } catch (IOException ex) {
\r
172 throw new GdxRuntimeException("Error loading effect: " + effectFile, ex);
\r
175 if (reader != null) reader.close();
\r
176 } catch (IOException ex) {
\r
181 public void loadEmitterImages (TextureAtlas atlas) {
\r
182 for (int i = 0, n = emitters.size; i < n; i++) {
\r
183 ParticleEmitter emitter = emitters.get(i);
\r
184 String imagePath = emitter.getImagePath();
\r
185 if (imagePath == null) continue;
\r
186 String imageName = new File(imagePath.replace('\\', '/')).getName();
\r
187 int lastDotIndex = imageName.lastIndexOf('.');
\r
188 if (lastDotIndex != -1) imageName = imageName.substring(0, lastDotIndex);
\r
189 Sprite sprite = atlas.createSprite(imageName);
\r
190 if (sprite == null) throw new IllegalArgumentException("SpriteSheet missing image: " + imageName);
\r
191 emitter.setSprite(sprite);
\r
195 public void loadEmitterImages (FileHandle imagesDir) {
\r
196 for (int i = 0, n = emitters.size; i < n; i++) {
\r
197 ParticleEmitter emitter = emitters.get(i);
\r
198 String imagePath = emitter.getImagePath();
\r
199 if (imagePath == null) continue;
\r
200 String imageName = new File(imagePath.replace('\\', '/')).getName();
\r
201 emitter.setSprite(new Sprite(loadTexture(imagesDir.child(imageName))));
\r
205 protected Texture loadTexture (FileHandle file) {
\r
206 return new Texture(file, false);
\r
209 /** Disposes the texture for each sprite for each ParticleEmitter. */
\r
210 public void dispose () {
\r
211 for (int i = 0, n = emitters.size; i < n; i++) {
\r
212 ParticleEmitter emitter = emitters.get(i);
\r
213 emitter.getSprite().getTexture().dispose();
\r
217 /** Returns the bounding box for all active particles. z axis will always be zero. */
\r
218 public BoundingBox getBoundingBox () {
\r
219 if (bounds == null) bounds = new BoundingBox();
\r
221 BoundingBox bounds = this.bounds;
\r
223 for (ParticleEmitter emitter : this.emitters)
\r
224 bounds.ext(emitter.getBoundingBox());
\r