OSDN Git Service

Merge branch 'master' of https://github.com/libgdx/libgdx
[mikumikustudio/libgdx-mikumikustudio.git] / gdx / src / com / badlogic / gdx / graphics / g2d / ParticleEffect.java
1 /*******************************************************************************\r
2  * Copyright 2011 See AUTHORS file.\r
3  * \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
7  * \r
8  *   http://www.apache.org/licenses/LICENSE-2.0\r
9  * \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
16 \r
17 package com.badlogic.gdx.graphics.g2d;\r
18 \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
26 \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
33 import com.badlogic.gdx.utils.StreamUtils;\r
34 \r
35 /** See <a href="http://www.badlogicgames.com/wordpress/?p=1255">http://www.badlogicgames.com/wordpress/?p=1255</a>\r
36  * @author mzechner */\r
37 public class ParticleEffect implements Disposable {\r
38         private final Array<ParticleEmitter> emitters;\r
39         private BoundingBox bounds;\r
40 \r
41         public ParticleEffect () {\r
42                 emitters = new Array(8);\r
43         }\r
44 \r
45         public ParticleEffect (ParticleEffect effect) {\r
46                 emitters = new Array(true, effect.emitters.size);\r
47                 for (int i = 0, n = effect.emitters.size; i < n; i++)\r
48                         emitters.add(new ParticleEmitter(effect.emitters.get(i)));\r
49         }\r
50 \r
51         public void start () {\r
52                 for (int i = 0, n = emitters.size; i < n; i++)\r
53                         emitters.get(i).start();\r
54         }\r
55 \r
56         public void reset () {\r
57                 for (int i = 0, n = emitters.size; i < n; i++)\r
58                         emitters.get(i).reset();\r
59         }\r
60 \r
61         public void update (float delta) {\r
62                 for (int i = 0, n = emitters.size; i < n; i++)\r
63                         emitters.get(i).update(delta);\r
64         }\r
65 \r
66         public void draw (SpriteBatch spriteBatch) {\r
67                 for (int i = 0, n = emitters.size; i < n; i++)\r
68                         emitters.get(i).draw(spriteBatch);\r
69         }\r
70 \r
71         public void draw (SpriteBatch spriteBatch, float delta) {\r
72                 for (int i = 0, n = emitters.size; i < n; i++)\r
73                         emitters.get(i).draw(spriteBatch, delta);\r
74         }\r
75 \r
76         public void allowCompletion () {\r
77                 for (int i = 0, n = emitters.size; i < n; i++)\r
78                         emitters.get(i).allowCompletion();\r
79         }\r
80 \r
81         public boolean isComplete () {\r
82                 for (int i = 0, n = emitters.size; i < n; i++) {\r
83                         ParticleEmitter emitter = emitters.get(i);\r
84                         if (!emitter.isComplete()) return false;\r
85                 }\r
86                 return true;\r
87         }\r
88 \r
89         public void setDuration (int duration) {\r
90                 for (int i = 0, n = emitters.size; i < n; i++) {\r
91                         ParticleEmitter emitter = emitters.get(i);\r
92                         emitter.setContinuous(false);\r
93                         emitter.duration = duration;\r
94                         emitter.durationTimer = 0;\r
95                 }\r
96         }\r
97 \r
98         public void setPosition (float x, float y) {\r
99                 for (int i = 0, n = emitters.size; i < n; i++)\r
100                         emitters.get(i).setPosition(x, y);\r
101         }\r
102 \r
103         public void setFlip (boolean flipX, boolean flipY) {\r
104                 for (int i = 0, n = emitters.size; i < n; i++)\r
105                         emitters.get(i).setFlip(flipX, flipY);\r
106         }\r
107 \r
108         public void flipY () {\r
109                 for (int i = 0, n = emitters.size; i < n; i++)\r
110                         emitters.get(i).flipY();\r
111         }\r
112 \r
113         public Array<ParticleEmitter> getEmitters () {\r
114                 return emitters;\r
115         }\r
116 \r
117         /** Returns the emitter with the specified name, or null. */\r
118         public ParticleEmitter findEmitter (String name) {\r
119                 for (int i = 0, n = emitters.size; i < n; i++) {\r
120                         ParticleEmitter emitter = emitters.get(i);\r
121                         if (emitter.getName().equals(name)) return emitter;\r
122                 }\r
123                 return null;\r
124         }\r
125 \r
126         public void save (File file) {\r
127                 Writer output = null;\r
128                 try {\r
129                         output = new FileWriter(file);\r
130                         int index = 0;\r
131                         for (int i = 0, n = emitters.size; i < n; i++) {\r
132                                 ParticleEmitter emitter = emitters.get(i);\r
133                                 if (index++ > 0) output.write("\n\n");\r
134                                 emitter.save(output);\r
135                                 output.write("- Image Path -\n");\r
136                                 output.write(emitter.getImagePath() + "\n");\r
137                         }\r
138                 } catch (IOException ex) {\r
139                         throw new GdxRuntimeException("Error saving effect: " + file, ex);\r
140                 } finally {\r
141                         StreamUtils.closeQuietly(output);\r
142                 }\r
143         }\r
144 \r
145         public void load (FileHandle effectFile, FileHandle imagesDir) {\r
146                 loadEmitters(effectFile);\r
147                 loadEmitterImages(imagesDir);\r
148         }\r
149 \r
150         public void load (FileHandle effectFile, TextureAtlas atlas) {\r
151                 loadEmitters(effectFile);\r
152                 loadEmitterImages(atlas);\r
153         }\r
154 \r
155         public void loadEmitters (FileHandle effectFile) {\r
156                 InputStream input = effectFile.read();\r
157                 emitters.clear();\r
158                 BufferedReader reader = null;\r
159                 try {\r
160                         reader = new BufferedReader(new InputStreamReader(input), 512);\r
161                         while (true) {\r
162                                 ParticleEmitter emitter = new ParticleEmitter(reader);\r
163                                 reader.readLine();\r
164                                 emitter.setImagePath(reader.readLine());\r
165                                 emitters.add(emitter);\r
166                                 if (reader.readLine() == null) break;\r
167                                 if (reader.readLine() == null) break;\r
168                         }\r
169                 } catch (IOException ex) {\r
170                         throw new GdxRuntimeException("Error loading effect: " + effectFile, ex);\r
171                 } finally {\r
172                         StreamUtils.closeQuietly(reader);\r
173                 }\r
174         }\r
175 \r
176         public void loadEmitterImages (TextureAtlas atlas) {\r
177                 for (int i = 0, n = emitters.size; i < n; i++) {\r
178                         ParticleEmitter emitter = emitters.get(i);\r
179                         String imagePath = emitter.getImagePath();\r
180                         if (imagePath == null) continue;\r
181                         String imageName = new File(imagePath.replace('\\', '/')).getName();\r
182                         int lastDotIndex = imageName.lastIndexOf('.');\r
183                         if (lastDotIndex != -1) imageName = imageName.substring(0, lastDotIndex);\r
184                         Sprite sprite = atlas.createSprite(imageName);\r
185                         if (sprite == null) throw new IllegalArgumentException("SpriteSheet missing image: " + imageName);\r
186                         emitter.setSprite(sprite);\r
187                 }\r
188         }\r
189 \r
190         public void loadEmitterImages (FileHandle imagesDir) {\r
191                 for (int i = 0, n = emitters.size; i < n; i++) {\r
192                         ParticleEmitter emitter = emitters.get(i);\r
193                         String imagePath = emitter.getImagePath();\r
194                         if (imagePath == null) continue;\r
195                         String imageName = new File(imagePath.replace('\\', '/')).getName();\r
196                         emitter.setSprite(new Sprite(loadTexture(imagesDir.child(imageName))));\r
197                 }\r
198         }\r
199 \r
200         protected Texture loadTexture (FileHandle file) {\r
201                 return new Texture(file, false);\r
202         }\r
203 \r
204         /** Disposes the texture for each sprite for each ParticleEmitter. */\r
205         public void dispose () {\r
206                 for (int i = 0, n = emitters.size; i < n; i++) {\r
207                         ParticleEmitter emitter = emitters.get(i);\r
208                         emitter.getSprite().getTexture().dispose();\r
209                 }\r
210         }\r
211         \r
212         /** Returns the bounding box for all active particles. z axis will always be zero. */\r
213         public BoundingBox getBoundingBox () {\r
214                 if (bounds == null) bounds = new BoundingBox();\r
215 \r
216                 BoundingBox bounds = this.bounds;\r
217                 bounds.inf();\r
218                 for (ParticleEmitter emitter : this.emitters)\r
219                         bounds.ext(emitter.getBoundingBox());\r
220                 return bounds;\r
221         }\r
222 }\r