import java.awt.*; public class centerletter //this class is an animated letter object that gravitates to a certain spot like the second animated heart pieces. { public char letter; public int gravX, gravY, currentX, currentY, shade, rfilter, gfilter, bfilter; double velX, velY; private boolean stopped, started; //Constructor- letter is the letter represesnted, gravX and gravY are the final position of the letter and startX and startY are the starting positions public centerletter(char letter, int gravX, int gravY, int startX, int startY) { this.letter=letter; this.gravX=gravX; this.gravY=gravY; if (Character.isUpperCase(letter)) this.gravX-=15; else if (letter == 'i' || letter == 't') this.gravX+=4; currentX=startX; currentY=startY; velX=0; velY=0; shade=0; do //to make sure I have bright colors, I allow any combination of red, green, and blue, as long as at least one is there (black is not allowed) { rfilter=(int)(Math.random()*2); gfilter=(int)(Math.random()*2); bfilter=(int)(Math.random()*2); } while (rfilter==0 && gfilter==0 && bfilter==0); stopped=false; started=false; } //the animate() method makes the basic changes needed to move the letter to the next place it will be drawn. public void animate() { if (!started) //if the motion hasn't started yet, but it's being animated, then it will slowly fade in. { //the variable shade will be multiplied by the red, green, and blue masks to form the current color of the letter. shade +=30; if (shade>255) { shade=255; started=true; } } else if (started &! stopped) //if animation has started and not yet stopped, modify the velocity and position as needed { changevelocity(); changeposition(); } else //if the letter has reached it's place and is animating again for some reason, make it go to it's exact gravitational place { //The way the applet uses these, it never uses this part of the method, which is why the letters don't quite line up. In currentX=gravX; //Centergrav (the second animated heart), it was important for the objects to line up, so it called to this point a few times. currentY=gravY; } } //this modifies the velocity vectors to 'gravitate' toward the final x/y coordinates. public void changevelocity() { if (started &! stopped) { if (gravX != currentX) velX+=((gravX-currentX)/Math.abs(gravX-currentX))*10; if (gravY != currentY) velY+=((gravY-currentY)/Math.abs(gravY-currentY))*10; } } //this method changes the position of the letter according to the velocity components public void changeposition() { currentX+=(int)(velX/10); currentY+=(int)(velY/10); velX=velX*.9; velY=velY*.9; if ((Math.abs(currentX-gravX)<=2) && (Math.abs(currentY-gravY)<=2)) //tests if we've arrived (close enought) to our final destination stopped=true; } //this returns true if this letter has reached close to it's final destination public boolean isStopped() { return stopped; } //this returns true if the letter has finished fading and is in motion still public boolean isMoving() { return started; } //this method draws the letter in the appropriate color public void paint(Graphics g) { g.setColor(new Color(shade*rfilter, shade*gfilter, shade*bfilter)); g.setFont(new Font("Serif", Font.BOLD, 60)); g.drawString(String.valueOf(letter), currentX, currentY); } }