© Lee Stemkoski 2018
Lee StemkoskiJava Game Development with LibGDXhttps://doi.org/10.1007/978-1-4842-3324-5_1

1. Getting Started with Java and LibGDX

Lee Stemkoski
(1)
DEPT OF MATH & CS, ADELPHI UNIVERSITY DEPT OF MATH & CS, Garden City, New York, USA
 
This chapter will explain how to set up a Java development environment and configure it to run with the LibGDX game development framework. You’ll see a simple example of a “Hello, World!” program and explore it in enough detail to understand the different parts. Finally, you’ll learn some of the advantages to be gained by working with the LibGDX library .

Choosing a Development Environment

Before diving into Java programming, you will need to set up an integrated development environment (IDE)— the software you will use for writing, debugging, and compiling code. There are many editors for writing your Java programs, each customized for different skill levels. BlueJ ( www.bluej.org ) and DrJava ( www.drjava.org ) are designed for beginners and educational use and are frequently used in introductory programming courses in schools and colleges. IntelliJ IDEA ( www.jetbrains.com/idea/ ), NetBeans (netbeans.org), and Eclipse (eclipse.org) are advanced editors that are preferred by practicing professionals. For compiling and running Java code, you’ll need the Java Development Kit (JDK) , which is available directly from the Oracle Corporation or is bundled directly with some of the editors just listed.
Each editor has advantages and disadvantages. BlueJ and DrJava are user friendly and have simple, minimal user interfaces, but lack some of the advanced editors’ features, such as autocompletion of fields, methods, and import statements. The advanced editors are faster, feature-packed, more powerful, highly customizable, and replete with various plug-ins, but they also have a steep learning curve and user interfaces that may be more daunting to beginners. Figure 1-1 illustrates this point with a side-by-side comparison of the Eclipse and BlueJ interfaces. The screenshots and descriptions of the BlueJ software in this chapter are from BlueJ version 4.1.0.
A352797_2_En_1_Fig1_HTML.jpg
Figure 1-1.
User interfaces for Eclipse (left) and BlueJ (right)
This chapter will cover how to set up BlueJ . I chose this particular IDE because it is quick and easy to set up and configure, which will enable you to start programming games even faster. However, if you are already familiar and comfortable with one of the more advanced editors, of course you should feel free to use it rather than BlueJ. A wealth of informational material is available for setting up Eclipse, NetBeans, and IntelliJ IDEA with LibGDX at the LibGDX wiki ( https://github.com/libgdx/libgdx/wiki ). If you choose to use one of these programs, then after your IDE is set up, skip ahead to the upcoming section “Creating a ‘Hello, World!’ Program for LibGDX.”

Setting Up BlueJ

This section will cover how to set up the BlueJ IDE . Since it was designed for beginners, the number of steps is small and the process is straightforward, as you will see.

Downloading and Installing

BlueJ can be downloaded from www.bluej.org .
There are multiple download options available for a variety of operating systems. Furthermore, some of these downloads are bundled with the JDK, and some are not. The JDK includes tools for developing and debugging Java applications; in particular, it is necessary for compiling your code. If you have used your computer to develop Java applications before, you likely already have the JDK installed and can just select the stand-alone BlueJ installer. If you aren’t sure, you should download and run the BlueJ combined installer.

Using BlueJ

When learning a new programming language or library, it is a well-established tradition in computer science to write a “Hello, World!” application as a first program. This section will cover the basics of using BlueJ to write this program:
  1. 1.
    Start up the BlueJ software. (The first time you run it, it may prompt you for the location of the directory where the JDK is stored, and it may also ask if you want to participate in helping to improve the software by providing information.)
     
  2. 2.
    When the main window appears, in the menu bar, select Project, then select New Project. BlueJ organizes your work into projects, which are stored as directories; all Java source code and compiled class files are stored in the project directory.
     
  3. 3.
    When prompted for a project name, navigate to a folder where you want to store your files, enter MyProject, and click the OK button. This creates a folder in the selected location with the same name.
    After Step 3, your screen should look similar to Figure 1-2.
    A352797_2_En_1_Fig2_HTML.jpg
    Figure 1-2.
    The BlueJ project window
     
  4. 4.
    Create a new class, either by clicking the New Class button or by selecting Edit and then selecting New Class from the menu bar.
     
  5. 5.
    When you are prompted to enter a name for the class, type HelloWorld and press the Enter key, or click the OK button. An orange rectangle appears with the name of your class at its top. The gray diagonal lines indicate that the code has not yet been compiled.
     
  6. 6.
    Either double-click the rectangle or right-click and select Open Editor to edit the file. You will see that some template code has been added. You should begin by deleting this code; the simplest way is to press Ctrl-A to select all the code, then press the Delete key. Then, enter the following code in its place:
    public class HelloWorld
    {
        public static void main()
        {
            System.out.print("Hello, World!");
        }
    }
    After entering this code into BlueJ, it should appear similar to the screenshot in Figure 1-3. Don’t worry about what this code does just yet. If there are any errors in the code, then that line number will be marked in red and the incorrect syntax will be underlined. If you hover the mouse pointer over the error, a popup will appear that provides a description of the error and sometimes a suggestion for how to fix it. Figure 1-4 illustrates what would happen if you accidentally typed pint instead of print in the preceding source code.
    A352797_2_En_1_Fig3_HTML.jpg
    Figure 1-3.
    A “Hello, World!” program displayed in the BlueJ code editor
    A352797_2_En_1_Fig4_HTML.jpg
    Figure 1-4.
    A syntax error caught by the BlueJ code editor
     
  7. 7.
    Click the Compile button to compile your code. (This action also automatically saves your code.) You should see the message “Class compiled – no syntax errors” in the status bar at the bottom of the window.
     
  8. 8.
    Return to the main BlueJ window. Right-click the orange rectangle representing the class (it contains the class name HelloWorld across the top), and select the method void main() from the list that appears. This runs the method that you have just written. A terminal window appears containing the text Hello, World!, as shown in Figure 1-5.
    A352797_2_En_1_Fig5_HTML.jpg
    Figure 1-5.
    Text displayed by the “Hello, World!” program
     
Congratulations on running your first program using BlueJ!
BlueJ has a number of features that make programming easier. While entering the preceding code, you may have noticed the syntax highlighting (Java keywords and strings appear in different colors) and also that classes and methods appear surrounded by different background colors, which makes it easier to visually inspect your code. (Later, you’ll notice that conditional statements and loops are similarly distinguished with background colors.) BlueJ contains additional features that you may find useful, such as the following:
  • Automatic code formatting. Selecting Auto-Layout from the Edit menu of the source code editing window will adjust the whitespace in your code so that nested statements are aligned consistently .
  • Listing available method names. After typing the name of a class or object, followed by a period, pressing Ctrl+Space will display a list of available method names.
  • Shortcut keys for indenting/un-indenting and commenting/uncommenting blocks of code. These are listed in the Edit menu.
  • A simple interface for adding breakpoints, which activates a debugger that allows you to step through code line by line and easily inspect objects.
For complete information on these and other features, see the BlueJ reference manual at www.bluej.org/doc/bluej-ref-manual.pdf . At this point, you can close the code editor window and terminal window.

Setting Up LibGDX

In this section, you’ll configure BlueJ so that it can use the LibGDX software library . Software libraries are collections of prewritten code and methods that can be used by other programs. Their value lies in their reusability—they accelerate and simplify the development process when they implement frequently needed processes, saving programmers from needing to “reinvent the wheel” every time they write a program. The LibGDX libraries, for example, contain methods for displaying graphics, playing sounds, and getting input from the user. (Advanced functions are available as well, which will be discussed later in this chapter.)
In Java, libraries are stored in Java Archive (JAR) files . A JAR file contains many compiled Java files (similar to a ZIP file), stored in a standardized directory structure that the JDK can navigate. Your first step is to obtain the LibGDX JAR files that you will need for our project. The most up-to-date official information on obtaining these files is at https://github.com/libgdx/libgdx/wiki/Updating-LibGDX , which may be confusing for beginners. Alternatively, a simpler option is to use the versions of these files included on the download website for this book at apress.com.1 The five JAR files you will need for all projects in this book are gdx.jar, gdx-sources.jar, gdx-natives.jar, gdx-backend-lwjgl.jar, and gdx-backend-lwjgl-natives.jar; they contain the core code for the LibGDX library.
Once these four JAR files have been obtained, BlueJ needs to be configured so that it recognizes and can use the contents of these files. There are two main ways to do so:
  • The easiest way to make BlueJ aware of JAR files is to create a directory named +libs within the project directory, copy the JAR files into this directory, and then restart the BlueJ software. By default, when a project is opened in BlueJ, it automatically scans for the presence of a folder named +libs and takes its contents into account when compiling new code. Although this is the easiest method, you will need to recreate this directory and make copies of the JAR files for every new project, which is not the most efficient method.
  • When there are JAR files that might be used in multiple projects, rather than creating redundant copies of these files in +libs directories for each of these projects, they can be copied to a special subdirectory, named userlib, in the folder where the BlueJ software is installed. The full path to the directory should be something similar to C:Program FilesBlueJlibuserlib; the exact name can be checked by selecting the menu option ToolsPreferences in Windows, or BlueJPreferences in OS X, and clicking the Libraries tab.
Once these steps are complete, BlueJ needs to be restarted, and then you’ll be ready to write your first program in LibGDX.

Creating a “Hello, World!” Program with LibGDX

Traditionally, a “Hello, World!” program displays a text message on the screen. Since our ultimate goal is to create video games—primarily visual programs—your first LibGDX program will draw a picture of the world in a window, as shown in Figure 1-6.
A352797_2_En_1_Fig6_HTML.jpg
Figure 1-6.
A “Hello, World!” program created using LibGDX
Here, you will begin to see some of the advantages of and start to understand what is meant by building upon the classes provided by the LibGDX libraries. Our first project contains two classes. The first class, called HelloWorldImage, makes use of the functionality of a LibGDX class called Game by extending it.
Extending A Class
One of the central principles of software engineering is to design programs that avoid redundancy by creating reusable code. One way to accomplish this is by the object-oriented concept of inheritance: the creation of a new class based on an existing class.
For example, if we were designing a role-playing game, it would probably have many types of playable characters, such as warriors, ninjas, thieves, and wizards. If we were to design classes to represent each of these characters, they would have certain features in common: they each have a name, a certain number of health points (HP) , and perhaps a method named attack that can be used when simulating combat.
Some features also may be unique to each character; for example, perhaps wizards also have a certain number of magic points (MP) , and a method named castSpell that is called when they use magic. Because of the differences between these characters, we can’t create a single class that represents all of them; at the same time, it feels redundant to keep entering the same fields over and over again in each of their separate classes. An elegant approach to this type of scenario is to create a base class that contains all the features common to these characters, and create other classes to extend this base class. The extending class has access to all the fields and methods of the base class, and can also contain its own fields and methods as usual. We could implement this scenario with the following code :
public class Person
{
        String name;
        int HP;
        public void attack(Person other)
        {
                // insert code here...
        }
}
And then we can extend the Person class as follows:
public class Wizard extends Person
{
        int MP;
        public void castSpell( String spellName )
        {
                // insert code here...
        }
}
Then, if we were to create instances of these classes:
Person percy = new Person();
Wizard merlin = new Wizard();
Then, commands such as merlin.MP += 10 and merlin.castSpell("fireball") are valid, as well as commands involving fields and methods of the base class, such as merlin.HP -= 3 and merlin.attack( percy ). However, the object called percy can use only the fields and methods of the Person class; code such as percy.HP += 5 will compile, but percy.castSpell("lightning") will result in an error when the file is compiled.
The concept of extending a class is not only useful for in-game entities, but also for framework-like elements. For example, it would be useful to have a Menu class that contains functionality common to all types of menus, such as opening and closing the menu. It might then be useful to create other classes that extend this one; for example, a class named SelectionMenu could be created, which is a Menu that specializes in displaying some sort of information and asks the player to make a selection from a set of options. An InformationMenu class might be a menu that displays some text-based information and simply closes when the player is finished reading it.
In BlueJ, the project named MyProject should still be open; if not, open the project. Create a new class in this project, called HelloWorldImage, and enter the source code that follows. Note that before the class itself, there are a number of import statements that indicate which of the LibGDX classes (from the JAR files you set up earlier) you’ll be using in this program. Also note that this program uses an image with the filename world.png; this image is included in the source code for this chapter, in the folder MyProject (the source code is available from apress.com). You should copy this image into your MyProject folder. Alternatively, you could use an image of your own choosing instead; a size of 256 by 256 pixels is recommended for this program, and don’t forget to change the filename in the following code accordingly if you do.
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.Texture;
public class HelloWorldImage extends Game
{
    private Texture texture;
    private SpriteBatch batch;
    public void create()
    {
        FileHandle worldFile = Gdx.files.internal("world.png");
        texture = new Texture(worldFile);
        batch = new SpriteBatch();
    }
    public void render()
    {
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        batch.draw( texture, 192, 112 );
        batch.end();
    }
}
The HelloWorldImage class contains two objects: a Texture and a SpriteBatch. A Texture is an object that stores image-related data: the dimensions (width and height) of an image and the color of each pixel. A SpriteBatch is an object that draws images to the screen.
The HelloWorldImage class also contains two methods: create and render.
The create method initializes the Texture and SpriteBatch objects. In particular, the Texture object requires an image file from which it will get its image data. For this purpose, you create a FileHandle: a LibGDX object that is used to access files stored on the computer. The Gdx class contains many useful static objects and methods (similar to Java’s Math class); here, you use a method named internal to generate a FileHandle object that will be used by the Texture object. The internal method will search for the file in the BlueJ project directory, the same location where the compiled class files are stored.
After the create method is finished, the render method will be called by LibGDX approximately 60 times per second (since this is what the Game class does by default).2 This method contains a pair of static method calls: one to select a particular background color (the values in this example correspond to the color white) and another to use that color to clear the window. After this, the SpriteBatch object is used to position and draw the texture to the window.
Next, you’ll create a second class that is used to start the program; it creates an instance of the HelloWorldImage class and activates its methods. Such a class is often called a driver class and requires you to write a static method.
Static Methods And Driver Classes
By default, the methods of a class are called by instances of that class. However, a method can also be declared to be static, meaning that it is called from the class directly (rather than an instance). Whether a method should be instance-based or class-based (static) depends on how the method is used and what data it requires.
An instance-based method usually depends on the internal data specific to that instance. For example, every String object has a method called charAt, which takes an integer as input and returns the character stored at that position in the String. If we create two String objects as follows:
String player1 = "Lee";
String player2 = "Dan";
then the expression player1.charAt(1) returns the character 'e', while player2.charAt(1) returns the character 'a'. The value returned by this method depends on the data stored in that instance, and thus charAt is most assuredly an instance-based method.
In object-oriented programming languages, most of the methods of a class will be instance-based because they either depend upon or potentially change the values of an instance’s variables. There are, of course, situations where static methods are more natural. In general, any method that does not involve the internal state of an object could be declared as static (such as mathematical formulas—all the methods of Java’s Math class are static).
A driver class (also sometimes referred to as a main, entry point, starter, or launcher class) is a class whose purpose is to drive the execution of another class, which often involves creating an instance of the class and calling one or more of its methods. The driver class typically requires only a single method to accomplish this task; this method is traditionally called main. Since it is the first method called by the program, the main method must be declared as static, because when a program starts, there are no instances available to run instance-based methods. If the main method were not static, we would have a problem similar to the philosophical conundrum: which came first, the chicken or the egg? Something has to be able to instantiate a class without itself being instantiated, and this is exactly what the static main method of a driver class does.
A standard “Hello, World!” program could be rewritten using a driver class as follows:
public class Greeter
{
        public void sayHello()
        {
                System.out.print("Hello!");
        }
}
public class Launcher
{
        public static void main()
        {
                Greeter greta = new Greeter();
                greta.sayHello();
        }
}
Next, in the same project, create a class called HelloLauncher that contains the following code:
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
public class HelloLauncher
{
    public static void main (String[] args)
    {
        HelloWorldImage myProgram = new HelloWorldImage();
        LwjglApplication launcher = new LwjglApplication( myProgram );
    }
}
As mentioned in the previous “Static Methods and Driver Classes” sidebar, this class first creates an instance of the HelloWorldImage class, called myProgram. Then, instead of running the methods of myProgram directly, the main method creates a LwjglApplication object, which sets up a window and manages the graphics and audio, keyboard and mouse input, and file access. The LwjglApplication object takes myProgram as input and then runs the create and render methods of myProgram as discussed previously.
The acronym LWJGL stands for the Lightweight Java Game Library , an open source Java library originally created by Caspian Rychlik-Prince to simplify game development in terms of accessing the desktop computer hardware resources. In LibGDX, LWJGL is used for the desktop backend to support all the major desktop operating systems, such as Windows, Linux, and Mac OS X.
Another benefit to having a driver class separate from the classes that contain the game functionality is the potential to create driver classes for other platforms, such as Android, which LibGDX also supports.
When you’ve entered all the code for both classes, return to the main window in BlueJ and click the Compile button. Then, right-click the orange rectangle for the HelloLauncher class, and in the list of methods that appears, select the method listed as void main(String[] args). A pop-up window appears, in which you could enter an array of strings as input if you needed to—but you don’t. Click the OK button, and you should see a window as shown previously in Figure 1-6.
Congratulations on completing your first application using LibGDX!
Note
Sometimes, your program will contain a runtime error, often caused by issues such as entering a filename incorrectly (which cannot be detected when the program is compiled). In this case, after fixing the error and running the program again, you may encounter a different error containing the message “No OpenGL context found in the current thread.” This is due to the prior unexpected shutdown of the application and can usually be fixed in BlueJ by resetting the Java virtual machine, which can be done via the Tools menu or with a shortcut key combination (Ctrl-Shift-R on Windows).

Advantages to Using LibGDX

In addition to the ability to compile your game so that it can run on multiple platforms, there are many other advantages to using the LibGDX game development framework. LibGDX makes it easy to accomplish tasks such as these:
  • Render 2D graphics, animations, bitmap-based fonts, and particle effects
  • Stream music and play sound effects
  • Process input from a keyboard, mouse, touchscreens, accelerometer, or game pad
  • Organize user interfaces using a scene graph and fully skinnable UI control library
  • Integrate third-party plug-ins, such as the Box2D physics engine (box2d.org), the Tiled map editor file format (mapeditor.org), and the Spine 2D animation software (esotericsoftware.com)
  • Render 3D graphics with materials and lighting effects and load 3D models from common file formats such as OBJ and FBX
A complete list of LibGDX features can be found at the website: http://libgdx.badlogicgames.com/features.html .

Summary

In this chapter, you’ve set up BlueJ, an integrated development environment for Java programming, and configured BlueJ to use the LibGDX game development framework. Then, you created your first application with LibGDX: a “Hello, World!” program that displays an image of the world in a window. This program involved extending LibGDX’s Game class and creating a driver class that runs the program on the desktop. Along the way, you learned about a few of the other classes involved in this program. Finally, you learned about some of the additional features of the LibGDX library, many of which will be discussed in detail in future chapters.
Footnotes
1
More recent versions of these files can be obtained from the website https://libgdx.badlogicgames.com/nightlies/dist/ . These are the nightly builds of the LibGDX libraries, which contain the most up-to-date code, but they are also under development and thus may contain a few bugs or glitches.
 
2
Since neither the texture nor the coordinates are changing in this example, the fact that the render method is called repeatedly is irrelevant here. However, if you were to periodically change the image, you could generate an animation; if you were to gradually change the coordinates, you could simulate motion. You will see how to accomplish both of these variations in the following chapter.
 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset