/** * This class represents an abstract shape that leaves a * trail behind as it moves. * * The shape is drawn MAX_STAGE times. The first * FADE_STAGE times it is drawn, it moves, and the preceding * image is faded by ALPHA_DECR. After FADE_STAGE iterations, * the image no longer moves, but fades out over the next * FADE_STAGE iterations. */ class TrailShape { float x; // center x float y; // center y float dx; // horizontal movement at each iteration float dy; // vertical movement float startSize; // starting size float dSizePercent; // size percentage change at each iteration float stage; // drawing stage color sColor; // shape color static final int FADE_STAGE = 15; static final int MAX_STAGE = 30; static final int ALPHA_DECR = 16; // ceil(256/FADE_STAGE) TrailShape(float x, float y, float dx, float dy, float size, float dSizePercent, color sColor){ this.x = x; this.y = y; this.dx = dx; this.dy = dy; this.startSize = size; this.dSizePercent = dSizePercent; this.sColor = sColor; stage = 0; } void display() { int alpha; int i; if (stage < MAX_STAGE) { noFill(); /* Repeatedly draw the shape up to but not including the current stage, but no more than FADE_STAGE times */ for (i = 0; i < min(stage, FADE_STAGE); i++) { alpha = int(255 - ALPHA_DECR * (stage - i)); if (alpha >= 0) // no need to draw a totally transparent object { stroke(setAlpha(sColor, alpha)); drawShape(x + i * dx, y + i * dy, startSize * (1 + i * dSizePercent)); } } /* Now draw the current stage. Since the current stage is *always* drawn, we need to take the stage number mod FADE_STAGE to keep it from disappearing prematurely */ alpha = floor(max(0, 255 - ALPHA_DECR * ((stage - i) % FADE_STAGE))); stroke(setAlpha(sColor, alpha)); drawShape(x + i * dx, y + i * dy, startSize * (1 + i * dSizePercent)); stage++; } } /** * Draws the shape at the given (x,y) location with sides of * length size. In the case of a circle, size gives the radius. */ void drawShape(float x, float y, float size) { println("Did you remember to override drawShape?"); } /** * Given a color c and an alpha value a, return a new * color with c's R, G, and B, but alpha set to A. * Since this program is in RGB 255 mode, it's easiest * to do by using bit manipulation. This is a convenience * method. */ color setAlpha(color c, int a) { color result = (c & 0xffffff) | ((a & 0xff) << 24); return result; } /** * Convert to a string */ String toString() { String result = "(" + x + ", " + y + "), speed (" + dx + ", " + dy + ") size " + startSize + " [" + dSizePercent + "%] color " + hex(sColor); return result; } }