The Source for Java Technology Collaboration
User: Password:
Register | Login help    

Search

Online Books:
java.net on MarkMail:


For Those About To Rock

Posted by malenkov on February 27, 2009 at 12:00 PM PST

This simple example produces the firework effect using JavaFX Script. The active use of random numbers brings variety to each firework volley.

To generate random numbers I'm employing the Random class, not the random method of the Math class, because the mobile profile of JavaFX is based on Java ME, and doesn't have this method. The difference between the mobile and desktop profiles is not limited to APIs. For example, the Math class in Java ME doesn't have functions like random or atan.

import java.util.Random;
def random = Random {}
...
          def r =   0 + 255 * random.nextFloat();

Have you paid attention to the nextFloat method I used instead of the nextDouble method? When all Java primitive numeric types had been added to the type system of JavaFX 1.1, the Number type was converted to the Float type instead of Double with a view of better performance on the mobile platform. Consider this fact and do not use Double in your applications for mobile devices.

The Flash class extends the CustomNode class and implements the create method. This method starts an indefinite timeline and generates a lot of circles of different sizes.

  override function create() {
    timer.play();
    Group {
      content: for (index in [1..18]) {
        def length = 50 + 10 * random.nextFloat();
        def radius =  2 +  2 * random.nextFloat();
        for (delta in [1.0, 0.8, 0.6]) Circle {
          fill: bind color
          radius: delta * radius
          centerX: bind delta * length * (1 - opacity)
          transforms: Rotate {
            angle: 20 * (index + random.nextFloat())
          }
        }
      }
    }
  }

Several circles with proportional radius and length (the maximum distance from the centre) are created on each iteration of the cycle. All circles are drawn using a single color that varies sometimes. Therefore I applied data binding here: fill: bind color. Another data binding construction is used to calculate the current position of a circle: centerX: bind delta * length * (1 - opacity). If the opacity value decreases, the circle is located farther from the center. The Rotate transformation defines an angle of a moving direction.

Now, consider key frames for animation.

      KeyFrame {
        time: 0s
        values: opacity => 0.0
        action: function() {
          def r =   0 + 255 * random.nextFloat();
          def g = 100 + 155 * random.nextFloat();
          def b =  50 + 205 * random.nextFloat();
          color = Color.rgb(r, g, b);
          translateX = 50 + random.nextFloat() * (scene.width  - 100);
          translateY = 50 + random.nextFloat() * (scene.height - 100);
        }
      }

When the animation cycle starts the opacity value is set to 0, and random numbers are used to calculate a color and position of the circle.

      KeyFrame {
        time: 1s * random.nextFloat()
        values: opacity => 1.0 tween Interpolator.DISCRETE
      }

Randomly the opacity value is set to 1.

      KeyFrame {
        time: 3s + 1s * random.nextFloat()
        values: opacity => 0.0
      }

Over approximately three seconds the opacity value smoothly changes to 0.

      KeyFrame {
        time: 4s
      }

This key frame is necessary to avoid volley desynchronization. It specifies the exact duration of the timeline.

Stage{
  title: "Firework (JavaFX sample)"
  scene: Scene {
    fill: Color.BLACK
    width: 480
    height: 320
    content: for (index in [1..5]) Flash {
    }
  }
}

The previous code fragment adds several instances to the scene... et voilà!

For Those About To Rock (We Salute You)

The source file of the example is available.

My special thanks to AC/DC for the title.

Related Topics >> Programming      
Comments
Comments are listed in date ascending order (oldest first)

This demo takes way too long to load. Have the 1.6 update 12 installed. Also, is it possible to avoid getting this popup saying "visit java.com"? Imagine if all plugins would do this...