Дата публикации: 04.11.2013 13:26:59
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()
Let's start created application.
My special thanks to The Beatles for the title and to Vaibhav for the idea.
PS. This article was originally posted on the Java.net site.