// Particles // Move your mouse around to see a trail of particles import pulpcore.animation.Easing; import pulpcore.animation.event.RemoveSpriteEvent; import pulpcore.animation.Timeline; import static pulpcore.image.Colors.*; import pulpcore.image.BlendMode; import pulpcore.image.CoreImage; import pulpcore.Input; import pulpcore.math.CoreMath; import pulpcore.scene.Scene2D; import pulpcore.sprite.FilledSprite; import pulpcore.sprite.Group; import pulpcore.sprite.ImageSprite; import pulpcore.sprite.Sprite; import pulpcore.Stage; public class Particles extends Scene2D { Sprite background; CoreImage[] images; Group particleLayer; int lastX, lastY; boolean wasMouseInside; @Override public void load() { background = new FilledSprite(BLACK); images = CoreImage.load("particles.png").split(6, 1); particleLayer = new Group(); // Particles should ignore mouse input particleLayer.enabled.set(false); // Particles look good with additive blending particleLayer.setBlendMode(BlendMode.Add()); add(background); addLayer(particleLayer); makeParticles(320, 240, 320, 240, 50); setCursor(Input.CURSOR_OFF); } @Override public void update(int elapsedTime) { if (Input.isMouseInside()) { int x = Input.getMouseX(); int y = Input.getMouseY(); if (wasMouseInside) { int dist = (int)Math.sqrt((lastX - x) * (lastX - x) + (lastY - y) * (lastY - y)); makeParticles(lastX, lastY, x, y, 2 + dist / 8); } lastX = x; lastY = y; wasMouseInside = true; } else { wasMouseInside = false; } } private void makeParticles(int x1, int y1, int x2, int y2, int numParticles) { Timeline timeline = new Timeline(); for (int i = 0; i < numParticles; i++) { int size = CoreMath.rand(4, 48); int duration = (200 - size) * 3; int moveDistance = CoreMath.rand(4, 80 - size); double moveDirection = CoreMath.rand(0, 2*Math.PI); int startX = x1 + i * (x2 - x1) / numParticles; int startY = y1 + i * (y2 - y1) / numParticles; int goalX = startX + (int)(moveDistance * Math.cos(moveDirection)); int goalY = startY + (int)(moveDistance * Math.sin(moveDirection)); double startAngle = CoreMath.rand(0, 2*Math.PI); double endAngle = startAngle + CoreMath.rand(-2*Math.PI, 2*Math.PI); CoreImage image = images[CoreMath.rand(images.length - 1)]; Sprite sprite = new ImageSprite(image, startX, startY); sprite.setAnchor(Sprite.CENTER); sprite.setSize(size, size); particleLayer.add(sprite); timeline.animateTo(sprite.x, goalX, duration, Easing.REGULAR_OUT); timeline.animateTo(sprite.y, goalY, duration, Easing.REGULAR_OUT); timeline.animate(sprite.angle, startAngle, endAngle, duration); timeline.at(100).animateTo(sprite.alpha, 0, duration - 100, Easing.REGULAR_OUT); timeline.add(new RemoveSpriteEvent(particleLayer, sprite, duration)); } addTimeline(timeline); } }