Preview only show first 10 pages with watermark. For full document please download

Beginning Java 8 Games Development | Vu Hung

Since there are literally billions of Java compatible consumer electronics devices, owned by billions of users all over the world, it stands to reason that developing popular Java 8 Games for all of these people could be an extremely lucrative undertaking, given that you have the right game concept, artwork, game design, and ...

   EMBED

  • Rating

  • Date

    January 2017
  • Size

    44.8MB
  • Views

    3,827
  • Categories


Share

Transcript

www.it-ebooks.info For your convenience Apress has placed some of the front matter material after the index. Please use the Bookmarks and Contents at a Glance links to access them. www.it-ebooks.info Contents at a Glance About the Author��������������������������������������������������������������������������������������������������������������� xix About the Technical Reviewer������������������������������������������������������������������������������������������� xxi Acknowledgments����������������������������������������������������������������������������������������������������������� xxiii Introduction���������������������������������������������������������������������������������������������������������������������� xxv ■■Chapter 1: Setting Up a Java 8 Game Development Environment�������������������������������������1 ■■Chapter 2: Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0������������������������19 ■■Chapter 3: A Java 8 Primer: An Introduction to Java 8 Concepts and Principles�����������43 ■■Chapter 4: An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine�������������������������������������������������������������������������������������75 ■■Chapter 5: An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder������������������������������������������������������������������������������������������������101 ■■Chapter 6: The Foundation of Game Design: The JavaFX Scene Graph and the InvinciBagel Game Infrastructure���������������������������������������������������������������������123 ■■Chapter 7: The Foundation of Game Play Loop: The JavaFX Pulse System and the Game Processing Architecture�������������������������������������������������������������������������145 ■■Chapter 8: Creating Your Actor Engine: Design the Characters for Your Game and Define Their Capabilities�����������������������������������������������������������������������������������������165 ■■Chapter 9: Controlling Your Action Figure: Implementing Java Event Handlers and Using Lambda Expressions�������������������������������������������������������������������������������������187 ■■Chapter 10: Directing the Cast of Actors: Creating a Casting Director Engine and Creating the Bagel Actor Class�������������������������������������������������������������������������������207 ■■Chapter 11: Moving Your Action Figure in 2D: Controlling the X and Y Display Screen Coordinates�������������������������������������������������������������������������������������������229 v www.it-ebooks.info ■ Contents at a Glance ■■Chapter 12: Setting Boundaries for Your Action Figure in 2D: Using the Node Class LocalToParent Attribute������������������������������������������������������������������������������251 ■■Chapter 13: Animating Your Action Figure States: Setting the Image States Based on KeyEvent Processing��������������������������������������������������������������������������273 ■■Chapter 14: Setting Up the Game Environment: Creating Fixed Sprite Classes Using the Actor Superclass������������������������������������������������������������������������������299 ■■Chapter 15: Implementing Game Audio Assets: Using the JavaFX AudioClip Class Audio Sequencing Engine��������������������������������������������������������������������323 ■■Chapter 16: Collision Detection: Creating SVG Polygons for the Game Actors and Writing Code to Detect Collision�����������������������������������������������������������������������������343 ■■Chapter 17: Enhancing Game Play: Creating a Scoring Engine, Adding Treasure and an Enemy Auto-Attack Engine�����������������������������������������������������393 Index���������������������������������������������������������������������������������������������������������������������������������455 vi www.it-ebooks.info Introduction The Java Programming Language is currently the most popular object-oriented (OOP) programming language in the world today. Java runs on everything from SmartWatches to HD Smartphones to Touchscreen Tablets to eBook Readers to Game Consoles to SmartGlasses to Ultra-High Definition (UHD) 4K Interactive Television Sets, with even more types of consumer electronics devices, such as those found in the automotive, appliances, health care, digital signage, security, and the home automation market, increasingly adopting the open source Java platform for use in their hardware devices as time goes on. Since there are literally billions of Java compatible consumer electronics devices, owned by billions of users all over the world, it stands to reason that developing popular Java 8 Games for all of these people could be an extremely lucrative undertaking, given that you have the right game concept, artwork, game design, and optimization work process, of course. Java 8 (and its multimedia engine, JavaFX 8) code can run on just about every operating system out there, including Windows XP; Vista, 7, 8, and 9; all Linux distributions; 32-bit Android 4 and 64-bit Android 5; Open Solaris; Macintosh OS/X, iOS; Symbian, and Raspberry Pi – it’s only a matter of time before the other popular OSes add support for this popular open source programming language. Additionally, every popular Internet browser has Java built in! Java provides the ultimate flexibility in installing software, as an application, or in the browser as an applet. You can even drag a Java application right out of the browser, and have it install itself on that user’s desktop! Java 8 is a truly remarkable technology. There are a plethora of embedded and desktop hardware support levels currently for Java 8 (and for JavaFX 8.0) including the full Java SE 8, Java SE 8 Embedded, Java ME (Micro Edition) 8, and Java ME 8 Embedded, as well as Java EE 8 for Enterprise Application Development. Talk about being able to “code once, deliver everywhere!” That is the dream of every programmer, and Oracle is making it a reality with the powerful Java 8 multimedia programming platform. This book will go a long way toward helping you to learn exactly how to go about developing Java 8 games, using the Java programming language in conjunction with the recently added JavaFX 8.0 multimedia engine. These Java 8 game applications will be able to run across a plethora of Java compatible consumer electronics devices. Developing Java 8 game applications that play smoothly across all of these different types of consumer electronics devices requires a very specific work process, including asset design, game code design, and optimization, all of which I will be covering during this book. I wrote the Beginning Java 8 Game Development title from scratch, using a real-world client game project that I am actually working on, and will be delivering to the public sometime in 2015. I am targeting those readers who are Beginning Game Developers, and who had not coded in Java 8 and JavaFX 8.0. These readers are technically savvy, but they are not that familiar with object-oriented computer programming concepts and techniques. Since Java is now at Version 8u40, this book will be more advanced than many of the other Java books out there. Java 8 has added some very advanced features, such as the JavaFX 8.0 API, which gives Java 8 its own multimedia engine, supporting SVG, 2D, 3D, audio, and video media. I designed this book to contain a comprehensive overview of the optimal Java 8 game development work process. Most beginning Java application development books only cover the language, however. If you really want to become that well-known Java game application developer that you seek to become, you will have to understand as well as master all of the areas of game design, including multimedia asset creation, user interface design, Java 8 Programming, JavaFX 8.0 class usage, and data footprint, memory, and CPU usage optimization. Once you’ve mastered these areas – hopefully, by the end of this book, you will be able to create the memorable user experience that will be required to create popular, best-selling Java 8 games. You can do it; I know you can! xxv www.it-ebooks.info ■ Introduction Java 8 games are not only developed using the NetBeans 8.0 Integrated Development Environment (IDE) alone, but also in conjunction with the use of JavaFX 8 and several other different types of new media content development software packages. For this reason, this book covers the installation and use of a wide variety of other popular open source software packages, such as GIMP 2.8 and Audacity 2.0.6, in conjunction with developing Java 8 game applications using the NetBeans 8.0 IDE and the JavaFX new media engine, which brings the “wow factor” to the Java programming language. I am architecting this book in this fashion so that you can ascertain precisely how your usage of new media content development software will fit into your overall Java 8 game development work process. This comprehensive approach will serve to set this unique book title distinctly apart from all of those other Java 8 game application development titles that are currently out on the market. The book starts out in Chapter 1 with downloading and installing the latest Java 8 JDK as well as the NetBeans 8.0 IDE, along with several popular open source content development applications. In Chapter 2, you will learn about NetBeans 8.0, and create your first Java 8 game application, and look at useful NetBeans features, such as code completion and code profiling. In Chapter 3, you will learn about the fundamentals of the Java 8 programming language, which you’ll be implementing to create a Java 8 game during the remainder of the book. In Chapter 4, you will learn all about the JavaFX 8.0 new media engine (API) and how its impressive features can take your Java 8 game development and place it into the stratosphere. In Chapter 5, you will learn all about the JavaFX 8 FXML (Java FX Markup Language) and about the underlying concepts of developing new media assets such as digital audio, digital images, digital video, 2D scalable vector graphics (SVG), and 3D geometry, for use with Java 8 games. In Chapter 6, you will learn about game design concepts, and create the foundation for your Java 8 game, its user interface, and a splashscreen. Thus the first third of this book is foundational material, which you’ll need to be able to understand how NetBeans 8.0, Java 8, JavaFX 8.0, and various new media asset types supported by the JavaFX engine function together as a platform. In Chapter 7 we will start to create the various game engines, starting with the game play loop 60 FPS timing engine, and we will learn about the JavaFX 8 Animation, Timeline, KeyFrame, KeyValue, Interpolator, and AnimationTimer classes, which allow the Java 8 game to tap into the JavaFX pulse event timing engine that gives Java 8 its multimedia power. In Chapter 8, we will create your game Actor and Hero Java abstract classes, the Actor engine, if you will, which will allow us to create the different types of game play components that we will need for the Java 8 game. This will teach you how to create custom foundational classes for a game project, and you will look at the Node, SVGPath, Shape, Image, and ImageView classes as we incorporate these JavaFX class (object) types into our Java 8 Game Actor design. In Chapter 9, you will learn how to add interactivity to your Java 8 Game projects, using event handling. We will add an event processing engine, which will process all of the different types of action, key, mouse, and drag events that you are likely to utilize in your Java 8 game development work process in the future when you create your own custom games. In Chapter 10, you will learn about Java List, Set, and Array classes. These are called Java collections, and we will create a custom Actor management engine, which we will call the CastingDirector class, during this chapter. This will allow you to automate the task of keeping track of the cast of your game for each level, and will be used for collision detection. In Chapter 11 we will start coding our primary Actor class for the InvinciBagel character, and add Java 8 code that controls movement on the screen, so that we can start to work on fusing character animation with game player key use so that we can allow our game players to control the InvinciBagel character completely. This involves “wiring up” the Bagel class to the GamePlayLoop (game play timing class created in Chapter 7) class, so we can start working in the fourth dimension of time. In Chapter 12 you will use your Actor and Hero abstract classes that you created in Chapter 8 to create the InvinciBagel primary character and his Bagel.java class, as well as learn how to implement code that sets the boundaries for your Java 8 game, so that the Actor does not go off the screen, forcing him stay inside of the field of play for the game. xxvi www.it-ebooks.info ■ Introduction In Chapter 13 you will add different InvinciBagel sprite image states into your Java 8 game, and when these are combined with the movement you coded in Chapters 11 and 12, allow your InvinciBagel character to run, jump, fly, land, wait impatiently to be moved, and even turn sideways to evade bullets. In Chapter 14, you will create a series of Prop classes that will allow you to place fixed props and obstacles into your Java 8 game levels. You will learn how to use one digital image asset to create four different scenery props, using the JavaFX ability to flip and mirror your image assets around either (or both of ) their X and Y axes. In Chapter 15, you’ll implement your Java 8 game audio engine, using the JavaFX AudioClip class, which allows digital audio sequencing to be integrated into your Java 8 game play, taking it an order of magnitude higher, by stimulating the aural senses of your game player. You’ll learn how to optimize digital audio assets so well, that you will not have to use any lossy compression, giving you perfect audio samples, and showing you exactly how much of the system’s memory your audio assets will be using. In Chapter 16, we’ll start getting into advanced topics, such as designing collision polygons using SVG data and the GIMP 2.8 and PhysicsEditor software packages. We will also learn about the JavaFX Bounds and Node classes, and how collision detection is accomplished for Java 8 game development, using the .getBoundsInLocal() and .getBoundsInParent() method calls, in conjunction with the Node.intersects() and Shape.intersect() method calls. In Chapter 17, we will pull everything together, and focus solely on implementing your game play. You will create Actor subclasses for Treasure, Projectile, and Enemy, and create an auto-attack engine that will turn a game player’s PC or mobile device into his or her adversary. We look at the most advanced topics, such as physics and AI, during this chapter, after which you will have enough of a foundation to create your own Java 8 games, using your own intellectual property! This book attempts to be the most comprehensive Java 8 game application development programming title on the market, by covering most, if not all, of the major Java 8 and JavaFX classes that will need to be used to create Java 8 Game Applications. Some of these include the Image, ImageView, Group, Node, StackPane, Scene, Stage, Application, ListArray, HashSet, Arrays, AudioClip, MediaPlayer, URL, Button, Shape, HBox, SVGPath, Insets, AnimationTimer, and more. If you’re looking for the most comprehensive, up-to-date overview of the Java 8 programming language for games, including JavaFX 8.0 and NetBeans 8.0 IDE all seamlessly integrated with new media content development work processes, as well as a “soup to nuts” knowledge about how to optimally use these technologies in conjunction with the leading open source new media game content design and development tools, then this book will really be of significant interest to you. It is the intention of this book to take you from being a Beginner in Java 8 game application development to a solid intermediate knowledge level regarding Java 8, NetBeans 8, and JavaFX 8.0 game application development. Be advised that this book, even though it’s ostensibly a Beginner title, contains a significant amount of technical knowledge. All of the work processes that are described during the book may well take more than one read through to assimilate into an application development knowledge base (your quiver of technical knowledge). It will be well worth your time, however, rest assured. xxvii www.it-ebooks.info Chapter 1 Setting Up a Java 8 Game Development Environment Welcome to the book Beginning Java 8 Games Development! Let’s get started by creating a solid development software foundation for use with this book. The core of this foundation will be Java SDK (Software Development Kit) 8, also called JDK (Java Development Kit) 8. I will also set you up with NetBeans IDE 8.0 (Integrated Development Environment), which will make coding Java 8 games much easier. After that, I will introduce you to the latest opensource new media content creation software packages for digital illustration (Inkscape), digital imaging (GIMP [GNU Image Manipulation Program]), digital video (EditShare Lightworks), digital audio (Audacity), and 3D modeling and animation (Blender). At the end of the chapter, I will also suggest some other professional-level software packages that you should consider adding to the professional game development workstation that you will be creating over the course of this chapter. To get the best results from all this free, professional-level software, you will want to have a modern, 64-bit workstation with at least 4GB of system memory (6GB or 8GB would be even better) and a multicore processor (central processing unit [CPU]), such as an AMD FX-6300 (hexa-core), AMD FX-8350 (octa-core), or Intel i7 (quadcore). Workstations such as these have become commodity items and can be purchased at Walmart or Pricewatch.com at an affordable price. The first thing that you will do in this chapter is make sure that you have removed any of the outdated versions of Java, such as Java 7 or Java 6, or any outdated versions of NetBeans, such as NetBeans 7 or NetBeans 6. This involves uninstalling (removing or deleting completely) these older development software versions from your workstation. You will do this using the Windows program management utility Programs and Features, which can be found in the Windows operating system (OS) Control Panel suite of Windows OS Management Utilities. There are similar utilities on the Linux and Mac platforms, if you happen to be using one of these less commonly used OSs. Because most developers use Windows 7, 8, or 9, you will be using the Windows 64-bit platform for the examples in this book. Next, I will show you where exactly to go on the Internet to get these software packages, so get ready to fire up your speedy Internet connection so that you can download nearly a gigabyte of all-new game content production software! After you download the latest versions of all this software, you will install the programming and content development packages and configure them for use with this book. The order in which you perform these software installations is important, because Java JDK 8 and Java 8 Runtime Environment (JRE) form the foundation of NetBeans IDE 8.0. This is because NetBeans IDE 8.0 was originally coded using the Java programming language, so you will see just how incredibly professional a piece of software can be using this language. Thus, the Java 8 software will be the first software you install. After you install Java 8, you will then install NetBeans 8.0, so that you have a graphical user interface (GUI), on top of the Java programming language, which will make the Java software development work process easier. After you have these two primary software development tools installed, you will get a plethora of new media content creation software packages, which you can use in conjunction with Java 8 and NetBeans 8.0 to create 2D and 3D games. 1 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Prepare a Workstation for Java 8 Game Development Assuming that you already have a professional-level workstation in place for new media content development and game development, you need to remove all the outdated JDKs and IDEs and make sure that you have the latest V8 (not the drink, silly!) Java and NetBeans software installed on your system and ready to go. If you are new to this and do not have a game-appropriate workstation, go to Walmart or Pricewatch.com, and purchase an affordable multicore (use a 4-, 6- or 8-core) 64-bit computer running Windows 8.1 (or 9.0 if it is available) that has 4GB, 6GB, or 8GB of DDR3 (1333 or 1600 memory access speed) system memory at the very least and a 750GB, or even 1TB, hard disk drive. The way that you remove old software is through the Windows Control Panel and its set of utility icons, one of which is the Programs and Features icon (Windows 7 and 8), displayed in Figure 1-1. Note that in earlier versions of Windows, this utility icon may be labeled differently, probably as something like Add or Remove Programs. Figure 1-1.  Use the Programs and Features utility icon to uninstall or change programs on your computer workstation Click the Programs and Features link, or double-click the icon in previous versions of Windows, to launch the utility. Then, scroll down to see if you have any old versions of the Java development tools (Java 5, Java 6, or Java 7) installed on your workstation. Note that if you have a brand new workstation, you should find no preinstalled versions of Java or NetBeans on your system. If you do find them, return the system, as it may have been used previously! As you can see in Figure 1-2, on my Windows 7 HTML5 development workstation, I had an older version of Java, Java 7, installed (on November 29, 2013), taking up 344MB of space. To remove a piece of software, select it by clicking it (it will turn light blue), and then click the Uninstall button, shown at the top of the figure. I left the tool tip, which says, “Uninstall this program,” showing in the screenshot so that you can see that if you hover your mouse over anything in the Programs and Features utility, it will tell you what that feature is used for. 2 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Figure 1-2.  Select any version of Java older than the current version (Java 8), and click the Uninstall button at the top Once you click the Uninstall button, the utility will remove the older version of Java. If you want to keep your old Java project files, make sure to back up your Java project files folder (if you have not done so already, that is). Make sure that you back up your workstation’s hard disk drive regularly so that you do not lose any of your work. Also make sure that you uninstall all versions of Java; in my case, there were 64-bit Java 7 update 45 and Java SDK 7u45, used to run or execute IDEs, such as NetBeans (or Eclipse), that were coded using the Java programming language. Next, you will want to ascertain if there are any older versions of the NetBeans IDE on your workstation. In my case, as you can see in Figure 1-3, there was indeed a NetBeans 7 IDE installation currently on my 64-bit Windows 7 workstation. I selected this for removal and then clicked the Uninstall/Change button, shown at left, which brought up a custom Uninstall Summary dialog, shown at right. Figure 1-3.  Find and select any version of NetBeans that is older than version 8.0; also, uninstall old GlassFish versions Manufacturers (in this case, the NetBeans development team) can create custom Uninstall Summary dialogs for their products to use during the uninstall process, as you can see here. This dialog allows you to select whether you want to uninstall GlassFish Server 4 and the NetBeans UserDir Configuration folder. Because you are installing new versions of NetBeans and GlassFish, select both check boxes, and then click the Uninstall button. 3 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Downloading Java JDK 8 and NetBeans 8.0 Now that the outdated versions of Java and NetBeans have been removed from your workstation, you will need to go on the Internet, to the Oracle and NetBeans web sites, respectively, to get the latest development SDKs and IDEs. I will show you how to do this using Google’s search engine (I am using this method in case the download links, or URLs, ever change) as well as demonstrate what the direct download URLs are currently, at the time of writing this book. Let’s get Java 8 first, as that is the foundation for everything that you are going to be doing as you read through this book. A Google search for Java JDK 8 will give you the search result that Oracle’s Java Downloads page, which is located in the Oracle Technology Network section, as shown at the top of the screenshot in Figure 1-4. The URL for this page is currently www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html. It is important to note that this URL could change at any time in the future and that you can always use Google Search to find the latest one. Before you can download the 170MB SDK installer file for Windows 7/8 64-bit, you will need to click the radio button next to the Accept License Agreement option shown at the top left of the Java 8 download table. Once you accept the license agreement, these 11 OS-specific links will become activated for use. Figure 1-4.  Google the term “Java JDK 8,” open the JDK 8 Downloads page, and select Accept License Agreement 4 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Be sure to match the Java JDK 8 software that you download to your OS and bit level (x86 signifies a 32-bit-level OS). Most modern-day workstations use a 64-bit Linux, Mac, Solaris (Oracle), Windows 7, or Windows 8 OS. This will be specified with the x64 delineation after the name of the OS. To find out the bit level of the OS, on Windows 7, open the Start Menu, right-click the Computer entry, and select the Properties option, at the bottom of the context-sensitive menu. On Windows 8, you click Start (a window pane icon at the bottom left of your desktop if you are in Windows 7 desktop mode) and then the down-arrow icon at the bottom left, then click the PC Settings purple gear icon and finally the PC Info entry at the bottom left of the screen. In both use cases, there should then be a text entry that says System type and either 32-bit Operating System or 64-bit Operating System. Now that you have downloaded the Java JDK 8 installer, the next thing that you need to do is download is NetBeans IDE 8.0. Do a Google search for the term NetBeans 8.0, as is shown at the top of Figure 1-5, and click the Download search result option, which will take you to the NetBeans IDE 8.0.1 Download page (currently https://netbeans.org/downloads). If you want to keep both tabs open in the browser, as I did, then right-click the Download link, and select the Open link in new tab option. Figure 1-5.  Google the term “NetBeans 8.0,” open the NetBeans IDE 8.0.1 Download page, and download all versions 5 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Once you are on the NetBeans IDE 8.0 Download page, select the language and platform (OS) that you are using from the drop-down menus at the top right of the page. I chose English and Windows. Now, you can click one of the three Download buttons at the bottom of the page to download a NetBeans IDE 8.0 that supports JavaFX 8 new media (and that will therefore support game development) programming language (application programming interface [API]). You will learn more about what an API is in Chapter 3, when I cover the Java programming language in detail. If you are only going to develop Java SE (Standard Edition) and JavaFX applications (games) for individuals, then click the first button. If you are going to develop Java EE (Enterprise Edition) and JavaFX applications (games) for enterprise (business), then click the second button. If you are going to develop both JavaFX and HTML5 applications (games), which is what I do for my business, then you click the fifth Download button, and download the “All” version of NetBeans IDE 8.0. This version will allow you to develop in all the programming languages supported by NetBeans! Because the NetBeans IDE is free, and your workstation hard disk drive can handle huge amounts of data, I recommend that you install this 204MB All version of the IDE, in case you ever find that you need any of the other capabilities that NetBeans IDE 8.0 is able to provide for you as a software developer (Java EE, Java ME, PHP, HTML5, Groovy, GlassFish, Tomcat, C++). This is an extra 120MB if you are going to install the client-side, or Java SE IDE, version, but is less than 20MB of extra disk space if you are going to install the server-side, or Java EE IDE, version. Once you click the Download button, the software download will commence. After it is finished, you will be ready to install Java 8 and then NetBeans IDE 8.0. Finally, to complete the setup of your comprehensive Java 8 game development workstation, you will get some ancillary new media content tools. You will be able to use the workstation as you read through this book (and thereafter) to create epic Java 8 game deliverables! This is getting exciting! Installing the Java 8 Software Development Environment NetBeans IDE 8.0 requires Java to be installed in order to function (run), so you will need to install the JDK and JRE first. Because you want to develop games using the latest and most feature-filled version of Java, so you are going to be installing Java 8, which was released in 2014. Installing the latest version of software ensures that you have the newest features and the fewest bugs possible. Make sure to check often that you are using the latest version of all your software packages; after all, these are open source and free to download, upgrade, and use! The first step is to find where you downloaded your installer files to on your system. The default should be set to the Download folder in Windows. I downloaded mine to a C:/Clients/Java8 folder, as you can see in Figure 1-6. Figure 1-6.  Find the JDK 8 install file on your hard disk drive, right-click it, and select Run as administrator The file will be named using the format jdk-version-platform-bitlevel, so find the latest version (in this case, it was jdk-8u25-windows-x64). Right-click it, and select the Run as administrator option so that the installer has all the OS “permissions” that it needs to create folders, transfer files into them, and the like. 6 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Once you launch the installer, you will see the Welcome dialog, shown in Figure 1-7 (left). Click the Next button to advance to the Select Features to Install dialog, shown in Figure 1-7 (right), and accept the defaults. Figure 1-7.  Click Next in the Welcome dialog to advance to the Select Features to Install dialog, and then click the Next button As you can see, the installer will install 180MB of software into the C:\ProgramFiles\Java\jdk1.8.0_25 folder on your workstation. Click the Next button to start the installation process, which will extract the installation files and then copy them onto your system, using an animated progress bar, as displayed in Figure 1-8 (left). Figure 1-8.  Java 8 installation will extract and copy install files (left) and then suggest the installation directory (right) After the Java SDK is installed on your system, you will get the JRE installation dialog, which is presented in Figure 1-8 (right). Make sure that you accept the default installation location for this JRE; it should be installed in the \Java\jre8 folder. It is best to allow Oracle (Java SDK) to put the software in an industry standard folder location, as other software packages that you will be using that use this JRE, such as NetBeans IDE 8.0, will be looking for it there first. Click the Next button to install the JRE. The installation will show a progress bar during the install, as seen in Figure 1-9 (left). When it is finished, it will display the Successfully Installed dialog, shown in Figure 1-9 (right). If you want to access tutorials, API documentation, developer guides, version release notes, and so on, you can click the Next Steps button. 7 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Figure 1-9.  During installation a progress bar shows you what is installing (left) and then gives you a completed dialog (right) Installing NetBeans IDE 8.0 Now, you are ready to install NetBeans, so locate your netbeans-8.0-windows file (see Figure 1-6. Right-click it, and select the Run as administrator option to launch the installer. Once it is launched, you will see the dialog shown in Figure 1-10, which gives you a Customize button that you can use to customize the install. Figure 1-10.  The Welcome to the NetBeans IDE 8.0 Installer dialog 8 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Click the Next button to begin the default (full) installation, and you will get the NetBeans IDE 8.0 License Agreement dialog, shown in Figure 1-11 (left). Select the I accept the terms in the license agreement check box, and click the Next button to advance to the JUnit License Agreement dialog, shown in Figure 1-11 (right). Figure 1-11.  Accept the terms of the license agreement, click the Next button (left), and then do the same for JUnit (right) In the JUnit License Agreement dialog, presented in Figure 1-11 (right), click the radio button next to the I accept the terms in the license agreement statement, and click the Next button to proceed with the installation. The next two installer dialogs, illustrated in Figure 1-12, will allow you to specify where NetBeans 8.0 and GlassFish 4.0 will be installed on your system. I suggest accepting the default installation locations in these two dialogs as well. As you will notice, the NetBeans installer has found your Java installation in its default location as well. Figure 1-12.  Accept the default installation directory suggestions for NetBeans IDE (left) and GlassFish 4.0 (right) Once you accept these default installation locations and click the Next button to advance through these dialogs, you will get a Summary dialog, shown in Figure 1-13 (left). This dialog contains an Install button, which will trigger the installation that you have set up over the previous five NetBeans IDE 8.0 installation dialogs. 9 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Figure 1-13.  Select the Check for Updates check box, and click the Install button (left) and the Finish button (right) During the installation, you will see the Installation dialog, and its progress bar, illustrated in Figure 1-14, which will tell you exactly what percentage of the installation has been completed as well as which IDE files are currently being extracted, and installed, on your workstation. Figure 1-14.  The Installation progress dialog, showing the percentage of install complete When the installation process is complete, you will see the Setup Complete dialog, which is shown in Figure 1-13 (right). Now, you are ready to develop Java 8 and JavaFX applications (games) on your workstation. Next, let’s download five of the most popular free open-source new media content development software packages so that you have all the tools that you will need for a Java 8 games development business! After that, you will take a look at some other impressive open-source software that I use on my workstation. That way, if you want to, you can put together the ultimate software development workstation before you have even finished this chapter, creating an incredibly valuable content production workstation for the cost of the hardware (and OS) alone! 10 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Installing New Media Content Production Software There are a number of “genres” of new media elements, or assets, as I call them, that are supported in JavaFX, which is the new media engine in Java 8 (and Java 7) and thus what you will be using as the foundation for your Java 8 game development. The primary genres of new media, for which you will be installing the leading open-source software in the remainder of this chapter, include digital illustration, digital imaging, digital audio, digital video, and 3D. Downloading and Installing Inkscape Because JavaFX supports 2D, or vector, technology, commonly used in digital illustration software packages, such as Adobe Illustrator and FreeHand, you will download and install the popular open-source digital illustration software package known as Inkscape. Inkscape is available for the Linux, Windows, and Mac OSs, just like all the software packages that you are installing in this chapter, so you can use any platform you like to develop games! To find the Inkscape software package on the Internet, go to Google Search, and type in Inkscape, as shown in Figure 1-15, at the top left. Click the Download link (or right-click, and open in a separate tab), and click the icon that represents the OS that you are using. The Penguin signifies Linux (far-left icon), the Window signifies Windows (center icon), and the stylized apple signifies Mac (far-right icon). Figure 1-15.  Google the term “InkScape,” go to the Inkscape Download page, and click the icon that matches your OS If you want to use the 64-bit Windows version of Inkscape, scroll down, and take a look at the text links below these three icons to access that particular OS download. Once you have downloaded the software, right-click it and Run as administrator, and install the software on your workstation. If you have a previous version of Inkscape, the installation will upgrade it to the latest version; you do not need to use the Programs and Features utility that you used earlier in the chapter to uninstall your SDK and IDEs, which do not upgrade previous versions, like new media production software packages tend to do. 11 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment After the software is installed, create a Quick Launch icon on your taskbar so that you can launch Inkscape with a single click of the mouse. Next, you will install a popular digital imaging software package, called GIMP, which will allow you to create “raster,” or pixel-based (bitmap), artwork for your games in JPEG, PNG, or GIF digital image file formats supported by JavaFX. Raster images are different from vector, or shape, illustrations, so you will need GIMP. Downloading and Installing GIMP JavaFX also supports 2D images that use raster image technology, which represents images as an array of pixels and is commonly used in digital image compositing software packages, such as Adobe Photoshop and Corel Painter. In this section, you will download and install the popular open-source digital image editing and compositing software package called GIMP. This software is available for the Linux, Windows, Solaris, FreeBSD, and Mac OSs. To find the GIMP software on the Internet, go to Google Search, and type in GIMP, as demonstrated in Figure 1-16. Figure 1-16.  Google the term “GIMP,” go to the GIMP Downloads page, and click the Download GIMP link 12 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Click the Download link (or right-click, and open it in a separate tab), and click Download GIMP 2.8.14 (or the latest version that represents the OS that you are using). The Downloads page will automatically detect the OS that you are using and give you the correct OS version; in my case, it is Windows. Download and install the latest version of GIMP, and then create a Quick Launch icon for your workstation taskbar, as you did for Inkscape. Next, you will install a powerful digital audio editing and audio effects software package, called Audacity. Downloading and Installing Audacity JavaFX supports digital audio sequencing, which uses digital audio technology. Digital audio represents analog audio by taking digital audio samples. Digital audio content is commonly created using digital audio composition and sequencer software packages, such as Propellerhead Reason and Cakewalk Sonar. In this section, you will download and install the popular open source digital audio editing and optimization software package known as Audacity. Audacity is available for the Linux, Windows, and Mac OSs, so you can use any OS platform that you like to create and optimize digital audio for your Java 8– and JavaFX–based games. To find the Audacity software package on the Internet, use the Google search engine, and type in Audacity, as shown in Figure 1-17, at the top left. Click the Download link (or right-click, and open in a separate tab), and click Audacity for Windows (or the version that represents the OS that you are using). Figure 1-17.  Google the term “Audacity,” go to the Audacity Download page, and click a link matching your OS Download and install the latest version of Audacity (currently, it is 2.0.6), and then create a Quick Launch Icon for your workstation taskbar, as you did for Inkscape and GIMP. Next, you will install a powerful digital video editing and special effects software package, called EditShare Lightworks. 13 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Downloading and Installing EditShare Lightworks JavaFX also supports digital video, which uses raster pixel-based motion video technology. Raster represents video as a sequence of frames, each of which contains a digital image based on an array of pixels. Digital video assets are usually created using digital video editing and special effects software packages, such as Adobe After Effects and Sony Vegas. In this section, you will download and install open-source digital video editing software known as Lightworks. EditShare’s Lightworks used to be a paid software package until it was made open source. You will have to register on the Lightworks web site to download and use the software. This package is available for Linux, Windows, and Mac OSs. To find Lightworks on the Internet, go to Google Search, and type in Lightworks, as shown in Figure 1-18, at the top left. Click the Download link (or right-click, and open in a separate tab), and click the appropriate Download button and the tab that represents the OS that you are using. The Downloads page will automatically detect the OS that you are using and select the correct OS tab; in my case, Windows. Figure 1-18.  Google the term “Lightworks,” go to the Lightworks Downloads page, and click the tab that matches your OS Register on the Lightworks web site, if you have not done so already. Once you are approved, you can then download and install the latest version of Lightworks. Install the software, and create a Quick Launch icon for your taskbar, as you did for the other software. Next, you will install a 3D modeling and animation package, called Blender. 14 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Downloading and Installing Blender JavaFX has recently moved to support 3D new media assets that are created outside the JavaFX environment, which means that you will be able to create 3D models, textures, and animation, using third-party software packages, such as Autodesk 3D Studio Max or Maya and NewTek Lightwave 3D. In this section, you will download and install the popular open-source 3D modeling and animation software package known as Blender. Blender is available for the Linux, Windows, and Mac OSs, so you can use any OS platform that you like to create and optimize 3D models, 3D texture mapping, and 3D animation for use in your Java 8 and JavaFX games. To find the Blender software on the Internet, using the Google search engine, type in Blender, as shown in Figure 1-19. Click the correct download link to download and install Blender, and then create the Quick Launch icon. Figure 1-19.  Google the term “Blender,” go to the Blender Download page, and click the tab for your OS 15 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Other Open-Source Software Packages of Interest There are a number of other professional-level open-source software packages that I use in my new media content production business that I thought I would let you know about, in case you had not heard about them. These will add even more power and versatility to the new media production workstation that you have built up to this point. It is important to note that you have already saved yourself thousands of dollars that would have otherwise been spent on similar paid content production software packages in the process of doing all this extensive downloading and installing. I guess you could say my motto is, “Do it right the first time, and be sure to go all the way,” so let me tell you about some of the other free, and even some of the more affordable, new media content production software packages that I have installed on my own content production workstations. One of the best values in open-source software, aside from the EditShare Lightworks package, which used to cost six figures back in the day, is a business productivity software suite that was made open source by Oracle after it acquired Sun Microsystems. Oracle transferred its OpenOffice software suite over to the popular Apache opensource project. OpenOffice 4.1 is an entire office productivity software suite that contains six full-fledged business productivity software packages! Because your content production agency is actually a full-fledged business concern, you should probably know about this software, as it is an exceptionally solid open-source software offering. You can find it at www.openoffice.org; this popular business software package has been downloaded by savvy professionals such as yourself more than a hundred million times, so it’s no joke, as they say! A great complement to the Audacity digital audio editing software is Rosegarden MIDI sequencing and music composition and scoring software, which can be used for music composition and printing out the resulting scores for music publishing. Rosegarden, currently in version 14.02, and being ported from Linux to Windows, can be found via Google Search or at www.rosegardenmusic.com. Another impressive audio, MIDI, and sound design software package is Qtractor If you are running the Linux OS, be sure to download and install this professional-level digital audio synthesis software package by doing a Google search or going to https://Qtractor.SourceForge.net. For 3D character modeling and animation, be sure to check out the 3D software packages from DAZ Studio (www.daz3d.com) when you have the chance. The current version of DAZ Studio Pro is 4.6, and yes, it is free! You have to log in and sign up, like you did for EditShare Lightworks, but that is a small price to pay! There is also a free 3D modeling software package on this web site, called Hexagon 2.5, and a popular terrain generation software package for less than 20 dollars, called Bryce 7.1 Pro. The most expensive software on the DAZ Studio web site is Carrara (150 dollars) and Carrara Pro (285 dollars). DAZ Studio makes most of its revenue selling character models of one type or another, so take a look, as it is a force to be reckoned with in the 3D content (virtual) world! Another impressive (and free, for the basic version) world generation software package is Terragen 3.2, from Planetside Software, in the United Kingdom. You can download the basic version from https://planetside.co.uk as well as join its forum. I have used this software in a couple of my Android application development books, so I know it works well for multimedia applications and games. It is also used by professional filmmakers, as the level of quality is pristine. Caligari TrueSpace 7.61 is also excellent, free 3D modeling and animation software. The program, which is “free and alive!” according to the Caligari web site (https://Caligari.us), from which you can still download it, used to cost nearly a thousand dollars when it was first developed by Roman Ormandy, the founder of the Caligari Corporation (later purchased by Microsoft). A professional-level 3D modeling and animation software package, this program had millions of users in its heyday. It is a really cool piece of software, with a fun-to-use user interface (UI), so be sure to grab it! Another 3D rendering software you should take a look at is POV-Ray (Persistence of Vision Raytracer), which works with any 3D modeling and animation software package to generate impressive 3D scenes, using advanced ray-traced rendering algorithms. The most recent version on the POV-Ray web site (www.povray.org), 3.7, is 64 bit and multicore (multithreaded) compatible, and it can be downloaded for free! Bishop3D is a cool 3D modeling software package that was specifically designed for use with POV-Ray. The software can be used to create custom 3D objects, which can then be imported into POV-Ray (and then into JavaFX) for use in your games. The most recent version, an 8MB download, is 1.0.5.2, for Windows 7. The software can be found at www.bishop3d.com and can currently be downloaded for free! 16 www.it-ebooks.info Chapter 1 ■ Setting Up a Java 8 Game Development Environment Yet another free 3D modeling software worth investigating is Wings 3D. This software can be used to create custom 3D objects, which can then be imported into JavaFX for use in your games. The most recent version, a 64-bit, 16MB download, is 1.5.3 and was released in April 2014, for Windows 7, Mac OS X, and Ubuntu Linux. The software can be found at www.wings3d.com and can currently be downloaded for free! For UI design prototyping, the free software package Pencil 2.0.6, from Evolus, allows you to easily prototype UI designs before you create them in Java, Android, or HTML5. The software is located at http://pencil.evolus.vn and is available for Linux, Windows, and Mac OSs. Next, you will take a look at how I organize some of the basic OS utilities and open-source software on my taskbar. Organizing Quick Launch Icons in Your Taskbar Area There are certain OS utilities, such as the calculator, text editor (Notepad), and file manager (Explorer), for which I create Quick Launch icons on my taskbar, as these utilities are used frequently in programming and new media content development work processes. I also keep as Quick Launch icons a wide range of new media development, programming, and office productivity applications. Figure 1-20 displays a dozen of these, including everything that you just installed, in the order in which you installed it, as well as a few others, such as OpenOffice 4.1, DAZ Studio Pro 4.6, and Bryce 7.1 Pro. Figure 1-20.  Make taskbar Quick Launch icons for key system utilities, NetBeans 8.0, and new media production software There are a couple of ways to create these Quick Launch icons: you can drag programs from the start menu and drop them onto the taskbar, or you can right-click icons on the desktop or in the Explorer file manager and select Pin this program to taskbar from the context-sensitive menu. Once icons are on the taskbar, you can change their position simply by dragging them to the left or to the right. Congratulations, you have just set up a new media Java 8 game development workstation that is highly optimized and that will allow you to create any new media Java 8 game that you or your clients can imagine! Summary In this first chapter I made sure that you have everything that you need to develop standout Java 8 games, including the latest versions of Java 8, JavaFX, and NetBeans 8.0 as well as all the latest open-source new media software. You started by downloading and installing the latest Java JDK 8 and NetBeans IDE 8.0 software. Then, you did the same for a plethora of professional open-source new media tools. In the next chapter, I will show you how to use NetBeans 8.0 to create a Java 8 project. 17 www.it-ebooks.info Chapter 2 Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Let’s get started here in Chapter 2 by considering NetBeans IDE 8.0, because that is the primary piece of software that you will be using to create your Java 8 games. Even though Java JDK 8 is the foundation for your Java 8 games, as well as for NetBeans 8.0, you will start your journey by learning about NetBeans, as it is the “front end,” the window through which you look at your Java game project. NetBeans 8.0 is the official IDE for Java JDK 8, and, as such, it is what you will be using for this book. That is not to say you cannot use another IDE, such as Eclipse or IntelliJ, which are the official IDEs for Android 4.x (32 bit) and Android 5.x (64 bit) respectively, but I prefer to use NetBeans 8.0 for my new media application and game development for the Java 8, JavaFX 8, HTML5, CSS3 (Cascading Style Sheets 3), and JavaScript software development markup and programming paradigms. This is not only because NetBeans 8.0 integrates JavaFX Scene Builder, which you will be learning about in Chapter 5 of this book, but also because it is an HTML5 IDE, too, and I create everything I design for my clients using Java 8, JavaFX 8, Android 4.x, or Android 5.x as well as HTML5. I do this so that the content works across (on) closed, or proprietary, OSs and platforms. I prefer open-source software and platforms, as you observed in Chapter 1. First, you will take a look at what is new in NetBeans 8.0. This version of NetBeans was released at the same time as Java 8, and the version number synchronization is no coincidence. You will discover why you will want to use NetBeans 8.0 rather than an older NetBeans version, such as NetBeans 7.4 or earlier. Next, you will examine the various attributes of NetBeans IDE 8.0 that make it an invaluable tool for Java 8 game development. You will not be able to get hands-on experience with all its features in the chapter, but you will be exploring all the cool things that it can do for you over the course of this book (you will need to put an advanced code base into place to really give some of the features a workout). Finally, you will learn how to create your Java 8 and JavaFX project, using NetBeans 8.0 so that you progress toward creating the Java 8 game that you will be developing as you read through this book. Primary Attributes of NetBeans 8.0: An Intelligent IDE Assuming that you already have a professional-level workstation in place for new media content and game development, you need to remove all the outdated JDKs and IDEs and make sure that you have the latest V8 Java and NetBeans software installed on your system and ready to go. If you are new to this and do not have a game-appropriate workstation, go to Walmart or PriceWatch.com, and purchase an affordable multicore (use a 4-, 6- or 8-core) 64-bit computer running Windows 8.1 (or 9.0 if it is available) that has 4GB, 6GB, or 8GB of DDR3 (1333 or 1600 memory access speed) system memory at the very least and a 750GB, or even 1TB, hard disk drive. 19 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 NetBeans 8.0 Is Smart: Put Your Code Editing into Hyperdrive Although it is true that an IDE is like a word processor, only geared toward writing code text rather than creating business documents, a programming integrated development environment such as NetBeans does a lot more for your programming work process than a word processor does for your document-authoring work process. For instance, your word processor does not make suggestions in real time regarding the content that you are writing for your business, whereas the NetBeans IDE will actually look at what you are coding while you are writing that code and will help you write your code statements and constructs. One of the things that NetBeans will do is finish lines of code for you as well as apply color to the code statements to highlight different types of constructs (classes, methods, variables, constants, references, and the like) (for more details, see Chapter 3). NetBeans will also apply the industry standard for code indenting to make your code much easier to read (for both yourself and the other members of your game application development team). In addition, NetBeans will provide matching code structure brackets, colons, and semicolons so that you do not get lost when you are creating complex, deeply nested, or exceptionally dense programming constructs. You will be creating constructs such as these as I take you from Java 8 game beginner to Java 8 game developer, and I will point out Java 8 code that is dense, complex, or deeply nested as you encounter it. NetBeans can also provide bootstrap code, such as the JavaFX game application bootstrap code that you will be creating a bit later in this chapter (see the section “Creating Your Java 8 Project: The InvinciBagel”), as well as code templates (which you can fill out and customize), coding tips and tricks, and code refactoring tools. As your Java code becomes more complex, it also becomes a better candidate for code refactoring, which can make the code easier to understand, easier to upgrade, and more efficient. NetBeans can also refactor your code automatically. In case you are wondering, code refactoring is changing the structure of existing computer code to make it more efficient or scalable without changing its external behavior, that is, what it accomplishes. For instance, you could take Java 6 or Java 7 code and make it more efficient by implementing Lambda Expressions, using Java 8. Furthermore, NetBeans offers pop-up helper dialogs of various types, containing methods, constants, asset references (see Chapter 3), and even suggestions regarding how to construct the code statement, for example, when it might be appropriate to use the powerful new Java 8 Lambda Expressions feature to make your code more streamlined and multithread compatible. NetBeans 8.0 Is Extensible: Code Editing with Many Languages Another thing that your word processor cannot do is allow you to add features to it, which NetBeans can do using its plug-in architecture. The term that describes this type of architecture is extensible, which means that if needed, it can be extended to include additional features. So, if you wanted to extend NetBeans 8.0 to allow you to program using Python, for instance, you could. NetBeans 8.0 can also support older languages, such as COBOL and BASIC, in this fashion as well, although with the majority of popular consumer electronics devices using Java, XML, JavaScript, and HTML5 these days, I am not really sure why anyone would want to take the time do this. I did a Google search for this, however, and there are people coding in Python and COBOL in NetBeans 8.0, so there is real-world proof that the IDE is indeed extensible. Probably because of its extensibility, NetBeans IDE 8.0 supports a number of popular programming languages, including C, C++, Java SE, JavaScript, XML, HTML5, and CSS on the client side and PHP, Groovy, Java EE, and JavaServer Pages (JSP) on the server side. Client-side software is run on the device that the end user is holding or using (in the case of an iTV); server-side software runs remotely, on a server, and talks to the end user over the Internet or a similar network while the software is running on the server. Client-side software is more efficient, as it is local to the hardware device that it is running on and thus is more scalable: no server is involved to experience overload as more and more people use the software at any given point in time. 20 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 NetBeans 8.0 Is Efficient: Organized Project Management Tools A good programming IDE needs to be able to manage projects that can grow to become quite massive, involving more than a million lines of code contained in hundreds of folders in the project folder hierarchy and thousands of files and new media assets. For this reason, project management features must be extremely robust in any mainstream IDE. NetBeans 8.0 contains a plethora of project management features that allow you to look at your Java 8 game development project, and its corresponding files and their interrelationships, in a number of different ways. There are four primary project management views, or “panes” that you can use to see the different types of interrelationships in your project. (I call them panes, as the entire IDE is in what I call a window). I jumped ahead (to the end of the chapter, once your Java 8 game project has been created) and created the screenshot presented in Figure 2-1. This screenshot displays the four project management panes opened in this new project so that you can see exactly what they will show you. Figure 2-1.  Project management panes, at the left of the IDE, include Projects, Files, Services, and Navigator The Projects pane, at the left of the screen, shows the Java Source Packages and Libraries that make up your (game) project. The next pane over is the Files pane, which has the project folder and file hierarchy on your hard disk drive. The Services pane contains the databases, servers, repositories, and build hosts, if they are used in the project (these are primarily server-side technologies, and technologies used with a development team, so I am not going to go into these in detail). The Projects pane should always be left open (as you will see in Figures 2-7 through 2-21). The Projects pane provides you with a primary access point for all the project source code and assets (content) in your Java 8 game project. The Files pane shows not only the project folder and file hierarchy, but also the data and FXML markup (JavaFX) or Java 8 code hierarchy inside each file. The Navigator pane (bottom) shows the relationships that exist inside your Java code structures. In this case, these are the InvinciBagel class, the .start() method, and the .main() method (for further information, see Chapter 3). 21 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 NetBeans 8.0 Is User Interface Design Friendly: UI Design Tools NetBeans 8.0 also has Design a GUI drag-and-drop design tools for a plethora of platforms, including Java SE, Java EE, Java ME, JavaFX, and Java Swing as well as C, C++, PHP, HTML5, and CSS3. NetBeans provides visual editors that write the application’s UI code for you, so all you have to do is make the visual on the screen look like what you want it to look like in your game application. Because games use the JavaFX new media (game) engine, you will be learning about the JavaFX Scene Builder, an advanced FXML-based visual design editor, in Chapter 5 of this book. JavaFX has the Prism game engine as well as 3D (using OpenGL ES [OpenGL for Embedded Systems]) support, so I will be focusing quite a bit on the JavaFX Scene Graph and JavaFX APIs. The assumption here is that you will want to build the most advanced Java 8 games possible, and leveraging the JavaFX engine, which is now a part of Java 8 (along with Lambda Expressions), is going to be the way to accomplish this. The fastest way to develop a game is to leverage advanced code and programming constructs that the Java 8 and JavaFX environments generously give you for your use in creating cutting-edge applications (in this case, games) that contain powerful new media elements. NetBeans 8.0 Is not Bug Friendly: Squash Bugs with a Debugger There is an assumption across all computer programming languages that the negative impact to your programming project of a “bug,” or code that does not do exactly what you want it to, increases in magnitude the longer it remains unfixed, so bugs must be squashed as soon as they are “born.” NetBeans bug-finding code analysis tools, and integrated NetBeans Debugger, and integration with the third-party FindBugs project, which, as you now know from experience (Audacity), can be found on the SourceForge web site (http://findbugs.sourceforge.net) (if you want the stand-alone version), all supplement the real-time, “as you type” code-correcting and efficiency tools I discussed earlier (see the section “NetBeans 8.0 Is Smart: Put Your Code Editing into Hyperdrive”). Your Java code will not be very complicated until a bit later in the book, so I will cover how these tools work when you need to use them, once your knowledge base is a bit more advanced. NetBeans 8.0 Is a Speed Freak: Optimize the Code with a Profiler NetBeans also has something called a Profiler, which looks at your Java 8 code while it is running and then tells you how efficiently it uses memory and CPU cycles. This allows you to refine your code and make it more efficient in its use of key system resources, which is quite important for Java 8 game development, as this will affect the smoothness of game play on systems that are not as powerful (e.g., on single- and dual-core CPUs). This Profiler is a dynamic software analysis tool, as it looks at your Java code while it is running, whereas the FindBugs code analysis tool is a static software analysis tool, as it simply looks at your code in the editor, when it is not compiled and running in system memory. The NetBeans Debugger will allow you to step through your code while it is running, so that tool can be viewed as a hybrid that ranges from a static (editing) to a dynamic (executing) code analysis mode. After you create the foundation for your Java 8 (JavaFX) game engine (in the following sections), you will run the Profiler to see how it works inside NetBeans IDE 8.0. I am going to present as many key features of NetBeans as possible up front so that you get comfortable with this software. 22 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Creating Your Java 8 Game Project: The InvinciBagel Let’s get down to business and create the foundation for your game. I am going to demonstrate how to create an original game so that you can see the process involved in developing a game that does not yet exist, as opposed to most game programming books, which replicate games that are already on the market. I got permission from my client Ira Harrison-Rubin, cartoonist/author/humorist for the BagelToons franchise, to let readers to see the process of creating his InvinciBagel cartoon game during the course of this book. Click the Quick Launch icon on your taskbar (or double-click the icon on your desktop) to launch NetBeans 8.0, and you will see the NetBeans start-up screen, illustrated in Figure 2-2. This screen contains a progress bar (in red) and will tell you what is being done to configure the NetBeans IDE for use. This involves loading the various components of the IDE into your computer system memory so that they can be used smoothly and in real time during development. Figure 2-2.  Launch NetBeans 8.0, using the Quick Launch icon After NetBeans IDE 8.0 has been loaded into your system memory, the NetBeans 8.0 start page will be displayed on your screen, as shown in Figure 2-3. Click the “x” at the right of the Start Page tab to close this page. 23 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Figure 2-3.  Close the Start Page tab, at the top left of the screen, by clicking the “x” at the right of the tab to reveal NetBeans IDE 8.0 This will display what I term the virgin IDE, with no projects active. Enjoy this now, as soon you will be filling this IDE with panes for your project components (you can see part of this empty IDE in Figure 2-4, which contains menus and shortcut icons and not much else). Figure 2-4.  Showing virgin NetBeans 8.0 IDE (left) and a JavaFX New Project dialog (right) 24 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 In case you are wondering, the start page displays every time you start the NetBeans IDE, and if you wanted to open the Start Page tab later on, perhaps to explore the Media Library section (demos) and tutorials, you can! To open the start page at any time, you use the NetBeans IDE 8.0 Help menu and the Start Page submenu. For future reference, I usually notate a menu sequence like this: Help ➤ Start Menu. The first thing that you will want to do in NetBeans IDE 8.0 is create a new InvinciBagel game project! To accomplish this, you will use the NetBeans 8.0 New Project series of dialogs. This is one of those helpful Java programming features that I mentioned earlier (see the section “NetBeans IDE 8.0 Is Smart: Put Your Editing into Hyperdrive”) that creates a bootstrap project with the correct JavaFX libraries, .main() and .start() methods, and import statements (for more details, see Chapter 3). Click the File menu, at the top-left corner of the DE, as displayed in Figure 2-4 (left), and then select New Project (the first menu item). Note that to the right of this selection, there is a keyboard shortcut given (Ctrl+Shift+N), in case you want to memorize it. If you want to use this keyboard short-cut to bring up the New Project series of dialogs, hold down the CTRL and Shift keys on your keyboard (both at the same time), and while they are depressed (held down), press the N key. This will do the same thing as using the File ➤ New Project menu sequence. The first in the series is the Choose Project dialog, shown in Figure 2-4 (right). Because you are going to use the powerful JavaFX new media engine in your game, select JavaFX from the list of programming language categories in the Categories pane, and because a game is a type of application, select JavaFX Application from the Projects pane. Remember that Oracle made JavaFX a part of Java 7 and Java 8, so a JavaFX game is also a Java game, whereas before Java 7 (in Java 6), JavaFX was its own separate programming language! The JavaFX engine had to be recoded as a Java (7 and 8) API (set of libraries) for it to become a seamless part of the Java programming language. The JavaFX API replaces AWT (Abstract Windowing Toolkit) and Swing, and although these older UI design libraries can still be used in Java projects, they are normally used only by legacy (older) Java code so that those projects can compile and run in Java 7 and 8. You will be compiling and running the new project you are creating here a bit later in this chapter. Note that there is a Description pane below the other panes that will tell you what your selections will give you. In this case, that would be a new Java application with enabled JavaFX features; here, “enabled” indicates that the JavaFX API libraries will be included (and started) in the Java application project’s class and methods, as you will soon see in the code (for further information on what the code means, see Chapter 3). Click the Next button to advance to the next dialog in the series, which is the Finding Feature dialog, shown in Figure 2-5. This dialog displays a progress bar while it is “Activating JavaFX 2,” which equates to installing the JavaFX API libraries in your project code infrastructure. You will find that sometimes JavaFX 8 is still referred to as JavaFX 2 (2.3 was the latest version of JavaFX before people started using the name JavaFX 8, probably to sync up with Java 8). I have also seen discussion of a JavaFX 3, which is now being called JavaFX 8, and because JavaFX is now a part of Java 8, I am going to refer to it simply as JavaFX for the duration of this book. Figure 2-5.  Step 2: Finding Feature dialog, showing the progress bar for the process of activating JavaFX 25 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Once the Finding Feature dialog has activated JavaFX for your game project, you will get the Name and Location dialog, which is presented in Figure 2-6. Name your project InvinciBagel, and leave the default Project Location, Project Folder, JavaFX Platform, and Create Application Class settings the way that NetBeans 8.0 has configured them. Figure 2-6.  Name the project InvinciBagel, and leave the other settings as they are It is usually a good idea to let NetBeans 8.0 do things for you. As you can see, NetBeans creates the logical C:\Users\user\My Documents\NetBeansProjects folder in your user folder and My Documents subfolder for the Project Location data field. For your Project Folder data field, NetBeans again logically creates a subfolder named InvinciBagel, below the NetBeansProjects folder, just like you would do yourself. For the JavaFX Platform drop-down menu, NetBeans 8.0 defaults to the very latest JDK 8, which is also known as JDK 1.8, and has the latest JavaFX 8 (which was supposed to be JavaFX 3.0). Because you are not creating multiple applications that will share libraries, leave the Use Dedicated Folder for Storing Libraries check box unchecked. Finally, select Create Application Class, which will be named InvinciBagel and will be in the invincibagel package; for the reason, the complete path and class name will be as follows: invincibagel.InvinciBagel (following the packagename.ClassName Java naming paradigm and style). (You will be learning more about packages and classes and methods in the Chapter 3, but you are ultimately going to be exposed to some of this information here, as NetBeans 8.0 will be writing some of the bootstrap Java code that will provide you with the foundation for your InvinciBagel Java 8 game. I will go over some of the basic components of the Java code shown in Figure 2-7, but I am primarily going to focus on the NetBeans IDE 8.0 in this chapter and concentrate on the Java 8 programming language in Chapter 3.) 26 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Figure 2-7.  Examine the bootstrap JavaFX code that NetBeans created for you, based on the New JavaFX Application dialog As you can see in the figure, NetBeans has written the package statement, seven JavaFX import statements, the class declaration, and the .start() and .main() methods. NetBeans 8.0 colors Java key programming statement words blue and comments gray. Data values are orange and input/output is green. Before you can run this bootstrap code, to make sure that NetBeans 8.0 wrote code for you that actually works, you will need to compile it into an executable format, which is run in your system memory. 27 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Compiling Your Java 8 Game Project in NetBeans 8.0 In showing you how to compile your Java 8 code before you run (test) it, I am demonstrating the “long way” here so that you are exposed to every step of the compile/run Java 8 code-testing process. Click the Run menu, and then select Compile File (the eleventh menu item) to compile your Java code, or use the F9 keyboard shortcut, as indicated at the right of the selection, as seen in Figure 2-8. Now your project is ready to run! Figure 2-8.  Click the Run menu, at the top of the IDE, and then select Compile File, or press the F9 function key 28 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Figure 2-9 illustrates the Compile progress bar, which will appear at the bottom of the IDE during compilation. Figure 2-9.  The Compile progress bar is shown at the bottom of the screen, along with expand and collapse icon functionality It is also important to note here that NetBeans will compile the project code when you use the File ➤ Save menu sequence (or the CTRL-S keyboard shortcut), so if you were to use the Save feature of the NetBeans IDE right after the bootstrap code is created, you would not have to undertake the compilation process that I just showed you, as this process is done “automagically,” (not manually) every time you save a game project. Also shown in the figure, right above the Compile progress bar, is a highlighted a block of code that was visible in Figure 2-7 but that I have collapsed, using the minus icon at the left of the code editor pane. You can see three uncollapsed minus icons in the middle of the code editor pane (under the InvinciBagel class) as well as three collapsed icons at the top of the code editor pane for the two comments and the import statement code block. A minus icon turns into a plus icon so that a collapsed code view can be expanded. Now that you have looked at how to compile your project in NetBeans as well as how to collapse and expand the views of logical blocks (components) of your project code, it is time to run the code. Running Your Java 8 Game Project in NetBeans 8.0 Now that you have created and compiled your bootstrap Java 8/JavaFX game project, it is time to run or execute the bootstrap code and see what it does. You can do this by using the Run ➤ Run Project menu sequence (see Figure 2-8), or you can use the shortcut icon at the top of the IDE (resembling a video transport play button), displayed in Figure 2-10. 29 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Figure 2-10.  Click the Run Project shortcut icon (green play button), at the top middle of the IDE (tool tip pop-up shown) Once you run the compiled Java code, a window will open with your software running in it, at the right of the screen, as seen in Figure 2-11. Currently, the program uses the popular “Hello World!” sample application. Figure 2-11.  Drag the separator bar upward to reveal the Compile Output area of the IDE (running the application seen at right) 30 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Click the divider line between the code editor pane and the Output tab, at bottom, and, holding down the mouse button, drag this divider line upward, revealing the Output tab contents, as demonstrated in Figure 2-11. The Output tab will contain different types of output in NetBeans, such as compile operation output from Ant, run operation output (shown in the figure), profiler operation output (which you will be exploring in the next section), and even output from the application itself. You may have noticed in Figure 2-10 that the code for this bootstrap Java 8/JavaFX application contains a (System.out.println("Hello World!"); Java statement in line 25, so if you wanted to see the application that you are currently running print to the Output pane (sometimes referred to in programming circles as the Output Console), click the Say “Hello World” button in the “Hello World!” application (running on top of the IDE). Once you click this button, “Hello World!” will appear in the Output tab, under the red text that says it is executing the InvinciBagel.jar file. A .jar (Java Archive) file is the distributable format for your Java application. Part of the compile process is creating this file, so if your compiled version works, you can have the .jar file ready to distribute if your application design and programming are complete! A .jar file does not contain your actual Java 8 code, but rather a compressed, encrypted “Java byte stream” version of the application, which the JRE can execute and run (like NetBeans 8.0 is doing now). The path that is attached to the front of the InvinciBagel.jar file tells you where the compiled .jar file resides and where NetBeans is accessing it from currently to run it. On my system this location was C:\Users\user\Documents\NetBeansProjects\ InvinciBagel\dist\run1331700299\InvinciBagel.jar. Let’s take a look at some of the other Output tab text to see what NetBeans did to get to the point where it could run the .jar file for this project. First, the compiler deletes and rebuilds the build-jar-properties file, in the \NetBeansProjects\InvinciBagel\build folder, based on the unique attributes of your game application. Next, Ant creates a \NetBeansProjects\InvinciBagel\dist\ distribution folder to hold project .jar files and then, detecting JavaFX usage, launches ant-javafx.jar to add JavaFX capabilities to the Ant build engine, which will create the .jar file. Finally, you will see a warning to change the manifest.custom.codebase property from an asterisk value (which means “everything”) to a specific value. I may get into the manifest and permissions area of application development later in the book, after you are a bit more advanced. JavaFX is then launched, and the .jar file is built. Ant is the build engine, or build tool, that creates your .jar file. Other build engines, such as Maven and Gradle, can also be used in NetBeans, because as you now know, NetBeans is extensible! Ant is used in the Eclipse IDE as well and is an Apache open-source project that has been around for a very long time. To learn more about the Ant build system and what it does, visit the Ant web site (http://ant.apache.org). Next, you will explore the profiling capabilities in NetBeans 8.0, which can analyze your code at runtime and let you know how efficiently (or inefficiently) your Java 8 code is running. This is important for a game, especially an arcade game or any game that is moving sprites around in real-time on a user’s screen. You will be learning game concepts and design in Chapter 6 of this book. Profiling Your Java 8 Game Project in NetBeans 8.0 To launch the Java 8 code profiling utility, using the Profile menu at the top of the IDE, select Profile Project (InvinciBagel) (the first menu item), as illustrated in Figure 2-12, or use the Profile Project shortcut icon, which is visible in the collapsed screen view given in Figure 2-13 (you can tell that I collapsed the screenshot by the Java code line numbering in the code editor pane, which contains only lines 1 and 38, the first and last numbers in the range; I removed lines 2–37, using Photoshop). 31 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Figure 2-12.  Click the NetBeans IDE 8.0 Profile menu, and select the Profile Project (InvinciBagel) menu option Figure 2-13.  The shortcut icon for the Profile Project utility, with tool tip (screen collapsed) As you can see in both the Profile menu and the Profile Project icon tool tip, at the top of the screen, the keyboard shortcut for the Profile Project tool is ALT+F2 (hold down the ALT key on your keyboard, and press the F2 function key, at the top left of the keyboard, simultaneously). 32 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Profiling Your Java 8 Game Application CPU Usage Using the Profile Project menu item or shortcut icon will open the Profile InvinciBagel (your game project’s name) dialog, as shown in Figure 2-14. Let’s click the center CPU button at the left of the dialog, which will put the dialog in Analyze Performance (selection characteristics) mode. You will look at profiling memory use a bit later on (see the section “Profiling Your Java 8 Game Application Memory Usage”). The Monitor (button) option enables real-time thread monitoring, which can be used while you write your Java code. Figure 2-14.  Set the filter, using the drop-down menu in the Profile Project dialog, and select the Advanced (instrumented) output setting In this dialog, you can select a Quick profile or an Advanced profile, which has graphical instruments that show the performance visually. As you can see, this is the option selected as well as the Profile only project classes option from the Instrumentation Filter drop-down menu. Leave Use defined Profiling Points selected to get NetBeans 8.0 to do the maximum amount of profiling work possible. Note as well the Overhead gauge (indicator) at the bottom of the dialog, indicating a 50 percent value. The first time that you run the NetBeans profiling tool, it needs to calibrate your workstation, as every workstation will have different characteristics, such as the amount of memory and number of CPU cores, or processors. 33 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Figure 2-15 displays the Calibration Information dialog, which suggests that only NetBeans run on your workstation during the calibration process and tells you how to calibrate again in the future (if you change the system hardware configuration), using the Profile ➤ Advanced Commands ➤ Manage Calibration Data menu sequence. Figure 2-15.  The first time you profile, a calibration is performed There is also a warning, saying that you should disable dynamic CPU frequency switching (this is typically referred to as overclocking), which is a common feature these days. Because I want to test for slower CPU speeds, I did not bother to do this, as it involves going into the system BIOS (Basic Input/Output System) on the workstation motherboard and is not something for beginners to be playing around with. Ultimately, the most thorough way to test a game application is across a wide range of different OSs and hardware configurations, but I wanted to show you this profiling feature, as it is a great way to get a good baseline on your application performance, which you can then improve on as you refine your code (and then run the profiler again and again, comparing the results with the original baseline measurements). Once you click the OK button, NetBeans IDE 8.0 will calibrate its profiling tool relative to your system hardware characteristics, which should not take long at all on a fast, modern-day, multicore workstation. If you are running the Windows OS (as seen here, in the 64-bit Windows 7 version), you will probably get a Windows Firewall has blocked some features of this program Windows Security Alert dialog. You want to have all the features of NetBeans 8.0 at your disposal, so let’s look at how to allow access to the Java SE 8 platform in Windows next. 34 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Unblocking the Java 8 Platform Binary via the Windows Firewall If you get the dreaded Blocked Features network dialog, presented in Figure 2-16, select the Allow Java Platform SE binary to communicate on Private networks, such as my home or work network check box, and then click the Allow access button, which will allow the Java 8 platform SE binary to communicate through the Windows firewall. Figure 2-16.  Allow Java features to be used by clicking Allow access After you allow access to the Java 8 platform SE binary, the NetBeans 8.0 profiling tool can (and will) run and will generate basic profiling telemetry results. You will take a closer look at these in the following sections, which deal how to analyze profiling results and what they reveal in terms of how your application uses memory and CPU resources. Analyzing the NetBeans IDE 8.0 Game Project CPU Profiling Tool Results The NetBeans Profiler essentially looks at memory usage and the CPU time used to execute your code. The less memory used, and the faster the CPU times (which equates to fewer CPU processing cycles required to execute code), the better optimized your application is. The Profiler also looks at code- (software-) related things, such as method calls and thread states, which you will be learning about over the course of this book. 35 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 After you run the NetBeans 8.0 Profiler, you will see that a Profiler tab has been added to your Projects, Files, and Services tabs, at the left of the IDE, as illustrated in Figure 2-17. You examined these other three tabs earlier in the chapter (see the section “NetBeans 8.0 Is Efficient: Organized Project Management Tools”), so let’s explore the Profiler tab now. Figure 2-17.  Profile’s Basic Telemetry section, at the left of the IDE, under the Profile tab, shows methods, threads, and total and used memory At the top of the Profiler tab is the Controls section, with Stop (Terminate) Profiled Application, Reset Collected Profiling Results Buffer, Garbage Collection, Modify Profiling Session, and VM Telemetry Overview icons. Below these is the Status section, showing the type of profiling you have selected (in this case, CPU), the configuration (Analyze Performance), and the Status (Running). The Profiling Results section contains icons that open tabs in the code editor section regarding profiling data results (reports), and the View section does the same thing for virtual memory (VM) telemetry, threads, and thread lock contention. You will be looking at some of these in the next section, when you profile memory usage (you are currently profiling CPU usage). You can save snapshots of various points in time during your code profiling sessions in the Saved Snapshots section. The Basic Telemetry section shows statistics regarding the profiling session, including number of methods, filter settings, threads running, and memory usage. 36 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Click the Live Results icon in the Profiling Results section, and open a live profiling result tab, shown in Figure 2-18, at the top, labeled with the CPU time (2:12:09 pm). Figure 2-18.  NetBeans Profiler output, shown in the cpu tab, at the top right, and the Output tab, at the bottom right As you can see, you are able to open your code hierarchy, including the .main() method, the .start() method, and the .handle() method, and see a visual representation of their percentage of total CPU time used as well as the actual CPU time used, in milliseconds, which is the time value that is employed in Java programming for both Java 8 and JavaFX and even for HTML5, JavaScript, and Android application development. Finally, as you can see in the Output pane at the bottom of the figure, there is also text output, just like when this Output pane is used for displaying the compiled, run, and executed code, showing what the Profiler is doing as well. After the “Hello World!” that you generated by clicking your application’s Say “Hello World” button, you can see the Profiler agent Initializing, caching classes, and so on. There are a ton of tabs and options in this area of NetBeans, and I cannot cover every single one of them in this basic NetBeans overview chapter, so play around with what you see on your screen! 37 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Profiling Your Java 8 Game Application Memory Usage Let’s take a look at Memory Profiling next. Click the Profile Project icon, and open the Analyze Memory dialog, presented in Figure 2-19. As you can see, if you select Record stack trace for allocations, the Profiler uses more system overhead. Figure 2-19.  Select the Memory section of the Profile InvinciBagel dialog and select Record stack trace for allocation Once the memory profiler is running, use a Window ➤ Profiling ➤ VM Telemetry Overview menu sequence, shown in Figure 2-20 (top), to open the VM Telemetry Overview tab (bottom). This tab shows memory allocated and memory used. You can hover the mouse over the visual bar to get an exact reading at any point in time. In programming terms, hovering a mouse over something will be accessed in your code using “mouse-over.” 38 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Figure 2-20.  Use the Window ➤ Profiling menu sequence to access the visual profiling tabs Check out some of the other visual report tabs in the Window ➤ Profiling menu sequence. Presented in Figure 2-21 are the Threads tab, showing all 11 threads (see the Basic Telemetry pane, at the left of the screen), including what each thread is doing (what code the thread is running), and the VM Telemetry tab, which displays virtual memory usage over time. 39 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 Figure 2-21.  Use the Window ➤ Profiling menu sequence to access the Threads and VM Telemetry tabs 40 www.it-ebooks.info Chapter 2 ■ Setting Up Your Java 8 IDE: An Introduction to NetBeans 8.0 The NetBeans Profiler is something that you learn how to use over time, first through experimentation and then, as you become familiar with what Profiler can do, by using it with your own projects as they become increasingly complex and observing what your code base does regarding threads, CPU usage, and memory allocation and usage. NetBeans Profiler is a powerful and useful tool of this that is going to serve as the code development foundation for your Java 8 game development. I included it in this chapter to give you a solid overview, as this knowledge base will help you leverage the software, using it to its fullest potential and capabilities. Clearly, this is an advanced IDE and software development tool that cannot be covered in one short chapter (maybe in a book; however, this is not a NetBeans 8.0 games development title), so you will be learning more about what NetBeans 8.0 can do for you in just about all the chapters in this book, as NetBeans 8.0 and Java 8 (and JavaFX 8) are inexorably intertwined. Summary In this second chapter, you learned about NetBeans IDE 8.0, which will serve as the foundation and primary tool for your Java 8 game development work process. This IDE is where your Java 8 (and JavaFX 8) code is written, compiled, run, tested, and debugged as well as where your new media (image, audio, video, 3D, font, shape, and so on) assets are stored and referenced, using your NetBeansProject folder and its subfolders. You started by taking a look at NetBeans 8.0 and the high-level features that make it the official IDE for Java 8 and that help programmers develop code quickly, efficiently, and effectively (i.e., make code that is bug free) the first time. After this overview, you created your Java 8 game project, using as a model a real-world game project that I am working on for a major client. You went through the New Java Application series of dialogs and created a JavaFX framework for your game, which will allow you to use new media assets, such as images, audio, video, and 3D. Then, you explored how to compile and run an application, using NetBeans 8.0. You also studied the Output tab and how that is used for compiler output, runtime output, and profiling output, which you considered next. You examined both CPU profiling and memory profiling in NetBeans 8.0; learned how to set up and start up the Profile Project tool; and studied some of the output, statistics, and visual reports that the NetBeans Profiler can create for you, based on your Java 8 game project. In the next chapter, I will present an overview of the Java 8 programming language to make sure that you are up to speed on how Java 8 works; a Java primer chapter, if you will. 41 www.it-ebooks.info Chapter 3 A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Let’s build on the knowledge you gained about NetBeans IDE 8.0 in the previous chapter by exploring the basic concepts and principles behind the Java 8 programming language. Java JDK 8 will be the foundation for your Java 8 games, as well as for your NetBeans IDE 8.0, so it is important that you take the time to study this chapter, a Java 8 “primer” that gives you an overview of this internationally popular computer (and device) programming language. You will of course learn about more advanced concepts, such as Lambda Expressions, and about other Java 8 components, such as the recent JavaFX multimedia engine, as you progress through the book, so be aware that this chapter will cover the most foundational Java programming language concepts, techniques, and principles, spanning the three major versions of Java SE currently in widespread use today, on computers, iTVs, and handheld devices. These versions of Java, used by billions of users, include Java 6, which is used in the 32-bit Android 4.x OS and applications; Java 7, which is used in the 64-bit Android 5.x OS and applications; and Java 8, which is used across many popular OSs, such as Microsoft Windows, Apple OS X, Oracle Solaris, and a plethora of popular Linux “distros,” or distributions (custom Linux OS versions, such as SUSE, Ubuntu, Mint, Mandrake, Fedora, and Debian). You will start with the easiest concepts, the highest level of Java, and progress to the more difficult ones, the guts of the Java programming constructs. You will begin, with a study of Java syntax, or lingo, including what Java keywords are, how Java delimits its programming constructs, and how to comment your code. Examining this first will give you a head start at being able to read Java code, as it is important to be able to discern the Java code from the commentary regarding that code (which is usually written by the author of the Java code using comments). Then, you will consider the top-level concept of APIs, as well as what a package is, and how you can import and use the preexisting code that is provided by Java packages. These Java packages are a part of the Java 8 API, and it is important to note that you can create custom Java packages of your own, containing your games or applications. After that, you will consider the constructs that are held inside of these Java packages, which are called Java classes. Java classes are the foundation of Java programming, and can be used to build your applications (in this case, your Java 8 games). You will learn about the methods, variables, and constants that these classes contain, as well as what superclasses and subclasses are, and what nested classes and inner classes are, and how to utilize them. Finally, you will discover what Java objects are, and learn how they form the foundation of Object Oriented Programming (OOP). You will also come to know what a constructor method is, and how it creates the Java object, by using a special kind of method called a constructor method that has the same name as the class that it is contained in. Let’s get started—we have a lot of ground to cover! The Syntax of Java: Comments and Code Delimiters There are a couple of things regarding syntax, meaning how Java writes things in its programming language, that you need to consider right off of the bat. These primary syntax rules are there to allow the Java compiler to understand how you are structuring your Java code. Java compilation is the part of the Java programming process, in which the 43 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles JDK compiler (program) turns your Java code into bytecode that is executed or run by a Java Runtime Engine (JRE). This JRE, in this case it is JRE 8, is installed on your end user’s computer system. The Java compiler needs to know where your Java code blocks begin and end, where your individual Java programming statements or instructions begin and end within those Java code blocks, and which parts of your code are Java programming logic, and which parts are comments to yourself, or comments (notes) to other members of your game project programming team. Let’s start with comments, as this topic is the easiest to grasp, and you have already seen comments in your InvinciBagel game bootstrap Java code, in Chapter 2. There are two ways to add comments into Java code: single-line, also referred to as “in-line,” comments, which are placed after a line of Java code logic, and multiple--line, or “block,” comments, which are placed before (or after) a line of Java code or a block of Java code (a Java code structure). The single-line comment is usually utilized to add a comment regarding what that line of Java logic, which I like to call a Java programming “statement,” is doing, that is, what that line of Java code is there to accomplish within your overall code structure. Single-line comments in Java start with the double forward slash sequence. For instance, if you wanted to comment one of the import statements in the InvinciBagel bootstrap code that you created in Chapter 2, you would add double forward slashes after the line of code. This is what your Java code would look like once it has been commented (see also Figure 3-1, bottom right):   import javafx.stage.Stage // This line of code imports the Stage class from JavaFX.stage package  Figure 3-1.  Multiline comments ( first five lines of code, at the top) and single-line comments (last three lines of code, at the bottom) Next, let’s take a look at multiline comments, which are shown at the top of Figure 3-1, above the package statement (which you will be learning about in the next section). As you can see, these Java block comments are done differently, using a single forward slash next to an asterisk to start the comment and the reverse of that, an asterisk next to a single forward slash, to end the multi-line comment. As you can see in the InvinciBagel.java code editing tab in NetBeans 8.0, just as I lined up the single-line comments to look pretty (cool) and organized, so too the Java convention in block commenting is to line up the asterisks, with one as the beginning comment delimiter and one as the ending comment delimiter. 44 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles ■■Definition A “convention” in Java programming is the way that most, if not all, Java programmers will implement a Java construct. In this case, this is the way that the Java code block commenting is styled. There is a third type of comment, called a Javadoc comment, which you will not be using in your Java 8 game development, as your code is intended to be used to create a game, and not to be distributed to the public. If you were going to write a Java game engine for use by others to create games, that is when you would use Javadoc comments to add documentation to your Java 8 game engine. A Javadoc comment can be used by the javadoc.exe tool in the JDK to generate HTML documentation for the Java class containing Javadoc comments, based on the text content that you put inside the Javadoc comment. A Javadoc comment is similar to a multiline comment, but it uses instead two asterisks to create the opening Javadoc comment delimiter, as shown here:   /** This is an example of a Java Documentation (Javadoc) type of Java code comment. This is a type of comment which will automatically generate Java documentation! */   If you wanted to insert a comment right in the middle of your Java statement or programming structure (which you should never do as a professional Java programmer), use the multiline comment format, like so:   import /* This line of code imports the Stage class */ javafx.stage.Stage;   This will not generate any errors, but would confuse the readers of this code, so do not comment your code in this way. The following single line comment way of commenting this code, using the double forward slash, would, however, generate compiler errors in NetBeans 8.0:   import // This line of code imports the Stage class javafx.stage.Stage   Here, the compiler will see only the word import, as the single-line comment goes to the end of the line, compared with the multiline comment, which is specifically ended using the block comment delimiter sequence (asterisk and a forward slash). So, the compiler will throw an error for this second improperly commented code, essentially asking, “Import what?” Just as the Java programming language uses the double forward slash and slash-asterisk pairing to delimit the comments in your Java code, so too a couple of other key characters are used to delimit Java programming statements as well as entire blocks of Java programming logic (I often call these Java code structures). The semicolon is used in Java (all versions) to delimit or separate Java programming statements, such as the package and import statements seen in Figure 3-1. The Java compiler looks for a Java keyword, which starts a Java statement, and then takes everything after that keyword, up to the semicolon (which is the way to tell the Java compiler, “I am done coding this Java statement”), as being part of the Java code statement. For instance, to declare the Java package at the top of your Java application, you use the Java package keyword, the name of your package, and then a semicolon, as follows (see also Figure 3-1):   package invincibagel;   Import statements are delimited using the semicolon as well, as can be seen in the figure. The import statement provides the import keyword, the package and class to be imported, and, finally, the semicolon delimiter, as shown in the following Java programming statement:   import javafx.application.Application;   45 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Next, you should take a look at the curly { braces ({. . .}) delimiter, which, like the multiline comment delimiter, has an opening curly brace, which delimits (that is, which shows a compiler) the start of a collection of Java statements, as well as a closing curly brace, which delimits the end of the collection of Java programming statements. The curly braces allow you to use multiple Java programming statements inside a number of Java constructs, including inside of Java classes, methods, loops, conditional statements, lambda expressions, and interfaces, all of which you will be learning about over the course of this book. As illustrated in Figure 3-2, Java code blocks delimited using curly braces can be nested (contained) inside of each other, allowing far more complex Java code constructs. The first (outermost) code block using curly braces is the InvinciBagel class, with other constructs then nested as follows: the start() method, the .setOnAction() method, and the handle() method. You will be examining what all this code does as this chapter progresses. What I want you to visualize now (with the help of the red squares in Figure 3.2) is how the curly braces are allowing your methods (and class) to define their own code blocks (structures), each of which is a part of a larger Java structure, with the largest Java structure being the InvinciBagel.java class itself. Note how each opening curly brace has a matching closing curly brace. Note as well the indenting of the code, such that the innermost Java code structures are indented the farthest to the right. Each block of code is indented by an additional four characters or spaces. As you can see, the class is not indented (0), the start() method is 4 spaces in, the .setOnAction() method is 8 spaces in, and the handle() method is 12 spaces in. NetBeans 8.0 will indent each of your Java code structures for you! Also notice that NetBeans 8.0 draws very fine (gray) indentation guide lines in the IDE so that you can line up your code structures visually, if you prefer. Figure 3-2.  Nested Java code blocks for the InvinciBagel class, start method, setOnAction method, and handle method The Java code inside each of the red squares begins with a curly brace and ends with a curly brace. Now that you are familiar with the various Java 8 code commenting approaches, as well as how your Java 8 game programming statements need to be delimited, both individually and as Java code blocks, you will next study the various Java code structures themselves—how they are used, what they can do for your applications and games, and which important Java keywords are employed to implement them. 46 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Java APIs: Using Packages to Organize by Function At the highest level of a programming platform, such as Google’s 32-bit Android 4, which uses Java SE 6; 64-bit Android 5, which uses Java SE 7; and the current Oracle Java SE platform, which was recently released as Java SE 8, there is a collection of packages that contain classes, interfaces, methods, and constants and that together form the API. This collection of Java code (in this case, the Java 8 API) can be used by application (in this case, game) developers to create professional-level software across many OSs, platforms, and consumer electronics devices, such as computers, laptops, netbooks, notebooks, tablets, iTV sets, game consoles, smartwatches, and smartphones. To install a given version of an API level, you install the SDK (Software Development Kit). The Java SDK has a special name, the JDK (Java Development Kit). Those of you who are familiar with Android (Java SE on top of Linux) OS development know that a different API level is released every time a few new features are added. This is because these new hardware features need to be supported, not because Google’s executives feel like releasing a new SDK every few months. Android has 24 different API levels, whereas Java SE has only eight, and only three of Java’s API levels (Java 6, Java 7, Java 8) are in use currently. Java SE 6 is used with Eclipse ADT (Android Developer Tools) IDE to develop for 32-bit Android (versions 1.5 through 4.5); Java SE 7 is used with IntelliJ IDEA to develop for 64-bit Android (version 5.0 and later); and Java 8 is used with the NetBeans IDE to develop for JavaFX and Java 8 across the Windows, Mac OS X, Linux, and Oracle Solaris OSs. I have three different workstations that are optimized for each of these Java API platforms and IDE software packages so that I can develop applications for Android 4 (Java 6), Android 5 (Java 7), and JavaFX (Java 8) at the same time. Fortunately, you can get a powerful Windows 8.1 hexacore or octacore 64-bit AMD workstation on PriceWatch. com for a few hundred dollars! Besides API level (the SDK you installed and are using), the highest-level construct in the Java programming language is the package. A Java package uses the package keyword to declare the application’s package at the top of your Java code. This must be the first line of code declared, other than comments (see Figure 3-1; see also Chapter 2). The New Project series of dialogs in NetBeans that you used in Chapter 2 will create your package for you and will import other packages that you will need to use, based on what you want to do in your application. In this case, these are JavaFX packages, so you can use the JavaFX new media engine. As you may have ascertained from the name, a Java package collects all the Java programming constructs. These include classes, interfaces, and methods that relate to your application, so the invinciBagel package will contain all your code, as well as the code that you imported to work with your code, to create, compile, and run the InvinciBagel game. A Java package is useful for organizing and containing all your own application code, certainly, but it is even more useful for organizing and containing the SDK’s (API’s) Java code, which you will use, along with your own Java programming logic, to create your Java 8 applications. You can use any of the classes that are part of the API that you are targeting by using the Java import keyword, which, in conjunction with the package and class that you want to use, constitutes an import statement. The import statement begins with the import keyword, followed by the fully qualified class name, which is the package name, any subpackage name, and the class name as a complete naming reference path (the full proper name for the class). A semicolon terminates an import statement. As you have already seen in Figure 3-1, the import statement used to import the JavaFX EventHandler class from the javafx.event package should look just like this:   import javafx.event.EventHandler;   The import statement tells the Java compiler that you will be using methods (or constants) from the class that is referenced, using the import keyword, as well as which package the class is stored in. If you use a class, method, or interface in your own Java class, such as the InvinciBagel class (see Figure 3-2), and you have not declared the class for use, using the import statement, the Java compiler will throw an error until you add the required import statement at the top of the class (after the Java package declaration statement, and before the Java class declaration statement). 47 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles ■■Note It is possible to use, instead of the Java import keyword, the fully qualified class name, that is, to preface the class name with the package name, right inside your Java code. Convention dictates using the import statement; however, line 20 in Figure 3-2 could be written as javafx.scene.control.Button btn = new javafx.scene.control. Button(); if you wanted to buck standard Java programming convention. Java Classes: Logical Java Constructs to Build On The next logical Java programming construct beneath the package level is the Java class level, as you saw in the import statement, which references both the package that contains the class and a class itself. Just as a package organizes all the related classes, so too a class organizes all its related methods, variables, and constants and, sometimes, other nested classes. Thus, the Java class is used to organize your Java code at the next logical level of functional organization, and so your class will contain Java code constructs that add functionality to your application. These may include methods, variables, constants, nested classes, or inner classes. Java classes can also be used to create Java objects. Java objects are constructed, using your Java class, and have the same name as the Java class and as that class’s constructor method. As you saw in Figure 3-2, you declare your class, using a Java class keyword, along with a name for your class. You can also preface the declaration with Java modifier keywords, which you will be studying later in this chapter (see the section “Java Modifier Keywords: Access Control and More”). Java modifier keywords are always placed before (or in front of ) the Java class keyword, using the following format:   class   One of the powerful features of Java classes is that they can be used to modularize your Java game code so that your core game application features can be a part of a high-level class that can be subclassed to create more specialized versions of that class. Once a class has been subclassed, it becomes a superclass, in Java class hierarchy terminology. A class will always subclass a superclass using a Java extends keyword. If a class does not extend a given superclass in this way, then it automatically extends the Java masterclass: java.lang.Object. This is so that every class in Java can create an object by implementing a constructor method. Using a Java extends keyword tells the compiler that you want the superclass’s capabilities and functionality added (extended) to your class, which, once it uses this extends keyword, becomes a subclass. A subclass extends the core functionality that is provided by the superclass. To extend your class definition to include a superclass, you add to (or extend, no pun intended) your existing class declaration, using the following format:   class extends   When you extend a superclass with your class, which is now a subclass of that superclass, you can use all the superclass’s features (nested classes, inner classes, methods, variables, constants) in your subclass, without having them all explicitly written (coded) in the body of your class, which would be redundant (and disorganized). 48 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles ■■Note If any of the data fields or methods in the superclass that you are extending (or, if you prefer, subclassing) have been declared using the private access control keyword, those variables (or constants) and methods are reserved for use only by (or within) that superclass, and thus will not be accessible to your subclass. The same rules apply to nested and inner classes; these class structures cannot use any code declared as private in the Java constructs that contain them (or that are above them, if you will). The body of your class is coded inside the curly braces (see Figure 3-2, outermost red box), which follow your class (and javafx.application.Application superclass, in this case) declaration. This is why you learned about Java syntax first, and you are building on that with the class declaration and the Java syntax that holds the class definition (variables, constants, methods, constructor, nested classes) constructs. As you can see in the figure, the InvinciBagel class extends an Application superclass from the JavaFX package. The inheritance diagram (a tool I will be using throughout the book to show you where things come from in the overall Java and JavaFX API schemas) for your current superclass-to-subclass hierarchy will therefore look like this:   > java.lang.Object > javafx.application.Application > invincibagel.InvinciBagel   By extending the javafx.application package and its Application class, you will give the InvinciBagel class everything it needs to host (or run) the JavaFX application. The JavaFX Application class “constructs” an Application object so that it can use system memory; call an .init() method, to initialize anything that may require initializing; and call a .start() method (see Figure 3-2, second-outermost red box), which puts things into place that will ultimately be needed to fire up (start) an InvinciBagel Java 8 game application. When the end user finishes using the InvinciBagel game application, the Application object, created by the Application class, using the Application() constructor method, will call its .stop() method and remove your application from system memory, thus freeing up that memory space for other uses by the your end-users. You will be learning about Java 8 methods, constructors, and objects soon, as you are progressing from the high-level package and class constructs, to lower-level method and object constructs, and so you are moving from a high-level overview to lower levels. You may be wondering if Java classes can be nested inside each other, that is, if Java classes contain other Java classes. The answer is yes, they certainly can (and do)! Let’s take a look at the concept of Java nested classes next. Nested Classes: Java Classes Living Inside Other Classes A nested class in Java is a class that is defined inside of another Java class. A nested class is part of the class in which it is nested, and this nesting signifies that the two classes are intended to be used together in some fashion. There are two types of nested classes: static nested classes, which are commonly referred to simply as nested classes, and nonstatic nested classes, which are commonly referred to as inner classes. Static nested classes, which I will refer to as nested classes, are used to create utilities for use with the class that contains them, and are sometimes used only to hold constants for use with that class. Those of you who develop Android applications are very familiar with nested classes, as they are quite commonly employed in the Android API, to hold either utility methods or Android constants, which are used to define things such as screen density settings, animation motion interpolation curve types, alignment constants, and user interface element scaling settings. If you are looking for an understanding regarding the concept of static, it can be thought of as fixed, or not capable of being changed. A photograph is a static image, whereas video is not static. We’ll look at this concept often during this book. 49 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles A nested class uses what is commonly referred to in Java as dot notation to reference the nested class “off of” its master, or parent, containing class. For instance, MasterClass.NestedClass would be the referencing format that would be used to reference a nested class via its master class (containing class) name, using generic class type names here. If you created an InvinciBagel SplashScreen nested class to draw the splash screen for your Java game, it would be referenced in your Java code as InvinciBagel.SplashScreen, using this Java 8 dot notation syntax. Let’s take a look at, for example, the JavaFX Application class, which contains a Parameters nested class. This nested class encapsulates, or contains, the parameters that you can set for your JavaFX application. Thus, this Application.Parameters nested class would be a part of the same javafx.application package as your Application class and would be referenced as javafx.application.Application.Parameters, if you were using an import statement. Similarly, the constructor method would be written as Application.Parameters(), because the constructor method must have the exact same naming schema as the class that it is contained in. Unless you are writing code for other developers, which is when nested classes are most often used (such as the JavaFX Application class or the many nested utility or constant provider classes which you will find in the Android OS), you are far more likely to utilize non-static nested classes (commonly referred to as Java inner classes). A nested class can be declared by using the Java static keyword. A Java keyword is also sometimes called a Java modifier. Therefore, if you were to do an InvinciBagel.SplashScreen nested class, the InvinciBagel class and its SplashScreen nested class declaration (Java 8 programming structure) would look something like this:   public class InvinciBagel extends Application { static class SplashScreen { // The Java code that creates and displays your splashscreen is in here } }   It is important to note if you use, for example, import javafx.application.Application.Parameters to import a nested class, you can reference that nested class within your class, using just the Parameters class name, rather than the full class name path that shows your class’s code how to travel through a parent class to its nested class via the Application.Parameter (ClassName.NestedClassName) dot notation syntax reference. As you will see many times throughout this book, Java methods can also be accessed using the dot notation. So, instead of using ClassName.NestedClassName.MethodName, you could, if you had used the import statement to import this nested class, simply use NestedClassName.MethodName. This is because the Java import statement has already been used to establish the full reference path to this nested class, through its containing class, and so you do not have to provide this full path reference for the compiler to know what code construct you are referring to! Next, let’s take a look at nonstatic nested classes, which are usually referred to as Java inner classes. Inner Classes: Different Types of Nonstatic Nested Classes Java inner classes are also nested classes, but they are not declared using the static keyword modifier before the class keyword and class name, which is why they are called nonstatic nested classes. Thus, any class declaration that is inside another class that does not use the static (keyword) modifier would be termed an inner class in Java. There are three types of inner classes in Java: member class, local class, and anonymous class. In this section, you will discover what the differences are between these inner classes, as well as how they are implemented . Like nested classes, member classes are defined within the body of the containing (parent) class. You can declare a member class anywhere within the body of the containing class. You would declare a member class if you wanted to access data fields (variables or constants) and methods belonging to the containing class without having to provide a path (via dot notation) to the data field or method (ClassName.DataField or ClassName.Method). A member class can be thought of as a nested class that does not use the Java static modifier keyword. Whereas a nested class is referenced through its containing, or top-level, class, using a dot notation path to the static nested class, a member class, because it is not static, is instance specific, meaning that objects (instances) created via that class can be different from each other (an object is a unique instance of a class), whereas a static 50 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles (fixed) nested class will only have one version, which does not change. For instance, a private inner class can only be used by a parent class that contains it. The SplashScreen inner class coded as a private class would look something like this:   public class InvinciBagel extends Application { private class SplashScreen { // The Java code that creates and displays your splashscreen is in here } }   Because this class is declared as private, it is for your own application usage (the containing class’s usage, specifically). Thus, this would not be a utility or constant class for use by other classes, applications, or developers. You can also declare your inner class without using the private access modifier keyword, which would look like the following Java programming construct:   public class InvinciBagel extends Application { class SplashScreen { // The Java code that creates and displays your splashscreen is in here } }   This level of access control is called package or package private and is the default level of access control applied to any class, interface, method, or data field that is declared without using one of the other Java access control modifier keywords (public, protected, private). This type of inner class can be accessed not only by the top-level, or containing, class, but also by any other class member of the package that contains that class. This is because the containing class is declared public, and the inner class is declared package private. If you want an inner class to be available outside the package, you declare it to be public, using the following Java code structure:   public class InvinciBagel extends Application { public class SplashScreen { // The Java code that creates and displays your splashscreen is in here } }   You can also declare an inner class protected, meaning that it can only be accessed by any subclasses of the parent class. If you declare a class inside a lower-level Java programming structure that is not a class, such as a method or an iteration control structure (commonly called a loop), it would technically be referred to as a local class. A local class is only visible inside that block of code; thus, it does not allow (or make sense to use) class modifiers, such as static, public, protected, or private. A local class is used like a local variable, except that it is a complex Java coding construct rather than a simple a data field value that is used locally. Finally, there is a type of inner class called an anonymous class. An anonymous class is a local class that has not been given a class name. You are likely to encounter anonymous classes far more often than you are local classes. This is because programmers often do not name their local classes (making them anonymous classes); the logic local classes contain is only used locally, to their declaration, and so these classes do not really need to have a name—they are only referenced internally to that block of Java code. Java Methods: Core Java Function Code Constructs Inside classes, you generally have methods and the data fields (variables or constants) that these methods use. Because we are going from outside to inside, or top-level structures to lower-level structures, I will cover methods next. Methods are sometimes called functions in other programming languages. Figure 3-2 provides an example 51 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles of the .start() method, showing how the method holds the programming logic that creates a basic “Hello World!” application. The programming logic inside the method uses Java programming statements to create a Stage object and a Scene object, place a button on the screen in a StackPane object, and define event-handling logic, such that when the button is clicked, the bootstrap Java code writes the “Hello World!” text to your NetBeans IDE output area. The method declaration starts with an access modifier keyword, either public, protected, private, or package private (which is designated by not using any access control modifier at all). As you can see in the figure, the .start() method has been declared, using the public access control modifier. After this access control modifier, you will need to declare the method’s return type. This is the type of data that the method will return after it is called, or invoked. Because the .start() method performs setup operations but does not return a specific type of value, it uses the void return type, which signifies that the method performs tasks but does not return any resulting data to the calling entity. In this case, the calling entity is the JavaFX Application class, as the .start() method is one of the key methods (the others being the .stop() and .init() methods) provided by that class to control the life cycle stages of a JavaFX application. Next, you will supply the method name, which, by convention (programming rules), should start with a lowercase letter (or word, preferably a verb), with any subsequent (internal) words (nouns or adjectives) starting with a capital letter. For instance, a method to display the splash screen would be named .showSplashScreen() or .displaySplashScreen() and because it does something but does not return a value, would be declared using this code:   public void displaySplashScreen() { Java code to display splashscreen goes in here }   If you need to pass parameters, which are named data values that have to be operated on within the body of the method (the part inside the curly braces), these go inside the parentheses that are attached to the method name. In Figure 3-2 the .start() method for your bootstrap “HelloWorld!” JavaFX application receives a Stage object, named primaryStage, using the following Java method declaration syntax:   public void start(Stage primaryStage) { bootstrap Java code to start Application goes in here }   You can provide as many parameters as you like, using the data type and parameter name pairs, with each pair separated by a comma. Methods can also have no parameters, in which case the parameter parentheses are empty, with the opening and closing parentheses right next to each other, for example, .start(), and .stop(). The programming logic that defines your method will be contained in the body of the method, which, as discussed previously, is inside the curly braces that define the beginning and the end of the method. The Java programming logic that is inside methods can include variable declarations, program logic statements, and iterative control structures (loops), all of which you will be leveraging to create your Java game. Before moving on, let’s focus on one other Java concept that applies to methods, namely, overloading Java methods. Overloading a Java method means using the same method name, but different parameter list configurations. What this means is that, if you have defined more than one method with the same name, Java can figure out which of your (overloaded) methods to use by looking at the parameters that are being passed into the method being called and then using that parameter list to discern which of the methods (that have the same name) to use by matching the parameter list data types and names and the order in which they appear. Of course, your parameter list configurations must all be unique for this Java method overloading feature to work correctly. You will be learning how to use and how to code Java methods over the course of this book, beginning in Chapter 4, so I am not going to spend too much time on them here, other than to define what they are and the basic rules for how they are declared, and used, inside Java classes. One specialized kind of method that I am going to cover in detail, however, is the constructor method. This is a type of method that can be used to create objects. Java objects are the foundation of OOP, so you will be taking a look at constructor methods next, as it is important to do so before learning about the Java object itself, which you will study later in the chapter (see the section “Java Objects: Virtual Reality, Using Java Constructs“). 52 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Creating a Java Object: Invoking a Class’s Constructor Method A Java class can contain a constructor method with the exact same name as the class that can be used to create Java objects using that class. A constructor method uses its Java class like a blueprint to create an instance of that class in memory, which creates a Java object. A constructor method will always return a Java object and thus does not use any of the Java return types that other methods will typically use (void, String, and so on). A constructor method is invoked by using the Java new keyword, because you are creating a new object. You can see an example of this in the bootstrap JavaFX code shown in Figure 3-2 (ll. 20, 28, and 30), where new Button, StackPane, and Scene objects are created, respectively, by using the following object declaration, naming, and creation Java code structure:   = new   The reason that a Java object is declared in this way, using the class name, the name of the object you are constructing, the Java new keyword, and the class’s constructor method name (and parameters, if any) in a single Java statement terminated with a semicolon, is because a Java object is an instance of a Java class. Let’s take a look at, for example, the Button object creation from line 20 of your current Java code. Here, via the part of the Java statement on the left-hand side of the equals operator, you are telling the Java language compiler that you want to create a Button object named btn, using the JavaFX Button class as the object blueprint. This declares the Button class (object type) and gives it a unique name. The first part of creating the object is thus called the object declaration. The second part of creating your Java object is called the object instantiation, and this part of the object creation process, seen on the right-hand side of the equals operator, involves a constructor method and the Java new keyword. To instantiate a Java object, you invoke the Java new keyword, in conjunction with an object constructor method call. Because this takes place on the right-hand side of the equals operator, the result of the object instantiation is placed in the declared object, which is on the left-hand side of the Java statement. As you will see a bit later in the chapter, when I discuss operators (see the section “Java Operators: Manipulating Data in the Application”), this is what an equals operator does, and a useful operator it is. This completes the process of declaring (class name), naming (object name), creating (using a new keyword), configuring (using a constructor method), and loading (using the equals operator) your very own custom Java object. It is important to note that the declaration and instancing parts of this process can be coded using separate lines of Java code as well. For instance, the Button object instantiation (see Figure 3-2, l. 20) could be coded as follows:   Button btn; btn = new Button();   This is significant, because coding an object creation in this way allows you to declare an object at the top of your class, where each of the methods inside the class that use or access these objects can see the object. In Java, unless declared otherwise, using modifiers, an object or data field is only visible inside the Java programming construct (class or method) in which it is declared. If you declare an object inside your class, and therefore outside all the methods contained in the class, then all the methods in your class can access (use) that object. Similarly, anything declared inside a method is local to that method and is only visible to other members of that method (Java statements inside the method scope delimiters). If you wanted to implement this separate object declaration (in the class, outside the methods) and object instantiation (inside the .start() method) in your current InvinciBagel class, the first few lines of Java code for your InvinciBagel class would change to look like the following Java programming logic:   public class InvinciBagel extends Application { Button btn; @Override public void start(Stage primaryStage) { btn = new Button(); 53 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles btn.setText("Say 'Hello World'"); // The other programming statements continue underneath here } }   When the object declaration and instantiation are split up, they can be placed inside (or outside) methods as needed for visibility. In the preceding code, other methods of your InvinciBagel class could call the .setText() method call shown without the Java compiler’s throwing an error. The way the Button object is declared in Figure 3-2, only the .start() method can see the object, and so only the .start() method can use this btn.setText() method call. Creating a Constructor Method: Coding an Object’s Structure A constructor method is more a method for creating objects in system memory, whereas other methods (or functions, if using a different programming language) are usually used to perform calculation or processing of one type or another. The constructor method’s use in creating Java objects in memory, rather than performing some other programming function, is evidenced by the use of the Java new keyword, which creates a new object in memory. For this reason, a constructor method will define the structure of an object as well as allow the calling entity to populate the object structure with custom data values, using the constructor method’s parameter list. You will create a couple of sample constructor methods in this section to learn the basics of how this is done as well as what a constructor method usually contains. Let’s say you are creating an InvinciBagel object for your game, so you declare a public InvinciBagel() constructor method, using the following Java code structure:   public InvinciBagel() { int lifeIndex = 1000; // Defines units of lifespan int hitsIndex = 0; // Defines units of damage ("hits" on the object) String directionFacing = "E"; // Direction that the object is facing Boolean currentlyMoving = false; // Flag showing if the object is in motion }   This constructor method, when called using an InvinciBagel mortimer = new InvinciBagel(); Java method call, creates an InvinciBagel object named mortimer, with 1,000 units of life and no hits, that is facing east and that is not currently moving. Next, let’s explore the concept of overloading the constructor method, which you learned about earlier (see the section “Java Methods: Java Core Function Code Constructs”), and create another constructor method that has parameters that allow you to define the lifeIndex and directionFacing variables of the InvinciBagel object while you are creating it. This constructor method looks like this:   public InvinciBagel(int lifespan, String direction) { int lifeIndex; int hitsIndex; String directionFacing = null; Boolean currentlyMoving = false; lifeIndex = lifespan; directionFacing = direction; }   54 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles In this version the lifeIndex and hitsIndex variables at the top are initialized to 0, the default value for an integer, so you do not have to use lifeIndex = 0 or hitsIndex = 0 in the code. The Java programming language accommodates method overloading, so if you use an InvinciBagel bert = new InvinciBagel(900, "W"); method call to instantiate the InvinciBagel object, the correct constructor method will be used to create the object. The InvinciBagel object named bert would have a lifeIndex of 900 units of life and no hits on its life, would be facing West, and would not be currently moving. You can have as many (overloaded) constructor methods as you like, so long as they are each 100 percent unique. This means that overloaded constructors must have different parameter list configurations, including parameter list length (the number of parameters) and parameter list types (order of data types). As you can see, it is the parameter list (length, data types, order) that allows a Java compiler to differentiate overloaded methods from one another. Java Variables and Constants: Values in Data Fields The next level down (progressing from API, to package, to class, to method, to the actual data values that are being operated on in Java classes and methods) is the data field. Data values are held inside something called a variable; if you fix, or make permanent, the data, it is called a constant. A constant is a special type of variable (which I will cover in the next section), because declaring a constant correctly is a bit more involved (advanced) than declaring a Java variable. In the Java lingo, variables declared at the top of a class are called member variables, fields, or data fields, although all variables and constants can be considered data fields, at a fundamental level. A variable declared inside a method or other lower-level Java programming structure declared inside a class or method, is called a local variable, because it can only be seen locally, inside the programming constructs delimited by curly braces. Finally, variables declared inside a parameter list area of a method declaration or method call are, not surprisingly, called parameters. A variable is a data field that holds an attribute of your Java object or software that can (and will) change over the course of time. As you might imagine, this is especially important for game programming. The simplest form of variable declaration can be achieved by using a Java data type keyword, along with the name that you want to use for the variable in your Java program logic. In the previous section, using the constructor method, you declared an integer variable named hitsIndex to hold the damage, or hits, that your InvinciBagel object will sustain during game play. You defined the variable data type, and named it, using the following Java variable declaration programming statement:   int hitsIndex; // This could also be coded as: int hitsIndex = 0; (the default Integer is Zero)   As you also saw in that section, you can initialize your variable to a starting value, using an equals operator, along with a data value that matches up with the data type declared: for example:   String facingDirection = "E";   This Java statement declares a String data type variable and names it facingDirection, on the left side of the equals operator, and then sets the declared variable to a value of “E,” which signifies the direction East, or right. This is similar to how an object is declared and instantiated, except that the Java new keyword and constructor method are replaced by the data value itself, because now a variable (data field) is being declared instead of an object being created. You will learn about the different data types (I have already covered Integer, String, and Object) later in chapter (see the section “Java Data Types: Defining Data in Applications”). You can also use Java modifier keywords with variable declarations, which I will do in the next section, when I show you how to declare an immutable variable, also known as a constant, which is fixed, or locked, in memory and which cannot be altered. Now that I am almost finished going from the largest Java constructs to the smallest (data fields), I will start to cover topics that apply to all levels (classes, methods, variables) of Java. These concepts will generally increase in complexity as you progress to the end of this Java 8 primer chapter. 55 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Fixing Data Values in Memory: Defining a Data Constant in Java If you are already familiar with computer programming, you know that there is often a need to have data fields that will always contain the same data value and that will not change during the duration of your application run cycle. These are called constants, and they are defined, or declared, using special Java modifier keywords that are used to fix things in memory so that they cannot be changed. There are also Java modifier keywords that will restrict (or unrestrict) object instances, or access to certain classes inside or outside a Java class or package (which you will be examining in detail in the next section). To declare Java variables fixed, you must use a Java final modifier keyword. “Final” means the same thing as when your parents say that something is final: it is fixed in place, an FOL (fact of life), and not going to change, ever. Thus, the first step in creating a constant is to add this final keyword, placing it in front of the data type keyword in your declaration. A convention, when declaring a Java constant (and constants in other programming languages), is to use uppercase characters, with underscored characters between each word, which signifies a constant in your code. If you want to create screen width and screen height constants for your game, you do so like this:   final int SCREEN_HEIGHT_PIXELS = 480; final int SCREEN_WIDTH_PIXELS = 640;   If you want all the objects created by your class’s constructor method to be able to see and use this constant, you add the Java static modifier keyword, placing it in front of the final modifier keyword, like this:   static final int SCREEN_HEIGHT_PIXELS = 480; static final int SCREEN_WIDTH_PIXELS = 640;   If you want only your class, and objects created by this class, to be able to see these constants, you declare the constants by placing the Java private modifier keyword in front of the static modifier keyword, using this code:   private static final int SCREEN_HEIGHT_PIXELS = 480; private static final int SCREEN_WIDTH_PIXELS = 640;   If you want any Java class, even those outside your package (i.e., anyone else’s Java classes), to be able to see these constants, you declare the constants by placing the Java public modifier keyword in front of the static modifier keyword, using the following Java code:   public static final int SCREEN_HEIGHT_PIXELS = 480; public static final int SCREEN_WIDTH_PIXELS = 640;   As you can see, declaring a constant involves a significantly more detailed Java statement than declaring a simple variable for your class! Next, you will take a deeper look at Java modifier keywords, as they allow you to control things such as access to your classes, methods, and variables as well as locking them from being modified and similar highlevel Java code control concepts that are fairly complicated. Java Modifier Keywords: Access Control and More Java modifier keywords are reserved Java keywords that modify the access, visibility, or permanence (how long something exists in memory during the execution of an application) for code inside the primary types of Java programming structures. The modifier keywords are the first ones declared outside the Java code structure, because the Java logic for the structure, at least for classes and methods, is contained within the curly braces delimiter, which comes after the class keyword and class name or after the method name and parameter list. Modifier keywords can be used with Java classes, methods, data fields (variables and constants), and interfaces. 56 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles As you can see at the bottom of Figure 3-2, for the .main() method, created by NetBeans for your InvinciBagel class definition, which uses the public modifier, you can use more than one Java modifier keyword. The .main() method first uses a public modifier keyword, which is an access control modifier keyword, and then a static modifier keyword, which is a nonaccess control modifier keyword. Access Control Modifiers: Public, Protected, Private, Package Private Let’s cover access control modifiers first, because they are declared first, before nonaccess modifier keywords or return type keywords, and because they are easier to understand conceptually. There are four access control modifier levels that are applied to any Java code structure. If you do not declare an access control modifier keyword, a default access control level of package private will be applied to that code structure, which allows it to be visible, and thus usable, to any Java programming structure inside your Java package (in this case, invincibagel). The other three access control modifier levels have their own access control modifier keywords, including public, private, and protected. These are somewhat aptly named for what they do, so you probably have a good idea of how to apply them to either share your code publicly or protect it from public usage, but let’s cover each one in detail here, just to make sure, as access (security) is an important issue these days, inside your code as well as in the outside world. I will start with the least amount of access control first! Java’s Public Modifier: Allowing Access by the Public to Java Program Constructs The Java public access modifier keyword can be used by classes, methods, constructors, data fields (variables and constants), and interfaces. If you declare something public, it can be accessed by the public! This means that it can be imported and used by any other class, in any other package, in the entire world. Essentially, your code can be used in any software that is created using the Java programming language. As you will see in the classes that you use from the Java or JavaFX programming platforms (APIs), the public keyword is most often used in open-source programming Java platforms or packages that are employed to create custom applications, such as games. It is important to note that if a public class that you are trying to access and use exists in a package other than your own (in your case, invincibagel), then the Java programming convention is to use the Java import keyword to create an import statement that allows use of that public class. This is why, by the time you reach the end of this book, you will have dozens of import statements at the top of your InvinciBagel.java class, as you will be leveraging preexisting Java and JavaFX classes in code libraries that have already been coded, tested, refined, and made public, using the public access control modifier keyword, so that you can create Java 8 games with them to your heart’s content! Owing to the concept of class inheritance in Java, all the public methods and public variables inside a public class will be inherited by the subclasses of that class (which, once it is subclassed, becomes a superclass). Figure 3-2 offers an example of a public access control modifier keyword, in front of the InvinciBagel class keyword. Java’s Protected Modifier: Variables and Methods Allow Access by Subclass The Java protected access modifier keyword can be used by data fields (variables and constants) and by methods, including constructor methods, but cannot be used by classes or interfaces. The protected keyword allows variables, methods, and constructors in a superclass to be accessed only by subclasses of that superclass in other packages (such as the invincibagel package) or by any class within the same package as the class containing those protected members (Java constructs). This access modifier keyword essentially protects methods and variables in a class that is intended to be (hoped to be used as) a superclass by being subclassed (extended) by other developers. Unless you own the package that contains these protected Java constructs (which you do not), you must extend the superclass and create your own subclass from that superclass to be able to use the protected methods. 57 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles You may be wondering, why would one want to do this, protecting Java code structures in this way? When you are designing a large project, such as the Android OS API, you will often want to have the higher-level methods and variables not be used directly, right out of, or from within, that class, but rather within a more well-defined subclass structure. You can achieve this direct usage prevention by protecting these methods and variable constructs from being used directly such that they become only a blueprint for more detailed implementations in other classes and are not able to be used directly. Essentially, protecting a method or variable turns it into a blueprint or a definition only. Java’s Private Modifier: Variables, Methods, and Classes Get Local Access Only The Java private access control modifier keyword can be used by data fields (variables or constants) and by methods, including constructor methods, but cannot be used by classes or interfaces. The private modifier can be used by a nested class; however, it cannot be used by an outer or the primary (topmost) class. The private access control keyword allows variables, methods, and constructors in a class to be accessed only inside that class. The private access control keyword allows Java to implement a concept called encapsulation, in which a class (and objects created using that class) can encapsulate itself, hiding its “internals” from outside Java universe, so to speak. The OOP concept of encapsulation can be used in large projects to allow teams to create (and, more importantly, debug) their own classes and objects. In this way, no one else’s Java code can break the code that exists inside these classes, because their methods, variables, constants, and constructors are private! The access modifier keyword essentially privatizes methods or variables in a class so that they can only be used locally within that class or by objects created by that class’s constructor method. Unless you own the class that contains these private Java constructs, you cannot access or use these methods or data fields. This is the most restrictive level of access control in Java. A variable declared private can be accessed outside the class if a public method that accesses a private variable from inside the class, called a public .get() method call, is declared public and thus provides a pathway (or doorway) through that public method to the data in the private variable or constant. Java’s Package Private Modifier: Variables, Methods, and Classes in Your Package If no Java access control modifier keyword is declared, then a default access control level, which is also referred to as the package private access control level, will be applied to that Java construct (class, method, data field, or interface). This means that these Java constructs are visible, or available, to any other Java class inside the Java package that contains them. This package private level of access control is the easiest to use with your methods, constructors, constants, and variables, as it is applied simply by not explicitly declaring an access control modifier keyword. You will use this default access control level quite a bit for your own Java applications (game) programming, as usually you are creating your own application in your own package for your users to use in its compiled executable state. If you were developing game engines for other game developers to use, however, you would use more of the access control modifier keywords I have discussed in this section to control how others would use your code. Nonaccess Control Modifiers: final, static, abstract, volatile, synchronized The Java modifier keywords that do not specifically provide access control features to your Java constructs are termed nonaccess control modifier keywords. These include the often used final, static, and abstract modifier keywords as well as the not so often used synchronized and volatile modifier keywords, which are employed for more advanced thread control and which I will not be covering in this beginner-level programming title, except to describe what they mean and do, in case you encounter them in your Java universe travels. I will present these concepts in the order of their complexity, that is, from the easiest for beginners to wrap their mind around to the most difficult for beginning OOP developers to wrap their mind around. OOP is like surfing, in that it seems very difficult until you have practiced doing it a number of times, and then suddenly you just get it! 58 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Java’s final Modifier: Variables, Methods, and Classes That Cannot Be Modified You have already explored the final modifier keyword as it is used to declare a constant, along with a static keyword. A final data field variable can only be initialized (set) one time. A final reference variable, which is a special type of Java variable that contains a reference to an object in memory, cannot be changed (reassigned) to refer to a different object; the data that are held inside the (final) referenced object can be changed, however, as only the reference to the object itself is the final reference variable, which is essentially locked in, using a Java final keyword. A Java method can also be locked using the final modifier keyword. When a Java method is made final, if the Java class that contains that method is subclassed, that final method cannot be overridden, or modified, within the body of the subclass. This basically locks what is inside the method code structure. For example, if you want the .start() method for your InvinciBagel class (were it ever to be subclassed) always to do the same things that it does for your InvinciBagel superclass (prepare a JavaFX staging environment), you use the following code:   public class InvinciBagel extends Application { Button btn;   @Override public final void start(Stage primaryStage) { btn = new Button(); // The other method programming statements continue here } }   This prevents any subclasses (public class InvinciBagelReturns extends InvinciBagel) from changing anything regarding how the InvinciBagel game engine (JavaFX) is set up initially, which is what the .start() method does for your game application (see Chapter 4). A class that is declared using a final modifier keyword cannot be extended, or subclassed, locking that class for future use. Java’s Static Modifier: Variables or Methods That Exist in a Class (Not in Objects) As you have already seen, the static keyword can be used in conjunction with the final keyword to create a constant. The static keyword is used to create Java constructs (methods or variables) that exist independently, or outside, any object instances that are created using the class that static variables or static methods are defined in. A static variable in a class will force all instances of the class to share the data in that variable, almost as if it is a global variable as far as objects created from that class are concerned. Similarly, a static method will also exist outside instanced objects for that class and will be shared by all those objects. A static method will not reference variables outside itself, such as an instanced object’s variables. Generally, a static method will have its own internal (local or static) variables and constants and will also take in variables, using the method parameter list, and then provide processing and computation, based on those parameters and its own internal (static local) constants if needed. Because static is a concept that applies to instances of a class, and is thus at a lower level than any class itself, a class would not be declared using a static modifier keyword. Java’s Abstract Modifier: Classes and Methods to Be Extended and Implemented The Java abstract modifier keyword has more to do with protecting your actual code than with code that has been placed in memory (object instances and variables, and so on) at runtime. The abstract keyword allows you to specify how the code will be used as a superclass, that is, how it is implemented in a subclass once it is extended. For this reason, it applies only to classes and methods and not to data fields (variables and constants). 59 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles A class that has been declared using the abstract modifier keyword cannot be instanced, and it is intended to be used as a superclass (blueprint) to create (extend) other classes. Because a final class cannot be extended, you will not use the final and abstract modifier keywords together at the class level. If a class contains any methods that have been declared using the abstract modifier keyword, the class must itself be declared an abstract class. An abstract class does not have to contain any abstract methods, however. A method that has been declared using the abstract modifier keyword is a method that has been declared for use in subclasses but that has no current implementation. This means that it will have no Java code inside its method body, which, as you know, is delineated in Java by using curly braces. Any subclass that extends an abstract class must implement all these abstract methods, unless the subclass is also declared abstract, in which case the abstract methods are passed down to the next subclass level. Java’s Volatile Modifier: Advanced Multithreading Control over Data Fields The Java volatile modifier keyword is used when you are developing multithreaded applications, which you are not going to be doing in basic game development, as you want to optimize your game well enough so that it only uses one thread. The volatile modifier tells the Java virtual machine (JVM), which is running your application, to merge the private (that thread’s) copy of the data field (variable or constant) that has been declared volatile with the master copy of that variable in system memory. This is similar to the static modifier keyword, the difference being that a static variable (data field) is shared by more than one object instance, whereas a volatile data field (variable or constant) is shared by more than one thread. Java’s Synchronized Modifier: Advanced Multithreading Control over Methods The Java synchronized modifier keyword is also used when you are developing multithreaded applications, which you are not going to be doing for your basic game development here. The synchronized modifier tells the JVM, which is running your application, that the method that has been declared synchronized can be accessed by only one thread at a time. This concept is similar to that of synchronized database access, which prevents record access collisions. A synchronized modifier keyword likewise prevents collisions between threads accessing your method (in system memory) by serializing the access to one at a time so that parallel (simultaneous) access to a method in memory by multiple threads will never occur. Now that you have studied primary Java constructs (classes, methods, and fields) and basic modifier keywords (public, private, protected, static, final, abstract, and so on), let’s journey inside the curly braces now, learning about the tools that are used to create the Java programming logic that will eventually define your game app’s game play. Java Data Types: Defining Data Type in Applications Because you have already learned about variables and constants encountered in a few of Java’s data types, let’s explore these next, as it is not too advanced for your current progression from easy to more difficult topics! There are two primary data type classifications in Java: primitive data types, which are the ones that you are the most familiar with if you have used a different programming language, and reference (object) data types, which you will know about if you have used another OOP language, such as Lisp, Python, Objective-C, C++, or C# (C Sharp). Primitive Data Types: Characters, Numbers, and Boolean (Flags) There are eight primitive data types in the Java programming language, as shown in Table 3-1. You will be using these as you work your way through the book to create your InvinciBagel game, so I am not going to go into detail regarding each one of them now, except to say that Java boolean data variables are used for flags or switches (on/off ), char is used for Unicode characters or to create String objects (an array of char), and the rest are used to hold numeric 60 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles values of different sizes and resolutions. Integer values hold whole numbers, whereas a floating point value holds fractional (decimal point value) numbers. It is important to use the right numeric data type for a variable’s scope, or range, of use, because, as you can see in Binary Size column in Table 3-1, large numeric data types can use up to eight times more memory than the smaller ones. Table 3-1.  Java Primitive Data Types, Along with Their Default Values, Size in Memory, Definition, and Numeric Range Data Type Default Binary Size Definition Range boolean false 1 bit True or false value 0 to 1 (false or true) char \u0000 16 bit Unicode character \u0000 to \uFFFF byte 0 8 bit Signed integer value –128 to 127 (256 total values) short 0 16 bit Signed integer value –-32768 to 32767 (65,536 total values) int 0 32 bit Signed integer value –2147483648 to 2147483647 long 0 64 bit Signed integer value –9223372036854775808 to 9223372036854775807 float 0.0 32 bit IEEE 754 floating point value ±1.4E-45 to ±3.4028235E+38 double 0.0 64 bit IEEE 754 floating point value ±4.9E-324 to ±1.7976931348623157E+308 Reference Data Types: Objects and Arrays (OOP languages also have reference data types, which provide a reference in memory to another structure containing a more complex data structure, such as an object or an array. These more complex data structures are created using code; in the case of Java, this is a class. There are Java Array classes of various types that create arrays of data (such as simple databases) as well as the constructor method in a Java class, which can create the object structure in memory, containing both Java code (methods) and data (fields). Java Operators: Manipulating Data in the Application In this section, you will learn about some of the most commonly used operators in the Java programming language, especially those that are the most useful for programming games. These include arithmetic operators, used for mathematical expressions; relational operators, used to ascertain relationships (equal, not equal, greater than, less than, and so on) between data values; logical operators, used for boolean logic; assignment operators, which do the arithmetic operations and assign the value to another variable in one compact operation (operator); and the conditional operator, also called a ternary operator, which assigns a value to a variable, based on the outcome of a true or false (boolean) evaluation. There are also the conceptually more advanced bitwise operators, used to perform operations at the binary data (zeroes and ones) level, the logic of which is beyond the beginner scope of this book and the use of which is not as common in Java game programming as these other, more mainstream types of operators, each of which you will be using over the course of this book to accomplish various programming objectives in your game play logic. 61 www.it-ebooks.info 5 Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Java Arithmetic Operators The Java arithmetic operators are the most commonly used in programming, especially in arcade type games, in which things are moving on the screen by a discrete number of pixels. Many more complex equations can be created using these basic arithmetic operators, as you have already learned in math class, from primary school through college. The only arithmetic operators shown in Table 3-2 that you may not be that familiar with are the modulus operator, which will return the remainder (what is left over) after a divide operation is completed, and the increment and decrement operators, which add or subtract 1, respectively, from a value. These are used to implement your counter logic. Counters (using increment and decrement operators) were originally used for loops, (which I will be covering in the next section); however, these increment and decrement operators are also extremely useful for game programming (point scoring, life span loss, game piece movement, and similar progressions). Table 3-2.  Java Arithmetic Operators, Their Operation Type, and a Description of the Arithmetic Operation Operator Operation Description Plus + Addition Adds the operands on either side of the operator Minus – Subtraction Subtracts the right-hand operand from the left-hand operand Multiply * Multiplication Multiplies the operands on either side of the operator Divide / Division Divides the left-hand operand by the right-hand operand Modulus % Remainder Divides the left-hand operand by the right hand-operand, returning remainder Increment ++ Add 1 Increases the value of the operand by 1 Decrement -- Subtract 1 Decreases the value of the operand by 1 To implement the arithmetic operators, place the data field (variable) that you want to receive the results of the arithmetic operation on the left side of the equals assignment operator and the variables that you want to perform arithmetic operations on the right side of the equals sign. Here is an example of adding an x and a y variable and assigning the result to a z variable:   Z = X + Y; // Using an Addition Operator   If you want to subtract y from x, you use a minus sign rather than a plus sign; if you want to multiply the x and y values, you use an asterisk rather than a plus sign; and if you want to divide x by y, you use a forward slash instead of a plus sign. Here is how those operations look:   Z = X - Y; // Subtraction Operator Z = X * Y; // Multiplication Operator Z = X / Y; // Division Operator   You will be using these arithmetic operators quite a bit, so you will get some great practice with these before you are finished with this book! Let’s take a closer look at relational operators next, as sometimes you will want to compare values rather than calculate them. 62 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Java Relational Operators The Java relational operators are used to make logical comparisons between two variables or between a variable and a constant, in some circumstances. These should be familiar to you from school and include equals, not equal, greater than, less than, greater than or equal to, and less than or equal to. In Java, equal to uses two equals signs side by side between the data fields being compared and an exclamation point before an equals sign to denote “not equal to.” Table 3-3 shows the relational operators, along with an example and a description of each. Table 3-3.  Java Relational Operators, an Example in Which A = 25 and B = 50, and a Description of the Relational Operation Operator Example Description == (A == B) not true Comparison of two operands: if they are equal then the condition equates to true != (A != B) is true Comparison of two operands: if they are not equal the condition equates to true > (A > B) not true Comparison of two operands: if left operand is greater than right operand, equates to true < (A < B) is true Comparison of two operands: if left operand is less than right operand, equates to true >= (A >= B) not true Compare two operands: if left operand is greater or equal to right operand equates to true <= (A <= B) is true Compare two operands: if left operand less than or equal to right operand, equates to true The greater than symbol is a right-facing arrow-head, and the less than symbol is a left-facing arrow-head. These are used before the equals sign to create greater than or equal to and less than or equal to relational operators respectively, as you can see at the bottom of Table 3-3. These relational operators return a boolean value of true or false, and as such are also used in control (loop) structures in Java quite a bit, and are also used in gameplay programming logic as well to control the path (result) that the gameplay will take. For instance, let’s say you want to determine where the left edge of the game screen is so that the InvinciBagel does not travel right off of the screen when he is moving to the left. Using this relational comparison:   boolean changeDirection = false; // Create boolean variable changeDirection, initialize to false changeDirection = (invinciBagelX <= 0); // boolean changeDirection is TRUE if left side reached   Notice that I have used the <= less than or equal to (yes, Java supports negative numbers too), so that if the InvinciBagel has gone past the (x=0) left side of the screen the changeDirection boolean flag will be set to the value of true, and the sprite movement programming logic can deal with the situation, by changing the direction of movement (so InvinciBagel bounces off of the wall) or stopping the movement entirely (so the InvinciBagel sticks to the wall). You will be getting a lot of exposure to these relational operators during this book as they are quite useful in creating gameplay logic, so we are going to be having a lot of fun with these soon enough. Let’s take a look at logical operators next, so we can work with Boolean Sets and compare things in groups, which is also important for games. 63 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Java Logical Operators: The Java logical operators are similar to the boolean operations (union, intersection, etc.) that you learned about in school, and allow you to determine if both boolean variables hold the same value (AND), or if one of the boolean variables is different (OR), from the other. There’s also a NOT operator that reverses the value of any of the compared boolean operands. Table 3-4 shows Java’s three logical operators, and an example of each, along with a description. Table 3-4.  Java Logical Operators, an Example in Which A = True and B = False, and a Description of Logical Operation Operator Example Description && (A && B) is false A logical AND operator equates to true when BOTH operands are the same value. || (A || B) is true A logical OR operator equates to true when EITHER operand is the same value. ! !(A && B) is true A logical NOT operator reverses the logical state of the operator (or set) it is applied to. Let’s use logical operators to enhance the game logic example in the previous section by including the direction in which the InvinciBagel is moving on the screen. The existing facingDirection String variable will control the direction the InvinciBagel is facing (and moving in, if in motion). You can now use the following logical operator to determine if the InvinciBagel is facing left (W, or West); if the travelingWest boolean variable is true; AND if the hit (or passed) boolean variable on the left-hand side of the screen, hitLeftSideScrn, is also equal to true. The modified code for doing this will include two more boolean variable declarations and initializations and will look like this:   boolean changeDirection = false; // Create boolean variable changeDirection, initialize to false boolean hitLeftSideScrn = false; // Create boolean variable hitLeftSideScrn, initialize to false boolean travelingWest = false; // Create boolean variable travelingWest, initialize to false hitLeftSideScrn = (invinciBagelX <= 0); // boolean hitLeftSideScrn is TRUE if left side reached travelingWest = (facingDirection == "W") // boolean travelingWest is TRUE if facingDirection="W" changeDirection = (hitLeftSideScrn && travelingWest) // Change Direction, if both equate to TRUE   To find out if the InvinciBagel is facing (or traveling, if also moving) West, you create another travelingWest boolean variable and initialize it (set it equal) to false (because your initial facingDirection setting is East). Then, you create a boolean variable called hitLeftSideScrn, setting that to the (invinciBagelX <= 0) relational operator statement. Finally, you create a relational operator statement with the travelingWest = (facingDirection == "W") logic, and then you are ready to use the changeDirection boolean variable with your new logical operator. This logical operator will make sure that both the hitLeftSideScrn and travelingWest boolean variables are set to true, using the changeDirection = (hitLeftSideScrn && travelingWest) logical operation programming statement. Now, you have a little practice declaring and initializing variables and using relational and logical operators to determine the direction and location of a primary game piece (called a sprite in arcade games; for more on game design lingo, see Chapter 6). Next, let’s take a look at assignment operators. Java Assignment Operators The Java assignment operators assign a value from a logic construct on the right-hand side of the assignment operator to a variable on the left-hand side of the assignment operator. The most common assignment operator is also the most commonly used operator in the Java programming language, the equals operator. The equals operator can be prefaced with any of the arithmetic operators to create an assignment operator that also performs an arithmetic operation, as can be seen in Table 3-5. This allows a more “dense” programming statement to be created when the variable itself is going to be part of the equation. Thus, instead of having to write C = C + A , you can simply use C+=A and achieve the same end result. You will be using this assignment operator shortcut often in your game logic design. 64 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Table 3-5.  Java Assignment Operators, What Each Assignment Is Equal to in Code, and a Description of the Operator Operator Example Description = C=A+B Basic assignment operator: Assigns value from right-hand operand to left-hand operand += C+=A equals C=C+A ADD assignment operator: Adds right-hand operand to left-hand operand; puts result in left-hand operand -= C-=A equals C=C-A SUB assignment operator: Subtracts right-hand operand from left-hand operand; puts result in left-hand operand *= C*=A equals C=C*A MULT assignment operator: Multiplies right-hand operand and left-hand operand; puts result in left-hand operand /= C/=A equals C=C/A DIV assignment operator: Divides left-hand operand by right-hand operand; puts result in left-hand operand %= C%=A equals C=C%A MOD assignment operator: Divides left-hand operand by right-hand operand; puts remainder in left-hand operand Finally, you are going to take a look at conditional operators, which also allow you to code powerful game logic. Java Conditional Operators The Java language also has a conditional operator that can evaluate a condition and make a variable assignment for you, based on the resolution of that condition, using only one compact programming construct. The generic Java programming statement for a conditional operator always uses the following basic format:   Variable = (evaluated expression) ? Set this value if TRUE : Set this value if FALSE ;   So, on the left-hand side of the equals sign, you have the variable, which is going to change (be set), based on what is on the right-hand side of the equals sign. This conforms to what you have learned thus far. On the right-hand side of the equals sign, you have an evaluated expression, for instance, “x is equal to 3,” followed by a question mark and then two numeric values that are separated from each other, using the colon, and, finally, a semicolon to terminate the conditional operator statement. If you wanted to set a variable y to a value of 25 if x is equal to 3, and to 10 if x is not equal to 3, you would write that conditional operator programming statement by using the following Java programming logic:   y = (x == 3) ? 25 : 10 ;   Next, you are going to look at Java logic control structures that leverage the operators you just learned about. Java Conditional Control: Decision Making or Loops As you have just seen, many of the Java operators can have a fairly complex structure and provide a lot of processing power, using very few characters of Java programming logic. Java also has several more complicated conditional control structures, which can automatically make decisions or perform repetitive tasks for you, once you have set up the conditions for those decisions or task repetitions by coding the Java logic control structure. 65 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles In this section, you will first explore decision-making control structures, such as the Java switch-case structure and the if-else structure. Then, you will take a look at Java’s looping control structures, including for, while, and do-while. Decision-Making Control Structures: Switch-Case and If-Else Some of the most powerful Java logic control structures allow you to define decisions that you want your program logic to make for you as the application is running. One such structure offers a case-by-case, “flat” decision matrix; the other has a cascading (if this, do this; if not, do this; if not, do this; and so on) type of structure that evaluates things in the order in which you want them examined. Let’s start by looking at the Java switch statement, which uses the Java switch keyword and an expression at the top of this decision tree and then uses the Java case keyword to provide Java statement blocks for each outcome for this expression’s evaluation. If none of the cases inside a switch statement structure (curly braces) are called (used) by the expression evaluation, you can also supply a Java default keyword and Java statement code block for what you want done. The variable used in the case statements can be one of four Java data types: char (character), byte, short, or int (integer). You will generally want to add a Java break keyword at the end of each of your case statement code blocks, at least in the use case, in which the values being switched between need to be exclusive, and only one is viable (or permissible) for each invocation of the switch statement. The default statement, which is the “if any of these do not match” is the last of the statements inside of the switch, and does not need this break keyword. If you do not furnish a Java break keyword in each of your case logic blocks, more than one case statement can be evaluated in the same pass through your switch statement. This would be done as your expression evaluation tree progresses from top (first case code block) to bottom (last case code block or default keyword code block). So if you had a collection of Boolean “flags” such as hasValue, isAlive, isFixed, and so on, these could all be processed on one single “pass” by using a switch-case statement structure that does not use any break statements at all. The significance of this is that you can create some fairly complex decision trees, based on case statement evaluation order, and whether you put this break keyword at the end of any given case statement’s code block. The general format for your switch-case decision tree programming construct would look like this:   switch(expression) { case value1 : programming statement one; programming statement two; break; case value2 : programming statement one; programming statement two; break; default : programming statement one; programming statement two; }   Let’s say you want to have a decision in your game as to which InvinciBagel death animation is called when the InvinciBagel is hit (shot, slimed, punched, and so on). The death animation routine (method) would be called, based on the InvinciBagel’s state of activity when he or she is hit, such as flying (F), jumping (J), running (R), or idle 66 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles (I). Let’s say these states are held in a data field called ibState, of the type char, which holds a single character. The switch-case code construct for using these game-piece state indicators to call the correct method, once a hit has occurred, would be:   switch(ibState) { // Evaluate ibState char and execute case code blocks accordingly case 'F' : deathLogicFlying(); // Java method controlling death sequence if InvinciBagel flying break; case 'J' : deathLogicJumping(); // Java method controlling death sequence if InvinciBagel jumping break; case 'R' : deathLogicRunning(); // Java method controlling death sequence if InvinciBagel running break; default : deathLogicIdle(); // Java method controlling death sequence if InvinciBagel is idle   This switch-case logic construct evaluates the ibState char variable inside the evaluation portion of the switch() statement (note that this is a Java method) and then provides a case logic block for each of the game-piece states (flying, jumping, running) and a default logic block for the idle state (which is a logical way to set this up). Because a game piece cannot be idle, running, flying, and jumping at the same time, you need to use the break keyword to make each of the branches of this decision tree unique (exclusive). The switch-case decision-making construct is generally considered more efficient, and faster, than the if-else decision-making structure, which can use just the if keyword for simple evaluations, like this:   if(expression = true) { programming statement one; programming statement two; }   You can also add an else keyword to make this decision-making structure evaluate statements that would need to execute if the boolean variable (true or false condition) evaluates to false rather than true, which makes this structure more powerful (and useful). This general programming construct would then look like this:   if(expression = true) { programming statement one; programming statement two; } else { // Execute this code block if (expression = false) programming statement one; programming statement two; }   In addition, you can nest if-else structures, thereby creating if{}-{else if}-{else if}-else{} structures. If these structures get nested too deeply, then you would want to switch (no pun intended) over to the switch-case structure, which will become more and more efficient, relative to a nested if-case structure, the deeper the if-else nesting goes. For example, the switch-case statement that you coded earlier for the InvinciBagel game, if translated into a nested if-else decision-making construct, would look like the following Java programming structure:   if(ibState = 'F') { deathLogicFlying(); } else if(ibState = 'J') { deathLogicJumping(); 67 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles } else if(ibState = 'R') { deathLogicRunning(); } else { deathLogicIdle(); }   As you can see, this if-else decision tree structure is quite similar to the switch-case that you created earlier, except that the decision code structures are nested inside each other rather than contained in a flat structure. As a rule of thumb, I would use the if and if-else for one- and two-value evaluations and a switch-case for three-value evaluation scenarios and greater. I use this switch-case structure extensively in my books covering Android. Next, let’s take a look at the other types of conditional control structures that are used extensively in Java, the looping programming structures. These allow you to execute a block of programming statements a predefined number of times (using the for loop) or until an objective is achieved (using a while or a do-while loop). Looping Control Structures: While, Do-While, and For Whereas the decision tree type of control structure is traversed a fixed number of times (once all the way through, unless a break [switch-case] or resolved expression [if-else] is encountered), looping control structures keep executing over time, which, with respect to the while and do-while structures, makes them a bit dangerous, as an infinite loop can be generated, if you are not careful with your programming logic! The for loop structure executes for a finite number of loops (the number is specified in the definition of the for loop), as you will soon see in this section. Let’s start with the finite loop, covering the for loop first. A Java for loop uses the following general format:   for(initialization; boolean expression; update equation) { programming statement one; programming statement two; }   As you can see, the three parts of the evaluation area of the for loop are inside the parentheses, separated by semicolons, as each contains a programming statement. The first is a variable declaration and initialization, the second is a boolean expression evaluation, and the third is an update equation showing how to increment the loop during each pass. To move the InvinciBagel 40 pixels diagonally on the screen, along both X and Y, the for loop is as follows:   for(int x=0; x < 40; x = x + 1) { // Note: an x = x + 1 statement could also be coded as x++ invinciBagelX++; // Note: invinciBagelX++ could be coded invinciBagelX = invinciBagelX + 1; invinciBagelY++; // Note: invinciBagelY++ could be coded invinciBagelY = invinciBagelY + 1; }   In contrast, the while (or do-while) type of loop does not execute over a finite number of processing cycles, but rather executes the statements inside the loop until a condition is met, using the following structure:   while(boolean expression) { programming statement one; programming statement two; }   68 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles To code the for loop to move the InvinciBagel 40 pixels, using a while loop structure, looks like this:   int x = 0; while(x < 40) { invinciBagelX++; invinciBagelY++; x++ }   The only difference between a do-while loop and a while loop is that, with the latter, the loop logic programming statements are performed before, instead of after, the evaluation. Thus, using a do-while loop programming structure, the previous example would be written as follows:   int x = 0; do { invinciBagelX++; invinciBagelY++; x++ } while(x < 40);   As you can see, the Java programming logic structure is inside curly braces, following the Java do keyword, with the while statement after the closing brace. Note that the while evaluation statement (and therefore the entire construct) must be terminated with a semicolon. If you want to make sure that the programming logic inside the while loop structure is performed at least one time, use the do-while, as the evaluation is performed after the loop logic is executed. If you want to make sure that the logic inside the loop is only executed after (whenever) the evaluation is successful, which is the safer way to code things, use the while loop structure. Java Objects: Virtual Reality, Using Java Constructs I saved the best, Java objects, for last, because they can be constructed in one fashion or another using all the concepts that I have covered thus far in the chapter and because they are the foundation of OOP language (in this case, Java 8). The fact is, everything in the Java 8 programming language is based on Java’s Object superclass (I like to call it the masterclass), which is in the java.lang package, so an import statement for it would reference java.lang.Object, the full pathname for the Java Object class. Java objects are used to “virtualize” reality by allowing the objects you see all around you in everyday life, or, in the case of your game, objects you are creating out from your imagination, to be realistically simulated. This is done by using the data fields (variables and constants) and the methods that you have been learning about in this chapter. These Java programming constructs will make up the object characteristics, or attributes (constants); states (variables); and behaviors (methods). The Java class construct organizes each object definition (constants, variables, and methods) and gives birth to an instance of that object, using the constructor method for the class that designs and defines the object via the various Java keywords and constructs. Creating an InvinciBagel Object: Attributes, States, and Behavior Let’s put together an example of an InvinciBagel object that shows how constants define characteristics, variables define states, and methods define behaviors. We will do this using Java coding constructs that you have learned about thus far in the chapter, including constants, variables, and methods that you have already defined, to some extent. 69 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Let’s start with characteristics, which are things about an object that will not change and which are thus represented using constants, variables that will not (cannot) change. An important bagel characteristic is the type (flavor). We all have our favorites; mine are plain, egg, rye, onion, and pumpernickel. Another characteristic is the size of bagel; as we all know, there are minibagels, normal-size bagels, and giant bagels.   private static final String FLAVOR_OF_BAGEL = "Pumpernickel"; private static final String SIZE_OF_BAGEL = "Mini Bagel";   Thus, constants are used to define the characteristics, or attributes, of an object. If you are defining a car, boat, or plane, the color (paint), engine (type), and transmission (type) are attributes (constants), as they generally do not change, unless you are a mechanic or own a body shop! Things about an object that will change, such as its location, orientation, how it is traveling (flying, driving, walking, running), and so on are called states and are defined using variables, which can constantly change in real time, based on what is happening in real life. These variables will allow any Java object to mimic, or virtualize, the real-world object that they are creating in your Java universe’s virtual reality. This is, of course, especially true in games, which is why the topic of this book, Java and games, is especially relevant and applicable. There will be more states (variables) than attributes (constants) for the InvinciBagel, as it is the game piece and will be especially active trying to save its hole and score points. Some of the states that you will want to define as variables include screen (x, y) location, orientation, travel direction, travel type, hits taken, and life span used.   public int invinciBagelX = 0; // X screen location of the InvinciBagel public int invinciBagelY = 0; // Y screen location of the InvinciBagel public String bagelOrientation = "side"; // Defines bagel orientation (front, side, top) public int lifeIndex = 1000; // Defines units of lifespan used public int hitsIndex = 0; // Defines units of damage (hits taken) public String directionFacing = "E"; // Direction that the object is facing public String movementType = "idle" // Type of movement (idle, fly, run, jump) public boolean currentlyMoving = false; // Flag showing if the object is in motion   As you progress through this book and create the InvinciBagel game, you will be adding attributes, states, and behaviors that will make the InvinciBagel, as well as its game environment and game play, more realistic, fun, and exciting, just as you would do in real life. In fact, you are using Java objects and Java constructs to model, a realistic virtual world in which InvinciBagel players can triumph over evil and shoot cream cheese balls at delicious targets. Let’s look at a couple of the methods that you might develop to control the InvinciBagel behavior. You will be creating complex methods over the course of this book to accomplish game play objectives, so I am just going to give you an idea here of how methods provide behaviors to objects for the purpose of demonstrating how objects can be created that reflect how real-world objects function. For your game play of the InvinciBagel, the main behaviors will be 2D movement around the screen, relative to the x (width) and y (height) dimension, which will access, use, and update the integer invinciBagelX, invinciBagelY, and the boolean currentlyMoving data fields discussed previously; the InvinciBagel character’s orientation (front facing, sideways, facing down, and so on), which will access, use, and update the bagelOrientation String field; the life expectancy of the InvinciBagel, which will access, use, and update the lifeIndex variable; the health of the InvinciBagel, which will access, use, and update the hitsIndex variable; the direction (East or West) in which the InvinciBagel is traveling, which will access, use, and update the directionFacing String variable; and the type of movement (flying, jumping, running, idle) that the InvinciBagel is using , which will access, use, and update the movementType String variable. Here is how you declare these methods (behaviors) and pseudocode regarding what they are going to do:   public void moveInvinciBagel(int x, int y) { currentlyMoving = true; invinciBagelX = x; invinciBagelY = y; 70 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles }   public String getInvinciBagelOrientation() { return bagelOrientation; }   public void setInvinciBagelOrientation(String orientation) { bagelOrientation = orientation; }   public int getInvinciBagelLifeIndex() { return lifeIndex; }   public void setInvinciBagelLifeIndex(int lifespan) { lifeIndex = lifespan; }   public String getInvinciBagelDirection() { return directionFacing; }   public void setInvinciBagelDirection(String direction) { directionFacing = direction; }   public int getInvinciBagelHitsIndex() { return hitsIndex; }   public void setInvinciBagelHitsIndex(int damage) { hitsIndex = damage; }   public String getInvinciBagelMovementType() { return movementType; }   public void setInvinciBagelMovementType(String movement) { movementType = movement; }   The convention is to create .get() and .set() methods, as is done here. These allow your Java code to easily access your object states (variables). Now, it is time to install all these attributes (constants), states (variables), and behaviors (methods) into a blueprint for your object. As mentioned earlier, this is done using the Java class programming structure. 71 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles Creating an InvinciBagel Blueprint: Create the GamePiece Class Let’s install all this InvinciBagel virtualization code into a GamePiece class to create a class and constructor method that is intended for game-piece objects:   public class GamePiece   private static final String FLAVOR_OF_BAGEL = "Pumpernickel"; // Flavor (or type) of bagel private static final String SIZE_OF_BAGEL = "Mini Bagel"; // Size (classification) of bagel   public int invinciBagelX = 0; // X screen location of the InvinciBagel public int invinciBagelY = 0; // Y screen location of the InvinciBagel public String bagelOrientation = "side"; // Define bagel orientation (front, side, top) public int lifeIndex = 1000; // Defines units of lifespan used public int hitsIndex = 0; // Defines units of damage (hits taken) public String directionFacing = "E"; // Direction that the bagel object is facing public String movementType = "idle"; // Type of movement (idle, fly, run, jump) public boolean currentlyMoving = false; // Flag showing if the object is in motion   public void moveInvinciBagel(int x, int y) { // Movement Behavior currentlyMoving = true; invinciBagelX = x; invinciBagelY = y; }   public String getInvinciBagelOrientation() { // Get Method for Orientation return bagelOrientation; }   public void setInvinciBagelOrientation(String orientation) { // Set Method for Orientation bagelOrientation = orientation; }   public int getInvinciBagelLifeIndex() { // Get Method for Lifespan return lifeIndex; }   public void setInvinciBagelLifeIndex(int lifespan) { // Set Method for Lifespan lifeIndex = lifespan; }   public String getInvinciBagelDirection() { // Get Method for Facing Direction return directionFacing; }   public void setInvinciBagelDirection(String direction) { // Set Method for Direction directionFacing = direction; }   public int getInvinciBagelHitsIndex() { // Get Method for Hits (damage) return hitsIndex; }   72 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles public void setInvinciBagelHitsIndex(int damage) { hitsIndex = damage; } // Set Method for Hits (damage)   public String getInvinciBagelMovementType() { return movementType; } // Get Method for Movement Type   public void setInvinciBagelMovementType(String movement) { movementType = movement; } // Set Method for Movement Type }   It is important to note that these constants, variables, and methods are for demonstration of how the class, method, and data field keywords let developers create (virtualize) their game components. As you develop the game, these will probably change, as game development is a process of refinement, in which you will be constantly changing and enhancing the Java code base to add features and capabilities. Now, all you have to do is add your GamePiece() constructor method, which will create a new object with the initialized variable settings that you want the default GamePiece to contain. Then, you will create the second overloaded constructor method. This second constructor method will allow parameters to be passed into a constructor method so that you can provide custom (nondefault) settings to these same variables (states). In this way, if you call GamePiece(), you get a default object; if you call GamePiece(parameter list here), you get a custom object. Creating a GamePiece() Constructor: Overloading a GamePiece Finally, let’s create the constructor method (two, actually), which takes the states (variables) from the GamePiece class and creates a default object. You will use this object to create the custom overloaded constructor method. The first constructor method will employ the package private access control method, using no access modifier keyword, so that any code in the invincibagel package can call this constructor method. Then, you will set your default variables, using the following Java code:   GamePiece() { invinciBagelX = 0; invinciBagelY = 0; bagelOrientation = "side"; lifeIndex = 1000; hitsIndex = 0; directionFacing = "E"; movementType = "idle"; currentlyMoving = false; }   The overloaded constructor method will have parameters declared in the method parameter list area for those variables that are logical to allow variations for upon object creation. The only two that are not logical to allow variations for are hitsIndex (a new object will not have sustained any damage points and will thus need to be 0) and 73 www.it-ebooks.info Chapter 3 ■ A Java 8 Primer: An Introduction to Java 8 Concepts and Principles currentlyMoving (a new object will not be moving when it appears, even if that is only for a fraction of a second) variables, which you will initialize, as you did for the default constructor. The other five variables (states) will be set using parameters passed in via a parameter list, using an equals assignment operator. This is done using the following code:   GamePiece(int x, int y, String orientation, int lifespan, String direction, String movement) { invinciBagelX = x; invinciBagelY = y; bagelOrientation = orientation; lifeIndex = lifespan; hitsIndex = 0; directionFacing = direction; movementType = movement; currentlyMoving = false; }   I bolded the variables in the parameter list, as well as where they are used inside the constructor method, to set the states (variables) for the object. These variables are declared at the top of the GamePiece class, which you have used to design, define, and create the GamePiece object. This second constructor method can be said to overload the first constructor method, because it uses the exact same method call (method name), with a different parameter list (full of parameters, versus empty or no parameters). This gives you the default object constructor method as well as a custom object constructor method, so in your game logic, you can create a default GamePiece or a custom GamePiece. Summary In this third chapter you took a look at some of the more important concepts and structures found in the Java 8 programming language. Certainly, I cannot cover everything in Java in one chapter, so I stuck with concepts, constructs, and keywords that you will be using to create a game over the course of this book. Most Java books are 800 pages or more, so if you want to get really deep into Java, I suggest Beginning Java 8 Fundamentals by Kishori Sharan (Apress, 2014). You started by taking a high-level view of Java, considering its syntax, including Java comments and delimiters, APIs, and the Java packages that a Java API contains. You also studied Java classes, including nested classes and inner classes, as the Java packages contain Java classes. You then went the next level down in Java, to the method, which is like the function in other programming languages, as well as to a special kind of Java method called a constructor method. Next, you explored how Java represents data, using fields, or data fields, examining the different types, such as constants, or fixed data fields, and variables, or data fields that can change their values. After that, you took a closer look at Java modifier keywords, including the public, private, and protected access control keywords and the final, static, abstract, volatile, and synchronized nonaccess control modifier keywords. After finishing with the basic code structures and how to modify them, you moved on to the primary Java data types, such as boolean, char, byte, int, float, short, long, and double and then explored the Java operators that are used to process, or bridge, these data types over to your programming logic. You studied arithmetic operators, for use with numeric values; logical operators, for use with boolean values; relational operators, to consider relationships between data values; conditional operators, which allow you to establish any conditional variable assignments; and assignment operators, which let you assign values to (or between) variables. Then, you looked at Java logic control structures, including decision-making control structures (I like to call them decision trees) and looping, or iterative, logic control structures. You learned about the Java switch-case structure, the if-else structure, the for loop structure, and the do-while loop structures. Finally, you examined Java objects and discovered how to define object attributes, states, and behaviors, using a Java class, methods, and constructor methods. In the next chapter, I will give you an overview of the JavaFX multimedia engine, and its classes and capabilities, as you will be leveraging JavaFX to add media elements to your games, such as images, video, and audio, and to control your games, using JavaFX object constructs (classes), such as the Stage, Scene, and StackPane. 74 www.it-ebooks.info Chapter 4 An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Let’s build on the knowledge of the Java programming language that you gained in the previous chapter here in Chapter 4, by learning about the capabilities, components, and classes that make up the JavaFX 8 multimedia engine. This amazing JavaFX 8 API was added to Java 8 using the javafx package that you saw in Chapters 2 and 3, which was released with Java 8. The JavaFX 8 package is significant to game programming because it contains advanced forms of classes that you will want to harness for game programming, including classes for organizing game components, using a scene graph; classes for user interface layout and design; classes for 2D digital illustration (also called vector graphics); and classes for digital imaging (also called raster graphics); 2D animation; digital video; digital audio; 3D; a web engine (WebKit); and much more, all of which I will be covering in this chapter, so that you know exactly what you have available to you, now that these JavaFX 8 libraries have been added into the Java 8 programming language. The rationale for going into such detail is not only so that you know what JavaFX 8.0 can do for your Java 8 game development, but also so that you have an overview of how the various components of this JavaFX multimedia engine are put together. You will learn about the JavaFX Quantum Toolkit, the Prism rendering technology, the WebKit web engine, the Glass Windowing Toolkit, the audio and video Media engine, and the Scene Graph API. The reason you will need this high-level overview of how JavaFX works before you actually start to use it in your games is because it is a fairly complex set of APIs (I like to call it an engine). This is due to the power that it brings to implementing user interface (UI) and user experience (UX) “wins” in your Java 8 applications (in this case, games). So, bear with me in these foundational chapters detailing how to master your IDE (NetBeans 8.0), your programming language (Java 8), and this new media engine (JavaFX 8) that is now a part of the Java 8 programming platform that is rapidly growing in power and popularity internationally. Once you have examined how JavaFX 8.0 comes together at the highest level (just like you did in Chapter 3), you will consider some of those key classes that you might be using to construct Java 8 games, such as the Node class as well as the Stage, Scene, Group, StackPane, Animation, Layout, Shape, Geometry, Control, Media, Image, Camera, Effect, Canvas, and Paint classes. You have already studied the JavaFX Application class (see Chapters 2 and 3), so now you will focus on the classes that can be used to build complex multimedia projects, such as Java 8 games. Finally, you will take an in-depth look at the bootstrap JavaFX application that you generated in Chapter 2, and at how the Java .main() method and the JavaFX .start() method create the primaryStage Stage object, using the Stage() constructor method, and, inside of that, create your Scene object named scene, using the Scene() constructor method. You will explore how to use methods from the Stage class to set the scene and title and show the Stage as well as how to create and use the StackPane and Button class (objects), and add an EventHandler to a Button. 75 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Overview of JavaFX: From Scene Graph Down to OS As in the previous chapter, on Java 8, I am starting this overview of JavaFX at the highest level, with the Scene Graph API and with visual editing tools, which are contained in a JavaFX application called Scene Builder, which we will not be using (Scene Builder is for application UI design not game design); we will use GIMP instead. As you observed in Chapter 1 (see Figure 1-5), Scene Builder is integrated into NetBeans 8.0 (JavaFX is listed as being supported specifically for use in NetBeans, primarily because Scene Builder has been made an integral part of NetBeans GUI). As Figure 4-1 demonstrates, these JavaFX application-building tools exist “on top of” the JavaFX 8 API (a collection of javafx packages, such as javafx.scene and javafx.application), which is what ultimately allows you to build (using Scene Graph) and UI design (using Scene Builder) your JavaFX new media creations (in this case, a Java 8 game). Note that the JavaFX 8.0 API is connected (here, using steel bearings, to denote plugs) not only to Scene Graph and Scene Builder, above it, but also to Java JDK 8 and the Quantum Toolkit, below it. As you can see, Java JDK 8 (and APIs) then connects the JavaFX new media engine to NetBeans, the JVM, and the various platforms that Java currently supports as well as to future platforms, such as Android 4 (32-bit Android), Android 5 (64-bit Android) and iOS. Figure 4-1.  How JavaFX 8 is stratified, from the Scene Graph at the top down through Java 8, NetBeans 8.0, JVMs, and OSs The Quantum Toolkit, which is connected to the JavaFX 8.0 API, ties together all the powerful new media engines that you are going to be learning about. The Quantum Toolkit also handles the thread management for all of these, so your game code, and your game’s new media (audio, video, 3D, and so on), can use separate processors on the dualcore, quadcore, hexacore and octacore CPUs that are so commonplace in today’s computers and consumer electronics devices. The Glass Windowing Toolkit controls window management for JavaFX 8.0, and is responsible for all of the discrete areas on the display screen, such as the stage and pop-up windows, including dialogs. Glass also manages the event processing queue, passing events up to JavaFX for processing, and sets up timers. As you can see in the figure, there is also a WebKit engine and a Media (player) engine, which are managed by the Quantum Toolkit. The WebKit engine renders your HTML5 and CSS3 web content, and the media player media playback engine plays your digital audio and digital video assets, respectively. The most important new media engine below the Quantum Toolkit is the Prism (game) engine, which renders 2D content, using Java 2D, and 3D content, using either OpenGL (Mac, Linux, Embedded OSs) or DirectX if your users are on the Windows Vista, Windows 7, or Windows 8.1 platform. Windows XP support was discontinued in April 2014, as most computers and consumer electronics devices out now are 64-bit capable (XP was 32-bit only). 76 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Prism bridges the powerful 3D game engines (DirectX, OpenGL) that are on the major OS platforms as well as on consumer electronics (embedded) devices so JavaFX 8.0 can offload complex rendering task processing to graphics processing unit (GPU) hardware from NVIDIA (GeForce), AMD (ATI Radeon), and Intel. This makes JavaFX (and thus Java 8) games faster and allows games to use less CPU processing power for rendering game assets to the screen. This in turn allows more CPU processing power be used for game play logic, such as AI and collision detection. You will be learning about these areas of game design after you master the JavaFX engine in this fourth chapter of the book. It is important to note that game developers do not need to understand the inner workings of the Quantum (threading), Glass (windowing), or Prism (rendering) engines to be able to take advantage of their amazingly powerful features. Throughout the book, you are going to be focusing on the top level (Scene Graph and Scene Builder) as well as the JavaFX and Java 8 API levels of the diagram. I will also be covering the NetBeans IDE 8.0 level, which you learned about in Chapter 2 but which you will also be exploring much further during the remainder of this book. As for the lower levels of the diagram, NetBeans 8.0 will generate a Java bytecode file that is read by the custom JVM for each of the OS platforms. The JVM, illustrated at the bottom of the figure, can be installed for any given OS platform by downloading a Java 8 JRE, which you already encountered in Chapter 1, when you installed it as part of Java JDK 8. This JVM layer lets your game be installed as an application across all popular OS platforms as well as on embedded devices, which are also moving to support JavaFX 8. Furthermore, you can generate your Java 8 game as a Java applet, which can be embedded in a web site, and there is even a deployment model, in which the application can be dragged out of the web site and onto your desktop, where it is installed as a full-fledged Java 8 application. In addition, there is already a way to run JavaFX 8 applications on iOS 8, and Android 4.4 and 5.0. If you are interested in the latest information on this, simply google “JavaFX on Android,” or “JavaFX on iOS,”; you can bet that by 2015, Android 5.0 and Chrome OS devices will be running JavaFX applications “natively,” meaning that you will someday (soon) be able to export Java (and JavaFX engine) applications directly to Android 5.0, using IntelliJ, or to Chrome OS, using NetBeans 8.0. You should eventually be able to “code once, run everywhere” with this Java 8 and JavaFX 8.0 dynamic duo! Oracle recently released Java 8 SE Embedded, Java 8 ME and Java 8 ME Embedded versions, all of which support JavaFX. ■■Note The JetBrains IntelliJ IDEA is now the official IDE used for creating 64-bit Android 5.0 applications. This IDE is examined in my Android Apps for Absolute Beginners, 3rd Edition (Apress, 2014), which covers developing 32-bit Android 4.0 applications, using an Eclipse IDE and Java 6, and 64-bit Android 5.0 applications, using an IntelliJ IDEA and Java 7. Let’s start at the top of the diagram, and take a look at the JavaFX Scene Graph and the javafx.scene package, which implements Scene Graph in the JavaFX API (you will look at Scene Builder in the next chapter). JavaFX Scene Package: 16 Core Java 8 Classes The first thing I want to do after our high-level overview is present one of the most important JavaFX packages, the javafx.scene package. In Chapters 2 and 3, you discovered that there is more than one JavaFX package. As you saw in Chapter 3 (see Figure 3-1), the InvinciBagel game application uses four different JavaFX packages. The javafx. scene package contains 16 powerful Java 8 classes (remember, JavaFX was recoded in Java 8), including the Camera, ParallelCamera and PerspectiveCamera, Cursor and ImageCursor, LightBase, PointLight, and AmbientLight classes; the Scene Graph classes (Node, Parent, Group, and SubScene); and some utility classes (see Figure 4-2). 77 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Figure 4-2.  The javafx.scene package and its 16-core Scene Graph, Scene utility, Lighting, Camera, and Cursor classes I have grouped these 16 javafx.scene package classes logically. The Scene class is inside the Scene Graph section of the diagram, because Scene objects, which are created using the Scene class, contain Scene Graph objects, which are created using these four Scene Graph–related classes (Node, Parent, Group, SubScene) and their subclasses. I will be covering the Scene Graph classes in detail later in the chapter (see the section “JavaFX Scene Graph: Organizing Scenes, Using Parent Nodes.” Scene Graph architecting classes in JavaFX start at the highest level, with a Node superclass, and its Parent class, and include the Group and SubScene classes, which are subclasses of the Parent class. These core classes are used to create the JavaFX Scene Graph hierarchy and to organize and group objects that have been created using the other JavaFX classes in the JavaFX packages. There are three Scene utility classes, as I call them, which allow you to take a snapshot (like a screenshot) of your scene or any of its Scene Graph nodes at any time as well as to turn SceneAntialiasing on and off if you are using 3D primitives in a scene. The other half (eight) of the classes in the javafx.scene package are used for scene lighting, scene cameras, and cursor control for your scene. I will be discussing these classes later in the chapter (see the section “JavaFx Scene Content: Lights, Camera, Cursor, Action!”), after you take a look at the Scene Graph classes, which create, group, manage, and manipulate your JavaFX scene content. Thus, I will be covering the javafx.scene package classes shown in the figure, from the left-hand side of the diagram to the right-hand side, in the order in which you are most likely to use them, from least to most. JavaFX Scene Class: Scene Size and Color and Scene Graph Nodes The two primary classes in the javafx.scene package are the Scene class and the Node class. I will be covering the Node class and its Parent, Group, and SubScene subclasses in the next section, as those classes, along with their subclasses (such as the StackPane class used in the InvinciBagel class) are used to implement the Scene Graph architecture in JavaFX. Also, in a sense (and in my diagram) the Node class and its subclasses can be viewed as being below the Scene class, although the Node class is not a subclass of the Scene class. In fact, the Node (Scene Graph) class and subclasses, or rather the objects created using these classes, are contained inside the Scene object itself. For this reason, you will first consider how the Scene class, and its Scene() constructor method, is used to create Scene objects for JavaFX applications. This section will provide reinforcement of what you learned in Chapter 3 regarding overloading constructor methods, as there needs to be several different ways to create a Scene object. 78 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine The Scene class is used to create a Scene object, using the Scene() constructor class, which takes between one and five parameters, depending on which of the six (overloaded) constructor methods you choose to use. These include the following constructor methods, along with their six different (and thus overloaded) parameter list data field configurations:   Scene(Parent root) Scene(Parent root, double width, double height) Scene(Parent root, double width, double height, boolean depthBuffer) Scene(Parent root, double width, double height, boolean depthBuffer, SceneAntialiasing aAlias) Scene(Parent root, double width, double height, Paint fill) Scene(Parent root, Paint fill)   The constructor currently used in your bootstrap Java and JavaFX code is the second one, called as follows:   Scene scene = new Scene(root, 300, 250);   If you wanted to add a black background to the scene, you would select the fifth overloaded constructor method, using a Color.BLACK constant from the Color class (this is a Paint object, because Color is a Paint subclass) as your fill data (in this case, a fill Color). You would do this by using the following Scene() object constructor method call:   Scene scene = new Scene(root, 300, 250, Color.BLACK);   Note that the root object is a Parent subclass, called the StackPane class, created using the StackPane() constructor method (two lines above the Scene() constructor method call) by using the following line of Java code:   StackPane root = new StackPane(); // StackPane subclassed from Parent, so Parent root satisfied   As you can see, any class can be used in the constructor that is a subclass of the object (class) type that is declared (required) for that constructor parameter position (data). You are able to use Color and StackPane objects in your parameter list because they have superclass origins from the Paint and Parent classes, respectively. In case you are wondering, the Boolean depthBuffer parameter is used for 3D scene components. Because these scene components are 3D and have depth (a z component, in addition to 2D x and y components), you will need to include this parameter, and set it to a value of true, if you are creating 3D scenes or combining 2D and 3D scene components. Finally, the SceneAntialiasing object (and class) that is passed in the parameter list for the fourth constructor method provides real-time smoothing for 3D scene components. JavaFX Scene Graph: Organizing Scenes, Using Parent Nodes A scene graph, which is not unique to JavaFX and which can be seen in quite a few new media content creation software packages, is a data structure that resembles an upside-down tree, with the root node at the top and branch nodes and leaf nodes coming off the root node. The first time I saw a scene graph approach to design was when I was 3D modeling using a software package on the Amiga called Real 3D from Realsoft Oy. This approach has been copied by many 3D, digital video, and digital imaging software packages since then and now is a part of how JavaFX organizes content and scenes. For this reason, many of you may be familiar (and comfortable) with this design paradigm. JavaFX Scene Graph data structure allows you not only to architect, organize, and design your JavaFX scene and its content, but also to apply opacity, states, event handlers, transformations, and special effects to entire logical branches of the Scene Graph hierarchy if you set up the Scene Graph correctly. Figure 4-3 shows the basic Scene Graph tree, with the root node at the top and branch and leaf nodes below it. 79 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Figure 4-3.  JavaFX Scene Graph hierarchy, starting with the root node and progressing to branch and leaf nodes The root node is the topmost node, which is why it is called the root, even though it is at the top, not the bottom, like a root would be in the plant world. A root node has no parent, that is, nothing above it in the Scene Graph hierarchy. A root node is itself a parent to the branch nodes and leaf nodes below it. The next most powerful (and complex) construct in the Scene Graph tree is the branch node, which uses the javafx.scene.Parent class as its superclass and which can contain children (this is logical, as it extends a class aptly named Parent). A branch node can contain other branch nodes, as well as leaf nodes, so it can be used to create some very complicated and powerful Scene Graph hierarchy (or Scene Graph architecture) constructs. The last level in the hierarchy is the leaf node. A leaf node is the end of the branch and, as such, cannot have children. It is important to note that leaf nodes can come directly off the root node, as you can see in Figure 4-3. Branch nodes can be created by using the Parent, Group, or SubScene classes (see Figure 4-2) or any of their subclasses, such as the WebView, PopupControl, Region, Pane, or StackPane class. Examples of leaf nodes include JavaFX classes (as objects), which can be configured using parameters, such as shapes, text, or an ImageView, but which are design or content components, in and of themselves, and have not been designed to have children (child objects). A leaf node will therefore always contain a JavaFX class that has not been subclassed (extended) from the Parent class, and that has not itself been specifically designed to have child elements (child objects) within it, or below it, in the JavaFX Scene Graph hierarchy. The four subclasses of the Parent class can all be used as branch nodes and include the Group class, for grouping child (leaf node) objects, so that opacity, transforms, and effects can be applied to them; the Region class, for grouping child (leaf node) objects to form screen layouts, which can also be styled using CSS; the Control class, which can be used to create custom user interface elements (called controls in JavaFX); and the WebView class, which is used to contain the JavaFX WebEngine class (this class renders HTML5 and CSS3 content into a WebView). JavaFX Scene Content: Lights, Camera, Cursor, Action! Next, let’s take a look at the eight classes listed in the center column in Figure 4-2. They provide powerful multimedia tools for controlling your application’s cursor as well as custom lighting special effects and custom camera capabilities for your 2D and 3D JavaFX applications (in this case, games, but they could also be e-books, or iTV shows, or anything else that requires the powerful new media capabilities that JavaFX offers via the Java language). The more generalized classes (Cursor, LightBase, Camera) in the figure are parent classes, and the more specialized ones (ImageCursor, PointLight, ParallelCamera, and so on) listed after each of those are the subclasses of those parent classes. Except the LightBase class, that seems to be stating the obvious! As you may have guessed (correctly), the JavaFX Cursor class can be used to control the application cursor graphic (arrow, hand, closed hand, crosshair, and so on) being used at any given time. The ImageCursor subclass can be used to define and supply a custom image-based cursor as well as an x and a y location within the custom cursor image that defines where its point (also called the cursor hot spot) is located. 80 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine The LightBase class, and its PointLight and AmbientLight subclasses, can be used to light your scenes. These classes are primarily used for 3D scenes, and they require 3D capabilities on any platform that the game is running on, which is not really a problem these days, as most of the major CPU manufacturers also make (and include) GPUs. Also, it is important to note that the Prism game engine will simulate a 3D environment (GPU), using 3D processing emulation, if one is not available on the platform that is rendering the game. In addition, if you set it up correctly, you can use the lighting classes with your 2D games or use lighting with a hybrid 2D-3D game. The Camera class, and its ParallelCamera and PerspectiveCamera subclasses, can be used to photograph or video your scene in 3D and 2D (and hybrid) game applications. Two of the camera classes, Camera and ParallelCamera, do not require that 3D (GPU) capabilities be present on the platform that is playing your JavaFX application (in this case, a game). The subclasses of the Camera class provide two different, specialized types of cameras. The ParallelCamera class can be used for rendering scenes without any depth perspective correction, which in the 3D industry is called an orthographic projection. What this means is that this class is perfect for use with 2D scenes (and for 2D games). The PerspectiveCamera class has a much more complex camera, used for 3D scenes, which will support 3D viewing volumes. Like the LightBase class and its subclasses, the PerspectiveCamera class requires 3D capabilities on the hardware platform that the application (or game) is running on. The PerspectiveCamera class has a fieldOfView attribute (state or variable), which can be used to change its viewing volume, just like a real camera zoom lens, when you zoom it in from wide angle. The default setting for the fieldOfView attribute is an acute angle of 30 degrees. If you remember your geometry from high school, you can visualize this field of view by looking down the y (vertical) axis at the camera. As you might expect, there are .getFieldOfView() and .setFieldOfView(double) method calls to control this camera class attribute. Next, let’s take a closer look at the Scene utility classes. After that, you will examine some of the javafx.scene subpackages, such as javafx.scene.text, javafx.scene.image, javafx.scene.shape, and javafx.scene.layout. JavaFX Scene Utilities: Scene Snapshots and Antialiasing Finally, you should take a quick look at the three utility classes, shown in the right-hand column in Figure 4-2, as they can be used to improve the quality of scene output on the user’s device’s screen (using antialiasing) as well as to provide screen capture capabilities to either your user (for social media sharing) or your game play logic itself. Let’s investigate the SceneAntialiasing class first. Antialiasing is a digital imaging industry term that references an algorithm that smoothes jagged edges where two colors come together, usually on a diagonal line or in the circular area of an image composite. An image composite is two separate images placed in layers to form one image. Sometimes, the edges between the image components of these two (or more) image layers will need to be smoothed. Smoothing (antialiasing) is required so that a final composite looks like it is one seamless image, which is the intention of the artist or game designer. Interestingly, you are already implementing the JavaFX “layer engine” in your InvinciBagel application, using the StackPane class (panes are layers). The “layer stack” image-compositing approach is common in games as well as in software, such as Photoshop and GIMP. The SceneAntialiasing class offers antialiasing processing (algorithm) to 3D scenes so that they can be composited over your 2D scene background, whether that is the default, Color.WHITE, or any other color value; a 2D image (creating a hybrid 2D-3D application); or anything else, for that matter. The SceneAntialiasing class allows you to set the static SceneAntialiasing data field to a value of DISABLED (turn antialiasing off ) or BALANCED (turn antialiasing on). The balanced option gives a balance of quality and performance, which simply means that the more processing power the device’s hardware brings to the table, the more antialiasing quality will be processed. Next, let’s explore the SnapshotParameters class (object), which is used to set up (contain) a rendering attribute parameter that will be used by the SnapshotResult class (object). The parameters include the type of Camera (parallel or perspective) object to be used; whether the depthBuffer (used for 3D) is on (true for 3D) or off (false for 2D); a Paint object, used to contain the image data; a Transform object, used to contain any transform data; and a Rectangle2D object, used to define the viewport area to be rendered (i.e., the snapshot dimensions). You will be looking at all these javafx.scene subpackage classes and concepts in this chapter as well as using many of them over the course of this book. Much of the functionality that you will be tapping into for your Java 8 game development will be found in these JavaFX 8.0 subpackages. 81 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine The SnapshotResult class (and, more important, the object created using this class) contains your resulting snapshot image data, the parameters that generated it, and the source node in the scene graph that it was generated from. For this reason, the three methods supported by the class should be obvious: the .getImage() method will get a snapshot image, the .getSource() method gets the source node information, and the .getSnapshotParameters() method will get the SnapshotParameters object contents. Scene Subpackages: The 13 Other Scene Packages You may be thinking, “Whew! That was a lot to cover in that javafx.scene package overview!,” and indeed the core javafx.scene package has a lot of classes in it, covering scene creation; scene graph organization; and scene utilities, such as lighting, cameras, cursors, and screenshots (or should we call these sceneshots?). There is a lot more in the javafx.scene package, in subpackages, as I call them, or packages that are below the javafx.scene package, referenced using another dot and another package name (description). In fact, there are 13 more javafx.scene packages (see in Table 4-1), covering things such as drawing, painting, charting, UI design, imaging, special effects, media (audio and video) playback, input-output, text, shapes (2D geometry), transforms, and web page (content created with HTML5, JavaScript and CSS3) rendering. You are going to explore these scene package classes in this section. Table 4-1.  Thirteen Second-Level JavaFX Scene Subpackages, Their Primary Functions, and a Description of Classes Package Name Functions Description of Contents javafx.scene.canvas Drawing Canvas class (and Canvas object); for a custom drawing surface javafx.scene.chart Charting Chart classes: PieChart, LineChart, XYChart, BarChart, AreaChart, BubbleChart javafx.scene.control UI controls UI control classes: Button, Menu, Slider, Label, ScrollBar, TextField javafx.scene.effect Special effects Special effects classes: Glow, Blend, Bloom, Shadow, Reflection, MotionBlur javafx.scene.image imaging Digital imaging classes: Image, ImageView, WritableImageView, PixelFormat javafx.scene.input Input (Events) Classes related to getting input from the user into the JavaFX application javafx.scene.layout UI layouts UI layout container classes: TilePane, GridPane, FlowPane, Border javafx.scene.media Media player Media playback classes: MediaPlayer, MediaView, Track, AudioTrack, AudioClip javafx.scene.paint Painting Paint classes: Paint, Color, LinearGradient, RadialGradient, Stop, Material, and so on javafx.scene.shape Geometry 2D and 3D geometry classes: Mesh, Shape, Shape3D, Arc, Circle, Line, Path, and so on javafx.scene.text Text and font Text rendering and font rendering classes: Font, Text, TextFlow, and so on javafx.scene.transform Transforms Transform classes: Transform, Scale, Rotate, Shear, Translate, Affine javafx.scene.web WebKit Web support classes: WebView, WebEvent, WebEngine, HTMLEditor 82 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Let’s start with the packages that have the fewest classes. The table lists subpackages alphabetically, but the first one, javafx.scene.canvas, coincidentally contains only one class, the Canvas class, which, as its name suggests, is employed to create a Canvas object that is used as a canvas for you to create things with! The next subpackage listed is javafx.scene.chart; this has charting classes, such as PieChart, LineChart, XYChart, BarChart, AreaChart, and BubbleChart, for use in business applications, which is a different book entirely, so I will not be covering charting. The next subpackage, javafx.scene.control, offers all the UI control (“widget,” in Android) classes, such as Button, Menu, CheckBox, RadioButton, DatePicker, ColorPicker, ProgressBar, Slider, Label, Scrollbar, and TextField and about eight dozen others. Because there are approximately a hundred classes in javafx.scene.control, I am not even going to attempt to cover it here; an entire book could probably be written about this subpackage! If you want to review these classes, simply reference “javafx.scene.control” on Google or on the Oracle Java website, and you can peruse what these classes can do for days on end. For this subpackage, “reference” is the key word, as you will want to reference this package and its classes individually at the time you need to implement a given UI element. The next subpackage, javafx.scene.effect, provides all the special effects classes, almost two dozen of them. These can be very useful for Java 8 game development, so this is one of the few subpackages that I am going to cover in detail in this section. The javafx.scene.image subpackage is used to implement digital imagery within JavaFX, and it has the Image, ImageView, WritableImage, PixelFormat, and WritablePixelFormat classes. The ImageView class is what you will normally use to hold your digital image assets, and the more advanced PixelFormat classes let you create digital imagery on a pixel-by-pixel basis if you want to do more advanced (algorithmic) pixel-based digital image creation. The javafx.scene.input subpackage includes classes that are used to get input from the JavaFX application’s user. This input is processed using the event handling capabilities, which you will be examining in great detail over the course of this book and which you have already experienced in your JavaFX application, in Chapter 3 (see Figure 3-2, ll. 22 to 24). The javafx.scene.layout subpackage contains classes that are used to create UI design layouts and that can be used for your screen layout designs as well. These layout classes include classes that control and manage backgrounds; add and style borders; and provide UI pane management, such as StackPane, TilePane, GridPane, FlowPane, and AnchorPane. These UI classes offer automatic screen layout algorithms for the UI controls in JavaFX. The Background class (and subclasses) furnishes screen background utilities, and the Border class (and its subclasses) supplies screen border utilities, which can be used for spicing up the graphics design for your UI screens. The javafx.scene.media subpackage holds classes that are used for the playback of audio or video media, including the Media, MediaPlayer, and MediaView classes. The Media class (or object, actually) references and contains the media (audio or video) asset, MediaPlayer plays that asset, and MediaView (in the case of video) displays the asset. This subpackage also has a Track superclass and AudioTrack, VideoTrack, and SubtitleTrack subclasses as well as the AudioClip, AudioEqualizer, and EquilizerBand classes, which provide advanced audio (equalizer) controls and short-form audio clips, or snippets of audio that are perfect for use in games. You will be using the AudioClip class later in the book (see Chapter 15). The javafx.scene.paint subpackage contains a Stop class and the Paint superclass and its Color, ImagePattern, LinearGradient, and RadialGradient subclasses as well as the Material superclass and its PhongMaterial subclass. Those of you who are familiar with 3D content production will recognize this Phong shader algorithm, which will allow different surface looks (plastic, rubber, and so on) to be simulated. The Material and PhongMaterial classes need 3D capabilities to be present on the playback hardware to function successfully, just like the SceneAntialiasing, PerspectiveCamera, and LightBase class (and subclasses). The Paint class creates your Paint object, the Color class colors this object (fills it with a color), the LinearGradient and RadialGradient classes fill the Paint object with color gradients, and the Stop class lets you define where gradient colors start and stop inside the gradients. Finally, there is an ImagePattern class, which can fill a Paint object with a tileable image pattern (this can be quite useful for games). The javafx.scene.shape subpackage provides classes for 2D geometry (commonly referred to as shapes) as well as for 3D geometry (commonly referred to as meshes). A Mesh superclass and its TriangleMesh subclass handle 3D geometry, as do the Shape3D superclass and its Box, Sphere, Cylinder, and MeshView subclasses. The Shape superclass has many more subclasses (11); these are 2D geometry elements and include the Arc, Circle, CubicCurve, Ellipse, Line, Path, Polygon, Polyline, QuadCurve, Rectangle, and SVGPath classes. A path support, a path being defined as an open shape (I like to call it a spline, as I am a 3D modeler), is also supplied by the PathElement superclass and its ArcTo, ClosePath, CubicCurveTo, HLineTo, LineTo, MoveTo, QuadCurveTo, and VLineTo subclasses, which allows you to draw spline curves to create your own custom shapes! 83 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine The javafx.scene.text subpackage has classes for rendering text shapes and fonts into your scenes. This includes the Font class, for employing any fonts that you may want to use that are not a JavaFX system font, as well as the Text class, for creating a text node that will display the text values using this font. There is also a specialized layout container class, called TextFlow, which is used to flow text, much like you would see done on a word processor. The javafx.scene.transform subpackage offers classes for rendering 2D and 3D spatial transformations, such as the Scale, Rotate, Shear, Translate, and Affine (3D rotation) subclasses of the Transform superclass. These can be applied to any Node object in the Scene Graph. This allows anything in your scene graph (text, UI controls, shapes, meshes, images, media, and so on) to be transformed in any way that you like, which affords JavaFX game developers a ton of creative power. In case you are wondering, translation is linear movement of an entire object; shear is linear movement on a 2D plane in two different directions or movement in one direction when another part of the 2D plane is fixed. Imagine moving the top of a plane, while the bottom remains fixed, such that the square becomes a parallelogram, or moving the top and bottom of the same plane (a square) in different directions. The javafx.scene.web subpackage furnishes classes for rendering web assets into a scene, using a collection of classes, including WebView, WebEvent, WebEngine, WebHistory, and HTMLEditor. The WebEngine (see, other people call things engines as well) class, as you might imagine, does the processing for showing HTML5 + CSS3 + JS in JavaFX, and the WebView class creates the node for displaying the WebEngine output in the Scene Graph. The WebHistory class (object, ultimately) holds the session history (from WebEngine instantiation to removal from memory) for the web pages visited, and WebEvent bridges the JavaScript web event processing with the JavaFX event processing. Now that you have looked at a plethora of important and useful classes (objects) in the javafx.scene package and its related subpackages, let’s take a look at the 15 top-level JavaFX packages to get a better idea of the key capabilities that JavaFX offers for application development (focusing of course, on those that can be used for game development). Other JavaFX Packages: The 15 Top-Level Packages There are 15 top-level packages (javafx.packagename being what I consider a top-level package), some of which have subpackage levels as well, as you have seen with the javafx.scene package and subpackages. Table 4-2 gives an overview of these packages and describes their contents. Table 4-2.  JavaFX Top-Level Packages, Their Primary Functions, and a Description of Their Functional Classes Package Name Functions Description of Contents javafx.animation Animation Timeline, Transition, AnimationTimer, Interpolator, KeyFrame, KeyValue javafx.application Application Application (init, start, stop methods), Preloader, Parameters, Platform javafx.beans JavaFX beans Java interfaces that define the most generic form of observability javafx.collections Collections Java collections that define the most generic form of observability javafx.concurrent Threading Threading classes: Task, Service, ScheduledService, WorkerStateEvent javafx.css CSS Classes related to implementing CSS in JavaFX javafx.embed Embeds Embeds deprecated Java Swing and Java AWT GUI paradigms javafx.event Event handler Event handling classes: Event, ActionEvent, EventType, WeakEventHandler javafx.fxml FXML FXML javafx.geometry 3D geometry 3D geometry classes (continued) 84 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Table 4-2.  (continued) Package Name Functions Description of Contents javafx.print Printing Printing classes javafx.scene Scene control Classes related to scene creation, organization, control, and realization javafx.stage Stage creation Stage creation classes javafx.util JavaFX utility JavaFX utility classes netscape.javascript JavaScript Allows Java code to invoke JavaScript methods and examine JavaScript properties I have discussed some of these already, such as the javafx.application package (see Chapters 2 and 3) and the javafx.scene package (see the section “JavaFX Scene Package: Sixteen Powerful Java 8 Classes”). There are a few other JavaFX packages that you should take a closer look at here, as they (along with the javafx.scene package) contain classes that you will want to use in your Java 8 game development (still others, such as the javafx.print, javafx.fxml, javafx.beans, and javafx.embed packages are not likely to be used in your Java game design and development work process); these are javafx.animation, javafx.stage, javafx.geometry, javafx.concurrent, and javafx.event. Let’s take an in-depth look at what these packages provide for your game development objectives next. JavaFX Animation for Games: Using javafx.animation Classes The javafx.animation package contains the Animation superclass, which has the Timeline and Transition subclasses as well as the AnimationTimer, Interpolator, KeyFrame, and KeyValue classes. Animation is an important design element in Java 8 games, and these animation classes are already coded for us, thanks to JavaFX, so all you have to do to add animation to your games is use them properly! The JavaFX Animation Class: The Foundation for Animation Objects The Animation class (or object, actually) provides the core functionality of animation in JavaFX. The Animation class contains two (overloaded) Animation() constructor methods; these are Animation() and Animation(double targetFramerate), and they will create in memory the Animation object, which will control an animation and its playback characteristics and life cycle. The Animation class contains the .play() method, the .playFrom(cuePoint) or .playFrom(Duration time) method, and a .playFromStart() method. These methods are used to start playback for the Animation object. There are also the .pause() method, which can pause the animation playback, and a .stop() method, to stop animation playback. The .jumpTo(Duration time) and .jumpTo(cuePoint) methods are used to jump to predefined positions in an animation. You can set the animation playback speed (also called the frame rate or frames per second [FPS]) by using the rate property. The cycleCount property (variable) allows you to specify how many times an animation will loop, and a delay property lets you specify a delay time before the animation starts. If your animation is looping, this delay property will specify the delay time between loops, which can help you create some realistic effects. You can specify a seamless animation loop by setting the cycleCount attribute or property (variable) to INDEFINITE and then using the autoReverse property (set to false), or you can use pong (back and forth) animation looping by specifying the true value for the autoReverse property. You can also set the cycleCount to a numeric value (use 1 if you want the animation to play only one time) if you do not want the animation to loop indefinitely. The .setRate() method sets the animation playback rate property, the .setDelay() method sets the delay property, and the .setCycleCount() and .setCycleDuration() methods control the cycling characteristics. There are also similar .get() methods to “get” the currently set values for these Animation object variables (properties, attributes, parameters, or characteristics; however you prefer to look at these data fields is fine). 85 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine You can assign an action to be executed when the animation has completed playback, using the onFinished property loaded with an ActionEvent object. The action will be executed when the animation reaches the end of each loop, and, as you can imagine, some very powerful things can be triggered in a game with this particular capability. There are also read-only variables (properties), which you can “poll” at any time to find the status, currentTime, currentRate, cycleDuration, and totalDuration for each Animation object. For example, you can use the currentTime property to see the position of the playback head (frame pointer) at any point in time in the animation playback cycle. The JavaFX TimeLine Class: An Animation Subclass for Property Timeline Management The JavaFX Timeline class is a subclass of the JavaFX Animation superclass, so its inheritance hierarchy starts with the Java 8 masterclass, java.lang.Object, progressing down to the Timeline class, as follows:   > java.lang.Object > javafx.animation.Animation > javafx.animation.Timeline   A Timeline object can be used to define a special kind of Animation object that is composed of JavaFX values (properties) of the object type WritableValue. Because all JavaFX properties are of that type, this class can be used to animate anything in JavaFX, which means that its use is limited only by your imagination. As mentioned earlier, Timeline animations are defined using KeyFrame objects, created via the KeyFrame class, which both creates and manages these objects. A KeyFrame object is processed by a Timeline object, according to a time variable (accessed via KeyFrame.time) and properties to be animated, which are defined using the KeyFrame object’s values variable (accessed via KeyFrame.values). It is important to note that you need to set up your KeyFrame objects before you start running the Timeline object, as you cannot change a KeyFrame object within a running Timeline object. This is because it is put into system memory once it has been started. If you want to change a KeyFrame object in a running Timeline object in any way, first, stop the Timeline object; then, make the change to the KeyFrame; and, finally, start the Timeline object again. This will reload the Timeline object and its revised KeyFrame objects into memory with their new values. The Interpolator class interpolates these KeyFrame.values in the Timeline object, based on the timeline direction. Interpolation is a process of creating in-between (or tween) frames, based on the beginning and ending values. In case you are wondering how the direction is inferred, it is kept in the rate and the read-only currentRate property of the Animation superclass (which is a part of the extended Timeline subclass). Inverting the value of the rate property (i.e., making it negative) will reverse (toggle) the playback direction; the same principle holds when reading the currentRate property (a negative value signifies the reverse, or backward, direction). Finally, the KeyValue class (object) is used to hold the values inside the KeyFrame object. The JavaFX Transition Class: An Animation Subclass for Transition Effects Application The JavaFX Transition class is a subclass of the JavaFX Animation superclass, so its inheritance hierarchy starts with the Java 8 masterclass, java.lang.Object, progressing down to the Transition class, as follows:   > java.lang.Object > javafx.animation.Animation > javafx.animation.Transition   The Transition class is a public abstract class, and, as such, it can only be used (subclassed or extended) to create transition subclasses. In fact, ten of these subclasses have already been created for you to use to create your own transition special effects; these are the SequentialTransition, FadeTransition, FillTransition, PathTransition, PauseTransition, RotateTransition, ScaleTransition, TranslateTransition, ParallelTransition, and StrokeTransition classes. As a subclass of Animation, the Transition class contains all the functionality of Animation. 86 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Chances are you will end up using the ten custom transition classes directly, as they provide the different types of transitions you are likely to want to use (fades, fills, path based, stroke based, rotate, scale, movement, and so on). I am going to move on to the AnimationTimer class next, as we will be using this class for our game engine during the book. The JavaFX AnimationTimer Class: Frame Processing, Nanoseconds, and Pulse The JavaFX AnimationTimer class is not a subclass of the JavaFX Animation superclass, so its inheritance hierarchy starts with the Java 8 masterclass, java.lang.Object, and looks like this:   > java.lang.Object > javafx.animation.AnimationTimer   What this means is that the AnimationTimer class is scratch coded specifically to offer AnimationTimer functionality to JavaFX and that it is not related to the Animation (or Timeline or Transition) class or subclasses in any way. For this reason, the name of this class may be somewhat misleading if you are mentally grouping the class in with the Animation, Interpolator, KeyFrame, and KeyValue classes that occupy the javafx.animation package with it, as is has no relation to these classes whatsoever! Like the Transition class, the AnimationTimer class has been declared a public abstract class. Because it is an abstract class, it can only be used (subclassed or extended) to create AnimationTimer subclasses. Unlike the Transition class, it has no subclasses that have been created for you; you have to create your own AnimationTimer subclasses from scratch, which we will be doing later on in the book to create our GamePlayLoop.java class. The AnimationTimer class is deceptively simple, in that it has only one method that you must override or replace, contained in the public abstract class: the .handle() method. This method provides the programming logic that you want to have executed on every frame of the JavaFX engine’s stage and scene processing cycle, which is optimized to play at 60FPS (this is perfect for games). JavaFX uses a pulse system, which is based on the new Java 8 nanosecond unit of time (previous versions of Java used milliseconds). JavaFX Pulse Synchronization: Asynchronous Processing for Scene Graph Elements A JavaFX pulse is a type of synchronization (timing) event, one that synchronizes the states of the elements that are contained within any given Scene Graph structure that you create for your JavaFX applications (games). The pulse system in JavaFX is administered by the Glass Windowing Toolkit. Pulse uses high-resolution (nanosecond) timers, which are also available to Java programmers using the System.nanoTime() method, as of the Java 8 API. The pulse management system in JavaFX is capped or throttled to 60FPS. This is so that all the JavaFX threads have the “processing headroom” to do what they need to do. A JavaFX application will automatically spawn up to three threads, based on what you are doing in your application logic. A basic business application will probably only use the primary JavaFX thread, but a 3D game will also spawn the Prism rendering thread, and if that game uses audio or video, or both, which it usually will, it will spawn a media playback thread as well. You will be using audio, 2D, 3D, and possibly video in the course of your game development journey, so your JavaFX game application will certainly be multithreaded! As you will see, JavaFX has been designed to be able to create games that take advantage of multithreading and nanosecond timing capabilities and 3D rendering hardware (Prism) support. Whenever something is changed in the Scene Graph, such as a UI control positioning, a CSS style definition, or an animation playing, a pulse event is scheduled and is eventually fired to synchronize the states of elements on the Scene Graph. The trick in JavaFX game design is to optimize pulse events so that they are focusing on the game play logic (animation, collision detection, and so on); thus, you will minimize the other changes (UI control location, CSS style changes, and so on) the pulse engine looks at. You will do this by using the Scene Graph as a fixed design system, meaning that you will use the Scene Graph to design your game structure but will not manipulate nodes in real time on the Scene Graph, using dynamic programming logic, as the pulse system will perform the updates. 87 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine A JavaFX pulse system allows developers to handle events asynchronously, like a batch processing system that schedules tasks on the nanosecond level, instead of once a day, like batch processing schedulers from the old mainframe computer days. Next, let’s examine how to schedule code in a pulse, using a .handle() method. Harnessing the JavaFX Pulse Engine: Extending the AnimationTimer Class to Generate Pulse Events Extending the AnimationTimer class is a great way to get the JavaFX pulse system to process your code for each pulse that it processes. Your real-time game programming logic will be placed inside the .handle(long now) method and can be started and stopped at will by using the other two AnimationTimer methods, .start() and .stop(). The .start() and .stop() methods are called from the AnimationTimer superclass, although the two methods can be overridden as well; just be sure eventually to call super.start() and super.stop() in your override code methods. If added as an inner class inside your current JavaFX public void .start() method structure, the code structure might look as follows (see Chapter 3, Figure 3-2):   public void start(Stage primaryStage) { Button btn = new Button; new AnimationTimer() { @Override public void handle(long now) { // Program logic that gets processed on every pulse that JavaFX processes } }.start(); }   The above programming logic shows how an AnimationTimer inner class would be constructed as well as how Java dot chaining works. The .start() method call to the AnimationTimer superclass is appended to the end of the new AnimationTimer(){. . .} code construct so that the entire AnimationTimer creation (using new), declaration (using the curly braces), and execution (using a .start() method call) are chained to the AnimationTimer object construct. If you want to create a more complex AnimationTimer subclass for something central to your game logic, such as Collision Detection, it would be a better idea (Java code design approach) to make this game logic its very own custom AnimationTimer subclass. This is especially true if you are going to be creating more than one AnimationTimer subclass to do pulse event–controlled high-speed processing. That’s right, you can have more than one AnimationTimer subclass running at the same time (just do not get carried away and use too many AnimationTimers). You can accomplish this with the extends keyword, creating your own AnimationTimer class, called GamePlayLoop, using the following class definition:   public class GamePlayLoop extends AnimationTimer { @Override public void handle(long now) { // Program logic that gets processed on every pulse that JavaFX processes } @Override public void start() { super.start(); } 88 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine @Override public void stop() { super.stop(); } }   Next, let’s investigate the JavaFX Stage class (object),which is passed into your InvinciBagel .start() method! JavaFX Screen and Window Control: Using javafx.stage Classes The javafx.stage package contains classes that can be considered top level, in terms of the display for your JavaFX application (in this case, a game). This display is at the top of the resulting game play, because it shows your game’s scenes to the end user of your application. Inside the Stage object are Scene objects, and inside these are Scene Graph Node objects, which contain the elements that make up an application. In contrast, the classes that are in this package could be considered fairly low level, from an OS perspective; these are the Stage, Screen, Window, WindowEvent, PopupWindow, Popup, DirectoryChooser, and FileChooser classes as well as the FileChooser.ExtensionFilter nested class. These classes can be used to interface with the device’s display hardware, and the OS software’s windowing management, file management, and directory (folder) management functionality. To get a description of the display hardware that is being used by the device that a JavaFX application is running on, you will want to use the Screen class. This class supports multiscreen (commonly referred to as second screen) scenarios, using the .getScreens() method, which can access an ObservableList object that will contain a list (array) with all the currently available screens. A primary screen is accessed using the .getPrimary() method call. You can get the physical resolution for the primary screen hardware by using a .getDpi() method call. There are also .getBounds() and .getVisualBounds() method calls for usable resolution. The Window superclass, and its Stage and PopupWindow subclasses, can be used by the JavaFX end user to interact with your application. As you saw in Chapter 3 (see Figure 3-2), this is done using the Stage object named primaryStage, which is passed into your .start() method, or using a PopupWindow (dialog, tool tip, context menu, notification, and so on) subclass, such as a Popup or PopupControl object. You can use the Stage class to create secondary stages within your JavaFX application programming logic. A primary Stage object is always constructed by the JavaFX platform, using the public void start(Stage primaryStage) method call, as you have already seen in Chapters 2 and 3 in the bootstrap JavaFX application created by NetBeans. All JavaFX Stage objects must be constructed using, and modified inside the primary JavaFX application thread, which I discussed in the previous section. Because a stage equates to a window on the OS platform it is running on, certain attributes or properties are read-only, as they need to be controlled at the OS level; these are Boolean properties (variables): alwaysOnTop, fullScreen, iconified, and maximized. All Stage objects have a StageStyle attribute and a Modality attribute, which can be set using constants. The stageStyle constants are StageStyle.DECORATED, StageStyle.UNDECORATED, StageStyle.TRANSPARENT, and StageStyle.UTILITY. The Modality constants are Modality.NONE, Modality.APPLICATION_MODAL, and Modality. WINDOW_MODAL. In the next section, I will show you how to do something really impressive using the StageStyle attribute and the TRANSPARENT constant that will make your JavaFX applications stand out from everyone else’s in the marketplace. The Popup class can be used to create custom pop-up notifications, and even custom game components, from scratch. Alternately, you can use the PopupControl class, and its ContextMenu and Tooltip subclasses, to provide these predefined (coded) JavaFX UI controls. The DirectoryChooser and FileChooser classes give support for passing through the standard OS file selection and directory navigation dialogs into your JavaFX applications. The FileChooser.ExtensionFilter nested class offers a utility for filtering the files that will come up in the FileChooser dialog, based on file type (file extension). Next, let’s take your current InvinciBagel Stage object to the next level and make it a windowless (floating) application. This is one of the impressive features of JavaFX that cannot be matched by Flash or other game engines. 89 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Using a JavaFX Primary Stage Object: Creating a Floating Windowless Application Let’s make the primary Stage for your InvinciBagel application transparent so that the Button UI control floats right on top of the OS desktop. This is something that JavaFX can do that you do not see very often, and it allows you to create 3D applications that float on top of the OS desktop (for 3D virtual objects, this is called a windowless ActiveX control). This is accomplished by using the StageStyle.TRANSPARENT constant, in conjunction with the .initStyle() method, from the Stage class. As Figure 4-4 demonstrates, I also used the technique I told you about in Chapter 3 (a technique that does not follow the proper Java coding convention regarding declaring an import statement for classes you are planning to use). In line 35 of the code, I reference the constant by using the fully qualified class name (package.subpackage.class.constant), javafx.stage.StageStyle.TRANSPARENT, inside the primaryStage. initStyle(StageStyle style) method call. This is done via the following line of Java code:   primaryStage.initStyle(javafx.stage.StageStyle.TRANSPARENT);   Figure 4-4.  Call an .initStyle() method with the StageStyle.TRANSPARENT constant, off the primaryStage Stage object As you can, I clicked the primaryStage Stage object in NetBeans IDE 8.0, in the code editing area, and it shows (tracks) the usage of that object in the code. The Stage object is set up (displaying title, style, and scene), using the .setTitle(), .initStyle(), .setScene(), and .show() method calls. I am going to leave the .setTitle() method call in the code, but make a mental note that once you get this windowless application treatment working, the title bar is part of the window’s “chrome,” or UI elements, and when these are gone (including the title bar), this setting of the title will amount to a moot point. If you have been worrying about memory optimization, at this point in the application development work process, you would remove the .setTitle() method call, because the title would not be shown using a StageStyle. TRANSPARENT constant for the StageStyle attribute. 90 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Next, use the Run icon (or Run menu), and run the application. As Figure 4-5 illustrates, what you are trying to achieve did not work: the window chrome elements are gone, and the transparency value is not evident. Figure 4-5.  Run the project to see if the Stage object is transparent; clearly, something is set to White There must be something else in the processing pipeline that is not yet defining its background using the transparency value. Transparency is defined using a hexadecimal value of #00000000, which signifies that all AARRGGBB (alpha channel, red, green, blue) color and opacity values are turned off. You will need to start thinking about the JavaFX components of your application as layers (currently, these are stage-scene-stackPane-button). You will be learning about digital imaging concepts such as color depth, alpha channels, layers, blending, and all the technical information that relates to processing pixels in a 2D plane as the book progresses. The next thing you should try to set to this transparent value is the next level down in the JavaFX Scene Graph hierarchy from the stage, which contains the Scene Graph itself. The next most top-level component, as discussed previously, is the Scene object, which also has a background color value parameter or attribute. Like the Stage class (object), the Scene class (object) does not have a style constant of TRANSPARENT, so you will have to approach setting the Scene object’s background to a transparency value in a different way, using a different method and constant. One thing you should know is that everything in JavaFX that writes itself to the screen will in some way support transparency to allow multiple-layer compositing in JavaFX applications. If you read the Scene class documentation, you will notice that there is a method, .setFill(Color value), that takes a Color (class or object) value, so let’s try that next. As Figure 4-6 shows, I called the .setFill() off the Scene object named scene, using a scene.setFill(Color.TRANSPARENT); statement, which NetBeans helps me construct! 91 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Figure 4-6.  Call the .setFill() method with the Color.TRANSPARENT constant, off the Scene object named scene Run the application again, to see if the transparency is showing yet. As you can see in Figure 4-7, it is not! 92 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Figure 4-7.  Run the project to look at the transparent Stage object; something is still set to White Because you are using a StackPane object to implement layers in the InvinciBagel application, this is the next level up that you need to try to set a transparency value for. Evidently, JavaFX uses a Color.WHITE default background color value for all its objects. If I were on the JavaFX design team, I would be arguing for this to be changed to the Color.TRANSPARENT constant, but, of course, this might confuse new users, as alpha channel and compositing layers are advanced concepts. The javafx.scene.layout.StackPane class is subclassed from the javafx.scene.layout.Region class, which has a .setBackground() method for setting the Background (class or object) value. Again, a TRANSPARENT value constant must be available, as you always need to set background values as transparent, especially for Java 8 game design. Interestingly, things are not always as straightforward and consistent as you would want them to be in Java programming, as, to achieve exactly the same end result (installing a transparent background color/image plate for the design element), you have used thus far three different method calls, passing three custom object types: .initStyle(StageStyle object), .setFill(Color object), and .setBackground(Background object). 93 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine This time, you are going to call the .setBackground(Background value) method, with yet another Background class (object) constant, EMPTY. As Figure 4-8 illustrates, NetBeans will help you find the constant once you call the method off the StackPane object named root, using the following Java statement: root.setBackground(Background. EMPTY);. NetBeans provides a method selector drop-down and, once you select a method, an information dialog showing you the origin (superclass) of the method as well as what it does and an in-depth description. In this case, null (nothing), or zero Color fill, or zero Image set equates to TRANSPARENT. You are now ready to test your windowless (transparent) application version by using the run project work process. Figure 4-8.  Call a .setBackground() method with a Background.EMPTY constant, off the StackPane object named root As you can see in Figure 4-9, you have now achieved your objective, and just the Button object is visible on the desktop. I pulled the top of NetBeans IDE 8.0 down a bit so that you can see how great this works and still see the three lines of Java code that you added to achieve this end result. Using 2D, 3D, and alpha channels, some crazy-cool applications can be created via this StageStyle.TRANSPARENT capability, so I thought I would show it to you early on in the book and get some JavaFX application Java coding experience into this JavaFX overview chapter. 94 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine Figure 4-9.  Windowless JavaFX application seen at the top; completed Java and JavaFX code that achieves it seen in the IDE Now that you have explored the javafx.stage package, let’s examine the javafx.geometry package next! JavaFX Bounds and Dimensions: Using javafx.geometry Classes Even though the term “geometry” technically applies to 2D and 3D assets, these are contained in a javafx.scene.shape package, which I covered earlier (see the section “Scene Subpackages: The 13 Other Scene Packages”). The javafx. geometry package could be considered more of a utility package, containing foundational classes for building 2D and 3D constructs from scratch. As such, the package offers classes such as a Bounds superclass and its BoundingBox subclass as well as Insets, Point2D, Point3D, Dimension2D, and Rectangle2D geometry content creation utility classes. All the classes in the javafx.geometry package, except the BoundingBox class, were extended directly from the java.lang.Object master class, meaning that they were each developed (coded) from scratch for providing points (also called vertices), rectangles, dimensions, boundaries, and insets (inside boundaries) for use as geometric utilities for JavaFX application development. 95 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine The Point2D and Point3D classes (objects, ultimately) hold x, y coordinates for a 2D point on a 2D plane or x, y, z coordinates for a 3D point in 3D space. These Point objects will be used to build more complex 2D or 3D structures made up of a collection of points, such as a 2D path or a 3D mesh. The Point2D and Point3D constructor method calls are not overloaded, and they use the following standard formats, respectively:   Point2D(double X, double Y) Point3D(double X, double Y, double Z)   The Rectangle2D class (object) can be used to define a rectangular 2D area, often referred to as a plane, and has many uses in graphics programming, as you might well imagine. A Rectangle2D object has a starting point in the upper left-hand corner of the rectangle specified, using an x and a y coordinate location as well as a dimension (width by height). A constructor method for a Rectangle2D object has the following standard format and is not overloaded:   Rectangle2D(double minX, double minY, double width, double height)   In addition, a Dimension2D class (object) specifies only the width and height dimensions and does not place the dimensions (which would make it a rectangle) on the screen using an x, y location. This class’s constructor method is as follows:   Dimension2D(double width, double height)   The Insets class (object) is like a Dimension2D class, in that it does not provide a location value for the inset but does offer offsets for a rectangular inset area, based on top, bottom, left, and right offset distances. The Insets method is in fact overloaded, so you can specify an equidistant inset or a customized inset, using the following code:   Insets(double topRightBottomLeft) Insets(double top, double right, double bottom, double left)   The Bounds class is a public abstract class and will never be an object, but instead is a blueprint for creating Node boundary classes, such as its BoundingBox subclass. The Bounds superclass also allows a negative value, which is used to indicate that a bounding area is empty (think of it as null, or unused). A BoundingBox class uses the following (overloaded) constructor methods to create a 2D (first constructor) or 3D (second constructor) BoundingBox object:   BoundingBox(double minX, double minY, double width, double height) BoundingBox(double minX, double minY, double minZ, double width, double height, double depth)   Next, let’s take a look at Event and ActionEvent processing in JavaFX, as this will add interactivity to your games. 96 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine JavaFX Input Control for Games: Using javafx.event Classes Because games are interactive by their very nature, let’s take a look at the javafx.event package next; it provides us with the Event superclass and its ActionEvent subclass, for handling ACTION events, such as UI element use and animation KeyFrame processing. Because you are going to be using ActionEvent in your JavaFX games (applications), I am describing its class inheritance hierarchy here, as this will show you the origins of the Event class as well:   Java.lang.Object > java.util.EventObject > javafx.event.Event > javafx.event.ActionEvent   Your InvinciBagel game application is already using this ActionEvent class (object), with the EventHandler interface and its .handle() method, which you code yourself to tell your application what to do to “handle” the Event (ActionEvent) once it has occurred (fired). The .handle() method catches this fired event and then processes it, according to the Java programming logic inside the body of the .handle() method. A Java interface is a class that furnishes empty methods, which are declared for use but which do not yet contain any Java programming constructs. The unimplemented methods will, at the time of their use, have to be implemented by you, the Java programmer. This Java interface defines only the methods to be implemented (in this case, a method for handling the ActionEvent so that the event gets processed in some fashion). It is important to note that the Java interface defines the method that needs to be coded but does not write the method code for you, so it is a road map of what you must do to complete, or interface with, the programming structure that is in place (in this case, the Java programming structure for handling ActionEvent objects, that is, fired action events. Now, let’s take a look at multithreading in JavaFX, which is another important concept for advanced games, to conclude this exploration of everything 2D- and 3D- (game) related in the JavaFX API and package hierarchy. JavaFX Thread Control for Games: javafx.concurrent Package Games require background, or asynchronous, processing. This can be done using additional threads besides the JavaFX application thread, Prism rendering thread, and media playback thread, which are all automatically created for you, based on which classes (objects) you are using in your scene graph. Your application programming logic can spawn its own Worker threads for processing so that you do not overload the primary JavaFX application thread. Let’s take a look at the javafx.concurrent package next, as it provides us with the Service superclass and its ScheduledService subclass, for creating Worker objects, as well as a Task class, used for one-off task processing. Because you are going to be using Service and ScheduledService in your JavaFX games (applications), I am demonstrating the ScheduledService class inheritance hierarchy here, as this will show you the java.lang.Object origins of the Service classes as well:   Java.lang.Object > javafx.concurrent.Service > javafx.concurrent.ScheduledService   Whereas Task (class) objects are used only one time, to accomplish a given task, a service is ongoing, and a Service object and a ScheduledService (class) object can be reused, that is, they are ready to perform their service at any time. This is more appropriate for game play processing, as game play continues for long periods of time, and the assumption here is that the types of game logic processing involved will also need to be calculated as time goes on during game play, and not just one single time, as with the Task class (object). The Worker Java construct is actually an interface, and the Task, Service, and ScheduledService classes have been created for you, based on this Worker interface (which is more than can be said for the EventHandler interface, which you have to implement yourself!). 97 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine A Worker object performs processing, using a background thread, and can be either reusable (such as in the Service class) or not reusable (such as in the Task class). Worker thread states are controlled by the Worker.State class (object) and contain the life cycle stages for a Worker thread. These apply across the three primary classes in the javafx.concurrent package, as they implement the Worker interface and its related nested classes. As mentioned in the previous chapter, a nested class is accessed via dot notation, so the State class is thus nested inside the Worker interface (class). Because the states of a Worker thread are very important to understand before you use it, I am going to detail them in the form of a table so that they are crystal clear to you (see Table 4-3). Table 4-3.  Worker Thread Life Cycle States, as Defined by the Worker.State Nested Class for Use with a Worker Interface Worker.State Constant Significance READY Worker object (thread) has been initialized (or reinitialized) and is ready to be used. SCHEDULED Worker object (thread) has been scheduled for execution but is not currently running. RUNNING Worker object (thread) is currently running and is executing the Java programming logic. SUCCEEDED Worker object (thread) has executed successfully, and a valid result is in the value property. FAILED Worker object (thread) has failed to execute successfully because of some unexpected condition. CANCELLED Worker object (thread) has been cancelled by invoking the Worker.cancel() method call. As with everything else in this JavaFX 8 multimedia engine overview chapter, you will be getting deep into the details of how to use these packages, classes, nested classes, interfaces, methods, constants, and variables over the course of the book, as you apply these JavaFX programming constructs and concepts! Summary In this fourth chapter, you took a closer look at some of the more important packages, concepts, components, classes, constructors, constants, and variables (attributes) that can be found in the JavaFX 8 API, an impressive collection of 36 javafx.packagename.subpackagename packages, which I outlined in tables and covered, one by one, as needed for multimedia 2D and 3D (and hybrid 2D-3D) game development. When I say, “an overview,” I mean an overview! Certainly, I cannot discuss every functional class in JavaFX in one chapter, so I started with a broad overview of the JavaFX engine and how it integrates with the JavaFX Scene Builder tool and the JavaFX Scene Graph API above it, and with the Java 8 API, NetBeans 8.0, and target OSs below it, which give JavaFX expansive OS support across so many popular platforms and devices and the leading web browsers. I presented a high-level technical view of JavaFX, detailing its structures, including JavaFX Scene Graph, APIs, Quantum, Prism, Glass, WebKit, and Media engine. You looked at how these multithreading, rendering, windowing, media, and web engines interface with the Java 8 API and Java JDK 8 as well as with NetBeans 8.0 and the JVM bytecode that it generates, which is read by all the various OS platforms currently running across a dozen different consumer electronics device types. You also explored JavaFX core concepts, such as the JavaFX Scene Graph and the JavaFX pulse events system, which you will be leveraging to create a Java 8 game as you work through this book, starting in the next chapter, when I explain how to use the JavaFX Scene Builder visual editing tool in NetBeans. Then, you dove deep into some of the key JavaFX packages and subpackages for game design, such as Application, Scene, Shape, Effect, Layout, Control, Media, Image, Stage, Animation, Geometry, Event, and Concurrent, and their package classes and subclasses and even, in some cases, their interfaces, nested classes, and constants. 98 www.it-ebooks.info Chapter 4 ■ An Introduction to JavaFX 8: Exploring the Capabilities of the Java 8 Multimedia Engine You even took a break to add some code to your InvinciBagel application that turned it into a windowless application and learned how to make the stage, scene, and stackPane background plates transparent, using alpha channels and hexadecimal #00000000 or Color.TRANSPARENT, Background.EMPTY, and SceneStyle.TRANSPARENT constants. I had to get some work with the NetBeans IDE 8.0, Java 8 programming language, and JavaFX API into this chapter somehow! In the next chapter, you are going to explore the JavaFX Scene Builder, which makes it easy to construct the Scene Graph structures that you learned about in this chapter. You will start to build your game splash screen as well, as I know you are eager to get started on a game infrastructure, even if it is just a splash screen! 99 www.it-ebooks.info Chapter 5 An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder In this chapter, you will build on your knowledge of the JavaFX multimedia engine by learning about the optimal way to use the scene graph paradigm in JavaFX and take a look at JavaFX Scene Builder tool and FXML, and why (or why not) to use these in certain types of Java game development scenarios. You will also examine basic game design optimization concepts, and the types of games, as well as game engines, that are available for the Java platform, including physics engines, such as JBox2D and Dyn4J, and 3D game engines, such as LWJGL and JMonkey. Finally, you will consider the new media concepts that you will need to understand to integrate digital imaging, digital audio, digital video, and animation into your game production pipeline. We will also look at some of the free open-source multimedia production tools that you installed back in Chapter 1, and can now use to create Java 8 games. First, you will revisit the underlying concept of static (fixed) versus dynamic (real time), which was covered in Chapter 3 (constant versus variable) and Chapter 4 (pulse) and which is one of the foundational principles of game optimization. This is important, because you will want your game to run smoothly across all the different platforms and devices that are used to play it, even if the device only uses a single processor (which is actually rare these days, with most devices featuring dual core (two processor) or quad core (four processor) CPUs). Next, you will study the concepts, techniques, and lingo of game design, including sprites, collision detection, physics simulation, background plates, animation, layers, levels, logic, and AI. You will also examine the different types of games that can be designed, and how they differ from each other. Then, you will explore the role that multimedia assets play in today’s visually (and aurally) impressive games. You will learn about the principles of digital imaging, digital video, and animation as well as digital audio, as you will be using many of these new media asset types over the course of the book, and will need this foundational knowledge to be able to work with them. Finally, you will take an in-depth look at the bootstrap JavaFX application code that you generated in Chapter 2 and at how the Java .main() method and the JavaFX .start() method create the primaryStage Stage object, using the Stage() constructor method, and, inside that, create a Scene object named scene, using the Scene() constructor method. You will look at how to use methods from the Stage class to set the scene, title the stage, and show the stage as well as how to create and use StackPane and Button class (objects) and how to add an EventHandler to a button. 101 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder High-Level Concept: Static vs. Dynamic I want to start out with a high-level concept that touches on everything that I will be talking about in this chapter, from the types of games you can create, to game optimization, to JavaFX Scene Builder and JavaFX Scene Graph. You took a look at this concept back in Chapter 3, whether you realized it or not, while exploring the concept of a Java constant, which is fixed, or static, and does not change, versus a Java variable, which is dynamic and changes in real time. Similarly, a UI design in JavaFX Scene Graph can be static (fixed and immovable) or dynamic (animated, draggable, or skinnable, meaning that you can change the UI look to suit your personal taste). The reason these concepts are important in game design and development is that your game’s engine, which you design to run or render your game, must constantly check on its dynamic portions to see if they have changed and require a response (update a score, move a sprite position, play an animation frame, change the game piece’s state, calculate collision detection, calculate physics, and so on). This checking (and the ensuing processing) on every frame update (called a pulse in JavaFX; see Chapter 4), to make sure that all your variables, positions, states, animations, collisions, physics, and the like are conforming to your Java game engine logic, can really add up, and, at some point, the processor that is doing all this work can get overloaded, which can slow it down! The result of this overloading of all the real-time, per-frame checking that enhances the dynamics of your game (play) is that the frame rate at which your game is running will decrease. That’s right, like digital video and animation, Java 8 games have frame rates, too, but Java 8 game frame rates are based upon the efficiency of your programming logic. The lower the frame rate of your game, the less smooth the game play becomes, at least for dynamic, real-time games, such as arcade games; how smoothly a game plays relates to how seamless (enjoyable) the user experience is for the customer, the game player. For this reason, the concept of static versus dynamic is very important to every aspect of game play design and makes it easier to achieve a great user experience with certain types of games than with others. I will be discussing different types of games later in the chapter (see the section “Types of Games: Puzzles, Board Games, Arcade Games, Hybrids”), but, as you might imagine, board games are more static in nature, and arcade games are more dynamic. That said, there are optimization approaches that can keep a game dynamic, that is, seem like a lot is going on, when, from a processing point of view, what is really going on is quite manageable. This is one of the many tricks of game design, which, when all is said and done, is about optimization. One of the most significant static-versus-dynamic design issues in Android (Java) programming is UI design using XML (static design) versus UI design using Java (dynamic design). The Android platform allows UI design to be done using XML instead of Java so that nonprogrammers (designers) can do the front-end design for an application. JavaFX allows exactly the same thing to be done using FXML. You have to create an FXML JavaFX application to do this, as you saw in Chapter 2 (see Figure 2-4, right-hand side, third option, “JavaFX FXML Application”). Doing so will add the javafx.fxml package and classes to the application, letting you design UIs, using FXML, and later having your Java programming logic “inflate” them so that the design consists of JavaFX UI objects. It is important to note that using FXML adds another layer, containing the FXML markup and its translation and processing, to the application development and compilation process. I am going to demonstrate later in the chapter how this is done, in case your design team wants to use FXML for the UI design work process, instead of Java (see the section “JavaFX Scene Builder: Using FXML for UI Design”). I am doing this because I want to cover all the design options in JavaFX, including FXML, to make sure that this book is complete in its coverage of what can be done using Java 8 and JavaFX 8.0. At the end of the day, this is a Java 8 programming title, however, so my primary focus during this book will be using Java 8, not FXML. In any event, the point that I am making regarding using XML (or FXML) to create the UI design is that this approach can be viewed as static, because the design is created beforehand, using XML, and is “inflated” at compile time, using Java. Java inflation methods use the designer-provided FXML structure to create the scene graph, which is filled with JavaFX UI (class) objects, based on the UI design structure (hierarchy) created using FXML. I will give you an overview of how this works later in the chapter so that you have a handle on how this works (see the section “JavaFX Scene Builder: Using FXML for UI Design”). 102 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Game Optimization: Balancing Static Elements with Dynamic Game optimization comes down to balancing static elements, which do not require processing in real time, with dynamic elements, which require constant processing. Too much dynamic processing, especially when it is not really needed, can make your game play jerky, or stilted. This is why game programming is an art form: it requires balance as well as great characters, a story line, creativity, illusion, anticipation, accuracy, and, finally, optimization. Some of the different game component considerations for optimization in a dynamic game are listed in Table 5-1. As you can see, there are a lot of areas of game play that can be optimized to make the processor’s workload significantly less “busy.” If you have even one of these primary dynamic game processing areas “run away” with the processor’s precious cycles per frame, this can greatly affect the user experience for your game. I will be getting into game terminology (sprites, collision detection, physics simulation, and so on) in the next section of the chapter. Table 5-1.  Aspects of Game Play That Can Be Optimized to Minimize System Memory and Processor Cycle Usage Game Play Aspect Basic Optimization Principle Sprite position (Move) Move sprites by as many pixels as possible to achieve smooth movement on the screen. Collision detection Check for collisions between objects on the screen only when necessary (in close proximity). Physics simulation Minimize the number of objects in a scene that require physics calculations to be performed. Sprite animation Minimize the number of frames that need to be cycled to create an illusion of smooth animation. Background animation Minimize background areas that are animated so that the entire background looks animated but is not. Game play logic Program game play logic (simulated or AI) to be as efficient as possible. Scoreboard updates Update scoreboard only when scoring, and minimize score updates to once per second maximum. UI design Use a static UI design so that pulse events are not used for UI element positioning or CSS3. Considering all these game programming areas makes game programming an extremely tricky endeavor! It is important to note that some of these aspects work together to create a given illusion for the player. For instance, the sprite animation will create the illusion of a character running, jumping, or flying, but without combining that code with sprite positioning (movement) code, the reality of the illusion will not be achieved. To fine-tune an illusion, the speed of the animation (frame rate) and the distance moved (in pixels per frame) may need to be adjusted (I like to call this tweaked) to get the most realistic result. We will be doing this during Chapter 13. If you can move game elements (primary player sprite, objectile sprites, enemy sprites, background) a greater number of pixels a fewer number of times, you will save processing cycles. It is the moving part that takes processing time, not the distance (how many pixels are moved). Similarly, with animation, the fewer frames needed to achieve a convincing animation, the less memory will be required to hold those frames. Remember that you are optimizing memory usage as well as processing cycles. Detecting collisions is a major part of game programming logic; it is important not to check for collisions between game elements that are not “in play” (on the screen), or active, and that are not near each other. Forces of nature (physics simulations) and game play logic if it is not well coded (optimized), are the most processor intensive aspects. These are subjects I will cover later in the book, when you are more advanced (see Chapters 16 and 17). 103 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Game Design Concepts: Sprites, Physics, Collision Let’s take a look at the various game design components that we you will need to understand to be able to build a game, as well as what Java 8 (or JavaFX) packages and classes you can use to implement these aspects of game play, which I like to term components of game play. These can include the game play elements themselves (commonly referred to as sprites) as well as processing engines, which you will either code yourself, or import preexisting Java code libraries for, such as physics simulation and collision detection. Sprites are the foundation of game play, defining your main character, projectiles used to damage this main character, and the enemies firing these projectiles. Sprites are 2D graphics elements and can be either static (fixed, a single image) or dynamic (animated, a seamless loop of several images). A sprite will be moved around the screen based on programming logic, which dictates how the game is to function. Sprites need to be composited with background imagery and other game elements as well as other sprites and so the graphics used to create the sprites will need to support transparent backgrounds. In Chapter 4, I introduced you to the concept of alpha channels and transparency. You will need to achieve this same end result with your sprites to create a seamless visual experience with your game. The next most important aspect of game play is collision detection, because if your sprites simply flew right past each other on the screen and never did anything cool when they touched, or “intersected” each other, then you really would not have much of a game! Once you add a collision detection engine (composed of intersection logic processing routines) your game can ascertain when any two sprites are touching (edges) or overlapping each other. A collision detection will call (trigger) other logic processing routines that will determine what happens when any two given sprites, such as a projectile and the main character, intersect. For example, when a projectile intersects the main character, damage points might accrue, life force index might be decreased, or a death animation may be started. In contrast, if a treasure item intersects with (is picked up by) the main character, power or capability points might accrue, the life force index might be increased, or an “I found it” jubilation animation might be started. As you can see, the collision detection for your game is one of the foundational design elements of your game play, besides the sprites (characters, projectiles, treasures, enemies, obstacles, and so on) themselves, which is why I am covering this concept early on in the book. The concept next in significance to your game play is real-world physics simulation. The addition of things like gravity; friction; bounce; drag; acceleration; motion curves, such as the JavaFX Interpolator class provides; and the like add an additional level of realism on top of the already photo-realistic sprites, synchronized animation sequences, scenic backgrounds, and highly accurate collision detection. Finally, the most proprietary attribute, or logic construct (Java code), to add to your game play is the custom game play logic, which makes your game truly unique in the marketplace. This logic should be kept in its own Java class or methods, separate from physics simulation and collision detection code. After all, Java 8 makes your code modularization well-structured if you learn the OOP concepts and apply them to your programming logic! When you start to add all these game components together, they begin to make the game more believable as well as more professional. One of the key objectives for a great game is suspension of belief, which means that your player is buying into the premise, characters, objectives, and game play completely. This is the same objective that any content producer, whether he or she be a filmmaker, television producer, author, songwriter, Java 8 game programmer, or application developer, is going for. Games these days have the same revenue-generating capability as any of the other content distribution genres, if not more. Next, let’s take a look at the different types of games that can be created and how these differ in their application of the core game components of sprites, collision detection, physics simulation, and game play logic. Types of Games: Puzzles, Board Games, Arcade Games, Hybrids Like everything else I have talked about in this chapter, games themselves can be categorized by using a static-versus-dynamic classification approach. Static games are not processor bound, because they tend to be turn based and not hand-eye coordination based in nature, and so, in a sense, they are easier to get working smoothly; only the programming logic for the rules of game play and the attractive graphics have to be put in place and 104 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder debugged. A significant opportunity also exists for developing new types of game genres that use a hybrid combination of static and dynamic game play in creative new ways that have never before been seen. I am working on a few of these myself! Because this is a Java 8 programming title, I am going to approach everything from this standpoint, which happens to be a great way to divide games into discrete categories (static, dynamic, hybrid), so let’s cover the static (fixed graphics), turn-based games first. These include board games, puzzle games, knowledge games, memory games, and strategy games, all of which should not be underestimated in their popularity and marketability. The thing that is cool about static games is that they can be just as fun to play as dynamic games and have significantly less processing overhead, as they do not have to achieve the 60FPS real-time processing target to achieve smooth, professional game play. This is because the nature of the game is not predicated on motion at all, but rather on making the right strategic move, but only when it is your turn to do so. There can be some forms of collision detection involved in static games regarding which game piece has been moved to a given location on the gameboard or playing surface; however, there is no danger of overloading the processor with collision detection, because the rest of the game board is static, with the exception of the one piece that is being strategically moved during that particular player’s turn. The processing logic for strategy games is more strategy logic–based programming, geared toward allowing the players to achieve an end win, given the right sequence of moves, whereas the dynamic game programming logic looks more at what collisions are taking place between game sprites. Dynamic games are focused on point score, dodging projectiles, finding treasures, completing level objectives, and killing enemies. Complicated strategy games with lots of interrelated rules, such as chess, are likely to have far more programming logic routines than dynamic games. Yet, because the execution of the code is not as time sensitive, the resulting game play will be smooth, no matter how powerful the platform and CPU are. Of course, the game rule set logic must be flawless for this type of game to truly be professional, so, in the end, both static and dynamic games are difficult to code, albeit for different reasons. Dynamic games could be termed action games or arcade games and include a lot of movement on the display screen. These highly dynamic games almost always involve shooting things, such as in the first-person shooter (e.g., Doom, Half-Life) as well as in the third-person shooter (Resident Evil, Grand Theft Auto) genres, or stealing things, or evading things. There is also the obstacle course navigation paradigm, commonly seen in platform games, such as Donkey Kong and Super Mario. It is important to note that any genre of game can be produced using 2D or 3D graphics and assets or even a combination of 2D and 3D assets, which, as I pointed out in Chapter 4, is allowed by JavaFX. There are so many popular game types that there is always the opportunity to create an entirely new genre of game by using a hybrid approach of a static (strategic) game type and a dynamic (action) game type. Game Design Assets: New Media Content Concepts One of the most powerful tools you have to make your game highly professional and desirable to buyers is the multimedia production software that you downloaded and installed back in Chapter 1. Before I go any further, I need to spend some time providing you with foundational knowledge regarding four primary types of new media assets that are supported in Java 8, using the JavaFX 8 multimedia engine: digital images, used for sprites, background imagery, and 2D animation; vector shapes, used in 2D illustration, collision detection, 3D objects, paths, and curves; digital audio, used for sound effects, narration, and background music; and digital video, used in games for animated background loops (birds flying through the sky, drifting clouds, and so on) once highly optimized. As illustrated in Figure 5-1, these four major genres, or areas, are all installed via the JavaFX Scene Graph, using packages that I described in Chapter 4. Some of the primary classes that will be used are ImageView, AudioClip, Media, MediaView, MediaPlayer, Line, Arc, Path, Circle, Rectangle, Box, Sphere, Cylinder, Shape3D, Mesh, and MeshView. 105 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Figure 5-1.  How new media assets are implemented, using Scene Graph through the JavaFX API in Java 8 via NetBeans Because you need to have a technical foundation before using any of these types of new media elements in a Java 8 game design and programming pipeline, I am going to go over basic concepts for each of these four new media areas, beginning with digital imaging and vector illustration. Digital Imaging Concepts: Resolution, Color Depth, Alpha, Layers JavaFX (and therefore Java8) supports a significant number of popular digital imaging file (data) formats, which gives game designers a ton of flexibility. Some of these have been around forever, such as CompuServe’s graphics interchange format (GIF) and the Joint Photographic Experts Group (JPEG) format. Some JavaFX graphics file formats are more modern, such as portable network graphics (PNG; pronounced “ping”), which is the file format that you will be using for your games, as it yields the highest quality level and supports image compositing. All these mainstream digital image file formats supported in Java are also supported in HTML5 browsers, and because Java applications can be used with HTML applications and web sites, this is a very logical synergy indeed! The oldest CompuServe GIF format is the lossless digital image file format. It is termed lossless because it does not throw away image data to achieve better compression results. The GIF compression algorithm is not as refined (powerful) as that of the PNG format, and GIF only supports indexed color, which is how it obtains its compression (smaller file size). If your game image assets are already created with the GIF format, you will be able to use them with no problem (other than a less efficient image compression algorithm and no compositing capability) with your Java 8 game applications. The most popular digital imaging file format that Java 8 (JavaFX) supports is JPEG, which uses a “truecolor” color depth, instead of an indexed color depth, as well as what is termed lossy digital image compression, in which the compression algorithm “throws away” image data so that it can achieve a smaller file size (the image data are lost forever, unless you are smart and save your original image!). If you magnify a JPEG image after compression, you will see a discolored area (effect) that clearly was not present in the original imagery. The degraded area or areas in the image are commonly referred to as compression artifacts. This will only occur in lossy image compression and is common with JPEG (and Moving Picture Experts Group [MPEG]) compression. 106 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder ■■Tip  I recommend that you use the PNG digital imaging format for your Java 8 games. This is a professional image-compositing format, and your games will essentially be a real-time sprite-compositing engine, so you will need to use PNG32 imagery. PNG has two truecolor file versions: PNG24, which cannot be used in image compositing, and PNG32, which carries an alpha channel used to define transparency. I recommend PNG for your games because it has a decent image compression algorithm and because it is a lossless image format. This means that PNG has great image quality as well as reasonable levels of data compression efficiency, which will make your game distribution file smaller. The real power of the PNG32 format lies in its ability to composite with other game imagery, using transparency and antialiasing (via its alpha channel). Digital Image Resolution and Aspect Ratio: Defining Image Size and Shape As you probably know, digital imagery is made up of 2D (two-dimensional) arrays of pixels (“pixel” stands for picture [pix] element [el]). The sharpness of an image is expressed by its resolution, which is the number of pixels in the image width (or W, sometimes referred to as the x axis) and height (or H, sometimes referred to as the y axis) dimensions. The more pixels an image has, the higher its resolution. This is similar to how digital cameras work, as the more megapixels in an image capture device (called a camera CCD), the higher the image quality that can be achieved. To find the total number of image pixels, multiply the width pixels by the height pixels. For instance, a wide video graphics array (VGA) 800 × 480 image contains 384,000 pixels, which is exactly three-eighths of a megabyte. This is how you would find the size of your image, both in terms of kilobytes (or megabytes) used and height and width on the display screen. The shape of a digital image asset is specified using the image aspect ratio. Aspect ratio is the width:height ratio for the digital image and defines the square (1:1 aspect ratio) or rectangular (also known as widescreen) digital image shape. Displays featuring a 2:1 (widescreen) aspect ratio, such as 2,160 × 1,080 resolution, are now available. A 1:1 aspect ratio display (or image) is always perfectly square, as is a 2:2 or 3:3 aspect ratio image. You might see this aspect ratio on a smart watch, for instance. It is important to note that it is the ratio between these two width and height (x and y) variables that defines the shape of an image or screen, not the actual numbers themselves. An aspect ratio should always be expressed as the smallest pair of numbers that can be achieved (reduced) on either side of the colon. If you paid attention in high school while you were learning about the lowest common denominator, then an aspect ratio will be very easy for you to calculate. I usually do aspect ratio calculation by continuing to divide each side of the colon by two. For example, if you take the SXGA 1,280 × 1,024 resolution, half of 1,280 × 1,024 is 640 × 512, and half of 640 × 512 is 320 × 256; half of 320 × 256 is 160 × 128, half of that again is 80 × 64, half of that is 40 × 32, and half of that is 20 × 16; half of 20 × 16 is 10 × 8, and half of that gives you the 5 × 4 aspect ratio for SXGA, which would be signified by using a colon between the two numbers, as in a 5:4 aspect ratio. Digital Image Color Theory and Color Depth: Defining Precise Image Pixel Colors The color values for each digital image pixel can be defined by the amount of three different colors, red, green, and blue (RGB), which are present in different amounts in every pixel. Consumer electronics display screens leverage additive colors, in which wavelengths of light for each RGB color channel are added together creating 16.8 million different color values. Additive color is used in liquid crystal display (LCD), light-emitting diode (LED), and organic light-emitting diode (OLED) displays. It is the opposite of subtractive color, which is used in printing. To show you the different results, under a subtractive color model, mixing red with green (inks) will yield purple colors, whereas in an additive color model, mixing red with green (light) creates a vibrant yellow coloration. Additive color can provide a much broader spectrum of colors than subtractive color. 107 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder There are 256 levels of brightness for each red, green, and blue color value that is held for each pixel. This allows you to set 8 bits of value-controlling color brightness variation for each of the red, green, and blue values, from a minimum of 0 (#00, or off, all dark, or black) to a maximum of 255 (#FF, or fully on, maximum color contributed). The number of bits that are used to represent digital image pixel color is referred to as the color depth of the image. Common color depths used in the digital imaging industry include 8 bit, 16 bit, 24 bit and 32 bit. I will outline these here, along with their formats. The lowest color depth exists in 8-bit indexed color images. These feature a maximum of 256 color values and use GIF and PNG8 image formats to hold this indexed color type of data. A medium color depth image will feature a 16-bit color depth and will thus contain 65,536 colors (calculated as 256 × 256). It is supported by the TARGA (TGA) and tagged image file format (TIFF) digital image formats. If you want to use digital image formats other than GIF, JPEG, and PNG in your Java 8 games, import the third-party ImageJ library. Truecolor color depth images will feature 24-bit color depth and will thus contain more than 16 million colors. This is calculated as 256 × 256 × 256, which yields 16,777,216 colors. File formats supporting 24-bit color depth include JPEG (or JPG), PNG, BMP, XCF, PSD, TGA, TIFF, and WebP. JavaFX supports three of these: JPG, PNG24 (24 bit), and PNG32 (32 bit). Using 24-bit color depth will give you the highest quality level. This is why I am recommending the use of PNG24 or PNG32 for your Java games. Next, let’s take a look at how to represent image pixel transparency values through alpha channels and how these can be used for compositing digital imagery in real time in Java 8 games! Digital Image Compositing: Using Alpha Channels and Transparency in Layers Compositing is the process of seamlessly blending together multiple layers of digital imagery. As you might imagine, this is an extremely important concept for game design and development. Compositing is useful when you want to create an image on the display that appears as though it is one single image (or animation), when it is actually the seamless collection of two or more composited image layers. One of the principle reasons you would want to set up an image or animation composite is to allow programmatic control over various elements in those images, by having them on different layers. To accomplish this, you need to have an alpha channel transparency value, which you can use to control the precision of the blending amount of a given pixel with another pixel (in the same x, y image location) on other layers (above and below it). Like the other RGB channels, an alpha channel has 256 transparency levels. In Java programming the alpha channel is represented by the first two slots in a hexadecimal representation of #AARRGGBB data values (which I will be covering in detail in the next section). Alpha channel ARGB data values use eight slots (32 bit) of data rather than the six data slots (#RRGGBB) used in a 24-bit image, which is really a 32-bit image with zero alpha channel data. Therefore, a 24-bit (PNG24) image has no alpha channel and will not be used for compositing, unless it is the bottom image plate in a compositing layer stack. In contrast, PNG32 images will be used as compositing layers on top of PNG24 (background plate) or PNG32 (lower, z-order compositing layers), which will need this alpha channel capability to show through (via alpha channel transparency values) in certain pixel locations in the image composite. How do digital image alpha channels, and the concept of image compositing, factor into Java game design? The primary advantage is an ability to break the game play screen, and the sprites, projectiles, and background graphic elements that it includes, into a number of component layers. The reason for doing this is to be able to apply Java 8 programming logic (or JavaFX classes) to individual graphic image elements to control parts of your game play screen that you would not otherwise be able to control individually were it one single image. Another part of image compositing, called blending modes, also factors heavily into professional imagecompositing capabilities. JavaFX blending modes are applied by using the Blend class with the BlendMode constant values found in the javafx.scene.effect subpackage (see Chapter 4). This JavaFX blending effect package gives Java game developers many of the same image-compositing modes that Photoshop (and GIMP) afford to a digital imaging artisan. This turns Java 8 (via JavaFX) into a powerful image-compositing engine, just like Photoshop, and the blending algorithms are controllable at a very flexible level, using custom Java 8 code. JavaFX blending mode constants include ADD, SCREEN, OVERLAY, DARKEN, LIGHTEN, MULTIPLY, DIFFERENCE, EXCLUSION, SRC_ATOP, SRC_OVER, SOFT_LIGHT, HARD_LIGHT, COLOR_BURN, and COLOR_DODGE. 108 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Representing Color and Alpha in Java 8 Game Code: Using Hexadecimal Notation Now that you know what color depth and alpha channels are, and that color and transparency are represented by using a combination of four different image channels (alpha, red, green, and blue [ARGB]) within any given digital image, it is important to understand how, as programmers, you are supposed to represent these four ARGB image color and transparency channel values in Java 8 and JavaFX. In the Java programming language, color and alpha are used not only in 2D digital imagery (commonly referred to as bitmap imagery), but also in 2D illustration (commonly referred to as vector imagery). Colors and transparency values are also often used across a number of different color setting options. As you have already seen with the Stage object and the Scene object, you can set a background color (or transparency value) for a stage, scene, layout container (StackPane), or UI control, among other things. In Java (and thus JavaFX) different levels of ARGB color intensity values are represented using hexadecimal notation. Hexadecimal (or hex) is based on the original Base16 computer notation. This was used long ago to represent 16 bits of data value. Unlike the more common Base10, which counts from 0 to 9, Base16 notation counts from 0 to F, where F represents the Base10 value of 15 (0 to 15 yields 16 data values). A hexadecimal value in Java always starts with a 0 and an x, like this: 0xFFFFFF. This hexadecimal color value represents the Color.WHITE constant and uses no alpha channel. Each of the six slots in this 24-bit hexadecimal representation stands for a single Base16 value, so to get the 256 values required for each RGB color will take two slots, as 16 × 16 = 256. Therefore, to represent a 24-bit image using hexadecimal notation, you would need to have six slots after the pound sign to hold each of the six hexadecimal data values (data pairs representing 256 levels of value each). If you multiply 16 × 16 × 16 × 16 × 16 × 16 you will get the 16,777,216 colors that are possible using 24-bit, truecolor image data. The hexadecimal data slots represent RGB values in the following format: 0xRRGGBB. For the Java constant Color.WHITE, all the red, green, and blue channels in the hexadecimal color data value representation are at the full (maximum color value) luminosity setting. If you add all these colors together, you will get white light. The color yellow would be represented by the red and green channels’ being on, and the blue channel’s being off, so a hexadecimal representation for Color.YELLOW would therefore be 0xFFFF00, where both the red and green channel slots are fully on (FF, or a 255 Base10 data value), and the blue channel slots are fully off (00, or a 0 value). The eight hexadecimal data slots for an ARGB value will hold data using the following format: 0xAARRGGBB. Thus, for the Color.WHITE, all alpha, red, green, and blue channels in the hexadecimal color data value representation would be at their maximum luminosity (or opacity), and the alpha channel would be fully opaque, that is, not transparent, as represented by an FF value. Therefore, the hexadecimal value for the Color.WHITE constant would be 0xFFFFFFFF. A 100 percent transparent alpha channel can be represented by setting an alpha slot to 0, as you observed when you created a windowless Java 8 application (see Chapter 4). Therefore, you would represent transparent image pixel values using any value between 0x00000000 and 0x00FFFFFF. It is important to note that if an alpha channel value equates to full transparency, it would follow that the 16,777,216 color values that could be contained in the other six (RGB) hexadecimal data value slots will not matter at all, because that pixel, being transparent, will be evaluated as not being there and thus will not be composited in the final image or animation composite image. Digital Image Masking: Using Alpha Channels to Create Game Sprites One of the primary applications for alpha channels in game design is to mask out areas of an image or animation (series of images) so that it can be used as a game sprite in a game play image-compositing scenario. Masking is the process of cutting subject matter out of a digital image so that the subject matter can be placed on its own virtual layer, using alpha channel transparency values. This is done using a digital imaging software package, such as GIMP. Digital image–compositing software packages, such as Photoshop and GIMP, feature tools that are included for use in masking and image compositing. You cannot do effective image compositing without doing effective masking, so this is an important area to master for game designers who wish to integrate graphics elements, such as image sprites and sprite animation, into their game designs. The art of digital image masking has been around for a very long time! 109 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Masking can be done for you automatically, using professional blue screen (or green screen) backdrops, along with computer software that can automatically extract those exact color values to create a mask, which is turned into alpha channel (transparency) information (data). Masking can also be done manually, using digital image software, via one of the algorithmic selection tools, in conjunction with various sharpening and blur algorithms. You will learn a lot about this work process over the course of this book, using common open-source software packages, such as GIMP. Masking can be a complex and involved work process. This chapter is intended to expose you to foundational knowledge that will underlie the processes you undertake while working through the book. A key consideration in the masking process is getting smooth, sharp edges around a masked object (subject matter). This is so that when you place a masked object (in this case, a game sprite) into (over) new background imagery, it looks as if it were photographed there in the first place. The key to doing this successfully lies in your selection work process, which entails using digital image software selection tools, such as the scissors tool in GIMP, or the magic wand tool in Photoshop, in the proper fashion. Choosing the correct work process is critical! For instance, if there are areas of uniform color around the object that you wish to mask (maybe you shot it against a blue screen), you will use a magic wand tool with a proper threshold setting to select everything except your object. Then, you invert the selection, which will give you a selection set containing the object. Often, the correct work process requires approaching something in reverse. Other selection tools contain complex algorithms that can look at color changes between pixels. These can be useful for edge detection, which you can use for other selection methods. Smoothing Digital Image Composites: Using Antialiasing to Smooth Image Edges Antialiasing is a popular digital image–compositing technique, in which two adjacent colors in a digital image are blended together along the edge that borders the two color areas. This tricks the viewer’s eye into seeing a smoother (less jagged) edge when the image is zoomed out, thereby eliminating what has come to be called image jaggies. Antialiasing provides an impressive result by using averaged color values (a color range that is a portion of the way between the two colors coming together), with just a few colored pixels along the edge that needs to be smoothed. Let’s take a look at an example to see what I am talking about. Figure 5-2 shows what appears to be a razor-sharp red circle on one layer, overlaying a yellow fill color on a background layer. I zoomed into the red circle’s edge and then made another screenshot, placing it to the right of the zoomed-out circle. This screenshot reveals a range of antialiasing color values (yellow-orange, to orange, to red-orange) right on the edge bordering the red and yellow colors, where the circle meets the background. Figure 5-2.  A red circle composited on a yellow background (left) and a zoomed-in view (right) showing antialiasing 110 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder It is important to note that the JavaFX engine will antialias 2D shapes and 3D objects against all background colors and background imagery, using the Java2D software renderer or the hardware rendered with the Prism engine, which can use OpenGL or DirectX. You will still be responsible for correctly compositing, that is, providing antialiasing for your multilayered imagery, using each image’s alpha channel. Digital Image Optimization: Using Compression, Indexed Color, and Dithering There are a number of factors that affect digital image compression and some basic techniques that you can use to achieve a better-quality result with a smaller data footprint. This is a primary objective in optimized digital imagery; obtaining the smallest possible data footprint for your application (in this case, a game), while achieving the highest quality visual result. Let’s start with the aspects that most significantly affect data footprint and examine how each of these contributes to data footprint optimization for any given digital image. Interestingly, their order of significance is similar to the order in which I have presented the digital imaging concepts thus far. The most critical contributor to a resulting digital image asset file size is what I like to call the data footprint, which is the number of pixels, or resolution of, a digital image. This is logical, because each of the pixels needs to be stored, along with the color and alpha values that are contained in their three (24 bit) or four (32 bit) channels. The smaller you can get your resolution, while still having the image look sharp, the smaller the resulting file size will be. Raw (or uncompressed) image size is calculated by width × height × 3 for 24-bit RBG images, and width × height × 4 for 32-bit ARGB images. For instance, an uncompressed, truecolor, 24-bit VGA image will have 640 × 480 × 3, equaling 921,600B of original (raw), uncompressed digital image data. To determine the number of kilobytes in this raw VGA image, you would divide as follows: 921,600 ÷ 1,024, the number of bytes that are in a kilobyte, giving you an even 900KB of data in a truecolor VGA image. It is important to optimize for raw (uncompressed) image size by optimizing your digital imagery resolution. This is because once an image is decompressed out of a game application file, into system memory, this is the amount of memory that it is going to occupy, as the image will be stored pixel for pixel, using a 24-bit (RGB) or 32-bit (ARGB) representation in memory. This is one of the reasons I use PNG24 and PNG32 for my game development, not indexed color (GIF or PNG8); if the OS is going to transmute the color to a 24-bit color space, then you should use that 24-bit color space for quality reasons and deal with (accept) a slightly larger application file size. Image color depth is the next most critical contributor to the data footprint of a compressed image, because the number of pixels in the image is multiplied by 1 (8 bit), 2 (16 bit), 3 (24 bit), or 4 (32 bit) color data channels. This small file size is the reason 8-bit indexed color images are still widely used, especially with the GIF image format. Indexed color images can simulate truecolor images if the colors that are used to make up the image do not vary too widely. Indexed color imagery uses only 8 bits of data (256 colors) to define the image pixel color, using a palette of up to 256 optimally selected colors, instead of 3 RGB color channels or 4 ARGB color channels, containing 256 levels of color each. Again, it is important to note that once you turn a 24-bit image into an 8-bit image by compressing it using a GIF or PNG8 codec, you only have a potential (maximum) 256 of the original 16,777,216 colors at your disposal. This is why I am advocating using PNG24 or PNG32 imagery rather than GIF or PNG1 (2 color), PNG2 (4 color), PNG4 (16 color), or PNG8 (256 color) images, which JavaFX also supports. Depending on how many colors are employed in any given 24-bit source image, using 256 colors to represent an image originally containing 16,777,216 colors can cause an effect called banding. This is when the transfer between adjoining colors in the resulting (from compression) 256- (or less) color palette is not gradual and thus does not appear to be a smooth color gradient. Indexed color images have an option to correct visually for banding, called dithering. Dithering is an algorithmic process of making dot patterns along the edges between any adjoining colors within an image to trick the eye into seeing a third color. Dithering will give you a maximum perceptual number of colors (of 65,536; 256 × 256), but this will only occur if each of those 256 colors borders on each of the other 256 colors. Still, you can see the potential for creating additional colors, and you would be amazed at the result that indexed color formats can achieve in some compression scenarios (with certain imagery). Let’s take a truecolor image, such as the one shown in Figure 5-3, and save it as a PNG5 indexed color image format, to show you this dithering effect. It is important to note that PNG5, although supported in Android and HTML5, is not supported in JavaFX, so if you do this exercise yourself, select the 2-, 4-, 16-, or 256-color option! The figure demonstrates the dithering effect on the driver-side rear fender in an Audi 3D image, as it contains a gray gradient. 111 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Figure 5-3.  A truecolor PNG24 image created with Autodesk 3ds Max, which you are going to compress as PNG5 Interestingly, it is permissible to use less than the 256-colormaximum in an 8-bit indexed color image. This is often done to reduce further the imagery’s data footprint. For instance, an image that can attain good results using only 32 colors is actually a 5-bit image and would technically be called a PNG5, even though the format itself is generally called PNG8 for the indexed color usage level. I have set this indexed color PNG image, shown in Figure 5-4, to use 5-bit color (32 color, or PNG5) to illustrate this dithering effect clearly. As you can see in the image preview area, on the left-hand side of the figure, the dithering algorithm makes dot patterns between adjacent colors to create additional colors. Figure 5-4.  Setting dithering to the diffusion algorithm and 32 colors (5 bit), with 100 percent dithering for PNG5 output 112 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Also, note that you can set the percentage of dithering that is used. I often select either the 0 percent or 100 percent setting; however, you can fine-tune the dithering effect anywhere between these two extreme values. You can also choose between dithering algorithms, because, as you probably have surmised, the dithering effect is created using dithering algorithms, which are part of the indexed file format (in this case, PNG8) compression routines. I use diffusion dithering, which gives a smooth effect along irregularly shaped gradients, as is seen in the car fender. You can also use a noise option, which is more randomized, or a pattern option, which is less so. The diffusion option usually gives the best results, which is why I choose it when I am using indexed color (which is not often). Dithering, as you might imagine, adds data patterns to an image that are more difficult to compress. This is because smooth areas in an image, such as gradients, are easier for the compression algorithm to compress than sharp transitions (edges) or random pixel patterns (e.g., dithering or “noise” from a camera CCD). Therefore, applying the dithering option will always increase the data footprint by a few percentage points. Be sure to check the resulting file size with and without dithering applied (selected in the Export dialog) to see if it is worth the improved visual result that it affords. Note that there is also a transparency option (check box) for indexed color PNG images but that the alpha channel used in PNG8 images is only 1 bit (on/off ), not 8 bit, as with PNG32. You can also increase the data footprint of your image by adding an alpha channel to define transparency for compositing. This is because by adding an alpha channel you will be adding in another 8-bit color channel (or a transparency channel, actually) to the image being compressed. If you need an alpha channel to define transparency for your image to support future compositing requirements, such as using the image as a game sprite, there is not much choice but to include the alpha channel data. If your alpha channel contains all zeroes (or uses an all-black fill color), which would define your imagery as being completely transparent, or contains all FF values (or uses an all-white fill color), which would define your image as being completely opaque, you would essentially (in practical terms) be defining an alpha that does not contain any useful alpha data values. The transparent image would therefore need to be removed, and the opaque image would need to be defined as a PNG24 rather than a PNG32. Finally, most alpha channels that are used to mask objects in the RGB layers of the digital image should compress very well. This is because the alpha channel is primarily areas of white (opaque) and black (transparent), with some medium-gray values along the edge between the two colors to antialias the mask (see Figure 5-2). These gray areas contain the antialiasing values in the alpha channel, and will provide the visually smooth-edge transitions between the object in the RGB layers of the image and any background color or background images that may be used behind it. The reason for this is that in the alpha channel image mask, an 8-bit transparency gradient (from white to black) defines levels of transparency, which could be thought of as per-pixel blending (opacity) strength. Therefore, the medium-gray values on the edges of each object in the mask (which is contained in the alpha channel) will serve essentially to average the colors of the object edge, and any target background, no matter what color (or image) value it may contain. This offers real-time antialiasing with any target background that may be used, including animated backgrounds. Digital Video and Animation: Frames, Rate, Looping, Direction Interestingly, all the concepts that I have just covered for digital images apply equally well to digital video and animation, as both formats use digital images as the foundation for their content. Digital video and animation extend digital imaging into the fourth dimension (time) by using frames. The two formats are composed of an ordered sequence of frames, which are displayed rapidly over time. The term “frame” comes from the film industry, in which, even today, frames of film are run through film projectors at a rate of 24 frames per second (24FPS), which creates the illusion of motion. Because both digital video and animation are made up of a collection of frames containing digital images, the concept of frame rate, expressed as frames per second, is also very important when it comes to the memory data footprint optimization work process (for animation assets) as well as the digital video file size data footprint optimization work process. As discussed previously, in JavaFX this attribute for animation is stored in the Animation object rate variable (see Chapter 4). 113 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder The optimization concept regarding frames in an Animation object or digital video asset is very similar to the optimization concept regarding pixels in an image (the resolution of a digital image): the fewer used, the better! This is because the number of frames in an animation or video multiplies both the system memory used and the filesize data footprint with each frame. In digital video, not only does each frame’s (image) resolution, but also the frame rate (specified in the Compression Settings dialog) impact file size. Earlier in this chapter, you learned that if you multiply the number of pixels in the image by its number of color channels, you will get the raw data footprint for the image. With animation and digital video, you will now multiply that number again by the number of frames that need to be used to create the illusion of motion. Therefore, if you have an animated VGA (RGB) background plate for your game (remember that each frame is 900KB) that uses five frames to create the illusion of motion, you are using 900KB × 5, or 4,500KB (4.5MB), of system memory to hold that animation. Of course, this is too much memory to use for a background, which is why you will be using static backgrounds with sprite overlays to achieve this exact same end result in less than a megabyte. The calculation for digital video is a bit different, as it has hundreds or thousands of frames. For digital video you would multiply your raw image data size by the number of frames per second (frame rate) at which the digital video is set to play back (this frame rate value is specified during the compression process), and then multiply that result by the total number of seconds of content duration contained in your video file. To continue with the VGA example, you know that a 24-bit VGA image is 900KB. This makes the calculation to take this to the next level easy. Digital video traditionally runs at 30FPS, so 1 second of standard definition raw (uncompressed) digital video would be 30 image frames, each of which is 900KB, yielding a total data footprint of 27,000KB! You can see why having video compression file formats such as MPEG-4 H.264 AVC, which can compress the massive raw data footprint that digital video can create, is extremely important. The JavaFX media package uses one of the most impressive video compression codecs (“codec” stands for code-decode) which is also supported in HTML5 and Android, the aforementioned MPEG-4 H.264 AVC (advanced video codec). This is quite convenient for developer asset optimization, as one single digital video asset can be used across JavaFX, HTML5, and Android applications. Just in case you want to use digital video in the background of your game (which I do not recommend), I am going to cover the basics of digital video compression and optimization next. Digital Video Compression Concepts: Bit Rate, Data Streaming, SD, HD, UHD Let’s begin with the primary or standard resolutions that are used in commercial video. These also happen to be common device screen resolutions, probably because if the screen pixel resolution matches the video pixel resolution that is being played full screen on a screen, there will be zero scaling, which can cause scaling artifacts. Before high definition came along, video was standard definition (SD) and used a vertical resolution of 480 pixels. VGA is an SD resolution, and 720 × 480 could be called wide SD resolution. High definition (HD) video comes in two resolutions, 1,280 × 720, which I call pseudo HD, and 1,920 × 1,080, which the industry calls true HD. Both HD resolutions feature a 16:9 aspect ratio and are used in TVs and iTVs, smartphones, tablets, e-book readers, and game consoles. There is also an ultra high definition (UHD) resolution out now that features 4,096 × 2,160 pixels. Video streaming is a more complicated concept than resolution, as it involves playing back video data over a wide expanse, such as the one between your Java 8 game application and the remote video data server that will hold your potentially massive digital video assets. Furthermore, the device that your Java game application is running on will be communicating in real time with remote data servers, receiving video data packets as the video plays (it is termed streaming because the video is streaming from the video server, over the Internet, and into the hardware device). Video streaming is supported by the MPEG-4 H.264 AVC format codec (encoder-decoder pair). The last concept that you need to understand is bit rate. Bit rate is the key setting used in the video compression process, as bit rates represent your target bandwidth, or the data pipe size that is able to accommodate a certain number of bits streaming through it every second. The bit-rate setting should also take into consideration the CPU processing power that exists within any given Java-capable device, making your digital video’s data optimization even more challenging. Fortunately, most devices these days feature dualcore or quadcore CPUs! 114 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Once the bits travel through a data pipe, they also need to be processed and displayed on the device screen. Thus, bit rates for digital video assets must be optimized not only for bandwidth, but also in anticipation of variances in CPU processing power. Some single-core CPUs may not be able to decode high-resolution, high–bit rate digital video assets without dropping frames, so do make sure to optimize low–bit rate video assets if you are going to target older or less expensive consumer electronics devices. Digital Video Data Footprint Optimization: Using Codecs and Their Settings As mentioned earlier, your digital video asset will be compressed, using software utilities called codecs. There are two “sides” to the video codec: one that encodes the video data stream and another that decodes it. The video decoder will be part of the OS, platform (JavaFX), or browser that uses it. The decoder is primarily optimized for speed, as smoothness of playback is a key issue, whereas the encoder is optimized to reduce the data footprint for the digital video asset it is generating. For this reason, the encoding process can take a long time, depending on how many processing cores a workstation contains. Most digital video content production workstations should support eight processor cores, like my 64-bit AMD octacore workstation. Codecs (the encoder side) are like plug-ins, in that they can be installed into different digital video–editing software packages to enable them to encode different digital video asset file formats. Because Java and JavaFX 8 support the MPEG-4 H.264 AVC format, you need to make sure that you are using one of the digital video software packages that supports encoding digital video data using (or into) this digital video file format. More than one software manufacturer makes MPEG-4 encoding software, so there will be different MPEG-4 AVC codecs that will yield different (better or worse) results, in terms of encoding speed and file size. The professional solution, which I highly recommend that you secure if you want to produce digital video professionally, is called Sorenson Squeeze Pro. There is also an open-source solution called EditShare LightWorks 12, which is scheduled to support output to the MPEG4 codec natively by 2014. When optimizing (setting compression settings) for digital video data file size, there are many variables that directly affect the digital video data footprint. I will discuss these in their order of importance, in in terms of effect on video file size, from the most important to the least, so that you will know which parameters to tweak to obtain the result you are looking for. Like with digital image compression, the resolution, or number of pixels, in each frame of video is the optimal place to start the optimization process. If your user is using 800 × 480 or 1,280 × 720 smartphones, e-readers, or tablets, then you do not need to use true HD 1,920 × 1,080 resolution to get good visual results for your digital video assets. With superfine density (small dot pitch) displays out there, you can scale a 1,280 video up 33 percent, and it will look reasonably good. The exception to this may be HD or UHD (popularly termed 4K iTV) games targeted at iTVs; for these huge, 55- to 75-inch (screen) scenarios, you would want to use the industry standard, true HD 1,920 × 1,080 resolution. The next level of optimization would come in the number of frames used for each second of video (or FPS), assuming the actual number of seconds in the digital video itself cannot be shortened. As mentioned earlier, this is known as the frame rate, and instead of setting the video standard 30FPS frame rate, consider using a film standard frame rate of 24FPS or even the multimedia standard of 20FPS. You may even be able to use a 15FPS frame rate, half the video standard, depending on the amount (and speed) of movement within the content. Note that 15FPS is half as much data as 30FPS (a 100 percent reduction in data encoded). For some video content this will play back (look) the same as 30FPS content. The only way to test this is to try frame rate settings during the encoding process. The next most optimal setting for obtaining a smaller data footprint would be the bit rate that you set for a codec to try to achieve. Bit rate equates to the amount of compression applied and thus sets a quality level for the digital video data. It is important to note that you could simply use 30FPS, 1,920 resolution HD video and specify a low bitrate ceiling. If you do this, the results will not be as good-looking as if you had experimented with using a lower frame rate and resolution, in conjunction with a higher (quality) bit-rate setting. There is no set rule for this, as every digital video asset contains completely unique data (from the codec’s point of view). The next most effective setting for obtaining a smaller data footprint is the number of key frames that the codec uses to sample your digital video. Video codecs apply compression by looking at each frame and then encoding only the changes, or offsets, over the next several frames so that the codec algorithm does not have to encode every single 115 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder frame in a video data stream. This is why a talking head video will encode better than a video in which every pixel moves on every frame (such as video that uses fast camera panning, or rapid field of view [FOV] zooming). A key frame is a setting in a codec that forces that codec to take a fresh sampling of your video data assets every so often. There is usually an auto setting for key frames, which allows a codec to decide how many key frames to sample, as well as a manual setting, which lets you specify a key frame sampling every so often, usually a certain number of times per second or over the duration of the entire video (total frames). Most codecs usually have either a quality or a sharpness setting (a slider) that controls the amount of blur applied to a video frame before compression. In case you are not familiar with this trick, applying a slight blur to your image or video, which is usually not desirable, can allow for better compression, as sharp transitions (edges) in an image are harder to encode, taking more data to reproduce, than softer transitions. That said, I would keep the quality (or sharpness) slider between 80 percent and 100% percent and try to reduce your data footprint using one of the other variables that I have discussed here, such as decreasing the resolution, frame rate, or bit rate. Ultimately, there will be a number of different variables that you will need to fine-tune to achieve the best data footprint optimization for any given digital video data asset. It is important to remember that each video asset will look different (mathematically) to a digital video codec. For this reason, there can be no standard settings that can be developed to achieve any given compression result. That said, experience tweaking various settings will eventually allow you to get a feel, over time, for the various settings that you have to change, in terms of the different compressions parameters, to get the desired end result. Digital Audio Concepts: Amplitude, Frequency, Samples Those of you who are audiophiles know that sound is created by sending sound waves pulsing through the air. Digital audio is complex; part of that complexity comes from the need to bridge analog audio technology, created with speaker cones, with digital audio codecs. Analog speakers generate sound waves by pulsing them into existence. Our ears receive analog audio in exactly the opposite fashion, catching and receiving those pulses of air, or vibrations with different wavelengths, and then turning them back into data that our brain can process. This is how we “hear” the sound waves; our brain then interprets the different audio sound wave frequencies as different notes, or tones. Sound waves generate various tones, depending on the frequency of the sound wave. A wide, or infrequent (long), wave produces a low (bass) tone, whereas a more frequent (short) wavelength produces a higher (treble) tone. Interestingly, different frequencies of light will produce different colors, so there is a close correlation between analog sound (audio) and analog light (color). There are many other similarities between digital images (and video) that will also carry through into your digital new media content production, as you will soon see. The volume of a sound wave will be determined by its amplitude, or the height (or size) of that wave. Thus, frequency of sound waves equates to how closely together the waves are spaced, along the x axis if you are looking at it in 2D, and amplitude equates to how tall the waves are, as measured along the y axis. Sound waves can be uniquely shaped, allowing them to “piggyback” various sound effects. A “pure,” or baseline, type of sound wave is called a sine wave (which you learned about in high school trigonometry, with the sine, cosine, and tangent math functions). Those of you who are familiar with audio synthesis are aware that other types of sound waves are also used in sound design, such as the saw wave, which looks like the edge of a saw (hence its name), and the pulse wave, which is shaped using only right angles, resulting in immediate on and off sounds that translate into pulses (or bursts) of audio. Even randomized waveforms, such as noise, are used in sound design to obtain edgy sound results. As you may have ascertained by using your recently acquired knowledge of data footprint optimization, the more “chaos,” or noise, present in your sound wave (and in new media data in general), the harder it will be to compress for a codec. Therefore, more complex sound waves will result in larger digital audio file sizes, owing to the chaos in the data. 116 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Converting Analog Audio to Digital Audio Data: Sampling, Accuracy, HD Audio The process of turning analog audio (sound waves) into digital audio data is called sampling. If you work in the music industry, you have probably heard about a type of keyboard (or even rack-mounted equipment) called a sampler. Sampling is the process of slicing an analog audio wave into segments so that you can store the shape of the wave as digital audio data, using a digital audio format. This turns an infinitely accurate analog sound wave into a discrete amount of digital data, that is, into zeroes and ones. The more zeroes and ones used, the more accurate the reproduction of the infinitely accurate (original) analog sound wave. Each digital segment of a sampled audio sound wave is called a sample, because it samples that sound wave at an exact point in time. The sample accuracy (resolution) you want will determine how many zeroes and ones are used to reproduce analog sound waves, so the precision of a sample is determined by the amount of data used to define each wave slice’s height. As with digital imaging, this precision is termed the resolution, or, more accurately (no pun intended), the sample resolution. Sample resolution is usually defined using 8-bit, 12-bit, 16-bit, 24-bit, or 32-bit resolution. Games mostly leverage 8-bit resolution for effects such as explosions, in which clarity is not as important; 12-bit resolution for crystal-clear spoken dialogue and more important audio elements; and, possibly, 16-bit resolution for background music. In digital imaging and digital video this resolution is quantified by the number of pixels, and in digital audio, by how many bits of data are used to define each of the analog audio samples taken. Again, as with digital imaging, in which more pixels yields better quality, with digital audio a higher sample resolution yields better sound reproduction. Thus, higher sampling resolutions, using more data to reproduce a given sound wave sample, will produce higher-quality audio playback, at the expense of a larger data footprint. This is the reason that 16-bit audio (commonly referred to as CD quality audio) sounds better than 8-bit audio. Depending on the audio involved, 12-bit audio can be a great compromise. In digital audio there is a new type of audio sample, known as HD audio in the consumer electronics industry. HD digital audio broadcast radio uses a 24-bit sample resolution, so each audio sample, or slice of the sound wave, contains 16,777,216 bits of sample resolution. Some of the newer hardware devices now support HD audio, such as the smartphones you see advertised featuring “HD-quality audio,” meaning that they have 24-bit audio hardware. These days, laptops (including PCs), as well as game consoles and iTVs, also come standard with 24-bit audio playback hardware. It is important to note that HD audio is probably not necessary for Java 8 games, unless your game is music oriented and makes use of high-quality music, in which case you can use HD audio samples via a WAVE file format. Another consideration is digital audio sampling frequency (also called the sampling rate), This is a measure of how many samples at a particular sample resolution are taken during 1 second of sampling time frame. In terms of digital image editing, sampling frequency is analogous to the number of colors contained in a digital image. You are probably familiar with the term “CD-quality audio,” which is defined as using a 16-bit sample resolution and a 44.1kHz sampling rate (taking 44,100 samples, each of which has 16 bits of sample resolution, or 65,536 bits of audio data). You can determine the amount of raw data in an audio file by multiplying the sampling bit rate by the sampling frequency by the number of seconds in the audio snippet. Obviously, this can potentially be a huge number! Audio codecs are really great at optimizing data down to an amazingly small data footprint with very little audible loss in quality. Thus, the exact same trade-off that exists in digital imaging and digital video occurs with digital audio as well: the more data you include, the higher quality the result, but always at the cost of a much larger data footprint. In the visual mediums the size of the data footprint is defined using color depth, pixels, and, in the case of digital video and animation, frames. In the aural medium it is defined via the sample resolution, in combination with the sampling rate. The most common sampling rates in the digital audio industry currently include 8kHz, 22kHz, 32kHz, 44.1kHz, 48kHz, 96KHz, 192kHz, and even 384kHz. Lower sampling rates, such as 8kHz, 11kHz, and 22kHz, are the ones that you are going to use in your games, as, with careful optimization, these can yield high-quality sound effects and arcade music. These rates would be optimal for sampling any voice-based digital audio as well, such as movie dialogue or an e-book narration track. Higher audio sample rates, such as 44.1kHz, would be more appropriate for music, and sound effects that need a high dynamic range (high fidelity), such as rumbling thunder, could use 48kHz. Higher sample rates will allow audio reproduction that exhibits movie theater (THX) sound quality, but this is not required for most games. 117 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Digital Audio Streaming: Captive Audio vs. Streaming Audio As with digital video data, digital audio data can be either captive within the application distribution file (in the case of Java, a .JAR file) or streamed, using remote data servers. Similar to digital video, the upside to streaming digital audio data is that it can reduce the data footprint of the application file. The downside is reliability. Many of the same concepts apply equally well to audio and video. Streaming audio will save the data footprint, because you do not have to include all that heavy new media digital audio data in your .JAR files. So, if you are planning on coding a Jukebox application, you may want to consider streaming your digital audio data; otherwise, try to optimize your digital audio data so that you can include them (captive) inside the .JAR file. This way, the data will always be available to the application’s users when they need it! The downside to streaming digital audio is that if a user’s connection (or the audio data server) goes down, your digital audio file may not always be present for your end users to play and listen to, using your game application! The reliability and availability of digital audio data are a key factor to be considered on the other side of this streamingversus-captive trade-off. The same would apply to digital video assets as well. Again, as with digital video, one of the primary concepts in regard to streaming your digital audio is the bit rate of the digital audio data. As you learned in the previous section, the bit rate is defined during the compression process. Digital audio files that need to support lower bit-rate bandwidth are going to have more compression applied to the audio data, which will result in lower quality. These will stream (play back) more smoothly across a greater number of devices, because fewer bits can be quickly transferred as well as processed more easily. Digital Audio in JavaFX: Supported Digital Audio Codecs and Data Formats There are considerably more digital audio codecs in JavaFX than digital video codecs, as there is only one video codec, MPEG-4 H.264 AVC. Android audio support includes .MP3 (MPEG-3) files, Windows WAVE (Pulse Code Modulation [PCM] audio) .WAV files, .MP4 (or .M4A) MPEG-4 AAC (Advanced Audio Coding) audio, and Apple’s AIFF (PCM) file format. The most common format supported by JavaFX (and thus Java 8) is the popular .MP3 digital audio file format. Most of you are familiar with MP3 digital audio files, owing to music download web sites, such as Napster or Soundcloud, and most of us collect songs in this format to use on MP3 players and in CD-ROM- or DVDROM-based music collections. The MP3 digital audio file format is popular because it has a fairly good compressionto-quality ratio and is widely supported. MP3 is an acceptable format to use in a Java 8 application, so long as you get the highest quality level possible out of it, using an optimal encoding work process. It is important to note that, like JPEG (used for images), MP3 is a lossy audio file format, in which some of the audio data (and thus quality) are thrown away during your compression process and cannot be recovered. JavaFX does have two lossless audio compression codecs, AIFF and WAVE. Many of you are familiar with these, as they were the original audio formats used with the Apple Macintosh and Microsoft Windows OSs, respectively. These files use PCM audio, which is lossless (in this case, because there is no compression applied whatsoever!). “PCM,” which, as stated, stands for “pulse code modulation,” refers to the data format it holds. PCM audio is commonly used for CD-ROM content as well as telephony applications. This is because PCM WAVE audio is an uncompressed digital audio format, with no CPU-intensive compression algorithms applied to the data stream. Thus, decoding (CPU data processing) is not an issue for telephony equipment or for CD players. For this reason, when you start compressing digital audio assets into the various file formats, you can use PCM as your baseline file format. It allows you to look at the difference between PCM (WAVE) and MP3 and MP4 audio compression results to get an idea of how much data footprint optimization you are getting for your JAR file; more important, you can also see how your sample resolution and sample frequency optimization are going to affect the system memory used for your game’s audio effects. Even if you used an MP3 or MP4 format, it would still have to be decompressed into memory before the audio asset could be used with the AudioClip class and employed as a sound effect in a Java 8 game. 118 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Because a WAVE or AIFF file will not have any quality loss (as there is also no decompression needed), the PCM data can be placed straight from the JAR file into system memory! This makes PCM audio great for game sound effects that are short in duration (0.1 to 1 second), and it can be highly optimized, using 8-bit and 12-bit sample resolution and 8kHz, 22kHz, or 32kHz sample frequency. Ultimately, the only real way to find out which audio format supported by JavaFX has the best digital audio compression result for any given digital audio data is to encode your digital audio in the primary codecs that you know are supported and efficient. I will be outlining this work process later on, when you add audio to the game, and you will observe the relative data footprint results between the different formats, using the same source audio sample (see Chapter 15). Then, you will listen to the audio playback quality so that you can make your final decision concerning the optimal balance between quality and file size . This is the work process that you will need to go through to develop JavaFX digital audio assets for use in your Java 8 game. JavaFX also supports the popular MPEG-4 AAC codec. These digital audio data can be contained in MPEG4 containers (.mp4, .m4a, .m4v), or file extensions, and can be played back using any OS. It is important to note that JavaFX does not contain an MPEG-4 decoder, but instead supports what is called a multimedia container, meaning that JavaFX uses the OS’s MPEG-4 decoder. For this reason, and because online listening studies have concluded that the MP3 format has better quality (for music) than the MP4, you will be using the MP3 format for longer-form audio (game background musical loops) via the Media and MediaPlayer classes. You will use the PCM WAVE audio format for short-form (1 second or less) audio (game sound effects, such as shots, bells, yelps, grunts, laughter, cheering, and other such digital audio assets), which you will use via the AudioClip digital audio sequencing engine (class) that JavaFX so generously provides. Digital Audio Optimization: Start with CD-Quality Audio, and Work Backward Optimizing your digital audio assets for playback across the widest range of hardware devices on the market is going to be easier than optimizing your digital video or digital imagery (and thus animation) across these devices. This is because there is a much wider disparity between target screen resolutions and display aspect ratios than there is between types of digital audio playback hardware support across hardware devices (with the possible exception of new hardware featuring 24-bit HD audio playback hardware compatibility). All hardware plays digital audio assets well, so audio optimization is a “one audio asset hits all devices” scenario, whereas with the visual (video, image, animation) part of the equation, you have display screens as large as 4,096 × 2,160 pixels (4K iTV Sets) and as small as 320 × 320 pixels (flip phones and smart watches). It is important to remember that the user’s ears cannot perceive the same quality difference with digital audio that the user’s eyes can with digital imagery, 2D animation, and digital video. Generally, there are three primary “sweet spots” of digital audio support across all hardware devices that you should target for support for Java game audio. Lower-quality audio, such as short narration tracks, character exclamations, and short-duration sound effects, can achieve remarkably high quality by using a sampling rate of 8kHZ or 22kHz, along with 8-bit or 12-bit sampling resolution. Medium-quality audio, such as long narration tracks, longer-duration sound effects, and looped background (ambient) audio, can achieve a very high quality level by using a 22kHz or 32kHz sampling rate, along with a 12-bit or 16-bit sampling resolution. The high-quality audio assets, such as music, should be optimized approaching CD-quality audio and will use a 32kHz or 44.1kHz sampling rate, along with the 16-bit data sampling resolution. For HD-quality audio, being at the ultra-high end of this audio spectrum, you would use the 48kHz sampling rate, along with the 24-bit digital audio data sampling resolution. There is also an unnamed, “somewhere in the middle” high-end audio specification, using a 48kHz sampling rate, along with a 16-bit data sampling resolution, which just happens to be what Dolby THX used to use for its high-end audio experience technology in movie theaters (back in the day). Ultimately, it comes down to the quality–file size balance results that emerge from the digital audio data footprint optimization work process, which can be amazing. Therefore, your initial work process for optimizing your digital audio assets across all these hardware devices is going to be to create baseline 16-bit assets, at either 44.1kHz or 48kHz, and then optimize (compress) them, using the different formats supported in JavaFX. Once that work process is completed, you can see which resulting digital audio assets provide the smallest data footprint, along with the highest quality digital audio playback. After that, you can reduce your 44.1KHz or 48kHz data to 32kHz and save 119 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder that out ,using first 16-bit and then 12-bit resolution. Next, reopen the original 48kHz data, downsample to 22kHz sample frequency, and export that, using 16-bit and 12-bit resolution, and so on. You will be performing this work process later on, when you add digital audio assets to the Java 8 game, so you will see the entire process (see Chapter 15). Next, let’s take a look at JavaFX Scene Builder and how it uses FXML to allow designers to design Java FX applications visually. I am not going to be using Scene Builder or FXML (just Java 8 code and JavaFX classes) over the course of this book, so pay attention! JavaFX Scene Builder: Using FXML for UI Design JavaFX Scene Builder is a visual design tool that generates an FXML (JavaFX markup language) UI Scene Graph construct to define your JavaFX application’s front-end design. This FXML UI definition can then be “inflated” in Java 8 to create your application’s JavaFX Scene Graph, nodes, groups, and SubScene objects filled with javafx. scene.control package classes (objects) defining your UI design. Oracle’s intention in offering both a Scene Builder visual development tool and FXML is to allow nonprogrammers, ostensibly UI designers, to design the front-end UIs for their Java 8 applications so that the Java programmers can then focus on back-end functional application task processing logic. Because FXML and Scene Builder are optimized for UI design (arranging controls, such as buttons, text entry fields, radio buttons, check boxes, and so on), I am not going to use Scene Builder and FXML over the course of this book. I am, however, going to cover it in this chapter so that you know how to use it if you want to for your other JavaFX applications. My reasoning is that, other than the initial game splash screen, which contains a few UI Button objects, which show game instructions, list the contributors, track the high scores, save a current game state, and start game play, UI design will not be a major focus of this book. To use FXML, and soon after use of the Scene Builder visual UI design tool, you must create a special kind of FXML application, as you learned in Chapter 2 (see Figure 2-4), when you created the JavaFX game. Creating an FXML application imports the javafx.fxml package and classes. This allows the Java 8 code to inflate FXML constructs created by the UI designers so that they can be used by the programmers to attach Java logic to the various UI controls. The Android OS does this as well, using basic XML, but in Android this approach is not optional; it is part of the way things are done. In JavaFX 8 (as you saw in Figure 2-4), it is simply one option. If you want to research XML-based UI design further for Android, check out my book Pro Android UI (Apress, 2014). The Scene Builder visual layout tool that writes FXML UI design constructs for you is a WYSIWYG drag and drop interface design tool. All a designer has to do is drag and drop any of the JavaFX UI controls onto the editing screen from a UI Control panel that contains every Control class (object) in the javafx.scene.control package (see Chapter 4). This Scene Builder is integrated into NetBeans 8.0 for easy access and integration with JavaFX, in case programmers also need to use it to quickly prototype UI designs for their clients. There is also a stand-alone version of the Scene Builder tool, at version 2.0, for designers who do not want to work inside the NetBeans IDE. You can switch back and forth from FXML editing and previewing in real time and see UI design and layout changes without having to compile the Java application. You can also apply all CSS styles to the Scene Builder tool and FXML structure in real time and see the results of those coding changes as well, again, without any Java compilation! In addition, you can add custom UI controls to the UI Control panel library, using third-party JAR files or FXML definitions. The Scene Builder Kit API is open source. This lets you customize your own integrations of Scene Builder’s UI panels and controls, allowing you to integrate Scene Builder into other IDEs, such as Eclipse or IntelliJ IDEA. A rich text TextFlow container has recently been added into the GUI component (Control) library, affording rich text– editing capabilities. With these new capabilities, you can build multiple-node, rich text constructs that can integrate other UI elements, or new media element types, with the TextFlow elements. For you 3D “aficionados,” 3D is also fully supported in the Scene Builder visual design editor and in FXML. A 3D object can be loaded and even saved out using the Scene Builder tool, and all of the object’s properties can be edited (and viewed) in real time, using the Inspector panel. It is not yet possible to create from scratch 3D objects using Scene Builder, and you cannot yet assign or edit complex Mesh or Materials properties at this time, but I am sure that these features will come, along with the advanced 3D OpenGL ES power that is scheduled to be added into JavaFX 8. 120 www.it-ebooks.info Chapter 5 ■ An Introduction to Game Design: Concepts, Multimedia, and Using Scene Builder Next, let’s take a look at FXML markup language specifically, at an in-depth level. After that, you will examine an actual FXML UI definition structure, and you will see exactly how the current JavaFX application’s UI design would be structured using an FXML UI definition construct. As you will see, FXML makes UI design a lot easier! FXML Definition: Anatomy of an XML UI Definition Construct The FXML structure is based on the JavaFX classes (objects), and their attributes, that the FXML tags, and parameters structures, which you can easily create, allow you to “mock up” a front-end UI more easily, using a mark-up language. The FXML structure lets you more easily construct your Scene Graph hierarchy, and the FXML tags and their parameters, which you will be looking at in the next section, match up 1:1 with the JavaFX API classes. Once you create your UI design, the Java programmers can use javafx.fxml classes and methods to inflate your UI layout container and UI control arrangement into a JavaFX scene and Scene Graph structure, based on Java objects. Then, the UI design can be used in the application Java code. As mentioned earlier, FXML is most useful for designing complex, static (fixed) UI design layouts containing lots of buttons, forms, check boxes and the like. Hello World UI FXML Definition: Replicating Your Current UI Design, Using FXML The first thing that you define in the FXML structure is the FXML processing instructions. Each processing instruction starts with a less-than sign, question mark sequence (]). The first processing instruction is a declaration of the XML language use, its version (1.0), and the text character set language-encoding format that you want to use (in this case, UTF-8 [universal character set transformation format, 8 bit]). Because it is 8 bit, there are 256 characters in this international character set, which was designed to span the many languages based on Germanic characters, that is, languages that use an A to Z alphabet (including accented characters). Following the declaration of an XML language and a character set are processing instructions. These import the Java language, utilities, and javafx.scene package as well as the javafx.scene.layout and javafx.scene.control packages, which are used to design the UI layout and the UI controls that the layout contains. For example, the StackPane UI layout container that you are using in the current application is in the javafx. scene.layout package, and the button UI control element is in the javafx.scene.control package. Because the FXML UI layout container is the parent element in this structure, it goes first, or outside the nested FXML UI definition structure that you are about to create. Inside the , you will nest children of the StackPane class (object), using the tags ( XML tags are coded using ). Nested inside these tags are the UI control elements (in this case, a button control, so you would use the