Tag Archives: JavaFX

Creating A Sci-Fi JavaFX World Clock @foojay.io

foojay.io

foojay.io

It has been awhile since I last blogged on CarlFX and I want to let my readers (you) know that I will mainly be blogging over at the new foojay.io site. What is foojay you may ask?

“Welcome to foojay, a place for friends oOpenJDK. Foojay’s user-focused Java and OpenJDK technical dashboards provide free data for daily Java developers. At the click of a button, you have access to updated analyses, selected highlights, and categorized lists arranged for easy consumption on all things Java.”

https://foojay.io/about/

In other words, it’s a community driven site where beginners to advanced Java developers will be able to collaborate and learn about all things Java. There, you’ll be able to learn from experts and Java Champions that discuss topics such as Java, JavaFX, Gaming, Microservices, Security, IDEs, Embedded, IoT, Cloud, etc. Foojay online also has tools that allow you to explore features and command options between Java releases.

What about CarlFX?

While I will be spending more time over at foojay.io I still plan to continue my existing work as time allows to just blog about interesting topics such as programming, algorithms, math, art, AI, gaming, science and design.

Creating a JavaFX World Clock from Scratch

Many of us these days are working from home. Most likely you will be using video chat to talk to co workers possibly around the world. Unfortunately there are many times when I lose track of time and do not realize the time difference while chatting with my co-workers. So in response to this problem I thought of creating a cool looking sci-fi world clock using JavaFX on the new Java 16 JDK.

The blog series are hosted on the foojay.io site if you are interested in following along. The blog series are still a work in progress (Part 1-6). Links will be available when they are published.

Looking forward to getting back into the swing of blogging again and connecting with all of you!

Advertisement

Science Fiction User Interfaces with JavaFX Part 1

Sci-Fi UI Shaped Window created using JavaFX

Can Fictional UIs become a Reality?

Growing up as an 80’s kid I’ve seen my share of science fiction movies that really inspired me to become quite fond of graphical user interfaces (GUIs) especially the idea of trying to make science fiction UIs possible in the real world. In this and a series of blog posts I want to try (attempt) to answer the question “Can Fictional UIs become a Reality?”

Since I am experimenting with different ideas (implementations) of what a sci-fi UI should look and behave  like, I won’t know exactly how many parts this blog series will be. So I hope you will join me in this journey towards the creation of a prototype and API capable of making science fiction UIs a reality. You might be wondering if there is something (UI framework) that already exists.

Shouldn’t we just use UI frameworks that already exist?

If you’re familiar with the excellent post from Jeff Atwood’s 2006 article “This Is What Happens When You Let Developers Create UI“. He talks about how most software developers aren’t really good at creating UIs. Is this really true? While I agree with most of his statements, I still believe anyone with enough passion will figure out a way to achieve their intended goal (within reason of course). As for me, most of my design choices are mainly through trial and error. I think UI design is very much like clothing where designs can be either trendy or classical.

Through the years many designers have made UI frameworks to build UIs that look great and are extremely functional, however they can look rather primitive (IMO) compared to the science fiction UIs that we see in movies today. When going the other direction science fiction UIs may look futuristic, but they don’t exactly map to anything real or functional.

Assuming you’re a developer (with some UI skills) and wishes to build sci-fi UIs the next section I’ll talk about what a sci-fi UI might look like or how it might behave.

Look and Feel Requirements

The following are features a typical science fiction UI window might have:

  • Create any shaped window (for now use line segments)
  • Style the visible shaped frame around the window
  • Create mouse a listener to define areas to resize & move window on the desktop
  • Resize the window using 8 directions (NW, N, NE, E, SE, S, SW, W)
  • Animate window and contents when entering and exiting the desktop (area)
  • Create Clipped region to display content such as video, 3D, Pane

Conclusion

As a kid I remember how my mind was simply blown away when I had seen futuristic and technologically advance civilizations on the big screen. Looking back at old sci-fi movies you will immediately realize how cheesy they were compared to today’s movies.

Hopefully I’ve given you compelling reasons why I would like to create such an API that would enable developers to easily style and create Sci-Fi looking UIs. As a developer/designer I would like to bridge the gap between Sci-Fi UIs and real UIs by listing some general requirements to start things off.

As always feel free to comment and let me know what you think.

Happy coding.:-)

References

Jeff Atwood’s 2006 article “This Is What Happens When You Let Developers Create UI
Chris Noessel on “How Design in Sci-Fi and the Real World Influence Each Other
Carl Dea’s video “JavaFX demo of a Sci-fi UI HUD Window

Raspberry Pi with Java: Programming the IoT (Book Review)

 

Cover of the book Raspberry Pi with Java: Programming the Internet of Things (IoT)

Raspberry Pi with Java: Programming the Internet of Things (IoT) Embedded Application Development for Home and Industry

Greetings Java/JavaFX/Raspberry Pi fans!,

Before beginning this book review it was brought to my attention that I had to disclose lawyer speak in order to comply with FTC rules relating to bloggers.

Disclosure of Material Connection: I received this book free from Oracle Press / McGraw-Hill Education (Publisher) In exchange for a book review. I was not required to write a positive review. The opinions I have expressed are my own. I am disclosing this in accordance with the Federal Trade Commission’s 16 CFR, Part 255: “Guides Concerning the Use of Endorsements and Testimonials in Advertising.”

Introduction

It is the year 2016, and by now we should be at more than a billion connected devices related to the Internet of Things (IoT) which numerous firms have predicted. If you’re like me a person who loves to tinker and discover things you have probably heard about the Raspberry Pi. On my journey to learn all things Pi I’ve come across many books related to the Raspberry Pi that utilized various programming languages, however when it came down to the Java language the books were pretty scarce.

Look no further, a new book has finally arrived that focuses on Java technologies to drive your Raspberry Pi projects. In this blog entry I will be reviewing the book Raspberry Pi with Java: Programming the Internet of Things (IoT) by Stephen Chin with James L. Weaver  (Oracle Press). Technical editor by Mark Heckler.

Book Review

The two book authors are some of the most respected in the IoT, Java and JavaFX communities. Both Stephen Chin (Oracle) and James Weaver (Pivotal) are Java champions who are renowned speakers at many major developer conferences worldwide. The technical editor Mark Heckler (Pivotal) is also a well known Java geek who also speaks at many prominate conferences around the world.

For starters the authors begin with a very good introductory and summary of the chapters. After the summary of the chapters the book points out two links to download the source code for the book. Other programming books with source code usually point to their publishing company’s website. Fortunately, this book provides two places to obtain the source code. One at the publishing company (www.mhprofessional.com) and the other is hosted at the Github (https://github.com/RaspberryPiWithJava).

Chapter 1: Baking Pie

The authors gets you started by listing all the component parts and software necessary to develop on the Raspberry Pi. The instructions on how to setup and configure the Raspbian OS are thoroughly explained. I like how the authors discuss how to connect all the different Raspberry Pi models to your network. Keep in mind that the book was written prior to the announcement of the Raspberry Pi Zero model, so the book has no mention of it.

In chapter 1 they show you how to connect your Raspberry Pi using Ethernet or Wireless connection. After, successfully connected, the authors show you how to ssh into your Raspberry Pi remotely from the three major OS platforms (MacOS, Linux and Windows) through your terminal (command-line console). Once able to ssh into your Raspberry Pi you will be able to code/compile and run a Hello World Java console application.

Chapter 2: Your First Java Project

In Chapter 2, the authors begin by walking you through setting up the NetBeans IDE to remotely debug live running code on a Raspberry Pi. Once you get comfortable with the developer workflow, the authors start out with a cool (hot) project on brewing the perfect cup of coffee! When beginning a project the authors always start off with a Bill of Materials detailing what and where to buy parts for a project.

In this chapter it delves into APIs (JSR 80) that allows your Java code to communicate with USB ports (usb4j). The authors show you how to read information from a USB port on an electronic scale device. The scale is used to measure the weight of things such as ground coffee beans. This chapter ends with the discussion of the topic of Commercial Licensing and FOSS. Learning about licensing options can help you navigate through legal matters if you decide to go commercial with your Java/Raspberry Pi product.

Chapter 3: Binary Timer

The authors goal in this chapter focuses on how to use GPIO (general purpose input output) pins. The GPIO pins are how the Raspberry Pi talks to analog and digital components such as LEDs, DC motors and light sensors. In this section you will learn the fundamentals of electronics such as power, Ohms law and what resistors you will need to purchase, etc. I love one of the tip blocks on “What is the Worst You Can Do to Your Raspberry Pi“. This tip allows you to not feel intimidated when approaching a Raspberry Pi by explaining how rugged the Raspberry Pi computer actually is, and how to prevent mishaps or damaging the Pi.

The authors mention two Java libraries commonly used for accessing GPIO pins on the Raspberry Pi. One being the Device I/O library and the other Pi4J. In this section the benefits of using each library are fully detailed. This chapter is very hands-on by creating a basic project using LEDs on a breadboard that can count down in binary. Many Fritzing diagrams are presented for step-by-step instruction on how to wire-up components properly. In this chapter the authors mention helpful troubleshooting tips such as Java code to solve the button debouncing issues when dealing with physical buttons or switches in your circuits. Lastly, this chapter provides bonus content that teaches you how to measure and compare performance metrics when using the two Java libraries Device I/O library and Pi4J by turning LEDs on and off very rapidly. Here, both memory-mapped access (Low-level) vs Sysfs access (Higher-level) were compared. This will help you decide which strategy is best depending on your use-case.

Chapter 4: IoT Hat

Now with the fundamentals of the Raspberry Pi, Java and basic electronics out of the way, you can now tackle a magical project that will astonish friends and family. This project involves creating a magicians top hat with the ability to know what playing card was chosen without seeing the face of the card. The authors teach you about how to configure your Raspberry Pi to enable I2C, SPI, and UART protocols. This chapter focuses on learning about NFC/RFID devices such as smart card readers. Beware: This section involves soldering so get your flux on. Here, you will learn how to communicate with an RFID reader’s breakout board.

This project also teaches you about compactness and portability (cordless) because you will be hiding stuff in a top hat. To make things portable the Pi will use a WiFi adapter and USB cell phone charging battery. The authors will also take you through native libraries required for Java to communicate with the NFC device so don’t be alarmed if you encounter Make files and permissions (typical in the Linux world).

Chapter 5: Line Runner

After learning skills for compactness and portability from chapter 4 the authors show you how to reuse your skills to build an autonomous robot! This should be the very reason to get this book. In the Bill of Materials all the parts (Makeblocks) you will need are detailed thoroughly. The robot will be able to anticipate obstacle while capable of following a lined path on a floor surface (Delivering mail comes to my mind). This chapter is focused on sensors, motors, and mechanical construction. With sensors the authors take you through how to use infrared and ultrasonic capabilities. When using motors this chapter explains pulse width modulation (PWM) to control the speed of the robot. The Java code examples are quite straight forward and concise.

Chapter 6: Tea Station

Not a coffee drinker? but a Java fanboy well, this project is for all the tea lovers (including you) out there! This project is building a tea station to steep the perfect cup of tea. In this chapter the author discusses electronic scales (again) except ones having better precision due to tea leaves being extremely light in weight. The author goes on to discuss about temperature sensors that can determine how hot the tea should be when below the temperature of boiling water with very good accuracy. The author delves into serial (RS232 to TTL) communications with various vendors selling electronic scales (In chapter 2, USB was used). Learning this skill is invaluable because many older devices still use serial communications, so you can adapt your ideas with just about anything.

In this chapter the author really takes things to the next level compared to chapter 2 (brewing coffee), because he teaches you how to implement a snazzy JavaFX UI on a touchscreen device! Just like the chapter on brewing coffee the authors have an incredible depth of knowledge on teas and types of teas.

Chapter 7: Autonomous Drone

I’m sure you’ve heard a lot about the drone craze well this chapter will knock your socks off! The authors will be employing a quadcopter and the Raspberry Pi capable of flying autonomously. Don’t be afraid the drone in this project it will not hurt you. Interestingly, enough this chapter will use two WiFi adapters to be attached to the Raspberry Pi (Model B). One adapter is to talk to the drone itself and the other is used as a wireless access point (WAP) to remotely talk to the Raspberry Pi. In this chapter the author highlights an API called Autonomous4j by Mark Heckler. Mr. Heckler is also the technical reviewer of this book. I’ve actually seen the drone in action at a JavaOne conference where Mr. Heckler and Mr. Weaver conducted a live demonstration. The APIs discussed in this chapter are very easy to use for example the following are some of the Java methods:

  • takeoff() – Causes drone to start and take off.
  • goLeft/goRight(int speed) – Given the percent of speed to fly left/right (its left or right)
  • forward/backward(int speed) – Cause drone to go forward/backward given a percent of speed
  • goHome() – Drone flies back to where it lifted off from
  • land() – Land and stop.

Chapter 8: Retro Video Game Emulator

Whoa!? If you are an 80s or 90s kid who enjoyed arcades and game consoles (I know I did) then this chapter is about creating an Nintendo Entertainment System (NES) game console! Most of the parts from the bill of materials can be obtained from the popular electronics company Adafruit. The author teaches you how to build a game controller, attach a speaker, and attach a LCD touch display. This project will involve learning how to connecting GPIO pins to the Kippah board to control a touchscreen display. The author walks you through using a NES emulation Java library halfNES by Andrew Hoffman. As most of you know when dealing with emulators it isn’t legal to play game ROMs of popular games back in the day, unless you actually own the old game cartridge, so the author suggest heading over to a site having free games you can play. I’m sure if you own Mario Brothers you can get the game ROM and try it out. The author ends the chapter with more hacking tips such as overclocking your chip to increase the performance of your Pi. It’s a game so you need it to run fast!

Chapter 9: NightHacking RetroPi

After you’ve learned from chapter 8 on how to build a game console, this chapter will show you how to make a portable hand-held game device just like a Nintendo Game boy!  The author is thoughtful in discussing about the pros and cons on various 3D printers and existing DIY communities at large. This chapter points out all the necessary software to print parts for your hand-held game device. The author provides great illustrations to step you through creating a polished product.

Conclusion

This book has opened my eyes to innovative ideas using Java with the Raspberry Pi. The content is well organized and easy to follow. Often other DIY books have difficulty explaining the integration between hardware and software, but this book blends the two together elegantly. This book is very definitive in terms of the numerous topics, vendors, components, comparisons and implementation strategies. The authors hit on practically every topic relating to how to command and control (many types of) devices.

A good number of projects are very hands-on with an emphasis on the engineering side of things as opposed to the software side (solely a software developer). If you like to build cool gadgets and comfortable with the Java programming language I urge you to get this book.

My only issue (tiny) is the paperback book’s illustrations are in black and white (gray-scale) which can make it difficult to see things such as colored resistors in the Fritzing diagrams or JavaFX UIs (User Interfaces). I believe the PDF version might be in color, but I’ve not seen it yet (just a hunch). But, overall I give this book a two thumbs up. By far, this book is the most comprehensive book combining two great technologies with a plethora of amazing DIY projects to date.

FX Playground

 

 

 

Update: The FX Playground project can be found at: https://bitbucket.org/cdea/fxplayground

Logo5

Introduction

FX Playground is a JavaFX-based prototyping tool or live editor that eliminates the step of compiling Java code. This concept isn’t new, for instance the Web world there are many HTML5 playgrounds that offer online editors that enable developers to quickly prototype or experiment with various JavaScript libraries. This allows the developer to focus on visualizations or UI details without needing to set-up an IDE project or mess with files. Even older (pre-dating) than playgrounds are REPLs (Read Eval Print Loop) where dynamic languages such as Groovy, Python, Ruby, etc. provide an interactive interpreter command line tool to allow developers to quickly script code to be executed. Scala is a compiled language, but also provides a REPL tool.

After finishing the book JavaFX 8 Introduction by Example I noticed each example was created as separate NetBeans projects which seemed a little overkill for small examples. Because the book is based on Java the language each program needed to be compiled (via javac) prior to execution. Larger projects will typically need to be set-up with a proper classpath and resources in the appropriate directory locations. Even larger projects will also need dependencies which typically reside on Maven repositories.

JavaOne 2014

Based on timing I was able to submit a talk regarding JavaFX based playgrounds just in time. After awhile I was pleasantly surprised that my proposal (talk) was accepted. You can check out the session here. Also, I will be presenting with my good friend Gerrit Grunwald (@hansolo_). So, be prepared to see awe-inspiring demos. Since the talk is a BoF (birds of a feather) the atmosphere will be low-key and very casual. I hope to see you there!

The JavaOne talk is titled “JavaFX Coding Playground (JavaFX-Based Live Editor Tool) [BOF2730]”.  Based on the description you’ll find that the tool will be using the NEW! Nashorn (JavaScript) engine to interact with JavaFX primitives. The figure below depicts the FX Playground tool’s editor windows and a JavaFX Display area. Starting clockwise at the lower left is the code editor window allowing the user to use JavaScript (Nashorn) to interact with nodes. Next, is the JavaFX FXML editor window allowing the user to use FXML (upper left). The FXML window is an optional.  In the upper right, you will notice the JavaFX CSS editor window allowing you to style nodes on the display surface. Lastly, to the bottom right is the output area or better known as the DISPLAY_SURFACE.

FXPlayground's editor windows

FXPlayground’s editor windows

FX Playground in Action

Because FX Playground is still in development I will give you a glimpse of some demos that I’ve created on Youtube. The following are examples with links to videos.

 

Roadmap

There are plans to opensource the code, but for now there is much needed functionality before public consumption.

The following features are a work in progress:

  • Make use of FXML editor window.
  • Pop out the display panel into its own window
  • Save, SaveAs, and Load Playgrounds
  • Build software to be an executable for tool users. (90% done)
  • Make the tool capable of using other languages (JSR 223)

I want to thank Oracle corp. especially the following engineers who helped me (some of the engineers below are not Oracle employees):

References

The FX Playground project can be found at: https://bitbucket.org/cdea/fxplayground

CarlFX’s Channel – https://www.youtube.com/channel/UCNBYRHaYk9mlTmn9oAPp1VA

7 of the Best Code Playgrounds – http://www.sitepoint.com/7-code-playgrounds

NetBeans – https://www.netbeans.org

JavaFX 8 Introduction by Example – http://www.apress.com/9781430264606

Nashorn – https://wiki.openjdk.java.net/display/Nashorn/Main

Enzo – https://bitbucket.org/hansolo/enzo/wiki/Home

Harmonic Code – http://harmoniccode.blogspot.com/

JavaFX 8u20 Days of Future Past (Always On Top)

It’s been a long time since I’ve posted topics relating to JavaFX. So, if you are still following along, awesome!

Introduction

In this blog post I want to blog about a very cool feature starting with JavaFX 8 update 20 that allows your application to always be on top of other applications. What this means is that on your desktop your JavaFX based application can be a floating widget that will remain above all other applications (z-order). An example would be a weather widget in the upper right corner never to be obscured by other applications. So, I’m very excited to share with you this amazing feature ‘Always On Top’.

History

In the past Java Swing developers would rely on the method Window.setAlwaysOnTop(boolean).  This feature allowed Swing developers to build native looking and native behaving desktop applications. Ever since JavaFX 1.x this very feature was highly requested (originally requested by Stephen Chin @steveonjava for the WidgetFX framework). This feature request is JIRA ticket RT-153. Figure 1 is the feature request shown with a status of ‘Resolved’.

Jira ticket RT-153

figure 1: Jira ticket RT-153

 

Although this feature didn’t get into JavaFX versions 1.x, 2.x and the version prior to Java 8u20, it is finally here now. For those who don’t know how to report bugs or file new features requests I encourage you to head over to the JavaFX JIRA system.

Example: Weather Widget

Assuming you know the basics of JavaFX since version 2.0 a typical application would consist of extending from the javafx.application.Application class. When developing JavaFX desktop applications the platform API would provide you with a (javafx.stage.Stage) window. The Stage object will have the following methods to access the always on top property.

  • alwaysOnTopProperty()
  • setAlwaysOnTop(boolean)
  • isAlwaysOnTop()

The following code snippet sets the Stage to be always on top using the method setAlwaysOnTop(boolean).

public class KeyholeDemo extends Application {

   @Override public void start(Stage primaryStage) {
      primaryStage.initStyle(StageStyle.TRANSPARENT);
      primaryStage.setAlwaysOnTop(true);
      // code omitted...
   }

   public static void main(String[] args) {
     launch(args);
   }
}

How it works

Shown in the listing above the start() method sets the stage to be transparent to be a JavaFX window without a title bar. This allows applications to have irregular shaped windows on the desktop. If a web person trolls you again about JavaFX ask them the following question: “Can  HTML5 create irregular shaped windows on the desktop? (always on top)”. Next, the stage is setup to be always on top via the setAlwaysOnTop() method.

Demo

After realizing that this highly requested feature was available I basically updated my old ‘KeyholeWidget‘ project at the Github and created a video demonstrating the widget on my desktop. Here is the video:

To see the full code listing visit the Github project ‘KeyholeWidget‘.

 

I hope you’ve enjoyed this cool feature (I know I did). As usual please leave comments below.

Happy coding,

Carl

Introduction by Example: JavaFX 8 Printing

I‘ve not blogged in awhile, and I miss sharing with others about all things JavaFX (My day job and family are likely excuses). For those who are new to this blog, I am the author of JavaFX 2 Introduction by Example (JIBE), co-author of Java 7 Recipes, and technical reviewer of the Pro JavaFX 2 books from Apress publishing. For those who already know me, I’d like to thank you for supporting me and the other authors by purchasing these books. More importantly, my hope is to reach out to  Java enthusiasts and share ideas.

The book JavaFX 2 Introduction by Example, was published in Nov. 2011 and many more APIs were added since then. During the writing of the book, I was working on the early editions of JavaFX 2.0 up until the announcement at JavaOne Oct. 2011. It was pretty crazy trying to update the book based on API changes as things were almost set in stone. I thought it was amazing how it even got out the door. However, I was pretty pleased. Some of you who have read the beginning of the book (JIBE) understand that the chapters of JIBE are also found in the book Java 7 Recipes (actually it is originally taken from Java 7 recipes). This little fact explains why the book, JavaFX 2 Introduction by Example, is reminiscent of recipe or cookbook style technical books. My intent was to help the reader get introduced quickly without a lot of tech blather. Instead of trying to convince people about the JavaFX platform, I’d rather demonstrate things with useful examples. I find it counter productive discussing  deep philosophical debates regarding why one particular technology is superior to the other (cheesy 80’s Highlander reference).

After the release of JavaFX 2.0, there came subsequent versions such as JavaFX 2.1, 2.2 and the upcoming release of JavaFX 8 (January 2014). In this blog entry, I will provide a recipe for the JavaFX 8’s Printing API. Similar to my book (JIBE), I will follow the same pattern as before where I present a problem, solution, code, and a “How it Works” section.

Declaimer: In this blog you will encounter Java Functional Interfaces using Lambda expressions. I will not be discussing them here, but will refer you to Oracle’s tutorials on Project Lambda .

Prerequisite software:

JDK 8 – https://jdk8.java.net/download.html

 

Problem

You want to create a JavaFX application that prints out a visited website.

Solution

Use the JavaFX 8 PrintJob and Printer APIs to print any JavaFX scene graph node. Also, use the WebView and WebEngine APIs to display a Website or Web page.

Instructions

Assuming you’ve compiled and have run the application, follow the instruction below:

  1. Enter website address or url into the text field.
  2. Hit the enter key
  3. After the page is loaded, click on the “Print” button
  4. Go to the printer to get the printed web page

Code

package org.carlfx;

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.concurrent.Worker.State;
import javafx.print.*;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.transform.Scale;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

/**
 * Demo to use JavaFX 8 Printer API.
 *
 * @author cdea
 */
public class PrintDemo extends Application {
    @Override
    public void start(Stage primaryStage) {

        final TextField urlTextField = new TextField();
        final Button printButton = new Button("Print");
        final WebView webPage = new WebView();
        final WebEngine webEngine = webPage.getEngine();

        HBox hbox = new HBox();
        hbox.getChildren().addAll(urlTextField, printButton);
        BorderPane borderPane = new BorderPane();
        borderPane.setTop(hbox);
        borderPane.setCenter(webPage);
        Scene scene = new Scene(borderPane, 300, 250);
        primaryStage.setTitle("Print Demo");
        primaryStage.setScene(scene);

        // print button pressed, page loaded
        final BooleanProperty printButtonClickedProperty = new SimpleBooleanProperty(false);
        final BooleanProperty pageLoadedProperty = new SimpleBooleanProperty(false);

        // when the a page is loaded and the button was pressed call the print() method.
        final BooleanProperty printActionProperty = new SimpleBooleanProperty(false);
        printActionProperty.bind(pageLoadedProperty.and(printButtonClickedProperty));

        // WebEngine updates flag when finished loading web page.
        webEngine.getLoadWorker()
                 .stateProperty()
                 .addListener( (ChangeListener) (obsValue, oldState, newState) -> {
                    if (newState == State.SUCCEEDED) {
                        pageLoadedProperty.set(true);
                    }
                 });

        // When user enters a url and hits the enter key.
        urlTextField.setOnAction( aEvent ->  {
            pageLoadedProperty.set(false);
            printButtonClickedProperty.set(false);
            webEngine.load(urlTextField.getText());
        });

        // When the user clicks the print button the webview node is printed
        printButton.setOnAction( aEvent -> {
            printButtonClickedProperty.set(true);
        });

        // Once the print action hears a true go print the WebView node.
        printActionProperty.addListener( (ChangeListener) (obsValue, oldState, newState) -> {
            if (newState) {
                print(webPage);
            }
        });

        primaryStage.show();

    }

    /** Scales the node based on the standard letter, portrait paper to be printed.
     * @param node The scene node to be printed.
     */
    public void print(final Node node) {
        Printer printer = Printer.getDefaultPrinter();
        PageLayout pageLayout = printer.createPageLayout(Paper.NA_LETTER, PageOrientation.PORTRAIT, Printer.MarginType.DEFAULT);
        double scaleX = pageLayout.getPrintableWidth() / node.getBoundsInParent().getWidth();
        double scaleY = pageLayout.getPrintableHeight() / node.getBoundsInParent().getHeight();
        node.getTransforms().add(new Scale(scaleX, scaleY));

        PrinterJob job = PrinterJob.createPrinterJob();
        if (job != null) {
            boolean success = job.printPage(node);
            if (success) {
                job.endJob();
            }
        }
    }

    /**
     * The main() method is ignored in correctly deployed JavaFX application.
     * main() serves only as fallback in case the application can not be
     * launched through deployment artifacts, e.g., in IDEs with limited FX
     * support. NetBeans ignores main().
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

Print Demo using JavaFX 8

Print Demo using JavaFX 8

How it Works

The code begins by creating a TextField, a Button, and a WebView control to be placed into a BorderPane. When using the BorderPane layout, you will be able to place controls into the following regions: Top, Right, Left, Bottom, and Center.

Similar to a web browser, the text field allows the user to enter a website url. Once the url is entered, the user will hit the enter key to load the web page into the WebView node. When placing controls on any of the side regions, the BorderPane layout will take on the preferred height of any controls that are added. The center region will allow a node to take up the available space minus the remaining space taken up by the width and height of the bordering side regions. In other words, if the side regions contain no nodes (empty), a node in the center region has the opportunity to take all the available width and height space provided by its parent (Scene). Since the WebView node will occupy the center region, it will take all the available width and height (minus top region) when the web page is fully loaded. You’ll also notice scroll bars allowing the user to view pages larger than the current view port.

After laying out all the components for the UI, you will need to wire things up. Here you will simply create three boolean property
(javafx.beans.property.SimpleBooleanProperty) instances. The first property variable printButtonClickedProperty is a flag indicating when the print button was clicked. The second property pageLoadedProperty is a flag indicating that the web page was finished loading. Lastly, you will want to note the printActionProperty which binds the printButtonClickedProperty and the pageLoadedProperty by using the fluent API. As they evaluate, the printActionProperty will be true if both the printLoadedProperty and the printLoadedProperty are true values.

// print button pressed, page loaded
final BooleanProperty printButtonClickedProperty = new SimpleBooleanProperty(false);
final BooleanProperty pageLoadedProperty = new SimpleBooleanProperty(false);

// when the a page is loaded and the button was pressed call the print() method.
final BooleanProperty printActionProperty = new SimpleBooleanProperty(false);
printActionProperty.bind(pageLoadedProperty.and(printButtonClickedProperty));

Continuing the wiring up of the UI, I took an event driven approach where the handler code will respond to events and property changes. Starting with the WebView node, I attached handler code to the statePropery instance (ChangeListener) in order that the pageLoadedProperty will be set to true once the web page is loaded successfully.

  // WebEngine updates flag when finished loading web page.
  webEngine.getLoadWorker()
           .stateProperty()
           .addListener( (ChangeListener) (obsValue, oldState, newState) -> {
               if (newState == State.SUCCEEDED) {
                    pageLoadedProperty.set(true);
               }
           });

Next, you will see the text field’s ‘setOnAction‘ method containing handler code that resets the pageLoadedProperty and printButtonClickedProperty objects. Also, the code will initiate the loading of the page via the WebView‘s WebEngine load() method.


  // When user enters a url and hits the enter key.
  urlTextField.setOnAction( aEvent ->  {
     pageLoadedProperty.set(false);
     printButtonClickedProperty.set(false);
     webEngine.load(urlTextField.getText());
  });

After the TextField control’s action code is wired up, the print button will also need handler code to set the printButtonClickedProperty flag to true. Lastly, the printActionProperty property will need a ChangeListener to respond when its state evaluates to true. When this evaluates to true, my print() method is invoked.

        // When the user clicks the print button the webview node is printed
        printButton.setOnAction( aEvent -> {
            printButtonClickedProperty.set(true);
        });

        // Once the print action hears a true go print the WebView node.
        printActionProperty.addListener( (ChangeListener) (obsValue, oldState, newState) -> {
            if (newState) {
                print(webPage);
            }
        });

Finally, the print() method takes a JavaFX Node object to be printed. The Printer object has a method which returns the default printer your computer is set to. Before actually printing, we can derive a default page layout to scale the node before printing the node. If you don’t do this, only part of the web page will be printed. With the default printer obtained, the createPrinterJob() method is invoked to return a PrinterJob instance that does the actual printing. To print a JavaFX displayable type node, you simply invoke the PrinterJob object’s printPage() method by passing in the Node instance as a parameter.

    /** Scales the node based on the standard letter, portrait paper to be printed.
     * @param node The scene node to be printed.
     */
    public void print(final Node node) {
        Printer printer = Printer.getDefaultPrinter();
        PageLayout pageLayout = printer.createPageLayout(Paper.NA_LETTER, PageOrientation.PORTRAIT, Printer.MarginType.DEFAULT);
        double scaleX = pageLayout.getPrintableWidth() / node.getBoundsInParent().getWidth();
        double scaleY = pageLayout.getPrintableHeight() / node.getBoundsInParent().getHeight();
        node.getTransforms().add(new Scale(scaleX, scaleY));

        PrinterJob job = PrinterJob.createPrinterJob();
        if (job != null) {
            boolean success = job.printPage(node);
            if (success) {
                job.endJob();
            }
        }
    }

In conclusion, I find that the APIs are simpler to use compared to Java Swing/AWT APIs. I would like to mention that there are many features you can play around with since this blog entry only scratches the surface on the APIs currently available.

NOTE: JavaFX 8 printer API is still in the early stages and there are still outstanding issues (Jira issues).

Please visit to vote and help test functionality at https://javafx-jira.kenai.com

Outstanding Tickets: http://bit.ly/1dw7Vc8

A Case Study: A JavaFX Widget Framework API

A prototype of a widget container

A prototype of a widget container

Building a better mousetrap

In short I want to revisit the idea of a cross platform widget framework using JavaFX. In this article I’d like to share some ideas, concepts and prototypes that might invigorate this old but ingenious idea for the desktop and embedded world. An old idea you say? Does anyone remember WidgetFX?

In the early days of JavaFX there were a few Java Champions and community members who decided to create a cross platform JavaFX 1.x widget framework for the desktop (year 2008). I was fortunate enough to know many of those contributors involved.  I grew to love the capabilities the framework and widgets were able to provide.  However, as we all know JavaFX is now redone as Java APIs as opposed to the JavaFX script language. This eventually became apparent regarding to the future of most frameworks back then. Before I begin I would like to give credit to the folks who contributed to the WidgetFX framework project.  I want to thank them for their enthusiasm and their tireless efforts on building the community to what it is today. To see some of their cool widgets please visit the site http://widgetfx.org (catch them before they’re gone). Two of the original founders of the project are Stephen Chin and Keith Combs. Even though I did not partake in the fun during the height of the project I was quite inspired.

Inception phase

To fast forward just last year at the JavaOne 2012 conference I was able to catch up with Keith Combs (Silicon Valley JavaFX User Group organizer) and Stephen Chin (Java Technology Evangelist at Oracle) after his keynote speaking to inquire about the WidgetFX project now that JavaFX 1.x is no more. Steve kindly asked if anyone would be interested in giving it a reboot on the JavaFX 2.x platform (As he peered over towards Keith and me). I believe I said, “I don’t think, so… “. I thought it might be too much to bite off than I could possibly chew. So I politely declined the offer. During the conference I was later enamored by all things Java embedded which later fueled to some of my home automation project ideas using JavaFX with (Arduino, Raspberry Pi, and Beagle Board).

After returning home I was not only excited about the things I’ve learned at the conference but, I also was in the middle of transitioning to a new job and company. Working as a UI and Visualization developer for cloud based monitoring software I often encountered stakeholders/SMEs mentioning the term “SPOG” or single pane of glass.

What does the term “SPOG” mean?

According to Floyd Strimling a cloud technical evangelist at Zenoss explains how so many organizations will create desperate (silos) systems and he goes on to say, “The Holy Grail is a single pane of glass that provides IT managers with a single access point to make sense of their entire underlying infrastructure in real time”. (Searching for the Mythical Single Pane of Glass)

Isn’t “SPOG” an interesting concept for large operation centers? So, I continued to rethink of the old idea of a flexible widget framework that would provide richer interfaces that would allow better desktop integration, decoupled services, higher performance, and capable of empowering users with many of the modern UI metaphors that they’d expect on their favorite OS platform. I believe such a framework should also work on embedded devices for home automation.  Actually I got the idea of a widget framework for embedded devices from my good friend Gerrit Grunwald (Java Champion and author of the popular Steel Series API) while exchanging ideas about graphics performance and launching JavaFX applications on embedded devices.

Wow, with so many different problem domains and so many perspectives could such a widget framework truly exist? Could such a widget framework be able to make everyone happy? Is it possible to create a simple widget framework to rule them all? I believe it is possible.

eWidgetFX is born

In the back of my mind I noticed similar use cases with many customers wanting widget frameworks having this concept of a “SPOG”, but also provide a framework that I could use myself on my own desktop or touch device. So, I kept going back and forth on the possibility of rebooting the old project WidgetFX. Instead I wanted to throw a monkey wrench into the whole business of widget frameworks. Since there are so many kinds of ways to launch, display, and manage widgets it would also be a good idea to build a single widget framework SPI (service provider interface API) which would enable developers to build their own widget containers thus allowing widget developers to run their widgets in any widget container. There would basically be two developer perspectives: Container Developers and Widget Developers. So, I’d like to propose a new API called eWidgetFX (core) that would allow the developers to create widget containers and widgets.

For now I will defer the work of designing the core APIs and make it a future post. So, in this article I’ve decided to generate some prototypes of widget containers that would basically depend on the future eWidgetFX framework API.

Prototyping Widget Containers

Prototyping is probably the most fun part during any software development activity. Shown below are videos I recently uploaded to Youtube.com to kick some ideas around for different kinds of widget containers (Icon App tray) on a desktop environment.

Conclusion

One of the main issue I found in UI development is that customers will often know what they want, but aren’t able to communicate what they ultimately want. It’s almost like playing a game of Charades or a game of Pictionary where guessing is a sought after skill in software design.  We are often faced with providing prototypes and end up settling on one particular view (one view, one way, one silo). The problem became pretty apparent where everyone had an opinion or philosophical stance on a particular GUI interface, usability aspect or UI metaphor. Sometimes it’s based on subjective personal preferences that can go into long discussions. No one person in the room was completely happy, but at the end of the day we compromised and we settled.

I believe that by creating a widget API it would allow organizations to build different single pane of glass instances (widget containers) and capable of sharing all widgets across other panes.

So, imagine seeing different types of widget containers in the wild. Some future widget containers could look like interfaces similar to the following movies: Avengers, Tron, or Minority Report

A final note: Many of of the ideas expressed and proposed are a collective effort from some of my friends (team members) of the JFXtras.org project (Mark Heckler, Hendrik Ebbers, and Gerrit Grunwald).

Would you like to see a talk regarding widget frameworks at JavaOne?

As always comments are welcome.

Carl 😉

Resources

JavaFX: http://www.oracle.com/technetwork/java/javafx/overview/index.html
Java Champions: https://java.net/website/java-champions/bios.html
WidgetFX: http://widgetfx.org
Keith Combs from the Silicon Valley JavaFX user group: http://www.svjugfx.org/member/10394895/?op=&memberId=10394895
Steve on Java by Stephen Chin: http://steveonjava.com
Arduino : http://www.arduino.cc
Raspberry Pi: http://www.raspberrypi.org
Beagle Board: http://beagleboard.org
Guest Post: Searching for the Mythical Single Pane of Glass: http://siliconangle.com/blog/2012/02/29/guest-post-searching-for-the-mythical-single-pane-of-glass
Anti-patterns: http://en.wikibooks.org/wiki/Introduction_to_Software_Engineering/Architecture/Anti-Patterns
Google Images of Operation centers: http://bit.ly/106p3h0
Avengers UI design: http://cargocollective.com/jayse/Avengers
Tron UI design: http://dlew.me/Tron-Legacy-Boardroom
Minority Report UI designer demos his tech at TED (video): http://www.engadget.com/2010/06/03/minority-report-ui-designer-demos-his-tech-at-ted
The Java Jungle by Mark Heckler: https://blogs.oracle.com/javajungle/entry/welcome_to_the_jungle
Gui Garage by Hendrik Ebbers: http://www.guigarage.com
Harmonic Code by Gerrit Grunwald: http://harmoniccode.blogspot.de
JFXtras.org : http://jfxtras.orgLeap Motion: https://www.leapmotion.comLeap Motion: https://www.leapmotion.com

JavaFX 2 GameTutorial Part 5

JavaFX sound effects

Figure 1: JavaFX Sound FX

Introduction

This is part five of a six part series related to a JavaFX 2 Game Tutorial. I know it’s been a long time since I blogged about gaming, but hopefully you’re still with me. If you would like a recap, please read Part 1Part 2Part 3, and Part 4 to find out where we left off. If you are up to date, then let’s get started!  In this blog entry we will be incorporating sounds into our game.

There are many elements which make games incredibly fun such as animated effects, collisions, AI, and input. However, one of the most important ingredients to game play is sound. When games incorporate sound effects and music, the gamer will become highly immersed (ugh… like not realizing you are about to see the sun rise). Before we get into the details, let me give you some background history on sound used in PC games for the home computer. If you want to skip the history and get down to business, jump to the section called the ‘Sound Manager Service.’ The Sound Manager Service is responsible for maintaining sound assets used during the game. If you are really impatient and don’t care about the implementation details, jump down to ‘JavaFX Sound Demo.’ Important note: Remember to read the requirements before launching the demo.

History

If you want to understand today, you have to search yesterday.  ~Pearl Buck 

Back in the day, when I was growing up, I learned that the Apple ][ computer was capable of playing sounds. The Apple ][ had one speaker that was only able to produce simple tones (8 bit mono sound). When I first generated tones (Mary had a little lamb), I was totally amazed. If you are interested in machine code using Applesoft Basic’s peek and poke commands to compose music, visit 8 bit Sound and Fury.  Even though 8 bits seemed very simple (because there were so few values), it was not. When creating sound effects for games, one of the most difficult things to manage was the timing or duration of the tones in conjunction with the sprites flying across the screen in a (near) simultaneous fashion. In the 90s during  the reign of the Intel x86 architecture (the PC), the most popular sound card was called the Sound Blaster 16 made by Creative Technologies. In its prime, this sound card was quite amazing when playing games because it was a separate card having a chip set with the ability to play midi sounds and music in stereo (two channels). The sound card was bundled with a CD rom player allowing one to pop in a music CD. Another cool feature of the Sound Blaster was its 15-pin MIDI/Joystick multiport enabling game input devices to be connected. Today (the future), sound cards are able to support surround sound (3D audio effects), various sound formats, record, various music formats, midi, and mixing.  Multitasking enables modern computers to  play sounds/music on parallel tracks (simultaneously).

Next, we will be creating a sound manager service that will be added to the game engine framework library (JFXGen).

Sound Manager Service

The GameWorld class contains services such as the sprite manager and (more recently) a reference to an instance of a SoundManager (singleton). The sound manager service is responsible for managing all of the game’s sound effects. This service allows the developer to load sound clips (AudioClip) using the loadSoundEffects() method. After loading sound effects each audio clip can be retrieved using a unique id (String) mapped to the sound. The last method is the shutdown() method. When the application is exited, the stop method will invoke the GameWorld‘s shutdown() method which, in turn, calls the SoundManager object’s shutdown to clean up any resources. The SoundManager instance has a thread pool that gets gracefully shutdown.

Note:  For brevity, I designed the SoundManager class to play simple audio clips, though not music, during the game. If you want to add music, please refer to the JavaDoc on the Media and MediaPlayer APIs.

Shown below is the SoundManager class diagram:

SoundManager Class Diagram

Figure 2: Class Diagram of the Sound Manager

The following is source code for the SoundManager class:

package carlfx.gameengine;

import javafx.scene.media.AudioClip;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Responsible for loading sound media to be played using an id or key.
 * Contains all sounds for use later.
*</pre>
<pre> * User: cdea
 */
public class SoundManager {
    ExecutorService soundPool = Executors.newFixedThreadPool(2);
    Map<String, AudioClip> soundEffectsMap = new HashMap<>();

    /**
     * Constructor to create a simple thread pool.
     *
     * @param numberOfThreads - number of threads to use media players in the map.
     */
    public SoundManager(int numberOfThreads) {
        soundPool = Executors.newFixedThreadPool(numberOfThreads);
    }

    /**
     * Load a sound into a map to later be played based on the id.
     *
     * @param id  - The identifier for a sound.
     * @param url - The url location of the media or audio resource. Usually in src/main/resources directory.
     */
    public void loadSoundEffects(String id, URL url) {
        AudioClip sound = new AudioClip(url.toExternalForm());
        soundEffectsMap.put(id, sound);
    }

    /**
     * Lookup a name resource to play sound based on the id.
     *
     * @param id identifier for a sound to be played.
     */
    public void playSound(final String id) {
        Runnable soundPlay = new Runnable() {
            @Override
            public void run() {
                soundEffectsMap.get(id).play();
            }
        };
        soundPool.execute(soundPlay);
    }

    /**
     * Stop all threads and media players.
     */
    public void shutdown() {
        soundPool.shutdown();
    }

}

How do I play sound effects in JavaFX?

In JavaFX 2, you can play small sound files efficiently with less overhead by using the AudioClip API. This API allows a sound to be played repeatably. An example would be a gamer firing the weapon (left mouse press) which makes a laser sound “pew pew!” Speaking of lasers in the demo game, I used a free sound file from the website FreeSound.org having the Creative Commons license. Since the file was a wav file format, it was larger than it needed to be. So, I decided to convert the file to an mp3 sound format. I felt it was important to reduce the size of the file (smaller footprint) for faster loading. When converting the file to an mp3 sound format, I used Sony’s Sound Forge software. Shown below is a code snippet to play small sound files:

   AudioClip sound = new AudioClip("laser.mp3");
   sound.play();

How do I play music in JavaFX?

Although the SoundManager(my implementation) doesn’t play music, it is easy to add the capability. The following code snippet shows how to load an MP3 file to be played using the Media and MediaPlayer API:

   Media media = new Media("hymetojoy.mp3");
   MediaPlayer player = MediaPlayerBuilder.create()
                         .media(media)
                         .onReady( new Runnable() {
                             @Override
                             public void run() {
                                player.play();
                             })
                         .build();

JavaFX Sound Demo

Requirements:

  • Java 7 or later
  • JavaFX 2.1 or later
  • Windows XP or later (Should be available soon for Linux/MacOS)

A simple Asteroid type game called ‘The Expanse’.

Instructions:

  • Right mouse click (on Windows) to fly ship.
  • Left mouse click (left click on Windows mouse) to fire weapon.
  • Key press ’2′ to change to large missiles. (blue circular projectiles)
  • Other key press defaults to smaller missiles. (red circular projectiles)
  • Space bar key press will toggle a force field to protect the ship from enemies and asteroids.

Click on the Launch button below to start the demo:

Tutorial demo

Part 5 ‘The Expanse’ Sound

References

Apple ][ specs: http://apple2history.org/history/ah03/
8 bit on the Apple ][: http://eightbitsoundandfury.ld8.org/programming.html
Sound Blaster : http://en.wikipedia.org/wiki/Sound_Blaster
JFXGen: https://github.com/carldea/JFXGen
JavaFX’s AudioClip API: http://docs.oracle.com/javafx/2/api/javafx/scene/media/AudioClip.html
Sony Sound Forge: http://www.sonycreativesoftware.com/soundforgesoftware
Freesound.org: http://www.freesound.org
Laser sound from Freesound.org: http://www.freesound.org/people/THE_bizniss/sounds/39459/
Creative commons license: http://creativecommons.org/licenses/sampling+/1.0/
Media API: http://docs.oracle.com/javafx/2/api/javafx/scene/media/Media.html
MediaPlayer API: http://docs.oracle.com/javafx/2/api/javafx/scene/media/MediaPlayer.html

JavaFX 2 GameTutorial Part 4

JavaFX 2 Game Tutorial Part 4

Figure 1 JavaFX 2 Game Tutorial Part 4

 

Introduction

This is part four of a six part series related to a JavaFX 2 Game Tutorial. If you’ve missed Part 1, Part 2, or Part 3, I encourage you to go through them before beginning this tutorial. To recap, in Part 3 I gave you a little history of the many classic arcade style games and the different input devices that were used. I then showed you how to create a simple game similar to the famous arcade ‘Asteroids’. The controls (movement of the ship) were, however, more similar to those of the PC game ‘Star Craft’. In Part 3, you should have a good understanding of how to receive input from your keyboard and mouse.

This tutorial is about tweaking Part 2’s game engine and updating the existing ‘Asteroids’ style game from Part 3 to handle collision detection. In this tutorial, I will briefly talk about sprites and how to handle collision detection. The spaceship will now have the ability to generate a force field to protect itself from enemies and asteroids. This is reminiscent of the classic arcade ‘Asteroids Deluxe’.  If you want to run the demo, scroll down and click on the WebStart button below. Please read the requirements before launching the game.

What is a Sprite?

According to Wikipedia, “a sprite is a two-dimensional image or animation that is integrated into a larger scene.” From the Java gaming world view, a sprite is an object containing image frames and additional data based on the context of an actor to be animated onto the scene area. In the days of Walt Disney, when cartoons were drawn with a pencil and paper, the artist  produced many drawings that became animations. This example points to the creation of the flip book. I’m sure you’ve created flip books as a kid. I know I did. I used to doodle and make cool animations with all the corners of my notebooks. In our Asteroid type game, I created a sprite object which contains all of the images (ImageView) of the ship pre-rotated just like a flip book. To animate the ship turning, I made the current frame visible and the rest of the frames not visible. Similar to a flip book, it will appear to be rotated about its center (pivot) point. A sprite can also contain other information, such as velocity or health points.

Collision Detection

When actors or sprites animate across the scene, the game engine will check each sprite against other sprites to determine if they have collided into one another. This process should be very efficient especially when you have numerous sprites moving about the screen. There are tradeoffs when it comes to being efficient. Because each cycle in the game loop will check for collision, being more accurate usually degrades your performance. Many games will use the bounding region of the image to determine if two sprites have collided into one another.  Some games use rectangles as bounding regions. Shown below in figure 2 are two sprites colliding:

Bounding box as a rectangular collision region.

Figure 2 Bounding box as a rectangular collision region.

I’m sure you’ll know by now that most actors (images) in games don’t appear rectangular when pixels surrounding the actor are transparent. However, the actor or image is indeed rectangular even if the pixels are transparent or not.


Actor Image

Figure 3 depicts an actor image

Those games which use rectangular bounding regions usually make the bounding box inscribed in the sprite’s image. Shown below in figure 4 two rectangular bounding regions (orange and green) are inscribed in the spaceship image.

Two rectangles used as collision bounding boxes.

Figure 4 Two rectangles used as collision bounding boxes.

I’m sure you will notice that the nose tip of the ship and wings are not covered by either bounding box. This means that when an asteroid overlaps the unbounded region of the sprite the collision will not occur. Some games use this strategy; you will notice that the sprites’ rectangular bounding regions are small and placed in key areas of the sprite image.  Greater precision will be found with better algorithms for polygons and other non-rectangular shapes. In this blog entry, I basically use circles as bounding regions and not rectangles. I could have made each sprite contain an array of collision shapes, but instead, I chose to have only one collision region for each sprite. Each collision region will be a circle shape on the scene graph. For the spaceship, I inscribed the circle based on the center point of the ship with the radius extended to the cock pit of the ship. Shown below in figure 5 the bounded circular collision area of the ship is depicted as a red circle.

The ship's collision region.

Figure 5 The ship’s collision region.

I chose a circle as the bounding region because of the relative ease to determine the collision of two objects based on the distance formula (Pythagorean theorem) which only requires each sprite’s bounding region’s center point and their radii.  After calculating the distance based on the two center points, you will compare the result to see if it is less than or equal to the sum of the two radii. If the result does indeed come out to be less than or equal to the sum of the two radii then a collision has occurred.  Figure 6 depicts  how the distance formula relates to the two center points of circular bounding regions.

Distance formula

Figure 6 distance formula between two center points.

The following code creates the main game loop from the GameWorld class:

  @Override
  public void handle(javafx.event.ActionEvent event) {

     // update actors
     updateSprites();

     // check for collision
     checkCollisions();

     // removed dead things
     cleanupSprites();

  }

The code below creates the checkCollision() method from the GameWorld class:

    protected void checkCollisions() {
        // check other sprite's collisions
        spriteManager.resetCollisionsToCheck();
        // check each sprite against other sprite objects.
        for (Sprite spriteA : spriteManager.getCollisionsToCheck()) {
            for (Sprite spriteB : spriteManager.getAllSprites()) {
                if (handleCollision(spriteA, spriteB)) {
                    // The break helps optimize the collisions
                    //  The break statement means one object only hits another
                    // object as opposed to one hitting many objects.
                    // To be more accurate comment out the break statement.
                    break;
                }
            }
        }
    }

The derived Game World (TheExpanse) class’ implementation of its handleCollision() method:

    /**
     * How to handle the collision of two sprite objects.
     *
     * @param spriteA Sprite from the first list.
     * @param spriteB Sprite from the second list.
     * @return boolean returns a true if the two sprites have collided otherwise false.
     */
    @Override
    protected boolean handleCollision(Sprite spriteA, Sprite spriteB) {
        if (spriteA != spriteB) {
            if (spriteA.collide(spriteB)) {

                if (spriteA != myShip) {
                    spriteA.handleDeath(this);
                }
                if (spriteB != myShip) {
                    spriteB.handleDeath(this);
                }
            }
        }

        return false;
    }

The Sprite Class’ default implementation of its collide() method using the distance formula:

    public boolean collide(Sprite other) {

        if (collisionBounds == null || other.collisionBounds == null) {
            return false;
        }

        // determine it's size
        Circle otherSphere = other.collisionBounds;
        Circle thisSphere = collisionBounds;
        Point2D otherCenter = otherSphere.localToScene(otherSphere.getCenterX(), otherSphere.getCenterY());
        Point2D thisCenter = thisSphere.localToScene(thisSphere.getCenterX(), thisSphere.getCenterY());
        double dx = otherCenter.getX() - thisCenter.getX();
        double dy = otherCenter.getY() - thisCenter.getY();
        double distance = Math.sqrt(dx * dx + dy * dy);
        double minDist = otherSphere.getRadius() + thisSphere.getRadius();

        return (distance < minDist);
    }

The Sprite Class’ default implementation of its handleDeath() method:

    public void handleDeath(GameWorld gameWorld) {
        gameWorld.getSpriteManager().addSpritesToBeRemoved(this);
    }

The Atom (an asteroid or missile) class will override the handleDeath() method:


    public void handleDeath(GameWorld gameWorld) {
        implode(gameWorld);
        super.handleDeath(gameWorld);
    }

JavaFX 2 Sprite and Collision Demo

This simple demo game will be a mix between StarCraft and Asteroids. When using the mouse to navigate the ship, you will notice that the controls will resemble StarCraft’s Battle Cruiser. The objective is to fire your weapon at the spheres before they hit your spaceship or other spheres which implode upon impact. Because this is a simple tutorial or even a game in its early stages of development, the game doesn’t keep track of the score. I encourage you to go to GitHub to download the code and enhance the game. For the sake of brevity, I will not be showing all of the code changes, but I trust you will visit GitHub here: https://github.com/carldea/JFXGen for all the demos and source code.

Requirements:

  • Java 7 or later
  • JavaFX 2.1 or later
  • Windows XP or later (Should be available soon for Linux/MacOS)

A simple Asteroid type game called ‘The Expanse’.

Instructions:

  • Right mouse click (on Windows) to fly ship.
  • Left mouse click (left click on Windows mouse) to fire weapon.
  • Key press ’2′ to change to large missiles. (blue circular projectiles)
  • Other key press defaults to smaller missiles. (red circular projectiles)
  • Space bar key press will toggle a force field to protect the ship from enemies and asteroids.

Click on the Launch button below to start the demo:

Tutorial demo

Part 4 ‘The Expanse’ sprites/collision

Part 4 ‘Sprites/Collision’

Next up is Part 5 (Sound) where you will be using JavaFX to produce sound effects for your game.

References

Definition of a sprite: http://en.wikipedia.org/wiki/Sprite_%28computer_graphics%29

Walt Disney: http://en.wikipedia.org/wiki/Walt_Disney

How to make a flip book: http://www.bitrebels.com/design/how-to-create-a-flip-book/

JavaFX’s ImageView : http://docs.oracle.com/javafx/2/api/javafx/scene/image/ImageView.html

Collision detection: http://zetcode.com/tutorials/javagamestutorial/collision/

AABBs Collision detection in Java: http://www.youtube.com/watch?v=JIxV-LXqa1g

Pythagorean theorem: http://en.wikipedia.org/wiki/Pythagorean_theorem

Distance formula: http://en.wikipedia.org/wiki/Distance

Serious game of Asteroids Deluxe (Youtube): http://www.youtube.com/watch?v=6DG-GJENHgg

JavaFX 2 GameTutorial Part 2

UPDATE: Link to the source code is at the end of the blog.

Demo of a JavaFX 2 game tutorial

Atom Smasher – Game Loop Demo.

 Introduction

This is the second installment of a series of blog entries relating to a JavaFX 2 Game Tutorial. If you have not read Part 1 please see the introduction section of the JavaFX 2 Game Tutorial. To recap in Part 1, I mention some aspects of game play and a simple demo of a prototype spaceship (comprised of simple shapes) that is capable of navigating via the mouse. Disclaimer: This is a long tutorial so if you just want to run the demo just Click HERE. The demo is called Atom Smasher where you generate atoms (spheres) that collide. You may freeze the game to add more atoms. The objective is to have more than one atom alive and bouncing around. A text displays the current number of atoms floating around. Before beginning our discussion on a game loop I wanted to give you some background history about games and animation.

History

Back in the day (during the 80s-90s) many game programmers attempted to animate images has encountered the infamous screen flicker problem. This is where your sprites (graphic images) will often flash and make the game look quite awful. All monitors have a refresh rate where certain intervals the pixels will be redrawn (called vertical retrace CRTs). For example, if the refresh rate is 80 Hz it is approximately 80 times a second the screen is redrawn. If you are modifying things on the screen you can often be out of sync because of being in the middle of a refresh interval. What should you do about this? Well, actually there are two things that will help remedy this problem (double buffering & knowing when the cycle is occurring). Some clever developers created a technique called double buffering. Double buffering is a technique which consists of two surfaces where each takes turns on becoming the displayable surface and the other is an offscreen area (buffer surface). This technique is really a digital sleight of hand trick where the developer can pre calculate the sprites and their positions to be drawn on the offscreen surface. Once you are finished drawing on the offscreen buffer the code will switch it as the displayable surface. An important thing to point out is that we still have an issue due to the fact that we need to be notified when the refresh interval is about to begin the redraw process. In Java this ability is built in via the BufferStrategy API. So, where am I going with this? Sometimes explaining the past strategies will help us appreciate what we have today. Do we need to do this in JavaFX? Nope. Have no fear JavaFX is here! All of the issues that I’ve mentioned are all taken care of for us by using JavaFX’s Scene graph API. However, most games will still use the old fashion way of animating graphics and updating the game world called the ‘Game Loop’.

The Game Loop

Simply put the game loop is responsible for updating sprites (graphics), checking collision, and cleanup. Older game loops will check for key and mouse events as part of the loop. Since JavaFX abstracts events to allow the Scene or individual nodes to handle events the ability to listen to low level events aren’t necessary in our game loop. Shown below is a source code snippet of a typical game loop which will update sprites, check collisions, and cleanup sprites at each cycle. You will notice the Duration object from JavaFX 2.x which represents 60 divided by 1000 milliseconds or 60 frames per second(FPS). Each frame will call the handle() method of the JavaFX’s EventHandler interface in order to update the game world. Hypothetically, I’ve create three methods updateSprites(), checkCollisions(), and cleanupSprites() that will be invoked to handle sprites in the game.


   final Duration oneFrameAmt = Duration.millis(1000/60);
   final KeyFrame oneFrame = new KeyFrame(oneFrameAmt,
      new EventHandler() {

      @Override
      public void handle(javafx.event.ActionEvent event) {

         // update actors
         updateSprites();

         // check for collision
         checkCollisions();

         // removed dead things
         cleanupSprites();

      }
   }); // oneFrame

   // sets the game world's game loop (Timeline)
   TimelineBuilder.create()
      .cycleCount(Animation.INDEFINITE)
      .keyFrames(oneFrame)
      .build()
      .play();

The above code snippet is really all you need to create a simple game or animation. However, you may want to take things to the next level. You may want to create a game engine that can manage sprites and the state of the game world.

Game Engine

A game engine is a fancy name for a utility or library responsible for encapsulating the game world,  running the game loop, managing sprites, physics, etc. This is essentially a small game framework that allows you to extend or reuse so you don’t have to reinvent the wheel when creating a 2D game from scratch. To fast forward I created a UML class diagram of a design of a game engine.

Shown below is Figure 1 A JavaFX Game Engine Class diagram.

Figure 1. A JavaFX 2 Game Engine Design

In Figure 1 A JavaFX 2 Game Engine Design you will notice three classes a GameWorld, SpriteManager, and Sprite. The GameWorld class is responsible for initializing the game state, executing the game loop, updating sprites, handling sprite collisions, and cleaning up. Next is the SpriteManager class which in charge of managing sprites by adding, removing, and other house keeping for collisions. Lastly, is the Sprite class which is responsible for maintaining the state of an image (Actor). In a 2D world a sprite can contain the object’s velocity, rotation, scene node or image that eventually gets rendered at each cycle (key frame/frames per second).

Just a quick reminder on UML notation:

  • Plus symbol ‘+‘ denotes that a class member is public.
  • Minus symbol ‘‘ denotes that a class member is private
  • Hash symbol ‘#‘ denotes that a class member is protected.

GameWorld

Below is the source code implementation of the GameWorld class. Click to expand. Later you will see a class diagram depicting a simple demo game that will extend the GameWorld class (see AtomSmasher).

package carlfx.gameengine;

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.animation.TimelineBuilder;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 * This application demonstrates a JavaFX 2.x Game Loop.
 * Shown below are the methods which comprise of the fundamentals to a
 * simple game loop in JavaFX:
*
 *  <strong>initialize()</strong> - Initialize the game world.
 *  <strong>beginGameLoop()</strong> - Creates a JavaFX Timeline object containing the game life cycle.
 *  <strong>updateSprites()</strong> - Updates the sprite objects each period (per frame)
 *  <strong>checkCollisions()</strong> - Method will determine objects that collide with each other.
 *  <strong>cleanupSprites()</strong> - Any sprite objects needing to be removed from play.
 *
 * @author cdea
 */
public abstract class GameWorld {

    /** The JavaFX Scene as the game surface */
    private Scene gameSurface;
    /** All nodes to be displayed in the game window. */
    private Group sceneNodes;
    /** The game loop using JavaFX's <code>Timeline</code> API.*/
    private static Timeline gameLoop;

    /** Number of frames per second. */
    private final int framesPerSecond;

    /** Title in the application window.*/
    private final String windowTitle;

    /**
     * The sprite manager.
     */
    private final SpriteManager spriteManager = new SpriteManager();

    /**
     * Constructor that is called by the derived class. This will
     * set the frames per second, title, and setup the game loop.
     * @param fps - Frames per second.
     * @param title - Title of the application window.
     */
    public GameWorld(final int fps, final String title) {
        framesPerSecond = fps;
        windowTitle = title;
        // create and set timeline for the game loop
        buildAndSetGameLoop();
    }

    /**
     * Builds and sets the game loop ready to be started.
     */
    protected final void buildAndSetGameLoop() {

        final Duration oneFrameAmt = Duration.millis(1000/getFramesPerSecond());
        final KeyFrame oneFrame = new KeyFrame(oneFrameAmt,
            new EventHandler() {

                @Override
                public void handle(javafx.event.ActionEvent event) {

                    // update actors
                    updateSprites();

                    // check for collision
                    checkCollisions();

                    // removed dead things
                    cleanupSprites();

                }
        }); // oneFrame

        // sets the game world's game loop (Timeline)
        setGameLoop(TimelineBuilder.create()
                .cycleCount(Animation.INDEFINITE)
                .keyFrames(oneFrame)
                .build());
    }

    /**
     * Initialize the game world by update the JavaFX Stage.
     * @param primaryStage
     */
    public abstract void initialize(final Stage primaryStage);

    /**Kicks off (plays) the Timeline objects containing one key frame
     * that simply runs indefinitely with each frame invoking a method
     * to update sprite objects, check for collisions, and cleanup sprite
     * objects.
     *
     */
    public void beginGameLoop() {
        getGameLoop().play();
    }

    /**
     * Updates each game sprite in the game world. This method will
     * loop through each sprite and passing it to the handleUpdate()
     * method. The derived class should override handleUpdate() method.
     *
     */
    protected void updateSprites() {
        for (Sprite sprite:spriteManager.getAllSprites()){
            handleUpdate(sprite);
        }
    }

    /** Updates the sprite object's information to position on the game surface.
     * @param sprite - The sprite to update.
     */
    protected void handleUpdate(Sprite sprite) {
    }

    /**
     * Checks each game sprite in the game world to determine a collision
     * occurred. The method will loop through each sprite and
     * passing it to the handleCollision()
     * method. The derived class should override handleCollision() method.
     *
     */
    protected void checkCollisions() {
        // check other sprite's collisions
        spriteManager.resetCollisionsToCheck();
        // check each sprite against other sprite objects.
        for (Sprite spriteA:spriteManager.getCollisionsToCheck()){
            for (Sprite spriteB:spriteManager.getAllSprites()){
                if (handleCollision(spriteA, spriteB)) {
                    // The break helps optimize the collisions
                    //  The break statement means one object only hits another
                    // object as opposed to one hitting many objects.
                    // To be more accurate comment out the break statement.
                    break;
                }
            }
        }
    }

    /**
     * When two objects collide this method can handle the passed in sprite
     * objects. By default it returns false, meaning the objects do not
     * collide.
     * @param spriteA - called from checkCollision() method to be compared.
     * @param spriteB - called from checkCollision() method to be compared.
     * @return boolean True if the objects collided, otherwise false.
     */
    protected boolean handleCollision(Sprite spriteA, Sprite spriteB) {
        return false;
    }

    /**
     * Sprites to be cleaned up.
     */
    protected void cleanupSprites() {
        spriteManager.cleanupSprites();
    }

    /**
     * Returns the frames per second.
     * @return int The frames per second.
     */
    protected int getFramesPerSecond() {
        return framesPerSecond;
    }

    /**
     * Returns the game's window title.
     * @return String The game's window title.
     */
    public String getWindowTitle() {
        return windowTitle;
    }

    /**
     * The game loop (Timeline) which is used to update, check collisions, and
     * cleanup sprite objects at every interval (fps).
     * @return Timeline An animation running indefinitely representing the game
     * loop.
     */
    protected static Timeline getGameLoop() {
        return gameLoop;
    }

    /**
     * The sets the current game loop for this game world.
     * @param gameLoop Timeline object of an animation running indefinitely
     * representing the game loop.
     */
    protected static void setGameLoop(Timeline gameLoop) {
        GameWorld.gameLoop = gameLoop;
    }

    /**
     * Returns the sprite manager containing the sprite objects to
     * manipulate in the game.
     * @return SpriteManager The sprite manager.
     */
    protected SpriteManager getSpriteManager() {
        return spriteManager;
    }

    /**
     * Returns the JavaFX Scene. This is called the game surface to
     * allow the developer to add JavaFX Node objects onto the Scene.
     * @return
     */
    public Scene getGameSurface() {
        return gameSurface;
    }

    /**
     * Sets the JavaFX Scene. This is called the game surface to
     * allow the developer to add JavaFX Node objects onto the Scene.
     * @param gameSurface The main game surface (JavaFX Scene).
     */
    protected void setGameSurface(Scene gameSurface) {
        this.gameSurface = gameSurface;
    }

    /**
     * All JavaFX nodes which are rendered onto the game surface(Scene) is
     * a JavaFX Group object.
     * @return Group The root containing many child nodes to be displayed into
     * the Scene area.
     */
    public Group getSceneNodes() {
        return sceneNodes;
    }

    /**
     * Sets the JavaFX Group that will hold all JavaFX nodes which are rendered
     * onto the game surface(Scene) is a JavaFX Group object.
     * @param sceneNodes The root container having many children nodes
     * to be displayed into the Scene area.
     */
    protected void setSceneNodes(Group sceneNodes) {
        this.sceneNodes = sceneNodes;
    }

}

SpriteManager

A sprite manager class is a helper class to assist the game loop to keep track of sprites. Normally a sprite manager will contain all sprites and each sprite contains a JavaFX Node that is displayed onto the Scene graph.
Shown below is the source code. Click to expand.

package carlfx.gameengine;

import java.util.*;

/**
 * Sprite manager is responsible for holding all sprite objects, and cleaning up
 * sprite objects to be removed. All collections are used by the JavaFX
 * application thread. During each cycle (animation frame) sprite management
 * occurs. This assists the user of the API to not have to create lists to
 * later be garbage collected. Should provide some performance gain.
 * @author cdea
 */
public class SpriteManager {
    /** All the sprite objects currently in play */
    private final static List GAME_ACTORS = new ArrayList<>();

    /** A global single threaded list used to check collision against other
     * sprite objects.
     */
    private final static List CHECK_COLLISION_LIST = new ArrayList<>();

    /** A global single threaded set used to cleanup or remove sprite objects
     * in play.
     */
    private final static Set CLEAN_UP_SPRITES = new HashSet<>();

    /** */
    public List getAllSprites() {
        return GAME_ACTORS;
    }

    /**
     * VarArgs of sprite objects to be added to the game.
     * @param sprites
     */
    public void addSprites(Sprite... sprites) {
        GAME_ACTORS.addAll(Arrays.asList(sprites));
    }

    /**
     * VarArgs of sprite objects to be removed from the game.
     * @param sprites
     */
    public void removeSprites(Sprite... sprites) {
        GAME_ACTORS.removeAll(Arrays.asList(sprites));
    }

    /** Returns a set of sprite objects to be removed from the GAME_ACTORS.
     * @return CLEAN_UP_SPRITES
     */
    public Set getSpritesToBeRemoved() {
        return CLEAN_UP_SPRITES;
    }

 /**
     * Adds sprite objects to be removed
     * @param sprites varargs of sprite objects.
     */
    public void addSpritesToBeRemoved(Sprite... sprites) {
        if (sprites.length > 1) {
            CLEAN_UP_SPRITES.addAll(Arrays.asList((Sprite[]) sprites));
        } else {
            CLEAN_UP_SPRITES.add(sprites[0]);
        }
    }

    /**
     * Returns a list of sprite objects to assist in collision checks.
     * This is a temporary and is a copy of all current sprite objects
     * (copy of GAME_ACTORS).
     * @return CHECK_COLLISION_LIST
     */
    public List getCollisionsToCheck() {
        return CHECK_COLLISION_LIST;
    }

    /**
     * Clears the list of sprite objects in the collision check collection
     * (CHECK_COLLISION_LIST).
     */
    public void resetCollisionsToCheck() {
        CHECK_COLLISION_LIST.clear();
        CHECK_COLLISION_LIST.addAll(GAME_ACTORS);
    }

    /**
     * Removes sprite objects and nodes from all
     * temporary collections such as:
     * CLEAN_UP_SPRITES.
     * The sprite to be removed will also be removed from the
     * list of all sprite objects called (GAME_ACTORS).
     */
    public void cleanupSprites() {

        // remove from actors list
        GAME_ACTORS.removeAll(CLEAN_UP_SPRITES);

        // reset the clean up sprites
        CLEAN_UP_SPRITES.clear();
    }
}

Sprite

The Sprite class represents an image or node to be displayed onto the JavaFX Scene graph. In a 2D game a sprite will contain additional information such as its velocity for the object as it moves across the scene area. The game loop will call the update() and collide() method at every interval of a key frame.
Shown below is the source code. Click to expand.

package carlfx.gameengine;

import java.util.ArrayList;
import java.util.List;
import javafx.animation.Animation;
import javafx.scene.Node;

/**
 * The Sprite class represents a image or node to be displayed.
 * In a 2D game a sprite will contain a velocity for the image to
 * move across the scene area. The game loop will call the update()
 * and collide() method at every interval of a key frame. A list of
 * animations can be used during different situations in the game
 * such as rocket thrusters, walking, jumping, etc.
 * @author cdea
 */
public abstract class Sprite {

    /** Animation for the node */
    public List animations = new ArrayList<>();

    /** Current display node */
    public Node node;

    /** velocity vector x direction */
    public double vX = 0;

    /** velocity vector y direction */
    public double vY = 0;

    /** dead? */
    public boolean isDead = false;

    /**
     * Updates this sprite object's velocity, or animations.
     */
    public abstract void update();

    /**
     * Did this sprite collide into the other sprite?
     *
     * @param other - The other sprite.
     * @return
     */
    public boolean collide(Sprite other) {
        return false;
    }
}

JavaFX 2 Game Loop Demo – Atom Smasher

Whew! If you’ve got this far you are one brave soul. Let’s take a small break and try out the demo I created using the game engine above.
Shown below is a Java Webstart button to launch the game demo. Later, you will see the design and source code detailing how it was created.

Requirements:

  • Java 7 or later
  • JavaFX 2.0.2 2.1 or later
  • Windows XP or later (Should be available soon for Linux/MacOS)

AtomSmasher Game loop demo

Demo

GameLoopPart2 Design

Below is a class diagram of the game demo called Atom Smasher which uses the game engine framework mentioned earlier.
Shown below is Figure 2 Atom Smasher Class Diagram.

Figure 2. Atom Smasher Class Diagram

GameLoopPart2

The GameLoopPart2 is the driver or main JavaFX application that runs the game. This creates a GameWorld object to be initialized and starts the game loop.
Shown below is the source code. Click to expand.

package carlfx;

import carlfx.gameengine.GameWorld;
import javafx.application.Application;
import javafx.stage.Stage;

/**
 * The main driver of the game.
 * @author cdea
 */
public class GameLoopPart2 extends Application {

    GameWorld gameWorld = new AtomSmasher(60, "JavaFX 2 GameTutorial Part 2 - Game Loop");
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        // setup title, scene, stats, controls, and actors.
        gameWorld.initialize(primaryStage);

        // kick off the game loop
        gameWorld.beginGameLoop();

        // display window
        primaryStage.show();
    }

}

AtomSmasher

AtomSmasher is a derived class of the GameWorld class. It creates many spheres that animate with random velocities, colors and positions. Button controls lets the user generate more ‘atoms’ (JavaFX Circle nodes). As each atom collides with one another they will invoke the implode() method that produces a fade transition animation. You will notice how easy it is to implement this game by simply implementing initialize(), handleUpdate(), handleCollision(), and cleanupSprites() methods. Once implemented the game engine does the rest. The initialize() method creates the button controls for the user. To update the sprites positions or change the game state you will implement the handleUpdate() method. To compare all sprites if they have collided with one another you will implement the handleCollision(). The last part of the game loop’s life cycle is cleaning up sprites. Cleaning up means updating the sprite manger and updating the JavaFX Scene (removing nodes).
Shown below is the source code. Click to expand.

package carlfx;

import carlfx.gameengine.GameWorld;
import carlfx.gameengine.Sprite;
import java.util.Random;
import javafx.animation.Timeline;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ButtonBuilder;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBoxBuilder;
import javafx.scene.layout.VBox;
import javafx.scene.layout.VBoxBuilder;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import static javafx.animation.Animation.Status.RUNNING;
import static javafx.animation.Animation.Status.STOPPED;

/**
 * This is a simple game world simulating a bunch of spheres looking
 * like atomic particles colliding with each other. When the game loop begins
 * the user will notice random spheres (atomic particles) floating and
 * colliding. The user is able to press a button to generate more
 * atomic particles. Also, the user can freeze the game.
 *
 * @author cdea
 */
public class AtomSmasher extends GameWorld {
    /** Read only field to show the number of sprite objects are on the field*/
    private final static Label NUM_SPRITES_FIELD = new Label();

    public AtomSmasher(int fps, String title){
        super(fps, title);
    }

    /**
     * Initialize the game world by adding sprite objects.
     * @param primaryStage
     */
    @Override
    public void initialize(final Stage primaryStage) {
        // Sets the window title
        primaryStage.setTitle(getWindowTitle());

        // Create the scene
        setSceneNodes(new Group());
        setGameSurface(new Scene(getSceneNodes(), 640, 580));
        primaryStage.setScene(getGameSurface());

        // Create many spheres
        generateManySpheres(150);

        // Display the number of spheres visible.
        // Create a button to add more spheres.
        // Create a button to freeze the game loop.
        final Timeline gameLoop = getGameLoop();
        VBox stats = VBoxBuilder.create()
            .spacing(5)
            .translateX(10)
            .translateY(10)
            .children(HBoxBuilder.create()
                .spacing(5)
                .children(new Label("Number of Particles: "), // show no. particles
                    NUM_SPRITES_FIELD).build(),

                    // button to build more spheres
                    ButtonBuilder.create()
                        .text("Regenerate")
                        .onMousePressed(new EventHandler() {
                            @Override
                            public void handle(MouseEvent arg0) {
                                generateManySpheres(150);
                            }}).build(),

                    // button to freeze game loop
                    ButtonBuilder.create()
                        .text("Freeze/Resume")
                        .onMousePressed(new EventHandler() {

                            @Override
                            public void handle(MouseEvent arg0) {
                                switch (gameLoop.getStatus()) {
                                    case RUNNING:
                                        gameLoop.stop();
                                        break;
                                    case STOPPED:
                                        gameLoop.play();
                                        break;
                                }
                            }}).build()
            ).build(); // (VBox) stats on children

        // lay down the controls
        getSceneNodes().getChildren().add(stats);
    }

    /**
     * Make some more space spheres (Atomic particles)
     */
    private void generateManySpheres(int numSpheres) {
        Random rnd = new Random();
        Scene gameSurface = getGameSurface();
        for (int i=0; i (gameSurface.getWidth() - (circle.getRadius() * 2))) {
                newX = gameSurface.getWidth() - (circle.getRadius()  * 2);
            }

            // check for the bottom of screen the height newY is greater than height
            // minus radius times 2(height of sprite)
            double newY = rnd.nextInt((int) gameSurface.getHeight());
            if (newY > (gameSurface.getHeight() - (circle.getRadius() * 2))) {
                newY = gameSurface.getHeight() - (circle.getRadius() * 2);
            }

            circle.setTranslateX(newX);
            circle.setTranslateY(newY);
            circle.setVisible(true);
            circle.setId(b.toString());

            // add to actors in play (sprite objects)
            getSpriteManager().addSprites(b);

            // add sprite's
            getSceneNodes().getChildren().add(0, b.node);

        }
    }

    /**
     * Each sprite will update it's velocity and bounce off wall borders.
     * @param sprite - An atomic particle (a sphere).
     */
    @Override
    protected void handleUpdate(Sprite sprite) {
        if (sprite instanceof Atom) {
            Atom sphere = (Atom) sprite;

            // advance the spheres velocity
            sphere.update();

            // bounce off the walls when outside of boundaries
            if (sphere.node.getTranslateX() > (getGameSurface().getWidth()  -
                sphere.node.getBoundsInParent().getWidth()) ||
                sphere.node.getTranslateX() < 0 ) {                 sphere.vX = sphere.vX * -1;             }             if (sphere.node.getTranslateY() > getGameSurface().getHeight()-
                sphere.node.getBoundsInParent().getHeight() ||
                sphere.node.getTranslateY() < 0) {
                sphere.vY = sphere.vY * -1;
            }
        }
    }

    /**
     * How to handle the collision of two sprite objects. Stops the particle
     * by zeroing out the velocity if a collision occurred.
     * @param spriteA
     * @param spriteB
     * @return
     */
    @Override
    protected boolean handleCollision(Sprite spriteA, Sprite spriteB) {
        if (spriteA.collide(spriteB)) {
            ((Atom)spriteA).implode(this);
            ((Atom)spriteB).implode(this);
            getSpriteManager().addSpritesToBeRemoved(spriteA, spriteB);
            return true;
        }
        return false;
    }

    /**
     * Remove dead things.
     */
    @Override
    protected void cleanupSprites() {
        // removes from the scene and backend store
        super.cleanupSprites();

        // let user know how many sprites are showing.
        NUM_SPRITES_FIELD.setText(String.valueOf(getSpriteManager().getAllSprites().size()));

    }
}

Atom

The Atom class extends from the Sprite class. An atom is a sprite that appears like a spherical object that moves across the scene. An atom will have a random radius, color, and velocity. As each atom sprite collides with another atom they will animate a fade transition (the implode() method).
Shown below is the source code. Click to expand.

package carlfx;

import carlfx.gameengine.GameWorld;
import carlfx.gameengine.Sprite;
import javafx.animation.FadeTransitionBuilder;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.paint.Color;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.RadialGradientBuilder;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Circle;
import javafx.scene.shape.CircleBuilder;
import javafx.util.Duration;

/**
 * A spherical looking object (Atom) with a random radius, color, and velocity.
 * When two atoms collide each will fade and become removed from the scene. The
 * method called implode() implements a fade transition effect.
 *
 * @author cdea
 */
public class Atom extends Sprite {

    public Atom(double radius, Color fill) {
        Circle sphere = CircleBuilder.create()
                .centerX(radius)
                .centerY(radius)
                .radius(radius)
                .cache(true)
                .build();

        RadialGradient rgrad = RadialGradientBuilder.create()
                    .centerX(sphere.getCenterX() - sphere.getRadius() / 3)
                    .centerY(sphere.getCenterY() - sphere.getRadius() / 3)
                    .radius(sphere.getRadius())
                    .proportional(false)
                    .stops(new Stop(0.0, fill), new Stop(1.0, Color.BLACK))
                    .build();

        sphere.setFill(rgrad);

        // set javafx node to a circle
        node = sphere;

    }

    /**
     * Change the velocity of the atom particle.
     */
    @Override
    public void update() {
        node.setTranslateX(node.getTranslateX() + vX);
        node.setTranslateY(node.getTranslateY() + vY);
    }

    @Override
    public boolean collide(Sprite other) {
        if (other instanceof Atom) {
            return collide((Atom)other);
        }
       return false;
    }

    /**
     * When encountering another Atom to determine if they collided.
     * @param other Another atom
     * @return boolean true if this atom and other atom has collided,
     * otherwise false.
     */
    private boolean collide(Atom other) {

        // if an object is hidden they didn't collide.
        if (!node.isVisible() ||
            !other.node.isVisible() ||
            this == other) {
            return false;
        }

        // determine it's size
        Circle otherSphere = other.getAsCircle();
        Circle thisSphere =  getAsCircle();
        double dx = otherSphere.getTranslateX() - thisSphere.getTranslateX();
        double dy = otherSphere.getTranslateY() - thisSphere.getTranslateY();
        double distance = Math.sqrt( dx * dx + dy * dy );
        double minDist  = otherSphere.getRadius() + thisSphere.getRadius() + 3;

        return (distance < minDist);
    }

    /**
     * Returns a node casted as a JavaFX Circle shape.
     * @return Circle shape representing JavaFX node for convenience.
     */
    public Circle getAsCircle() {
        return (Circle) node;
    }

    /**
     * Animate an implosion. Once done remove from the game world
     * @param gameWorld - game world
     */
    public void implode(final GameWorld gameWorld) {
        vX = vY = 0;
        FadeTransitionBuilder.create()
            .node(node)
            .duration(Duration.millis(300))
            .fromValue(node.getOpacity())
            .toValue(0)
            .onFinished(new EventHandler() {
                @Override
                public void handle(ActionEvent arg0) {
                    isDead = true;
                    gameWorld.getSceneNodes().getChildren().remove(node);
                }
            })
            .build()
            .play();
    }
}

Conclusion

Hopefully you’ve got a chance to understand the fundamentals of a gaming loop and later apply the knowledge by implementing a robust game engine. Although, I briefly mention collision I am saving that for Part 4 of these tutorials. Please stay tuned for Part 3 where we will get into input using the keyboard or mouse. Feel free to experiment. Let me know what you come up with. 😉

Carl

UPDATE: Link to the source code is below:

To obtain the source code please download the link to a jar file below by using the ‘Save link As‘ option in your browser. If you are on a Windows system you can change the extension from ‘jar‘ to ‘zip‘ to be easily expanded. It will contain a directory ‘src‘ with the source code.

The source code location:

http://www.jroller.com/carldea/resource/javafx2.0_games/part2source_code.jar

The published version of the source code is at the GitHub called (JFXGen) for you to clone and fork to your hearts content (It’s there for you to use for your own projects). Enjoy.

https://github.com/carldea/JFXGen

git clone http://github.com:carldea/JFXGen.git

References:

CRTshttp://en.wikipedia.org/wiki/Refresh_rate

Double bufferinghttp://en.wikipedia.org/wiki/Double_buffering#Double_buffering

Developing Games in Java by David Brackeen with Bret Barker and Laurence Vanhelsuwe. Page 56 “Getting Rid of Flicker and Tearing”
BufferStrategy API – http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferStrategy.html