Jim has posted 66 posts at DZone. You can read more from them at their website. View Full User Profile

JavaFX Whack-a-Janssen Game for Devoxx

12.10.2008
| 4182 views |
  • submit to reddit

This year I had to miss Devoxx 2008, but really wanted to go. Not only is it a great conference, but this year it is the first major conference since the JavaFX SDK 1.0 was released, so there are some great JavaFX sessions and speakers on the agenda.

 

Whack-a-janssen

So, in honor of the Devoxx conference and the excellent leadership that Stephan Janssen provides to it, I've created a game in JavaFX.  I'm not a game programmer nor am I a graphic designer, and I didn't enlist the help of either for this quick effort.  With those disclaimers, and the hope that Stephan Janssen will take this in good-natured fun, I give you: "Whack-A-Janssen", styled loosely after the old "Whac-a-Mole" game.

Click on the Launch icon to run it as a Java Web Start application.  To play the game, simply click the Start Game button and then click on Stephan's faces when they pop up.  While the game is in progress the Start Game button changes to Stop Game.  If all three faces appear, the game is over and the Start Game button reappears.

Webstart.small2

The Code Behind the Game

This game makes use of the transition convenience classes in the javafx.animation.transition package to achieve animated movement, scaling and fading.  It also uses the Timeline and KeyFrame classes in the javafx.animation package to popup the many faces of Stephen:

/*
* WhackAJanssen.fx
*
* Developed 2008 by James L. Weaver (jim.weaver at javafxpert.com)
* to demonstrate creating applications using JavaFX SDK 1.0, and for
* having some good-natured fun with Stephan Janssen of Devoxx.
*/

package javafxpert;

import javafx.animation.*;
import javafx.animation.transition.*;
import javafx.ext.swing.*;
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.image.*;
import javafx.scene.input.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.text.*;
import javafx.scene.transform.*;
import javafx.stage.Stage;
import java.lang.Math;

Stage {
// Transitions for popups
var popupRefs:Transition[] = [
ScaleTransition {
node: bind stephen1Ref
duration: 1s
fromX: 0.1
fromY: 0.1
toX: 1.0
toY: 1.0
},
TranslateTransition {
node: bind stephen2Ref
duration: 1s
fromY: 0
byY: -70
//autoReverse: true
},
FadeTransition {
node: bind stephen3Ref
duration: 1s
fromValue: 0.0
toValue: 1.0
//autoReverse: true
}
];
// Transitions for knock-downs
var knockdownRefs:Transition[] = [
ScaleTransition {
node: bind stephen1Ref
duration: 500ms
fromX: 1.0
fromY: 1.0
toX: 0.1
toY: 0.1
},
TranslateTransition {
node: bind stephen2Ref
duration: 500ms
fromY: -70
byY: 70
//autoReverse: true
},
FadeTransition {
node: bind stephen3Ref
duration: 500ms
fromValue: 1.0
toValue: 0.0
//autoReverse: true
}
];
var stephen1Ref:ImageView;
var stephen2Ref:ImageView;
var stephen3Ref:ImageView;
// Timeline that causes random Stephens to popup
var gameTimeline = Timeline {
keyFrames: [
KeyFrame {
time: 2s
action: function():Void {
var stephenNum:Integer =
(Math.random() * sizeof stephensDown) as Integer;
if (stephensDown[stephenNum]) {
stephensDown[stephenNum] = false;
popupRefs[stephenNum].playFromStart();
}
}
}
]
repeatCount: Timeline.INDEFINITE
}
// Position that the stephens are in. The trigger evaluates whether
// the game is over and stops the game Timeline
var stephensDown:Boolean[] = [true, true, true] on replace {
var downs = for (stephen in stephensDown where stephen == true) stephen;
if (sizeof downs == 0) {
gameTimeline.stop();
}
};
title: "Whack-A-Janssen"
scene: Scene {
var btn:SwingButton;
width: 300
height: 450
fill: Color.rgb(1, 1, 1)
content: [
ImageView {
transforms: Translate.translate(24, 56)
image: Image {
url: "{__DIR__}images/devoxx250.jpg"
}
},
// Left-most face
stephen1Ref = ImageView {
transforms: [
Translate.translate(63, 99),
]
opacity: 1.0
image: Image {
url: "{__DIR__}images/sj_face_small.gif"
}
cursor: Cursor.HAND
onMouseClicked: function(me:MouseEvent):Void {
stephensDown[0] = true;
knockdownRefs[0].playFromStart();
}
},
// Middle face
Group {
transforms: Translate.translate(120, 20)
content: [
Group {
content: [
stephen2Ref = ImageView {
transforms: Translate.translate(0, 90)
image: Image {
url: "{__DIR__}images/sj_head_small.gif"
}
},
]
//66 x 98
//36x10
clip: Group {
content: [
Polygon {
points: [
0, 0,
0, 46
15, 80
51, 80,
66, 46,
66, 0
]
},
Arc {
centerX: 33
centerY: 80
startAngle: 180
length: 180
radiusX: 18
radiusY: 10
}
]
}
},
Rectangle {
width: 66
height: 98
fill: Color.TRANSPARENT
cursor: Cursor.HAND
onMouseClicked: function(me:MouseEvent):Void {
stephensDown[1] = true;
knockdownRefs[1].playFromStart();
}
}
]
},
// Right-most face
stephen3Ref = ImageView {
transforms: Translate.translate(190, 95)
image: Image {
url: "{__DIR__}images/sj_left_facing.gif"
}
opacity: 0.0
effect: Glow {}
cursor: Cursor.HAND
onMouseClicked: function(me:MouseEvent):Void {
stephensDown[2] = true;
knockdownRefs[2].playFromStart();
}
},
// Start Game button
btn = SwingButton {
transforms: [
Translate.translate(200, 207),
Scale.scale(0.7, 0.7),
Rotate { angle: -4}
]
text: bind if (gameTimeline.running) "Stop Game" else "Start Game"
foreground: bind if (gameTimeline.running) Color.BLACK else Color.RED
font: Font {
name: "Arial Bold"
}
action: function():Void {
if (not gameTimeline.running) {
stephensDown[0] = true;
stephensDown[1] = true;
stephensDown[2] = true;
knockdownRefs[0].playFromStart();
knockdownRefs[1].playFromStart();
knockdownRefs[2].playFromStart();
gameTimeline.playFromStart();
}
else {
gameTimeline.stop();
}
}
},
ImageView {
transforms: Translate.translate(0, 325)
image: Image {
url: "{__DIR__}images/devoxx_logo.jpg"
}
},

]
}
}

 

Enjoy the conference if you're attending, and this very simple and lame Whack-A-Janssen game!

Regards,

Jim Weaver
JavaFXpert.com

Published at DZone with permission of its author, Jim Weaver.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Mike P(Okidoky) replied on Wed, 2008/12/10 - 12:54pm

When I look at source like this, then I find more than ever before, that it is so much better to use aligned braces.

code
{
  code
  {
    code
  }
}

Why are people so religiously gun ho on putting the braces at the end?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.