Presentation Physically Attractive

Based on “Gaming JavaFX”, the fun and popular talk from Devoxx '09 showing how to use JavaFX to build fun, interesting, and attractive casual games using physics, graphics, animations, and the power of the JavaFX platform. Watch as Jasper Potts and Richard Bair show how JavaFX makes creating casual games fun and productive. Come see some techniques that can be used to create your next casual game or marketing campaign.


PDF: slides.pdf



Physically Attractive

Physically Attractive Jasper Potts & Richard Bair Oracle


Agenda • From 2D to 3D • Creating 3D with 2D primitives • Linking physics engine to graphics • Using a physics engine • Bullets! • Bombs! • Explosions! • Inflict Damage! 2


Origins X Y X Y Z 3


Transforms • Translate (x, y, z) • Rotate (angle, axis, pivot) • Scale (x, y, z, pivot) • Affine (tx,ty,tz,mxx,mxy.....mzz) TX TY TZ Transla*on MXX MXY MXZ MYX MYY MYZ MZX MZY MZZ Rota*on,  Scale &  Skew 4

Z Buffering

Z Buffering Demo

Linking Physics Engine to Graphics

Linking Physics Engine to Graphics • Stepping physics • Synching state from physics to graphics • Using pulse • JBullet vs. NVidia PhysX • Scale 8

Simple Physics Demo NVidia Debugger

Simple Physics Demo NVidia Debugger Demo

Simple Physics Demo Code

Using a physics engine

Bullet Code

Physics Video Wall

Physics Video Wall Demo

Bomb Code

Bomb Code private void fireBomb(float startX, float startY, float startZ, float velocityX, float velocityY, float velocityZ) { final Bomb bomb = new Bomb(startX,startY,startZ); getPhysicsGroup().getContent().add(bomb); // throw bomb.setLinearVelocity(velocityX, velocityY, velocityZ); // after 5s explode Timeline bombTimeline = new Timeline(); bombTimeline.getKeyFrames().add(new KeyFrame(new Duration(5000), new Function0() { @Override public Void invoke() { Affine bombPos = bomb.getPosition(); Point3D bombCenter = new Point3D(bombPos.getTx(),bombPos.getTy(),bombPos.getTz()); // remove bomb as it has exploded getPhysicsGroup().getContent().remove(bomb); // explode Explosion.explodeAt(DuelingDudes3D.this,bombCenter); return null; } }));; } 14

Explosion Code

Explosion Code forceSphere = new Sphere(100, 1, null, 0, 2000, 0); forceSphere.setKinematic(true); physicsGroup.getContent().add(forceSphere); explosionVisualTimeline.getKeyFrames().add( new KeyFrame(new Duration(1150),new Function0() { @Override public Void invoke() { forceSphere.setPosition( AffineUtils.newAffine(0, 2000, 0)); explosionCache.push(Explosion.this); return null; } }) ); 15

Explosion Code

Explosion Code private static Image[] explostionImages = new Image[33]; static { for(int i=1; i<=33; i++) { String iStr = (i<10)? "0"+i : Integer.toString(i); explostionImages[i-1] = new Image( DuelingDudes3D.class.getResourceAsStream( "images/explosion/explosion"+iStr+".png")); } } Timeline explosionVisualTimeline = new Timeline(); for(int i=0;i() { @Override public Void invoke() { imgView.setImage(img); return null; } }); explosionVisualTimeline.getKeyFrames().add(kf); } 16

Inflicting Damage Code

Inflicting Damage Code • // calculate and inflict damage for (Node child: new ArrayList(physicsGroup.getContent())) { if(child instanceof Damageable) { Damageable damagable = (Damageable)child; Affine pos = damagable.getPosition(); float distance = center.distance(pos.getTx(),pos.getTy(),pos.getTz()); if (distance<250){ damagable.inflictDamage(1-(distance/250f)); } } } public interface Damageable { public void inflictDamage(float damage); public float getDamage(); public Affine getPosition(); } 17

Dueling Dudes 3D

Dueling Dudes 3D Demo