Audio recorded at Chris Hoffman speak at CESOL. Not good quality but audible.
Download: chris_hoffman_mozilla_engineering_director_cesol_2008.ogg
Audio recorded at Chris Hoffman speak at CESOL. Not good quality but audible.
Download: chris_hoffman_mozilla_engineering_director_cesol_2008.ogg
A simple demo using some techniques described in the post JavaFX side scrolling gaming.
[youtube]yNUfo538mfA[/youtube]
Original ogg video: blackdot.ogg
Source (NetBeans project): BlackDot.tar.gz
Source (one file only): blackdot.fx
Java Web Start: launch.jnlp
Ãudio da palestra do Marcelo D’elia Branco, Projeto cibercrimes-Azeredo e a Sociedade em Rede: desafios para construção de um modelo social, democrático no Brasil.
Download: marcelo_Branco_CESOL_2008_Fortaleza.ogg. Aproximadamente 20MiB.
obs: esse audio cortou um pedaço do começo da apresentação e não inclui a seção de perguntas no fim da apresentação.
I started to make several small JavaFX game demos. I’m doing that to fell where JavaFX is good to make this sort of game and what patterns would be frequently needed to implement, where I will place a little framework for fast development of simple casual games. What I’m calling now just ‘GameFX’. My first experiment was to creating a side scrolling animation that’s is usefull to create the parallax effect in side scrolling games. For that I created the class Slidding. You create an Slidding with a set of nodes and they will slide from right to left and when a node reaches the left side it back to the right side.
Example:
Slidding {
content: [
Circle {
centerX: 100, centerY: 100, radius: 40
fill: Color.RED
},
Circle {
centerX: 300, centerY: 100, radius: 40
fill: Color.BLUE
}
]
clock: 0.05s
}
That produces:
You create a Slidding with a list of Nodes at content, a clock (that will determine the speed of that animation) and a width. If you don’t provide a width, the slidding will do the best effort to determine one. You can use this approach to create more complex scenarios, using more Slidding groups.
This is a example of that:
import javafx.application.*;
import javafx.animation.*;
import javafx.scene.geometry.*;
import javafx.scene.paint.*;
import javafx.scene.*;
import gamefx.Slidding;
var SCREENW = 500;
var SCREENH = 400;
/* the sky is a light blue rectangle */
var sky = Rectangle {
width: SCREENW, height: SCREENH
fill: LinearGradient {
startX: 0.0 , startY: 0.0
endX: 0.0, endY: 1.0
proportional: true
stops: [
Stop { offset: 0.0 color: Color.LIGHTBLUE },
Stop { offset: 0.7 color: Color.LIGHTYELLOW },
Stop { offset: 1.0 color: Color.YELLOW }
]
}
}
/* the ground is a olive rectangle */
var ground = Rectangle {
translateY: 300
width: 500, height: 100
fill: LinearGradient {
startX: 0.0 , startY: 0.0
endX: 0.0, endY: 1.0
proportional: true
stops: [
Stop { offset: 0.2 color: Color.OLIVE },
Stop { offset: 1.0 color: Color.DARKOLIVEGREEN }
]
}
}
/* a clod cloud is like an ellipse */
class Cloud extends Ellipse {
override attribute radiusX = 50;
override attribute radiusY = 25;
override attribute fill = Color.WHITESMOKE;
override attribute opacity = 0.5;
}
/* we create a slidding of clouds */
var clouds = Slidding {
content: [
Cloud{centerX: 100, centerY: 100},
Cloud{centerX: 150, centerY: 20},
Cloud{centerX: 220, centerY: 150},
Cloud{centerX: 260, centerY: 200},
Cloud{centerX: 310, centerY: 40},
Cloud{centerX: 390, centerY: 150},
Cloud{centerX: 450, centerY: 30},
Cloud{centerX: 550, centerY: 100},
]
clock: 0.2s
}
var SUNX = 100;
var SUNY = 300;
var rotation = 0;
/* the sun, with it's corona */
var sun = Group {
rotate: bind rotation
anchorX: SUNX, anchorY: SUNY
content: [
for (i in [0..11]) {
Arc {
centerX: SUNX, centerY: SUNY
radiusX: 500, radiusY: 500
startAngle: 2 * i * (360 / 24), length: 360 / 24
type: ArcType.ROUND
fill: Color.YELLOW
opacity: 0.3
}
},
Circle {
centerX: SUNX, centerY: SUNY, radius: 60
fill: Color.YELLOW
},
]
}
/* animate the corona changing the it rotation angle */
var anim = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames : [
KeyFrame {
time : 0s
values: rotation => 0.0 tween Interpolator.LINEAR
},
KeyFrame {
time : 2s
values: rotation => (360.0/12) tween Interpolator.LINEAR
},
]
}
anim.start();
/* a tree is a simple polygon */
class Tree extends Polygon{
public attribute x = 0;
public attribute y = 0;
override attribute points = [0,0, 10,30, -10,30];
override attribute fill = Color.DARKOLIVEGREEN;
init{
translateX = x;
translateY = y;
}
}
/* a forest is a lot of trees */
var forest = Slidding{
content: [
Tree{x: 20, y: 320}, Tree{x: 80, y: 280}, Tree{x:120, y: 330},
Tree{x:140, y: 280}, Tree{x:180, y: 310}, Tree{x:220, y: 320},
Tree{x:260, y: 280}, Tree{x:280, y: 320}, Tree{x:300, y: 300},
Tree{x:400, y: 320}, Tree{x:500, y: 280}, Tree{x:500, y: 320}
]
clock: 0.1s
width: SCREENW
}
Frame {
title: "Side Scrolling"
width: SCREENW
height: SCREENH
closeAction: function() {
java.lang.System.exit( 0 );
}
visible: true
stage: Stage {
content: [sky, sun, clouds, ground, forest]
}
}
Producing:
If you want to try these examples, place this Slidding implementation as Slidding.fx in a directory named gamefx, or grab here the NetBeans project.
package gamefx;
import javafx.scene.CustomNode;
import javafx.scene.Node;
import javafx.scene.Group;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
/*
* The slidding group of nodes for side scrolling animations.
*
* @example
* Slidding {
* width: 300
* content: [
* Circle { centerX: 100, centerY: 100, radius: 40, fill: Color.RED },
* Circle { centerX: 200, centerY: 100, radius: 40, fill: Color.BLUE },
* ]
* clock: 0.05s
* }
*/
public class Slidding extends CustomNode {
public attribute content: Node[];
public attribute clock = 0.1s;
public attribute width: Number;
public attribute autostart = true;
public attribute cycle = true;
public attribute anim = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames : [
KeyFrame {
time : clock
action: function() {
for(node in content){
node.translateX--;
if (node.getX() + node.translateX + node.getWidth() <= 0){
if(cycle){
node.translateX = width - node.getX();
} else {
delete node from content;
}
}
}
} // action
} // keyframe
]
} // timeline
public function create(): Node {
// if width is not setted, we try to figure out
if(width == 0) {
for(node in content) {
if(node.getX() + node.getWidth() > width) {
width = node.getX() + node.getWidth();
}
}
}
// normaly the slidding will start automaticaly
if(autostart){
anim.start();
}
// just a Group of Nodes
return Group {
content: content
};
}
}
Is not the final implementation but it’s a idea. Soon I’ll show a demo game I did using theses codes.
This month, August 2008, from days 18 to 22 you have a opportunity to ask question about the JavaFX SDK Preview and get answers from experts on that topics. The Ask the Experts program requires no login, and allows you to submit questions at a time convenient to you.
These three experts Software Engineers from Sun Microsystems and related with JavaFX project will be answering questions about JavaFX:
It’s a good event to get answers for your JavaFX questions.
O Netbeans.org anunciou a disponibilidade do NetBeans IDE 6.5 Beta. Abaixo a tradução do anúncio:
O NetBeans IDE 6.5 introduz várias novas funcionalidades, incluindo uma IDE robusta para PHP, deputação de JavaScript para o Firefox e IE, e suporte a Groovy e Grails. Esse lançamento também inclui várias melhorias para o desenvolvimento em Java, Ruby e Rails, e C/C++. Dentre as melhorias no Java destacam-se: suporte nativo ao Hibernate, importação de projetos do Eclipse, e compilação no salvamento.
Links:
Outros destaques:
O NetBeans IDE 6.5 final está planejado para ser lançado em Outubro de 2008. Como sempre, é bem vindo e nós encorajamos seu feedback sobre sua experiência usando a IDE NetBeans. Visite nossas listas de email ou faça uma postagem no seu blog.
One thing that I like a lot to do with JavaFX is draggable objects. Due to some recent changes in the JavaFX syntax my old codes for that are no longer working. Joshua Marinacci from Sun’s JavaFX engineering team and other guys from the JavaFX community gave me some tips. Here some strategies I’m using for making draggable nodes in JavaFX.
In this first example, a simple draggable ellipse.
import javafx.application.*;
import javafx.scene.paint.*;
import javafx.scene.geometry.*;
import javafx.input.*;
Frame {
width: 300, height: 300, visible: true
stage: Stage {
content: [
Ellipse {
var endX = 0.0; var endY = 0.0
var startX = 0.0; var startY = 0.0
centerX: 150, centerY: 150
radiusX: 80, radiusY: 40
fill: Color.ORANGE
translateX: bind endX
translateY: bind endY
onMousePressed: function(e:MouseEvent):Void {
startX = e.getDragX()-endX;
startY = e.getDragY()-endY;
}
onMouseDragged: function(e:MouseEvent):Void {
endX = e.getDragX()-startX;
endY = e.getDragY()-startY;
}
}
]
}
}
When you need to create a group of draggable objects, you can try thie approach of a draggable group like this. Inside on it, you can put whatever you want.
import javafx.application.*;
import javafx.scene.paint.*;
import javafx.scene.geometry.*;
import javafx.input.*;
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.image.*;
import javafx.animation.*;
// a graggable group
public class DragGroup extends CustomNode{
public attribute content: Node[];
private attribute endX = 0.0;
private attribute endY = 0.0;
private attribute startX = 0.0;
private attribute startY = 0.0;
public function create(): Node {
return Group{
translateX: bind endX
translateY: bind endY
content: bind content
}
}
override attribute onMousePressed = function(e:MouseEvent):Void {
startX = e.getDragX()-endX;
startY = e.getDragY()-endY;
}
override attribute onMouseDragged = function(e:MouseEvent):Void {
endX = e.getDragX()-startX;
endY = e.getDragY()-startY;
}
}
// angle animation, cycles between 0 to 360 in 36 seconds
var angle = 0.0;
var angleAnimation = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames : [
KeyFrame {
time: 0s
values:
angle => 0.0
},
KeyFrame{
time: 36s
values :
angle => 360.0 tween Interpolator.LINEAR
}
]
}
// some pictures from my Flickr albums
var me = "http://farm4.static.flickr.com/3042/2746737338_aa3041f283_m.jpg";
var dog = "http://farm4.static.flickr.com/3184/2717290793_ec14c26a85_m.jpg";
var plant = "http://farm4.static.flickr.com/3014/2731177705_bed6d6b8fa_m.jpg";
var bird = "http://farm4.static.flickr.com/3190/2734919599_a0110e7ce0_m.jpg";
var me_89 = "http://farm3.static.flickr.com/2138/2308085138_7b296cc5d0_m.jpg";
Frame {
width: 640, height: 480, visible: true
stage: Stage {
fill: Color.BLACK
content: [
DragGroup{
content: ImageView {
anchorX: 120, anchorY: 90
rotate: bind 30 + angle
image: Image { backgroundLoading: true, url: me }
}
},
DragGroup {
translateX: 300, translateY: 50
content: ImageView {
anchorX: 120, anchorY: 90
rotate: bind -30 + angle
image: Image { backgroundLoading: true, url: dog }
}
},
DragGroup {
translateX: 300, translateY: 300
content: ImageView {
anchorX: 120, anchorY: 90
rotate: bind 90 + angle
image: Image { backgroundLoading: true, url: plant }
}
},
DragGroup {
translateX: 200
translateY: 200
content: ImageView {
anchorX: 120, anchorY: 90
rotate: bind 90 + angle
image: Image { backgroundLoading: true, url: bird }
}
},
DragGroup {
translateX: 30
translateY: 200
content: ImageView {
anchorX: 85, anchorY: 120
rotate: bind angle + 180
image: Image { backgroundLoading: true, url: me_89 }
}
},
]
}
closeAction: function() {
java.lang.System.exit( 0 );
}
}
angleAnimation.start();
One more example, using the same class DragGroup, we can put multiple nodes using lists.
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.geometry.*;
import javafx.scene.paint.*;
import javafx.input.*;
import javafx.animation.*;
import java.lang.Math;
// Class to create a draggable group of objects
public class DragGroup extends CustomNode{
public attribute content: Node[];
private attribute endX = 0.0;
private attribute endY = 0.0;
private attribute startX = 0.0;
private attribute startY = 0.0;
override attribute onMousePressed = function(e:MouseEvent):Void {
startX = e.getDragX()-endX;
startY = e.getDragY()-endY;
}
override attribute onMouseDragged = function(e:MouseEvent):Void {
endX = e.getDragX()-startX;
endY = e.getDragY()-startY;
}
public function create(): Node {
return Group{
translateX: bind endX
translateY: bind endY
content: bind content
}
}
}
// angle animation, cycles between 0 to 360 in 10 seconds
var angle = 0.0;
var angleAnimation = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames : [
KeyFrame {
time: 0s
values: angle => 0.0
},
KeyFrame{
time: 10s
values : angle => 360.0 tween Interpolator.LINEAR
}
]
}
// breath animation, go and back from 0.0 to 10.0 in 2 seconds
var breath = 0.0;
var breathAnimation = Timeline {
repeatCount: Timeline.INDEFINITE
autoReverse: true
keyFrames : [
KeyFrame {
time: 0s
values: breath => 0.0
},
KeyFrame{
time: 1s
values : breath => 10.0 tween Interpolator.LINEAR
}
]
}
// Creates n multi colored floating circles around a bigger circle
var n = 12;
var colors = [
Color.BLUE, Color.AQUA, Color.MAGENTA, Color.RED,
Color.YELLOW, Color.ORANGE, Color.HOTPINK, Color.LIME
];
var chosen = Color.YELLOW;
var floatingCircles = Group{
rotate: bind angle
content: for (i in [1..n])
Circle {
fill: colors[i mod sizeof colors]
radius: 10
centerX: Math.cos(i * 2 * Math.PI/n) * 70
centerY: Math.sin(i * 2 * Math.PI/n) * 70
onMouseClicked: function( e: MouseEvent ):Void {
chosen = colors[i mod sizeof colors];
}
}
}
var circle = Circle{
radius: bind 50 + breath
fill: bind chosen
}
Frame {
width: 400, height: 400, visible: true
stage: Stage {
fill: Color.BLACK
content: [
DragGroup{
translateX: 200, translateY: 200
content: [circle, floatingCircles]
}
]
}
closeAction: function() {
java.lang.System.exit( 0 );
}
}
// starts all animations
angleAnimation.start();
breathAnimation.start();
Inkscape is a Open Source vector graphics editor that works with SVG (Scalable Vector Graphics) format, Inkscape works with transparency, gradients, node editing, pattern fills, PNG export, and more. It also runs on Linux, Windows and OSX, those three are officially supported, but also runs in a broad list of Operational Systems. Is a software that I work daily and frequently is featured here in my blog.
You can download Inkscape or directly install it via some package system like Apt:
sudo apt-get install inskcape
But sometimes we need some special feature that is not available yet in the repositories or we want gain speed by having special binaries for our platforms or we want to help developing a new feature. In those cases we need to compile the software by ourself.
Those tips are valid for Ubuntu 8.04 but some part of them can be applied in others distributions. The Inkscape compiled here is the version 0.46+devel so newest versions can have compiling procedures slightly different.
Getting sources via APT.The easiest way to compile Inkscape on Ubuntu is
sudo su
apt-get build-dep inkscape
apt-get source inkscape
cd inkscape
./autogen.sh
./configure
make
make install
This will get a version of inkscape, compile it and install. If the first step doesn’t work well, you can try install all necessary packages by yourself using:
sudo apt-get install autotools-dev fakeroot dh-make build-essential autoconf automake intltool libglib2.0-dev libpng12-dev libgc-dev libfreetype6-dev liblcms1-dev libgtkmm-2.4-dev libxslt1-dev libboost-dev libpopt-dev libgsl0ldbl libgsl0-dev libgsl0-dbg libgnome-vfsmm-2.6-dev libssl-dev libmagick++9-dev libwpg-dev
Getting sources via SVN. The recipe I showed above will compile a stable version of Inkscape but not the last version of Inkscape. For that we need to grab the source directly from the Subversion repositories and so compile it.
At your home folder:
sudo apt-get install subversion
svn checkout https://inkscape.svn.sourceforge.net/svnroot/inkscape/inkscape/trunk inkscape
A alternative way to subversion is getting sources from here. Those are tarballs built every hour after someone change something in the development repositories. Download a tarball, and decompress it on your home folder.
Install all tools we need to compile Inkscape, this should fits:
sudo apt-get install autotools-dev fakeroot dh-make build-essential autoconf automake intltool libglib2.0-dev libpng12-dev libgc-dev libfreetype6-dev liblcms1-dev libgtkmm-2.4-dev libxslt1-dev libboost-dev libpopt-dev libgsl0ldbl libgsl0-dev libgsl0-dbg libgnome-vfsmm-2.6-dev libssl-dev libmagick++9-dev libwpg-dev
Enter in the directory with the Inkscape source and do:
./autogen.sh
mkdir build
cd build
../configure
make
sudo make install
In both cases, grabbing sources via svn or via apt, or can set the place where the software will be installed so it not cause conflicts with you already installed version of Inkscape. You can do that replacing the ./configure step with something like:
./configure –prefix=/home/yourname/inkscape
If you had some trouble in one of those steps, consider reading some of those other tutorials:
ps: thanks guys from the inkscape-devel@lists.sourceforge.net specially heathenx.