Skip to main content

Baby, you can drive my car

Posted by malenkov on December 29, 2008 at 6:00 AM PST

Let's steal a car, repaint it, and do this quickly. What is more, do this in JavaFX and consider several programming hints by the way.

1. Steal a car.

To start we need a car. It is not a problem with the car image available on web or located in the application. Image functionality is described in detail in the Image class overview. But what should we do, if the image is contained in another application or archive? Say, I'd like to borrow the car from my colleague who created the PathAnimation sample. Recall that JavaFX employs all power of the Java technology, which supports the specific URL format to retrieve archived content.

def id = "/PathAnimation";
def url = "http://javafx.com/samples{id}/webstart{id}.jar";
def file = "pathanimation/resources/large/car.png";
def image = Image {
  url: "jar:{url}!/{file}"
}

2. Repaint it.

Now repaint the car so nobody could recognize it. What should we do if our game units should differ in color? It is possible to create two different sets of images for every opponent. But you may want to create a game with many opponents, not only two or three. There is only one solution - change the color programmatically, especially because JavaFX provides many visual effects that can be applied to nodes. You can play with these effects using the EffectsPlayground sample.

Use the ColorAdjust effect to tune hue, saturation, brightness, and contrast of any node including images. The particular tint is defined by the hue element of the HSB color space. Thus, change the color of the car using the hue variable of the ColorAdjust object.

    for (i in [1..count]) ImageView {
      image: image
      effect: ColorAdjust {
        hue: 1.0 - 2.0 * i / count
      }
    }

3. Do this quickly.

Remember that stealing car is a bad thing! In my example you should download an archive to retrieve an image. And the size of an archive may be even bigger than the image size. So your application will waste a lot of time to download the archive. But a client is always right, and he doesn't like waiting. Don't load the image twice. JavaFX does not cache images by it's URL, because it may be a special web-service that generates images on query. So, load the image once and use it everywhere as shown in my application. Be careful with binding. Never use the following code.

for (i in [1..count]) ImageView {
  image: Image {
    url: "jar:{url}!/{file}"
  }
}

or

Group {
  content: bind [
    ImageView {
      image: Image {
        url: "jar:{url}!/{file}"
      }
    }
    node // it reloads the image above
  ]
}

4. Let's go!

Now, start the race! Create a separate timeline for every car. Note that short notation for the KeyFrame class can't be used, because the only time literal is allowed in parenthesis. You can't use expression or variable here. Actually, the first key frame is not necessary, because it defines the value that equals to the current value of the changed variable.

for (node in stage.scene.content) Timeline {
  repeatCount: Timeline.INDEFINITE
  keyFrames: [
    at (0s) {node.translateX => -image.width}

    KeyFrame {
      time: 2s + 200ms * random()
      values: node.translateX => stage.scene.width
    }
  ]
}.play()

The source file of the example is available.

My special thanks to The Beatles for the title and to Vaibhav for the idea.

original post

Related Topics >>

Comments

@chapury: All Java classes are available from JavaFX.

Say that my JavaFx script is a CRUD application that doesnt use a DB but reads and writes info from / to a txt file. How would u suggest to implement this concept ?

Works for me on Vista, JDK 6u12-b03, latest Firefox 3.1 nightly. I sometimes notice page scrolling artifacts but these are not FX's fault, more likely plugin or FF3.1 bugs.

Can you reproduce this in your environment by installing 6u12b03? I don't really have time to start uninstalling and reinstalling the different 6u* builds. And it also looks like the Java console is broken in 6u12 as said in the last comment at http://forums.java.net/jive/thread.jspa?messageID=321993&tstart=0

Kirill, this sounds like a bug in FX deployment toolkit. Which version of jre will report java console after you start browser and open java console? Also, could you try to remove 6u12b03 for a moment and see if it helps? Anyway, i suggest to file a bug on FX at http://javafx-jira.kenai.com/ and attach part of your registry describing installed JREs.

Seems it is a problem of 6u12b03 plug-in, because I have no problem with 6u11 and my colleague has no problem with 6u10. I think JavaFX script asks plug-in for its version and can't parse something like "java 1.6.0_12-internal"...

Yes i do. I have Firefox 3.0.5, Java 6u10, 6u11 and 6u12b03 installed on my Windows 2003 machine.

Hi Kirill, Do you have a problem with the applets on javafx.com? For example, http://javafx.com/samples/Draw/

Stealing the image is awesomely written. I thought we need to literally steal the image, I mean by copy paste. But it was a magical 3-4 lines. Car racing outline is ready in 50 lines of code !

And you're still kicking out your readers with the JavaFX script.