[changed] ParticleEmitter to take Sprite rather than Texture.
[added] Sprite copy constructor.
[fixed] Sprite scale bug.
this.inputDir = inputDir;\r
this.filter = filter;\r
\r
- minWidth = filter.width != -1 ? filter.width : settings.minWidth;\r
- minHeight = filter.height != -1 ? filter.height : settings.minHeight;\r
- maxWidth = filter.width != -1 ? filter.width : settings.maxWidth;\r
- maxHeight = filter.height != -1 ? filter.height : settings.maxHeight;\r
- xPadding = images.size() > 1 && filter.direction != Direction.x && filter.direction != Direction.xy ? settings.padding : 0;\r
- yPadding = images.size() > 1 && filter.direction != Direction.y && filter.direction != Direction.xy ? settings.padding : 0;\r
-\r
// Collect and squeeze images.\r
File[] files = inputDir.listFiles(filter);\r
if (files == null) return;\r
}\r
if (images.isEmpty()) return;\r
\r
+ minWidth = filter.width != -1 ? filter.width : settings.minWidth;\r
+ minHeight = filter.height != -1 ? filter.height : settings.minHeight;\r
+ maxWidth = filter.width != -1 ? filter.width : settings.maxWidth;\r
+ maxHeight = filter.height != -1 ? filter.height : settings.maxHeight;\r
+ xPadding = images.size() > 1 && !filter.direction.isX() ? settings.padding : 0;\r
+ yPadding = images.size() > 1 && !filter.direction.isY() ? settings.padding : 0;\r
+\r
System.out.println(inputDir);\r
if (filter.format != null)\r
System.out.println("Format: " + filter.format);\r
}\r
\r
private void writePage (String prefix, File outputDir) throws IOException {\r
- // Remove existing image pages in output dir.\r
- int imageNumber = 1;\r
- File outputFile = new File(outputDir, prefix + imageNumber + ".png");\r
- while (outputFile.exists())\r
- outputFile = new File(outputDir, prefix + ++imageNumber + ".png");\r
-\r
- writer.write("\n" + prefix + imageNumber + ".png\n");\r
- Format format;\r
- if (filter.format != null) {\r
- writer.write("format: " + filter.format + "\n");\r
- format = filter.format;\r
- } else {\r
- writer.write("format: " + settings.defaultFormat + "\n");\r
- format = settings.defaultFormat;\r
- }\r
- if (filter.minFilter == null || filter.magFilter == null)\r
- writer.write("filter: " + settings.defaultFilterMin + "," + settings.defaultFilterMag + "\n");\r
- else\r
- writer.write("filter: " + filter.minFilter + "," + filter.magFilter + "\n");\r
- writer.write("repeat: " + filter.direction + "\n");\r
-\r
// Try reasonably hard to pack images into the smallest POT size.\r
Comparator bestComparator = null;\r
Comparator secondBestComparator = imageComparators.get(0);\r
int grownPixels = 0, grownPixels2 = 0;\r
int i = 0, ii = 0;\r
while (true) {\r
- if (width > maxWidth && height > maxHeight) break;\r
for (Comparator comparator : imageComparators) {\r
// Pack as many images as possible, sorting the images different ways.\r
Collections.sort(images, comparator);\r
}\r
}\r
}\r
+ if (width == maxWidth && height == maxHeight) break;\r
if (bestComparator != null) break;\r
if (settings.pot) {\r
- // 64,64 then 64,128 then 128,64 then 128,128 then 128,256 etc.\r
- if (i % 3 == 0) {\r
- width *= 2;\r
- i++;\r
- } else if (i % 3 == 1) {\r
- width /= 2;\r
+ // 64,64 then 64,128 then 64,256 etc then 128,64 then 128,128 then 128,256 etc.\r
+ grownPixels += width;\r
+ width *= 2;\r
+ if (width > maxWidth) {\r
+ width -= grownPixels;\r
+ grownPixels = 0;\r
height *= 2;\r
- i++;\r
- } else {\r
width *= 2;\r
- i++;\r
}\r
} else {\r
// 64-127,64 then 64,64-127 then 128-255,128 then 128,128-255 etc.\r
i++;\r
}\r
}\r
+ width = Math.min(maxWidth, width);\r
+ height = Math.min(maxHeight, height);\r
}\r
if (bestComparator != null) {\r
Collections.sort(images, bestComparator);\r
}\r
\r
int type;\r
- switch (format) {\r
+ switch (filter.format != null ? filter.format : settings.defaultFormat) {\r
case RGBA8888:\r
case RGBA4444:\r
type = BufferedImage.TYPE_INT_ARGB;\r
default:\r
throw new RuntimeException();\r
}\r
+\r
+ int imageNumber = 1;\r
+ File outputFile = new File(outputDir, prefix + imageNumber + ".png");\r
+ while (outputFile.exists())\r
+ outputFile = new File(outputDir, prefix + ++imageNumber + ".png");\r
+\r
+ writer.write("\n" + outputFile.getName() + "\n");\r
+ Format format;\r
+ if (filter.format != null) {\r
+ writer.write("format: " + filter.format + "\n");\r
+ format = filter.format;\r
+ } else {\r
+ writer.write("format: " + settings.defaultFormat + "\n");\r
+ format = settings.defaultFormat;\r
+ }\r
+ if (filter.minFilter == null || filter.magFilter == null)\r
+ writer.write("filter: " + settings.defaultFilterMin + "," + settings.defaultFilterMag + "\n");\r
+ else\r
+ writer.write("filter: " + filter.minFilter + "," + filter.magFilter + "\n");\r
+ writer.write("repeat: " + filter.direction + "\n");\r
+\r
BufferedImage canvas = new BufferedImage(width, height, type);\r
insert(canvas, images, bestWidth, bestHeight);\r
System.out.println("Writing " + canvas.getWidth() + "x" + canvas.getHeight() + ": " + outputFile);\r
g.drawRect(0, 0, width - 1, height - 1);\r
}\r
// Pretend image is larger so padding on right and bottom edges is ignored.\r
- if (filter.direction != Direction.x && filter.direction != Direction.xy) width += xPadding;\r
- if (filter.direction != Direction.y && filter.direction != Direction.xy) height += yPadding;\r
+ if (!filter.direction.isX()) width += xPadding;\r
+ if (!filter.direction.isY()) height += yPadding;\r
Node root = new Node(0, 0, width, height);\r
int usedPixels = 0;\r
for (int i = images.size() - 1; i >= 0; i--) {\r
final byte[] a = new byte[1];\r
int top = 0;\r
int bottom = source.getHeight();\r
- if (filter.direction != Direction.y && filter.direction != Direction.xy) {\r
+ if (!filter.direction.isY()) {\r
outer:\r
for (int y = 0; y < source.getHeight(); y++) {\r
for (int x = 0; x < source.getWidth(); x++) {\r
}\r
int left = 0;\r
int right = source.getWidth();\r
- if (filter.direction != Direction.x && filter.direction != Direction.xy) {\r
+ if (!filter.direction.isX()) {\r
outer:\r
for (int x = 0; x < source.getWidth(); x++) {\r
- for (int y = top; y <= bottom; y++) {\r
+ for (int y = top; y < bottom; y++) {\r
alphaRaster.getDataElements(x, y, a);\r
int alpha = a[0];\r
if (alpha < 0) alpha += 256;\r
}\r
outer:\r
for (int x = source.getWidth(); --x >= left;) {\r
- for (int y = top; y <= bottom; y++) {\r
+ for (int y = top; y < bottom; y++) {\r
alphaRaster.getDataElements(x, y, a);\r
int alpha = a[0];\r
if (alpha < 0) alpha += 256;\r
if (imageName.startsWith("/") || imageName.startsWith("\\")) imageName = imageName.substring(1);\r
int dotIndex = imageName.lastIndexOf('.');\r
if (dotIndex != -1) imageName = imageName.substring(0, dotIndex);\r
- imageName = imageName.replace("_" + filter.format, "");\r
+ imageName = imageName.replace("_" + formatToAbbrev.get(filter.format), "");\r
imageName = imageName.replace("_" + filter.direction, "");\r
imageName = imageName.replace("_" + filterToAbbrev.get(filter.minFilter) + "," + filterToAbbrev.get(filter.magFilter),\r
"");\r
int height = -1;\r
Settings settings;\r
\r
- public Filter (Settings settings, Direction direction, Format format, int width, int height, TextureFilter minFilter,\r
- TextureFilter magFilter) {\r
- this.settings = settings;\r
+ public Filter (Direction direction, Format format, int width, int height, TextureFilter minFilter, TextureFilter magFilter) {\r
this.direction = direction;\r
this.format = format;\r
this.width = width;\r
}\r
\r
static private enum Direction {\r
- x, y, xy, none\r
+ x, y, xy, none;\r
+\r
+ public boolean isX () {\r
+ return this == x || this == xy;\r
+ }\r
+\r
+ public boolean isY () {\r
+ return this == y || this == xy;\r
+ }\r
}\r
\r
static final HashMap<TextureFilter, String> filterToAbbrev = new HashMap();\r
}\r
\r
static private void process (Settings settings, File inputDir, File outputDir, File packFile) throws Exception {\r
+ if (inputDir.getName().startsWith(".")) return;\r
+\r
// Clean existing page images.\r
if (outputDir.exists()) {\r
String prefix = inputDir.getName();\r
TextureFilter mag = filters.get(iii);\r
if ((min == null && mag != null) || (min != null && mag == null)) continue;\r
\r
- Filter filter = new Filter(settings, Direction.none, format, -1, -1, min, mag);\r
+ Filter filter = new Filter(Direction.none, format, -1, -1, min, mag);\r
new SpriteSheetPacker(settings, inputDir, filter, outputDir, packFile);\r
\r
for (int width = settings.minWidth; width <= settings.maxWidth; width <<= 1) {\r
- filter = new Filter(settings, Direction.x, format, width, -1, min, mag);\r
+ filter = new Filter(Direction.x, format, width, -1, min, mag);\r
new SpriteSheetPacker(settings, inputDir, filter, outputDir, packFile);\r
}\r
\r
for (int height = settings.minHeight; height <= settings.maxHeight; height <<= 1) {\r
- filter = new Filter(settings, Direction.y, format, -1, height, min, mag);\r
+ filter = new Filter(Direction.y, format, -1, height, min, mag);\r
new SpriteSheetPacker(settings, inputDir, filter, outputDir, packFile);\r
}\r
\r
for (int width = settings.minWidth; width <= settings.maxWidth; width <<= 1) {\r
for (int height = settings.minHeight; height <= settings.maxHeight; height <<= 1) {\r
- filter = new Filter(settings, Direction.xy, format, width, height, min, mag);\r
+ filter = new Filter(Direction.xy, format, width, height, min, mag);\r
new SpriteSheetPacker(settings, inputDir, filter, outputDir, packFile);\r
}\r
}\r
File[] files = inputDir.listFiles();\r
if (files == null) return;\r
for (File file : files)\r
- if (file.isDirectory()) process(settings, file, new File(outputDir, file.getName()), packFile);\r
+ if (file.isDirectory()) process(settings, file, outputDir, packFile);\r
}\r
\r
static public void process (Settings settings, String input, String output) throws Exception {\r
}\r
input = args[0];\r
output = args[1];\r
- // input = "c:/temp/pack-in";\r
- // output = "c:/temp/pack-out";\r
- process(new Settings(), input, output);\r
+ Settings settings = new Settings();\r
+ process(settings, input, output);\r
}\r
}\r
lastDir = dir;\r
ParticleEffect effect = new ParticleEffect();\r
try {\r
- effect.loadEmitters(Gdx.files.getFileHandle(new File(dir, file).getAbsolutePath(), FileType.Absolute));\r
+ effect.loadEmitters(Gdx.files.absolute(new File(dir, file).getAbsolutePath()));\r
editor.effect = effect;\r
emitterTableModel.getDataVector().removeAllElements();\r
editor.particleData.clear();\r
heightLabel.setText("Height: " + icon.getIconHeight());\r
revalidate();\r
emitter.setImagePath(new File(dir, file).getAbsolutePath());\r
- emitter.setTexture(null);\r
+ emitter.setSprite(null);\r
} catch (Exception ex) {\r
ex.printStackTrace();\r
}\r
import com.badlogic.gdx.Gdx;\r
import com.badlogic.gdx.InputProcessor;\r
import com.badlogic.gdx.backends.lwjgl.LwjglCanvas;\r
+import com.badlogic.gdx.files.FileHandle;\r
import com.badlogic.gdx.graphics.BitmapFont;\r
import com.badlogic.gdx.graphics.Color;\r
import com.badlogic.gdx.graphics.GL10;\r
ParticleData data = particleData.get(emitter);\r
if (data == null) particleData.put(emitter, data = new ParticleData());\r
data.enabled = enabled;\r
+ emitter.reset();\r
}\r
\r
public boolean isEnabled (ParticleEmitter emitter) {\r
}\r
\r
activeCount = 0;\r
+ boolean complete = true;\r
for (ParticleEmitter emitter : effect.getEmitters()) {\r
- if (emitter.getTexture() == null && emitter.getImagePath() != null) loadImage(emitter);\r
+ if (emitter.getSprite() == null && emitter.getImagePath() != null) loadImage(emitter);\r
boolean enabled = isEnabled(emitter);\r
if (enabled) {\r
- if (emitter.getTexture() != null) emitter.draw(spriteBatch, delta);\r
+ if (emitter.getSprite() != null) emitter.draw(spriteBatch, delta);\r
activeCount += emitter.getActiveCount();\r
+ if (emitter.isContinuous()) complete = false;\r
+ if (!emitter.isComplete()) complete = false;\r
}\r
}\r
- if (effect.isComplete()) effect.start();\r
+ if (complete) effect.start();\r
\r
maxActive = Math.max(maxActive, activeCount);\r
maxActiveTimer += delta;\r
spriteBatch.end();\r
\r
// gl.drawLine((int)(viewWidth * getCurrentParticles().getPercentComplete()), viewHeight - 1, viewWidth, viewHeight -\r
-// 1);\r
+ // 1);\r
}\r
\r
private void loadImage (ParticleEmitter emitter) {\r
final String imagePath = emitter.getImagePath();\r
+ String imageName = new File(imagePath.replace('\\', '/')).getName();\r
try {\r
- emitter.setTexture(Gdx.graphics.newTexture(Gdx.files.getFileHandle(imagePath, FileType.Absolute),\r
- TextureFilter.Linear, TextureFilter.Linear, TextureWrap.ClampToEdge, TextureWrap.ClampToEdge));\r
+ FileHandle file;\r
+ if (imagePath.equals("particle.png"))\r
+ file = Gdx.files.classpath(imagePath);\r
+ else\r
+ file = Gdx.files.absolute(imagePath);\r
+ emitter.setSprite(new Sprite(Gdx.graphics.newTexture(file, TextureFilter.Linear, TextureFilter.Linear,\r
+ TextureWrap.ClampToEdge, TextureWrap.ClampToEdge)));\r
} catch (GdxRuntimeException ex) {\r
+ ex.printStackTrace();\r
EventQueue.invokeLater(new Runnable() {\r
public void run () {\r
JOptionPane.showMessageDialog(ParticleEditor.this, "Error loading image:\n" + imagePath);\r
static final int VERTEX_SIZE = 2 + 1 + 2;\r
static final int SPRITE_SIZE = 4 * VERTEX_SIZE;\r
\r
- Texture texture;\r
- private float[] vertices = new float[20];\r
+ private Texture texture;\r
+ private final float[] vertices = new float[20];\r
private float x, y;\r
private float width, height;\r
private float originX, originY;\r
private float rotation;\r
private float scaleX = 1, scaleY = 1;\r
- private Color color = new Color(1, 1, 1, 1);\r
+ private final Color color = new Color(1, 1, 1, 1);\r
private boolean dirty;\r
\r
/**\r
}\r
\r
/**\r
+ * Creates a sprite that is a copy in every way of the specified sprite.\r
+ */\r
+ public Sprite (Sprite sprite) {\r
+ if (sprite == null) throw new IllegalArgumentException("sprite cannot be null.");\r
+ texture = sprite.texture;\r
+ System.arraycopy(sprite.vertices, 0, vertices, 0, 20);\r
+ x = sprite.x;\r
+ y = sprite.y;\r
+ width = sprite.width;\r
+ height = sprite.height;\r
+ originX = sprite.originX;\r
+ originY = sprite.originY;\r
+ rotation = sprite.rotation;\r
+ scaleX = sprite.scaleX;\r
+ scaleY = sprite.scaleY;\r
+ color.set(sprite.color);\r
+ dirty = sprite.dirty;\r
+ }\r
+\r
+ /**\r
* Sets the position and size of the sprite when drawn, before scaling and\r
* rotation are applied. If origin, rotation, or scale are changed, it is\r
* slightly more efficient to set the bounds after those operations.\r
dirty = false;\r
\r
float[] vertices = this.vertices;\r
- float localX = -originX * scaleX;\r
- float localY = -originY * scaleY;\r
- float localX2 = (-originX + width) * scaleX;\r
- float localY2 = (-originY + height) * scaleY;\r
+ float localX = -originX;\r
+ float localY = -originY;\r
+ float localX2 = localX + width;\r
+ float localY2 = localY + height;\r
+ float worldOriginX = this.x - localX;\r
+ float worldOriginY = this.y - localY;\r
if (scaleX != 1 || scaleY != 1) {\r
localX *= scaleX;\r
localY *= scaleY;\r
localX2 *= scaleX;\r
localY2 *= scaleY;\r
}\r
- float worldOriginX = this.x + originX;\r
- float worldOriginY = this.y + originY;\r
if (rotation != 0) {\r
float cos = MathUtils.cosDeg(rotation);\r
float sin = MathUtils.sinDeg(rotation);\r
private final PackedSprite[] images;\r
\r
public SpriteSheet (FileHandle packFile, FileHandle imagesDir) {\r
+ this(packFile, imagesDir, false);\r
+ }\r
+\r
+ public SpriteSheet (FileHandle packFile, FileHandle imagesDir, boolean flip) {\r
PriorityQueue<PackedSprite> sortedSprites = new PriorityQueue(16, indexComparator);\r
\r
BufferedReader reader = new BufferedReader(new InputStreamReader(packFile.read()), 64);\r
int width = Integer.parseInt(tuple[0]);\r
int height = Integer.parseInt(tuple[1]);\r
\r
- PackedSprite image;\r
+ PackedSprite sprite;\r
if (rotate) {\r
- image = new PackedSprite(pageImage, left, top, height, width);\r
- image.rotate90(true);\r
+ sprite = new PackedSprite(pageImage, left, top, height, width);\r
+ sprite.rotate90(true);\r
} else\r
- image = new PackedSprite(pageImage, left, top, width, height);\r
- image.name = line;\r
+ sprite = new PackedSprite(pageImage, left, top, width, height);\r
+ sprite.name = line;\r
\r
readTuple(reader);\r
- image.originalWidth = Integer.parseInt(tuple[0]);\r
- image.originalHeight = Integer.parseInt(tuple[1]);\r
+ sprite.originalWidth = Integer.parseInt(tuple[0]);\r
+ sprite.originalHeight = Integer.parseInt(tuple[1]);\r
\r
readTuple(reader);\r
- image.offsetX = Integer.parseInt(tuple[0]);\r
- image.offsetY = Integer.parseInt(tuple[1]);\r
- image.setPosition(image.offsetX, image.offsetY);\r
+ sprite.offsetX = Integer.parseInt(tuple[0]);\r
+ sprite.offsetY = Integer.parseInt(tuple[1]);\r
+ sprite.setPosition(sprite.offsetX, sprite.offsetY);\r
\r
- image.index = Integer.parseInt(readValue(reader));\r
- if (image.index == -1) image.index = Integer.MAX_VALUE;\r
+ sprite.index = Integer.parseInt(readValue(reader));\r
+ if (sprite.index == -1) sprite.index = Integer.MAX_VALUE;\r
\r
- sortedSprites.add(image);\r
+ if (flip) sprite.flip(false, true);\r
+ sortedSprites.add(sprite);\r
}\r
}\r
} catch (IOException ex) {\r
super.setBounds(x + offsetX, y + offsetY, width, height);\r
}\r
\r
+ public void setOrigin (float originX, float originY) {\r
+ super.setOrigin(originX + offsetX, originY + offsetY);\r
+ }\r
+\r
/**\r
* The name of the original image file, with any trailing numbers or special flags removed.\r
*/\r
import java.io.Writer;\r
import java.util.ArrayList;\r
\r
-import com.badlogic.gdx.Files.FileType;\r
import com.badlogic.gdx.Gdx;\r
import com.badlogic.gdx.files.FileHandle;\r
+import com.badlogic.gdx.graphics.Sprite;\r
import com.badlogic.gdx.graphics.SpriteBatch;\r
+import com.badlogic.gdx.graphics.SpriteSheet;\r
+import com.badlogic.gdx.graphics.SpriteSheet.PackedSprite;\r
import com.badlogic.gdx.graphics.Texture;\r
import com.badlogic.gdx.graphics.Texture.TextureFilter;\r
import com.badlogic.gdx.graphics.Texture.TextureWrap;\r
loadEmitterImages(imagesDir);\r
}\r
\r
- void loadEmitters (FileHandle file) {\r
- InputStream input = file.read();\r
+ public void load (FileHandle effectFile, SpriteSheet spriteSheet) {\r
+ loadEmitters(effectFile);\r
+ loadEmitterImages(spriteSheet);\r
+ }\r
+\r
+ public void loadEmitters (FileHandle effectFile) {\r
+ InputStream input = effectFile.read();\r
emitters.clear();\r
BufferedReader reader = null;\r
try {\r
while (true) {\r
ParticleEmitter emitter = new ParticleEmitter(reader);\r
reader.readLine();\r
- emitter.setImagePath(ParticleEmitter.readString(reader, "Image Path"));\r
+ emitter.setImagePath(reader.readLine());\r
emitters.add(emitter);\r
if (reader.readLine() == null) break;\r
if (reader.readLine() == null) break;\r
}\r
} catch (IOException ex) {\r
- throw new GdxRuntimeException("Error loading effect: " + file, ex);\r
+ throw new GdxRuntimeException("Error loading effect: " + effectFile, ex);\r
} finally {\r
try {\r
if (reader != null) reader.close();\r
}\r
}\r
\r
- private void loadEmitterImages (FileHandle imagesDir) {\r
+ public void loadEmitterImages (SpriteSheet spriteSheet) {\r
+ for (int i = 0, n = emitters.size(); i < n; i++) {\r
+ ParticleEmitter emitter = emitters.get(i);\r
+ String imagePath = emitter.getImagePath();\r
+ if (imagePath == null) continue;\r
+ String imageName = new File(imagePath.replace('\\', '/')).getName();\r
+ int lastDotIndex = imageName.lastIndexOf('.');\r
+ if (lastDotIndex != -1) imageName = imageName.substring(0, lastDotIndex);\r
+ Sprite sprite = spriteSheet.get(imageName);\r
+ if (sprite == null) throw new IllegalArgumentException("SpriteSheet missing image: " + imageName);\r
+ emitter.setSprite(sprite);\r
+ }\r
+ }\r
+\r
+ public void loadEmitterImages (FileHandle imagesDir) {\r
for (int i = 0, n = emitters.size(); i < n; i++) {\r
ParticleEmitter emitter = emitters.get(i);\r
String imagePath = emitter.getImagePath();\r
if (imagePath == null) continue;\r
String imageName = new File(imagePath.replace('\\', '/')).getName();\r
- emitter.setTexture(loadTexture(imagesDir.child(imageName)));\r
+ emitter.setSprite(new Sprite(loadTexture(imagesDir.child(imageName))));\r
}\r
}\r
\r
private ScaledNumericValue spawnHeightValue = new ScaledNumericValue();\r
private SpawnShapeValue spawnShapeValue = new SpawnShapeValue();\r
\r
- private Texture texture;\r
+ private Sprite sprite;\r
private Particle[] particles;\r
private int minParticleCount, maxParticleCount = 4;\r
- private float imageAspectRatio;\r
private int x, y;\r
private String name;\r
private String imagePath;\r
}\r
\r
public ParticleEmitter (ParticleEmitter emitter) {\r
- texture = emitter.texture;\r
- imageAspectRatio = emitter.imageAspectRatio;\r
+ sprite = emitter.sprite;\r
setMaxParticleCount(emitter.maxParticleCount);\r
minParticleCount = emitter.minParticleCount;\r
delayValue.load(emitter.delayValue);\r
restart();\r
}\r
\r
+ public void reset () {\r
+ emissionDelta = 0;\r
+ durationTimer = 0;\r
+ start();\r
+ }\r
+\r
private void restart () {\r
delay = delayValue.active ? delayValue.newLowValue() : 0;\r
delayTimer = 0;\r
if (velocityValue.active && velocityValue.active) updateFlags |= UPDATE_VELOCITY;\r
if (scaleValue.timeline.length > 1) updateFlags |= UPDATE_SCALE;\r
if (rotationValue.active && rotationValue.timeline.length > 1) updateFlags |= UPDATE_ROTATION;\r
- if (windValue.active && windValue.timeline.length > 1) updateFlags |= UPDATE_WIND;\r
- if (gravityValue.active && gravityValue.timeline.length > 1) updateFlags |= UPDATE_GRAVITY;\r
+ if (windValue.active) updateFlags |= UPDATE_WIND;\r
+ if (gravityValue.active) updateFlags |= UPDATE_GRAVITY;\r
if (tintValue.timeline.length > 1) updateFlags |= UPDATE_TINT;\r
}\r
\r
private void activateParticle (int index) {\r
Particle particle = particles[index];\r
if (particle == null) {\r
- particles[index] = particle = new Particle(texture);\r
+ particles[index] = particle = new Particle(sprite);\r
particle.flip(flipX, flipY);\r
}\r
\r
particle.angle = angleValue.newLowValue();\r
particle.angleDiff = angleValue.newHighValue();\r
if (!angleValue.isRelative()) particle.angleDiff -= particle.angle;\r
+ float angle = 0;\r
if ((updateFlags & UPDATE_ANGLE) == 0) {\r
- float angle = particle.angle + particle.angleDiff * angleValue.getScale(0);\r
+ angle = particle.angle + particle.angleDiff * angleValue.getScale(0);\r
particle.angle = angle;\r
particle.angleCos = MathUtils.cosDeg(angle);\r
particle.angleSin = MathUtils.sinDeg(angle);\r
}\r
\r
- particle.scale = scaleValue.newLowValue() / texture.getWidth();\r
- particle.scaleDiff = scaleValue.newHighValue() / texture.getWidth();\r
+ particle.scale = scaleValue.newLowValue() / sprite.getWidth();\r
+ particle.scaleDiff = scaleValue.newHighValue() / sprite.getWidth();\r
if (!scaleValue.isRelative()) particle.scaleDiff -= particle.scale;\r
if ((updateFlags & UPDATE_SCALE) == 0) particle.setScale(particle.scale + particle.scaleDiff * scaleValue.getScale(0));\r
\r
particle.rotation = rotationValue.newLowValue();\r
particle.rotationDiff = rotationValue.newHighValue();\r
if (!rotationValue.isRelative()) particle.rotationDiff -= particle.rotation;\r
- if ((updateFlags & UPDATE_ROTATION) == 0)\r
- particle.setRotation(particle.rotation + particle.rotationDiff * rotationValue.getScale(0));\r
+ if ((updateFlags & UPDATE_ROTATION) == 0) {\r
+ float rotation = particle.rotation + particle.rotationDiff * rotationValue.getScale(0);\r
+ if (aligned) rotation += angle;\r
+ particle.setRotation(rotation);\r
+ }\r
}\r
\r
if (windValue.active) {\r
if (radiusX == 0 || radiusY == 0) break;\r
float scaleY = radiusX / (float)radiusY;\r
if (spawnShapeValue.edges) {\r
- float angle;\r
+ float spawnAngle;\r
switch (spawnShapeValue.side) {\r
case top:\r
- angle = -MathUtils.random(179f);\r
+ spawnAngle = -MathUtils.random(179f);\r
break;\r
case bottom:\r
- angle = MathUtils.random(179f);\r
+ spawnAngle = MathUtils.random(179f);\r
break;\r
default:\r
- angle = MathUtils.random(360f);\r
+ spawnAngle = MathUtils.random(360f);\r
break;\r
}\r
- x += MathUtils.cosDeg(angle) * radiusX;\r
- y += MathUtils.sinDeg(angle) * radiusX / scaleY;\r
+ x += MathUtils.cosDeg(spawnAngle) * radiusX;\r
+ y += MathUtils.sinDeg(spawnAngle) * radiusX / scaleY;\r
} else {\r
int radius2 = radiusX * radiusX;\r
while (true) {\r
}\r
}\r
\r
- int texWidth = texture.getWidth();\r
- int texHeight = texture.getHeight();\r
- particle.setBounds(x - texWidth / 2, y - texHeight / 2, texWidth, texHeight);\r
+ float spriteWidth = sprite.getWidth();\r
+ float spriteHeight = sprite.getHeight();\r
+ particle.setBounds(x - spriteWidth / 2, y - spriteHeight / 2, spriteWidth, spriteHeight);\r
}\r
\r
private boolean updateParticle (int index, float delta, int deltaMillis) {\r
} else {\r
velocityX = velocity * particle.angleCos;\r
velocityY = velocity * particle.angleSin;\r
- if ((updateFlags & UPDATE_ROTATION) != 0) {\r
+ if (aligned || (updateFlags & UPDATE_ROTATION) != 0) {\r
float rotation = particle.rotation + particle.rotationDiff * rotationValue.getScale(percent);\r
if (aligned) rotation += particle.angle;\r
particle.setRotation(rotation);\r
this.y = y;\r
}\r
\r
- // BOZO - Should be setSprite.\r
- public void setTexture (Texture texture) {\r
- this.texture = texture;\r
- if (texture == null) return;\r
- imageAspectRatio = texture.getHeight() / (float)texture.getWidth();\r
- float originX = texture.getWidth() / 2;\r
- float originY = texture.getHeight() / 2;\r
+ public void setSprite (Sprite sprite) {\r
+ this.sprite = sprite;\r
+ if (sprite == null) return;\r
+ float originX = sprite.getOriginX();\r
+ float originY = sprite.getOriginY();\r
+ Texture texture = sprite.getTexture();\r
for (int i = 0, n = particles.length; i < n; i++) {\r
Particle particle = particles[i];\r
if (particle == null) break;\r
}\r
}\r
\r
- public Texture getTexture () {\r
- return texture;\r
+ public Sprite getSprite () {\r
+ return sprite;\r
}\r
\r
public String getName () {\r
float gravity, gravityDiff;\r
float[] tint;\r
\r
- public Particle (Texture texture) {\r
- super(texture);\r
+ public Particle (Sprite sprite) {\r
+ super(sprite);\r
}\r
}\r
\r