Using the plain char from My Free Charset I drew this nerdy guy.
With 2x zoom:
The plain character I’m using to create new characters:
Using the plain char from My Free Charset I drew this nerdy guy.
With 2x zoom:
The plain character I’m using to create new characters:
JavaFX 1.0 is out and is absolutely amazing. You guys did really a great work on it.
As I really need a working SDK on Linux to continue to study and I don’t have any Windows/Mac near me, I’m using the Weiqi Gao’s workaround. I tried to simplify a little bit more the process for those who need JavaFX SDK working on Linux right now.
Download javafxsdk_linux_unofficial.tar.bz2 (~18Mb).
And then
tar -xjvf javafxsdk_linux_unofficial.tar.bz2
sudo cp javafx /opt/javafx
echo “PATH=\$PATH:/opt/javafx/bin” >> ~/.profile
echo “JAVAFX_HOME=/opt/javafx” >> ~/.profile
source ~/.profile
Now you can call javafx, javafxc, javafxdoc and javafxpackager from your terminal. Don’t forget that you need Java 1.6 or greater installed.
Here’s a video showing the SDK working, I’m compiling and running two sample applications. Remeber that as a temporary unofficial port for Linux, there’s not native video support nor hardware acceleration.
[youtube]ENf5mXEIiD8[/youtube]
A simple plain char in a “pokemonic” style I’m doing to use with My Free TileSet. These will be base to create another free and open characters for games.
Animated:
And here a lot of them in home:
Under Creative Commons Attribution-Share Alike license.
Changelog since the last version:
I’m trying to find a good style for outside building for this set. I tried some kinds of roofs but they are not good yet.
At November, 26, on the main page of java.sun.com at the section From The Blogosfere
Thanks for all comments, suggestions and feedback on the post Inkscape and JavaFX working together. The JavaFX guru James Weaver posted about on his blog and it also figured out on java.sun.com on the From The Blogosfere section.
Bob said that there are build binaries of Inkscape for Windows, so we can already see it 0.46-devel working without compiling yourself yours.
\o/
And hey, Project Xort won a second place prize at the MySQL and GlassFish Student Reviews Contest. A lot of guys here from Brazil were prized, congractulations guys!
Two vector drawing I did to a friend. It’s anime-chiby style character, the first mixed with a cat and the second with a bunny. I did using Inkscape. As always, both under the Creative Commons Attribution-Share Alike license.
Download: black_cat.svg
Download: white_bunny.svg
Inkscape is a open source cross-platform vector graphics editor application that I use daily to create draws.
When Project Nile was launched, me and some others guys complained about lack of open source alternatives in the workflow of creation with JavaFX. So we developed a module inside Inkscape that converts your SVG drawings to JavaFX code.
I’ll show here step by step how would be a designer-developer workflow from designing graphical elements, such interfaces, to integrating it to a JavaFX Script code in NetBeans. In this example I’m using Inkscape 0.46-devel, build from the unstable sources and NetBeans 6.1 with the JavaFX module. See here how to build Inkscape from sources and here how to do some optimizations on the build.
Here’s a artwork (a modified version from another one I did in another post) made with Inkscape.
Doesn’t matter the complexity of the drawing it is made of discrete elements such circles, rectangles, paths and others. What the exporting module does is converting these SVG elements into JavaFX Scene Graph API elements.
To do that just click on File → Save As… or Shift+Ctrl+S.
Select JavaFx as the output format.
And chose a name. I’m saving the drawing as Girl.fx.
Now the drawing is a JavaFX class that extends from CustomNode. Once in your classpath (in this case the same directory of your main code) you can call it.
Girl{}
Another example, the famous SVG tiger.
Tiger{}
Actually, you can get the elements of your drawing as attributes nodes of the main node. We use the name you gave to your object to name the attributes.
import javafx.scene.paint.Color;
var girl = Girl{}
girl.rightiris.fill = Color.LIME;
girl.fringe.fill = Color.WHITE;
girl.backhair.fill = Color.DARKGRAY;
girl.hair.fill = Color.GRAY;
import javafx.scene.paint.Color;
var girl = Girl{}
girl.rightiris.fill = Color.GREEN;
girl.backhair.fill = Color.DARKRED;
girl.hair.fill = Color.RED;
You can also put event handling by code.
import javafx.input.MouseEvent;
var p = Player{}
p.x.onMouseClicked = function( e: MouseEvent ):Void {
java.lang.System.exit(0);
}
As a ordinary JavaFX Node, you can do whatever you do with a Node, like using it inside a application or applying effects or transformations.
import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.effect.SepiaTone;
var girl = Girl{
scaleX: 0.5
scaleY: 0.5
effect: SepiaTone{}
}
Frame {
visible: true
stage: Stage {
content: [girl]
}
}
Using this approach you can have the reference and total control under all those elements that compose your drawing. You can design complete interfaces and attach event handling by code.
The module is already on the main Inkscape dev tree and working properly. I guess it will be officially released to all users in the next Inkscape release.
Thanks for all guys that worked on this module and also on the projects Inkscape and JavaFX. Specially thanks for Bob Jamison, Jim Clarke, Joshua Marinacci and others. That’s my first contribution to a big free software, I’m very glad and I want to do much more. 😀
Two SVG fanart drawings of the very cute animation There She Is!! from South-Korean.
The first one is a sign that is shown from first to last episode, love between cats and bunnies is not allowed. 🙂
The second, from the pro-love campaign from the fourth episode.
Enjoy, share, print and modify. They are under Creative Commons Attribution Share-Alike license. I also did a more complete post (in portuguese) in my another blog.
You can optimizing your building times using a parallel build process.
The GNU Make supports it using the parameter –jobs=N (or -j=N), where N is the maximum number of jobs that can be realized at the same time, usually compilation jobs. By default, Make will perform just a job per time. Using -j without arguments imposes no limits on job number. There’s also the load approach using –load-average.
Here’s a benchmark I did showing four different complete builds of the Inkscape project, from one to four jobs at the same time. I used a Intel (Yonah FSB667 Mhz/2MbL2) Dual Core with 2 Gb of Ram with a common Ubuntu 8.10 and default build parameters and no additional optimizations.
Just compiling with make –jobs=2 instead of just make, almost doubles the speed of the build. As I’m using a dual core processor and the heavy compilations dominate the build process, the best result was with 2 jobs.
I had no trouble with those builds but it’s known that you can have problems such implicit dependencies among targets or memory exhaustion. There’s a good article, Optimizing Build Times Using Parallel “make”, on this subject. On the Make manual, there’s also a section on parallel excetution.
So, next time you try a make, try using make –jobs=2 and see the results. 🙂
I continue to develop simple games demos to feel better the strengths and weakness of JavaFX for game development.
Preview:
Click to play via Java Web Start:
There’s a little JavaFX game demo where you have to transport a bomb to a defuse point without touching in the walls. I’m using the collision detection methods I described early in this post to detect when the bomb hits a wall and then explode or when a bomb is inside the defuse point and the game ends. As it’s only a demo, it’s just one single level, but adding more levels would be easy.
Basically we have this four images:
The code is petty simple. A little bit more than 300 lines with even with all comments and declarations. I transform the bomb image into a draggable node, create a list of collidable nodes and a especial node, the goal. I check the collisions when the bomb is dragged by mouse, if it hits something, it blows up.
I use extensively the TimeLine class from the animation framework (javafx.animation) to create chained animations and even to control some game logic.
As I focused in the simplicity, I don’t declared any classes to after instantiate their objects. I just was using common classes from JavaFX and putting logic on ir throught event and binding to external variables.
import javafx.application.Frame;
import javafx.application.Stage;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.animation.Interpolator;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.geometry.Circle;
import javafx.scene.geometry.Rectangle;
import javafx.scene.geometry.Shape;
import javafx.scene.text.Text;
import javafx.scene.Font;
import javafx.scene.FontStyle;
import javafx.input.MouseEvent;
/* Fade variable modified in some animations and used in the fadescreen */
var fade = 0.0;
/* The Bomb */
var lock = false;
var tx = 0.0;
var ty = 0.0;
var bomb:Node = Group{
opacity: bind bombfade;
content: [
ImageView {
image: Image {
url: "{__DIR__}/bomb.png"
}
},
Circle {
centerX: 45, centerY: 21, radius: 7, fill: Color.LIME
opacity: bind led
},
Circle {
centerX: 30, centerY: 30, fill: Color.WHITE
radius: bind fireradius
},
],
var startX = 0.0;
var startY = 0.0;
translateX: bind tx
translateY: bind ty
onMousePressed: function( e: MouseEvent ):Void {
if (lock) {return;}
startX = e.getDragX() - tx;
startY = e.getDragY() - ty;
}
onMouseDragged: function(e:MouseEvent):Void {
if (lock) {return;}
tx = e.getDragX() - startX;
ty = e.getDragY() - startY;
checkcollissions();
}
}
/* Big rectangle that covers all the screen (bomb explosion or game end) */
var fadescreen = Rectangle {
x: 0, y: 0, width: 640, height: 480, fill: Color.WHITE
opacity: bind fade
}
/* The wood floor image for the scenario. */
var floor = ImageView {
image: Image {
url: "{__DIR__}/floor.png"
}
}
/* The goal image where the bomb should be placed. */
var goal = ImageView {
x: 470, y: 360
image: Image {
url: "{__DIR__}/goal.png"
}
}
/* List of obstacles nodes that the bomb can collide with. */
var obstacles = [
Rectangle { x: 120, y: 0, width: 100, height: 300, fill: Color.BLACK},
Rectangle { x: 350, y: 200, width: 100, height: 300, fill: Color.BLACK},
Rectangle { x: 370, y: 50, width: 50, height: 50, fill: Color.BLACK},
Rectangle {
x: 250, y: 120, translateX: bind move, width: 100, height: 50
fill: Color.BLACK
},
];
/* Visible representations of obstacles */
var wallimage = Image {
url: "{__DIR__}/wall.png"
}
var walls = for(obs in obstacles){
ImageView {
x: obs.x, y: obs.y, translateX: bind obs.translateX
clip: obs, image: wallimage
}
}
/* Animation for a blinking green led */
var led = 0.0;
var bombclock = Timeline {
repeatCount: Timeline.INDEFINITE
autoReverse: true
keyFrames : [
KeyFrame {
time : 0s
values : led => 0.0 tween Interpolator.LINEAR
},
KeyFrame {
time : 1s
values : led => 1.0 tween Interpolator.LINEAR
}
]
}
/* Animation for the bomb explosion and game reset */
var fireradius = 0.0;
var explosion:Timeline = Timeline {
repeatCount: 1
keyFrames : [
KeyFrame {
time : 0s
values : [
fireradius => 0.0,
fade => 0.0
]
},
KeyFrame {
time : 2s
values : [
fireradius => 200.0 tween Interpolator.LINEAR,
fade => 1.0 tween Interpolator.LINEAR
]
action: gamereset
},
KeyFrame {
time : 3s
values: fade => 0.0 tween Interpolator.LINEAR
},
]
}
/* Reset variables for initial values */
function gamereset(){
lock = false;
fireradius = 0.0;
tx = 0.0;
ty = 0.0;
bombfade = 1.0;
moveblock.start();
specialcollison.start();
bombclock.start();
}
/* Animation when the bomb reaches the goal. Bomb disapear. */
var bombfade = 1.0;
var bomdisapear = Timeline {
repeatCount: 1
keyFrames : [
KeyFrame {
time : 1s
values: [
bombfade => 0.0 tween Interpolator.EASEBOTH,
fade => 0.0
]
},
KeyFrame {
time : 2s
values:
fade => 1.0 tween Interpolator.LINEAR;
action: gamereset
},
KeyFrame {
time : 3s
values:
fade => 0.0 tween Interpolator.LINEAR;
},
]
}
/* Animation for a moving block. */
var move = 0.0;
var moveblock = Timeline {
repeatCount: Timeline.INDEFINITE
autoReverse: true
keyFrames : [
KeyFrame {
time : 0s
values :
move => 0.0
},
KeyFrame {
time : 3s
values :
move => 200.0 tween Interpolator.EASEBOTH
},
]
}
/* Check and handle possible collisions. */
function checkcollissions(): Void {
if(checkobstacles()){
lock = true;
specialcollison.stop();
moveblock.stop();
explosion.start();
}
if (insidenode(bomb,goal)) {
lock = true;
moveblock.stop();
bomdisapear.start();
}
}
/* There was a bug, when the bomb is stopped, not been gragged, in front of
the moving block, it could pass through it because checkcollissions() was
only called on mouse moving. This make sure checking this special case. */
var specialcollison:Timeline = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames : [
KeyFrame {
time : 1s/5
action: function(){
if(hitnode(obstacles[sizeof obstacles-1], bomb)){
lock = true;
moveblock.stop();
explosion.start();
specialcollison.stop();
}
}
}
]
}
/*
* The next four functions are for collision detection.
* @See http://silveiraneto.net/2008/10/30/javafx-rectangular-collision-detection/
*/
/*
* Check collision between two rectangles.
*/
function collission(ax, ay, bx, by, cx, cy, dx, dy): Boolean {
return not ((ax > dx)or(bx < cx)or(ay > dy)or(by < cy));
}
/*
* Check if the first rectangle are inside the second.
*/
function inside (ax, ay, bx, by, cx, cy, dx, dy):Boolean{
return ((ax > cx) and (bx < dx) and (ay > cy) and (by < dy));
}
function hitnode(a: Node, b:Node): Boolean {
return (collission(
a.getBoundsX(), a.getBoundsY(),
a.getBoundsX() + a.getWidth(), a.getBoundsY() + a.getHeight(),
b.getBoundsX(), b.getBoundsY(),
b.getBoundsX() + b.getWidth(), b.getBoundsY() + b.getHeight()
));
}
function insidenode(a:Node,b:Node):Boolean {
return (inside(
a.getBoundsX(), a.getBoundsY(),
a.getBoundsX() + a.getWidth(), a.getBoundsY() + a.getHeight(),
b.getBoundsX(), b.getBoundsY(),
b.getBoundsX() + b.getWidth(), b.getBoundsY() + b.getHeight()
));
}
/*
* Check collision of bomb against each obstacle.
*/
function checkobstacles(): Boolean{
for(obst in obstacles){
if (hitnode(obst, bomb)){
return true;
}
}
return false;
}
/* Pack visual game elements in a Frame's Stage, unresizable. */
Frame {
title: "Defuse the Bomb"
width: 640
height: 480
resizable: false
closeAction: function() {
java.lang.System.exit( 0 );
}
visible: true
stage: Stage {
content: bind [floor, goal, walls, bomb, fadescreen]
}
}
/* Call gamereset to set initial values and start animations */
gamereset();
Downloads: