LibGDX Tutorial 1

download LibGDX Tutorial 1

of 45

Transcript of LibGDX Tutorial 1

  • 8/10/2019 LibGDX Tutorial 1

    1/45

    LibGDX Tutorial 1: Creating an initial project

    In case youve never heard of it, LibGDX is a Java based game library capable of targeting iOS, Android,

    Desktop ( Windows, Mac and Linux ) and HTML5. It provides a full suite of 2D game functionality including Input,

    Graphics, Fonts, Physics, Storage and increasingly, 3D. So basically LibGDX is pretty much a one stopgamedevelopment library. This series is going to look at all of those aspects of LibGDX eventually.

    The first part of getting started with LibGDX is

    installation. If you havent got a Java/Android

    development environment set up yet, this portion is

    going to be a bit annoying. In a nutshell you need to

    install in order theJava JDK,Android SDK, Eclipse,

    thenGoogle ADTand finally theGoogle Plugin for

    Eclipse( for GWT ). I am not going into specifics about

    how to install all of these, however I went into pretty

    extreme detail inthese instructions for setting up

    PlayNthat cover most of the Eclipse related

    configuration. If you run into a problem during the install, those instructions might help. The process is actually

    pretty straight forward, its just long. Oh yeah, one more thing you are going to need of course is LibGDX

    itself! You candownload it here. In my limited experience, the nightly builds are actually pretty safe to

    use. Common sense dictates you should use the stable version, but I am neither common nor sensible, so Im

    going to risk it.

    From this point on, I am going to assume you have a properly configured Eclipse install. I am no huge fan of

    Eclipse and you have other options likeNetBeans(instructions) orIntelliJ(instructions), but they are the less

    supported and slightly more complicated route. Like it or not, if you are working with Android, Eclipse is still the

    path of least resistance. Android Studiois a very encouraging option but sadly its Android focus make it a poor

    fit for LibGDX.

    OK, lets get started

    If you havent already, unzip theLibGDX archive somewhere. I personally went with C:\dev\libgdx-0.9.8. Keep

    the zip archive however.

    Located and double click gdx-setup-ui.jar in the root directory of the libGDX.

    The following Window should load:

    http://www.gamefromscratch.com/post/2013/09/19/LibGDX-Tutorial-1-Creating-an-initial-project.aspxhttp://www.gamefromscratch.com/post/2013/09/19/LibGDX-Tutorial-1-Creating-an-initial-project.aspxhttp://www.oracle.com/technetwork/java/javase/downloads/index.htmlhttp://www.oracle.com/technetwork/java/javase/downloads/index.htmlhttp://www.oracle.com/technetwork/java/javase/downloads/index.htmlhttp://developer.android.com/sdk/index.htmlhttp://developer.android.com/sdk/index.htmlhttp://developer.android.com/sdk/index.htmlhttp://www.oracle.com/technetwork/java/javase/downloads/index.htmlhttp://www.oracle.com/technetwork/java/javase/downloads/index.htmlhttp://developer.android.com/tools/sdk/eclipse-adt.htmlhttp://developer.android.com/tools/sdk/eclipse-adt.htmlhttp://developer.android.com/tools/sdk/eclipse-adt.htmlhttp://developer.android.com/tools/sdk/eclipse-adt.htmlhttp://developer.android.com/tools/sdk/eclipse-adt.htmlhttp://developer.android.com/tools/sdk/eclipse-adt.htmlhttp://developer.android.com/tools/sdk/eclipse-adt.htmlhttp://www.gamefromscratch.com/post/2011/10/13/Getting-started-with-PlayN.aspxhttp://www.gamefromscratch.com/post/2011/10/13/Getting-started-with-PlayN.aspxhttp://www.gamefromscratch.com/post/2011/10/13/Getting-started-with-PlayN.aspxhttp://www.gamefromscratch.com/post/2011/10/13/Getting-started-with-PlayN.aspxhttp://libgdx.badlogicgames.com/download.htmlhttp://libgdx.badlogicgames.com/download.htmlhttp://libgdx.badlogicgames.com/download.htmlhttps://netbeans.org/https://netbeans.org/https://netbeans.org/http://home.heeere.com/tech-libgdx-netbeans.htmlhttp://home.heeere.com/tech-libgdx-netbeans.htmlhttp://home.heeere.com/tech-libgdx-netbeans.htmlhttp://www.jetbrains.com/idea/http://www.jetbrains.com/idea/http://www.jetbrains.com/idea/https://code.google.com/p/libgdx/wiki/IntelliJIDEALibgdxhttps://code.google.com/p/libgdx/wiki/IntelliJIDEALibgdxhttps://code.google.com/p/libgdx/wiki/IntelliJIDEALibgdxhttp://www.gamefromscratch.com/post/2013/05/15/A-first-look-at-Googles-new-IDE-Android-Studio.aspxhttp://www.gamefromscratch.com/post/2013/05/15/A-first-look-at-Googles-new-IDE-Android-Studio.aspxhttp://www.gamefromscratch.com/image.axd?picture=libGDX.pnghttp://www.gamefromscratch.com/post/2013/05/15/A-first-look-at-Googles-new-IDE-Android-Studio.aspxhttps://code.google.com/p/libgdx/wiki/IntelliJIDEALibgdxhttp://www.jetbrains.com/idea/http://home.heeere.com/tech-libgdx-netbeans.htmlhttps://netbeans.org/http://libgdx.badlogicgames.com/download.htmlhttp://www.gamefromscratch.com/post/2011/10/13/Getting-started-with-PlayN.aspxhttp://www.gamefromscratch.com/post/2011/10/13/Getting-started-with-PlayN.aspxhttp://developer.android.com/tools/sdk/eclipse-adt.htmlhttp://developer.android.com/tools/sdk/eclipse-adt.htmlhttp://developer.android.com/tools/sdk/eclipse-adt.htmlhttp://www.oracle.com/technetwork/java/javase/downloads/index.htmlhttp://developer.android.com/sdk/index.htmlhttp://www.oracle.com/technetwork/java/javase/downloads/index.htmlhttp://www.gamefromscratch.com/post/2013/09/19/LibGDX-Tutorial-1-Creating-an-initial-project.aspx
  • 8/10/2019 LibGDX Tutorial 1

    2/45

    If it doesnt, you appear to have a problem with your Java install.

    Click Create.

    Fill in the resulting dialog. You can see the values I used above. You can optionally create a desktop, html and

    ios project. The core and Android projects are mandatory. Note, if you change the destination, you will have to

    specify the path to the LibGDX zip file.

    Once youve specified the LibGDX path ( or if you didnt change Destination ), the Generation button should be

    enabled:

    http://www.gamefromscratch.com/image.axd?picture=image_971.pnghttp://www.gamefromscratch.com/image.axd?picture=image_970.pnghttp://www.gamefromscratch.com/image.axd?picture=image_971.pnghttp://www.gamefromscratch.com/image.axd?picture=image_970.png
  • 8/10/2019 LibGDX Tutorial 1

    3/45

    Click it.

    The following screen appears:

    Click Launch.

    All things according to plan, you should see:

    If you dont see the above messages,welcome to the LibGDX forums. StackOverflowis another good place

    for LibGDX related support as there are already 1,500 LibGDX tagged questions.

    http://www.badlogicgames.com/forum/viewforum.php?f=11&sid=a3b55f3ae98c503cba7544437fdae242http://www.badlogicgames.com/forum/viewforum.php?f=11&sid=a3b55f3ae98c503cba7544437fdae242http://www.badlogicgames.com/forum/viewforum.php?f=11&sid=a3b55f3ae98c503cba7544437fdae242http://stackoverflow.com/questions/tagged/libgdxhttp://stackoverflow.com/questions/tagged/libgdxhttp://www.gamefromscratch.com/image.axd?picture=image_974.pnghttp://www.gamefromscratch.com/image.axd?picture=image_973.pnghttp://www.gamefromscratch.com/image.axd?picture=image_972.pnghttp://www.gamefromscratch.com/image.axd?picture=image_974.pnghttp://www.gamefromscratch.com/image.axd?picture=image_973.pnghttp://www.gamefromscratch.com/image.axd?picture=image_972.pnghttp://www.gamefromscratch.com/image.axd?picture=image_974.pnghttp://www.gamefromscratch.com/image.axd?picture=image_973.pnghttp://www.gamefromscratch.com/image.axd?picture=image_972.pnghttp://www.gamefromscratch.com/image.axd?picture=image_974.pnghttp://www.gamefromscratch.com/image.axd?picture=image_973.pnghttp://www.gamefromscratch.com/image.axd?picture=image_972.pnghttp://stackoverflow.com/questions/tagged/libgdxhttp://www.badlogicgames.com/forum/viewforum.php?f=11&sid=a3b55f3ae98c503cba7544437fdae242
  • 8/10/2019 LibGDX Tutorial 1

    4/45

    At this point we are done with the setup tool, you can close it. If you navigate to folder you specified as the

    destination, you should see the following folder structure:

    It should mirror the platforms you selected during setup.

    Now its time to fire up Eclipse.

    Now select File> Import

    Then select General->Existing Projects into Workspace and click Next.

    http://www.gamefromscratch.com/image.axd?picture=image_976.pnghttp://www.gamefromscratch.com/image.axd?picture=image_975.pnghttp://www.gamefromscratch.com/image.axd?picture=image_976.pnghttp://www.gamefromscratch.com/image.axd?picture=image_975.png
  • 8/10/2019 LibGDX Tutorial 1

    5/45

    Then the following dialog will appear:

    http://www.gamefromscratch.com/image.axd?picture=image_977.png
  • 8/10/2019 LibGDX Tutorial 1

    6/45

    With Select Root Directory checked, click Browse and navigate to the folder you chose as a destination

    earlier. You should then see a list of available projects, all of which should be checked. Then optionally choose

    if you want the project file copied within your Eclipse workspace. When complete click Finish.

    Now you should see:

    hello-world ( or whatever you named the project ) is the common project, while each additional platform has a

    platform suffix.

    http://www.gamefromscratch.com/image.axd?picture=image_979.pnghttp://www.gamefromscratch.com/image.axd?picture=image_978.pnghttp://www.gamefromscratch.com/image.axd?picture=image_979.pnghttp://www.gamefromscratch.com/image.axd?picture=image_978.png
  • 8/10/2019 LibGDX Tutorial 1

    7/45

    Running the desktop project

    Lets run the Desktop project now.

    Right click helloworld-desktop, select Debug As->Java Application:

    A dialog will appear and ask you what you want to run. Locate your project main, then click OK.

    http://www.gamefromscratch.com/image.axd?picture=image_980.png
  • 8/10/2019 LibGDX Tutorial 1

    8/45

    Congratulations, your first ever LibGDX application!

    http://www.gamefromscratch.com/image.axd?picture=image_981.png
  • 8/10/2019 LibGDX Tutorial 1

    9/45

    Running the HTML project

    Now try the same thing with the html5 appllication, right click, this time select Debug As->Web Application

    A few seconds later you should see:

    http://www.gamefromscratch.com/image.axd?picture=image_984.pnghttp://www.gamefromscratch.com/image.axd?picture=image_983.pnghttp://www.gamefromscratch.com/image.axd?picture=image_982.pnghttp://www.gamefromscratch.com/image.axd?picture=image_984.pnghttp://www.gamefromscratch.com/image.axd?picture=image_983.pnghttp://www.gamefromscratch.com/image.axd?picture=image_982.pnghttp://www.gamefromscratch.com/image.axd?picture=image_984.pnghttp://www.gamefromscratch.com/image.axd?picture=image_983.pnghttp://www.gamefromscratch.com/image.axd?picture=image_982.png
  • 8/10/2019 LibGDX Tutorial 1

    10/45

    Double click the link and:

    By the way, if you are running Chrome on WIndows 8,expect trouble. This is why I hate working with Google

    tools anyways, the 5th suggestion in thispost fixes the problem. Or you could just use Firefox.

    When working with HTML5 builds in Eclipse, there is something you should be aware of. Running the web

    application again in the way listed above will fail. It will try to start another web server and find the built in one

    already running and throw up. You have two options, both in the Development Server window.

    You can either use the red stop icon to shut down the internal web server, allowing you to run it using Debug As-

    >Web Application. Or you can hit the yellow arrows to reload your code.

    Running an Android Project

    When it comes to running an Android application, youve got a couple options. First you can plug in an actual

    device. If you use a device, make sure the ADB driver for it has been installed. The ADB usb driver is part of theAndroid SDK. This is by far the best way to work with Android.

    http://www.gamefromscratch.com/post/2013/09/01/Looking-at-LibGDX-and-once-again-I-find-myself-hating-Google-and-Java-developer-tools.aspxhttp://www.gamefromscratch.com/post/2013/09/01/Looking-at-LibGDX-and-once-again-I-find-myself-hating-Google-and-Java-developer-tools.aspxhttp://www.gamefromscratch.com/post/2013/09/01/Looking-at-LibGDX-and-once-again-I-find-myself-hating-Google-and-Java-developer-tools.aspxhttps://code.google.com/p/google-web-toolkit/issues/detail?id=7778https://code.google.com/p/google-web-toolkit/issues/detail?id=7778https://code.google.com/p/google-web-toolkit/issues/detail?id=7778http://www.gamefromscratch.com/image.axd?picture=image_986.pnghttp://www.gamefromscratch.com/image.axd?picture=image_985.pnghttp://www.gamefromscratch.com/image.axd?picture=image_986.pnghttp://www.gamefromscratch.com/image.axd?picture=image_985.pnghttps://code.google.com/p/google-web-toolkit/issues/detail?id=7778http://www.gamefromscratch.com/post/2013/09/01/Looking-at-LibGDX-and-once-again-I-find-myself-hating-Google-and-Java-developer-tools.aspx
  • 8/10/2019 LibGDX Tutorial 1

    11/45

    If you dont have a device, you can instead run the emulator. If Eclipse doesnt detect an attached device, it will

    try to launch the emulator. If it cant find an emulator, it will fail. Just a heads up, working with the emulator,

    especially for games, SUCKS. Get a device, really, trust me on this one.

    If you havent got a device and havent created an emulator yet, do so now. You can do it from within

    Eclipse. Select Window->Android Virtual Device Manager.

    In the resulting dialog, click New:

    http://www.gamefromscratch.com/image.axd?picture=image_987.png
  • 8/10/2019 LibGDX Tutorial 1

    12/45

    Here is an example Ive used. Prefer emulating the Intel Atom chipset, it runs much faster. If you are running an

    Intel chipset with HyperVisor support install the Intel Hardware Accelerated Execution Managerwhich can be

    downloaded here. Or better yet, get a real device. Did I mention that already?

    http://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-managerhttp://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-managerhttp://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-managerhttp://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-managerhttp://www.gamefromscratch.com/image.axd?picture=image_988.pnghttp://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-managerhttp://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager
  • 8/10/2019 LibGDX Tutorial 1

    13/45

    The emulator is notoriously fragile, you will come to hate it quickly. Did I mention you are better off getting a realdevice?

    Now that your emulator is created, select it and click Start

    http://www.gamefromscratch.com/image.axd?picture=image_989.png
  • 8/10/2019 LibGDX Tutorial 1

    14/45

    Go make some tea

    Drink your tea

    Perhaps a few crumpets? A bagel perhaps?

    Oh, hey, happy birthday!

    Congratulations on your first born!!

    Ok, it should be loaded now. For the record leave the emulator loaded.

    Now you can run your Android application using Debug As or Run As->Android Application

    http://www.gamefromscratch.com/image.axd?picture=image_990.png
  • 8/10/2019 LibGDX Tutorial 1

    15/45

    And a few moments later, you should see:

    http://www.gamefromscratch.com/image.axd?picture=image_991.png
  • 8/10/2019 LibGDX Tutorial 1

    16/45

    Back in Eclipse, get to know and love LogCat.

    Its a great source of Android debug information. This is where all trace, debug and error information is

    displayed.

    So, what about iOS. Well first off, Im running on Windows right now, so there is no option. Second, libGDX iscurrently in a bit of a transition state. Previously it relied on MonoDevelop to deploy to iOS. Now it is transitioning

    to RoboVM for iOS support. In the future I may specifically cover deploying to iOS when I am on my Mac

    would be a good start!

    In the next part we will look closer at project layout as well as get down to some coding.

    LibGDX Tutorial 2: Hello World26. September 20139 Comments

    Previous Part Table Of Contents Next Part

    http://www.gamefromscratch.com/post/2013/09/26/LibGDX-Tutorial-2-Hello-World.aspxhttp://www.gamefromscratch.com/post/2013/09/26/LibGDX-Tutorial-2-Hello-World.aspxhttp://www.gamefromscratch.com/post.aspx?id=49e16a8e-f86f-4f16-b336-ff32603c5fd6#disqus_threadhttp://www.gamefromscratch.com/post.aspx?id=49e16a8e-f86f-4f16-b336-ff32603c5fd6#disqus_threadhttp://www.gamefromscratch.com/post/2013/09/19/LibGDX-Tutorial-1-Creating-an-initial-project.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/image.axd?picture=image_993.pnghttp://www.gamefromscratch.com/image.axd?picture=image_992.pnghttp://www.gamefromscratch.com/image.axd?picture=image_993.pnghttp://www.gamefromscratch.com/image.axd?picture=image_992.pnghttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/post/2013/09/19/LibGDX-Tutorial-1-Creating-an-initial-project.aspxhttp://www.gamefromscratch.com/post.aspx?id=49e16a8e-f86f-4f16-b336-ff32603c5fd6#disqus_threadhttp://www.gamefromscratch.com/post/2013/09/26/LibGDX-Tutorial-2-Hello-World.aspx
  • 8/10/2019 LibGDX Tutorial 1

    17/45

    There is an old law, possibly predating the age of man, that all tutorials must start with Hello World. I am nothing

    if not law abiding, so therefore lets create a Hello World app. Hello World is generally one of the simplest

    programs you can create, you simply display the words Hello World on screen. Of course, there are always

    complications in life thats what makes it interesting!

    To get started I created a simple project using the Project Setup tool we discussed in theprior tutorial.

    We are going to jump in with the code in a second, but first lets take a quick look at the code created by the

    project tool, gdx-setup-ui. Your project should look like this:

    Obviously your file names will vary depending on what you used during the project setup tool. The key thing to

    note is the basics of how code is laid out. The non-suffixed folder ( hello-world ) is where the shared code

    goes. Theandroid,desktop andhtml folders are where platform specific code goes and hopefully you will

    have minimal need to use these. I will look at them a bit closer in a few minutes, but for now its the file

    HelloWorld.java that we are interested in. This is where a very important class called an ApplicationListener is

    implemented. Here is the code I used:

    package com.gamefromscratch.helloworld;

    import com.badlogic.gdx.ApplicationListener;import com.badlogic.gdx.Gdx;

    import com.badlogic.gdx.graphics.Color;

    import com.badlogic.gdx.graphics.GL10;

    import com.badlogic.gdx.graphics.g2d.BitmapFont;

    import com.badlogic.gdx.graphics.g2d.SpriteBatch;

    public class HelloWorld implements ApplicationListener {

    private SpriteBatch batch;

    private BitmapFont font;

    @Overridepublic void create() {

    batch = new SpriteBatch();font = new BitmapFont();

    http://www.gamefromscratch.com/post/2013/09/19/LibGDX-Tutorial-1-Creating-an-initial-project.aspxhttp://www.gamefromscratch.com/post/2013/09/19/LibGDX-Tutorial-1-Creating-an-initial-project.aspxhttp://www.gamefromscratch.com/post/2013/09/19/LibGDX-Tutorial-1-Creating-an-initial-project.aspxhttp://www.gamefromscratch.com/image.axd?picture=image_996.pnghttp://www.gamefromscratch.com/post/2013/09/19/LibGDX-Tutorial-1-Creating-an-initial-project.aspx
  • 8/10/2019 LibGDX Tutorial 1

    18/45

    font.setColor(Color.RED);}

    @Override

    public void dispose() {batch.dispose();

    font.dispose();}

    @Overridepublic void render() {

    Gdx.gl.glClearColor(1, 1, 1, 1);

    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    batch.begin();

    font.draw(batch, "Hello World", 200, 200);

    batch.end();

    }

    @Override

    public void resize(int width, int height) {}

    @Override

    public void pause() {

    }

    @Override

    public void resume() {

    }

    }

    The first thing you may notice is theres no Main! Well there is one and we will take a look at it in a second. At

    the end of the day though, LibGDX is an event driven engine. You implement an ApplicationListener and GDX

    calls a number of functions that you can respond to. The render() method will be called each from, so if you want

    to, you can think of that as your event loop. Otherwise there are functions that are called in response to various

    events, these include create, resize, pause and resume. I imagine you can guess what event each one is in

    response to!

    The bulk of our code is in create() and render(). In create() we allocate a new SpriteBatch, BitmapFont and set

    the font to the colour red. SpriteBatching is a common activity in 2D game engines built over 3D libraries, if

    youve used XNA you are used to it. Basically behind the scenes, LibGDX is using OpenGL ( or WebGL

    depending on platform ) to do the rendering. In OpenGL there is a fair bit of overhead in drawing well,

    anything. A spritebatch combines them all into a single operation to reduce the amount of overhead. In a

    nutshell, it makes 2D rendering a great deal faster. A BitmapFont is exactly what it sounds like, a 2D bitmap

    containing all the characters. If you dont specify a Font in the constructor, you will get the default font Arial-15

    included with LibGDX. The font file looks like this:

    http://www.gamefromscratch.com/image.axd?picture=image_997.png
  • 8/10/2019 LibGDX Tutorial 1

    19/45

    In the render() method we clear the screen to white by making the OpenGL function call glClear() and

    glClearColor(). The parameters to glClearColor are the red, green, blue and alpha ( transparency ) values to

    clear the screen with. The function glClear actually clears the screen. As you can see, the underlying OpenGL

    functionality is exposed in Gdx.gl, although generally you wont work at that level very often.

    Next we start our sprite batch by calling begin(), then render our text to the batch using the font.draw

    method. The parameters to draw() are the batch to draw to, the text to draw and the x and y coordinates to draw

    the text at. If you run this code ( right click hello-world-desktop and select Run As->Java Application ) you will

    see:

    Voila! Its Hello World.

    One important thing to be aware of is the project hello-world is not an application that you can run, its a library

    used by the other projects. Ill show you what I mean, take a look at code in hello-world-desktop for example:

    http://www.gamefromscratch.com/image.axd?picture=image_998.png
  • 8/10/2019 LibGDX Tutorial 1

    20/45

    Hey look, its Main! Lets check out the code:

    package com.gamefromscratch.helloworld;

    import com.badlogic.gdx.backends.lwjgl.LwjglApplication;import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;

    public class Main {

    public static void main(String[] args) {

    LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();

    cfg.title = "hello-world";cfg.useGL20 = false;

    cfg.width = 480;

    cfg.height = 320;

    new LwjglApplication(new HelloWorld(), cfg);}

    }

    This is the actual entry point for your application, or at least it is for the desktop target. This is where the Desktop

    specific configuration happens. You then start your game off by creating a LwjglApplication object, passing in an

    instance of your ApplicationListener as well as the Lwjgl specific configuration settings. If Lwjgl is new to you, its

    a Java based game wrapper over top of OpenGL and is what LibGDX uses for desktop rendering. Beyond

    configuring it here, you will have no other interactions with it, LibGDX takes care of all of that for you.

    To really understand how cross platform magic works in LibGDX, lets also take a look at the Main for the html

    project. In this case its not actually called Main, but instead GwtLauncher.java.

    http://www.gamefromscratch.com/image.axd?picture=image_999.png
  • 8/10/2019 LibGDX Tutorial 1

    21/45

    Gwt stands for Google Web Toolkit, and its a technology Google provides for compiling Java into JavaScript for

    use in a browser. Its the secret sauce that LibGDX uses to make your game run in HTML. Its also horrifically

    annoying at times, you have been warned! That said, if you dont care about HTML, you can remove this project

    completely and save yourself a number of headaches.

    Lets take a look at GwtLauncher.java:

    package com.gamefromscratch.helloworld.client;

    import com.gamefromscratch.helloworld.HelloWorld;

    import com.badlogic.gdx.ApplicationListener;

    import com.badlogic.gdx.backends.gwt.GwtApplication;

    import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration;

    public class GwtLauncher extends GwtApplication {@Override

    public GwtApplicationConfiguration getConfig () {GwtApplicationConfiguration cfg = new GwtApplicationConfiguration(480, 320);

    return cfg;

    }

    @Override

    public ApplicationListener getApplicationListener () {return new HelloWorld();

    }

    }

    Looks a lot like the desktop project main doesnt it? The basic concept is exactly the same, you create the

    platform specific configuration bits, and create an instance of your ApplicationListener. The GwtApplication class

    is callback based however, so it looks a bit different. Once again, you should rarely be working at this level. One

    important thing to note though is the values being passed to GwtApplicationConfiguration this represents the

    size of the HTML canvas being created. So if you want your HTML app to be more than a small square in the

    middle of the screen, this is where you change it.

    So basically LibGDX works by having you create a single common library that implements your game in a cross

    platform way in the form of an ApplicationListener. To support multiple platforms, you have a project for each

    platform where you create a platform specific application ( an instance of GwtApplication in the case of HTML

    targets, LwjglApplication for desktop targets, AndroidApplication for Android targets, Application for iOS targets

    not shown because I am working on Windows currently ) , configure it and pass in the ApplicationListener. It is

    http://www.gamefromscratch.com/image.axd?picture=image_1000.png
  • 8/10/2019 LibGDX Tutorial 1

    22/45

    this application class that will be calling back to your ApplicationListener each frame. The nice news is, most of

    the time, you wont care about any of this but its handy to understand whats happening behind the curtains.

    Oh yeah about GWT

    Remember I said it was a bit of a pain? Well lets take a look at what happens when you run the hello-world-html

    application ( right click hello-world-html->Run As->Web Application):

    Ugh so basically our code is trying to do something GWT does not permit. If we flip back to Eclipse in the

    Console panel we can get a bit more insight into the nature of the exception.

    http://www.gamefromscratch.com/image.axd?picture=image_1001.png
  • 8/10/2019 LibGDX Tutorial 1

    23/45

    Its line 17 in HelloWorld.Java that is causing the exception:

    font = new BitmapFont();

    So, what exactly is going on here? Well, remember earlier when I told you that BitmapFonts default constructor

    would use the built-in arial-15 font. Well, when I said built in, that file actually resides in gdx.jar which is included

    in your project. A jar file is actually just a zip, so if you extract the file you can see all the code and assets that

    make up the gdx library itself. Of particular interest to us is the folder \gdx\com\badlogic\gdx\utils, this is where

    the font file resides among other files:

    Basically the GwtApplication is trying to access this file and doesnt have permission to do so. Whats the moral

    to the story? Cross platform is awesome but not always free! Unless you need to support HTML, I would

    suggest not creating an HTML project, as it is by far the most fragile part of LibGDX and working with GWT

    causes all kinds of heartache and complication. Your mileage may vary!

    http://www.gamefromscratch.com/image.axd?picture=image_1006.pnghttp://www.gamefromscratch.com/image.axd?picture=image_1002.pnghttp://www.gamefromscratch.com/image.axd?picture=image_1006.pnghttp://www.gamefromscratch.com/image.axd?picture=image_1002.png
  • 8/10/2019 LibGDX Tutorial 1

    24/45

    That said, there is a very simple fix to this, and it nicely illustrates how you deal with files between your projects

    a process that may not be particularly intuitive. The simple solution is to add the files arial-15.fnt and arial-15 to

    the project and change the line:

    font = new BitmapFont();

    to

    font = new BitmapFont(Gdx.files.internal("data/arial-15.fnt"),false);

    This version of BitmapFonts constructor takes a file handle of the font file you want the BitmapFont to

    use. Gdx.files is used for file manipulation, internal returns a file handle to a file that is included within the

    project. The false parameter is specifying that the fonts graphic isn't flipped upside down.

    So, how do you actually add the file to the project? You add them to the assets\data folder of the hello-world-

    android project:

    You can add the files by simply dragging/dropping from Finder or Explorer to the data folder in the Package

    Explorer.

    Now that the font file has been added, we can now run the HTML target:

    http://www.gamefromscratch.com/image.axd?picture=image_1004.png
  • 8/10/2019 LibGDX Tutorial 1

    25/45

    So thats Hello World in LibGDX. Next up we look at something more advanced than Hello World.

    LibGDX Tutorial 3: Basic graphics2. October 201331 Comments

    Previous Part Table Of Contents Next Part

    This is the part people always find the most fun, the actual act of putting graphics up on screen. Lets start with

    about the simplest project that we can.

    We are going to display this sprite (created in this tutorial):

    http://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post.aspx?id=a4c8c44d-af9b-4c43-bbe1-95541272fd76#disqus_threadhttp://www.gamefromscratch.com/post.aspx?id=a4c8c44d-af9b-4c43-bbe1-95541272fd76#disqus_threadhttp://www.gamefromscratch.com/post/2013/09/26/LibGDX-Tutorial-2-Hello-World.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/post/2013/12/09/LibGDX-Tutorial-3B-Simple-Animation.aspxhttp://www.gamefromscratch.com/post/2013/12/09/LibGDX-Tutorial-3B-Simple-Animation.aspxhttp://www.gamefromscratch.com/post/2013/12/09/LibGDX-Tutorial-3B-Simple-Animation.aspxhttp://www.gamefromscratch.com/www.gamefromscratch.com/page/Complete-Blender-Game-Art-Tutorial-From-zero-experience-to-2D-or-3D-game-ready-asset.aspxhttp://www.gamefromscratch.com/www.gamefromscratch.com/page/Complete-Blender-Game-Art-Tutorial-From-zero-experience-to-2D-or-3D-game-ready-asset.aspxhttp://www.gamefromscratch.com/www.gamefromscratch.com/page/Complete-Blender-Game-Art-Tutorial-From-zero-experience-to-2D-or-3D-game-ready-asset.aspxhttp://www.gamefromscratch.com/image.axd?picture=jet_3.pnghttp://www.gamefromscratch.com/image.axd?picture=image_1005.pnghttp://www.gamefromscratch.com/image.axd?picture=jet_3.pnghttp://www.gamefromscratch.com/image.axd?picture=image_1005.pnghttp://www.gamefromscratch.com/www.gamefromscratch.com/page/Complete-Blender-Game-Art-Tutorial-From-zero-experience-to-2D-or-3D-game-ready-asset.aspxhttp://www.gamefromscratch.com/post/2013/12/09/LibGDX-Tutorial-3B-Simple-Animation.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/post/2013/09/26/LibGDX-Tutorial-2-Hello-World.aspxhttp://www.gamefromscratch.com/post.aspx?id=a4c8c44d-af9b-4c43-bbe1-95541272fd76#disqus_threadhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspx
  • 8/10/2019 LibGDX Tutorial 1

    26/45

    On screen. One important thing to note, the above graphic is 512x256. OpenGL in general and LibGDX in

    specific, require your image files to be in power of two dimensions. This means your width and height are

    2,4,8,16,32,64,128,256,512,1024,2048, etc pixels in size. Be sure to add this file to the assets\data folder in

    the android project before continuing.

    Lets jump right in with code:

    package com.gamefromscratch.graphicsdemo;

    import com.badlogic.gdx.ApplicationListener;

    import com.badlogic.gdx.Gdx;

    import com.badlogic.gdx.graphics.GL10;

    import com.badlogic.gdx.graphics.Texture;import com.badlogic.gdx.graphics.g2d.Sprite;

    import com.badlogic.gdx.graphics.g2d.SpriteBatch;

    public class GraphicsDemo implements ApplicationListener {private SpriteBatch batch;private Texture texture;

    private Sprite sprite;

    @Override

    public void create() {

    batch = new SpriteBatch();texture = new Texture(Gdx.files.internal("data/jet.png"));

    sprite = new Sprite(texture);

    }

    @Overridepublic void dispose() {

    batch.dispose();texture.dispose();

    }

    @Overridepublic void render() {

    Gdx.gl.glClearColor(1, 1, 1, 1);

    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    batch.begin();sprite.draw(batch);

    batch.end();

    }

    @Overridepublic void resize(int width, int height) {}

    @Override

    public void pause() {

    }

    @Override

    public void resume() {

    }

    }

    And if you run it:

  • 8/10/2019 LibGDX Tutorial 1

    27/45

    The image is drawn relative to the origin. In the case of LibGDX (0,0) is the bottom left corner of the screen.

    As to the code, there isnt actually a ton new compared to the Hello World example in the previous tutorial. The

    only new concepts are the Texture and the Sprite. The texture represents the underlying OpenGL texture. One

    important thing to keep in mind with Texture ( and other similar classes ) is they implement the Disposable

    interface. This means when you are done with it, you have to call the dispose() method, or you will leak

    memory! A Sprite holds the geometry and colour data of a texture, this means the positional data ( such as its X

    and Y location ) are stored in the Sprite. We construct our texture by passing its path in, obtained in the same

    manner we access the font in the prior tutorial. We then construct the Sprite by passing in our newly created

    texture. There are other ways of creating Sprites, that we will see shortly. Just like in the Hello World sample,

    we start a SpriteBatch, and draw our sprite to it using the draw() method.

    Dynamic textures with Pixmap

    Your Textures source doesnt have to come from a file. Here we are going to use the Pixmap class to create the

    textures source dynamically.

    package com.gamefromscratch.graphicsdemo;

    import com.badlogic.gdx.ApplicationListener;

    import com.badlogic.gdx.Gdx;

    import com.badlogic.gdx.graphics.Color;import com.badlogic.gdx.graphics.GL10;

    import com.badlogic.gdx.graphics.Pixmap;

    import com.badlogic.gdx.graphics.Texture;

    import com.badlogic.gdx.graphics.g2d.Sprite;

    import com.badlogic.gdx.graphics.g2d.SpriteBatch;

    public class GraphicsDemo implements ApplicationListener {

    http://www.gamefromscratch.com/image.axd?picture=image_1021.png
  • 8/10/2019 LibGDX Tutorial 1

    28/45

    private SpriteBatch batch;private Pixmap pixmap;

    private Texture texture;

    private Sprite sprite;

    @Override

    public void create() {batch = new SpriteBatch();

    // A Pixmap is basically a raw image in memory as repesented by pixels// We create one 256 wide, 128 height using 8 bytes for Red, Green, Blue and Alpha

    channels

    pixmap = new Pixmap(256,128, Pixmap.Format.RGBA8888);

    //Fill it red

    pixmap.setColor(Color.RED);

    pixmap.fill();

    //Draw two lines forming an X

    pixmap.setColor(Color.BLACK);

    pixmap.drawLine(0, 0, pixmap.getWidth()-1, pixmap.getHeight()-1);pixmap.drawLine(0, pixmap.getHeight()-1, pixmap.getWidth()-1, 0);

    //Draw a circle about the middle

    pixmap.setColor(Color.YELLOW);

    pixmap.drawCircle(pixmap.getWidth()/2, pixmap.getHeight()/2, pixmap.getHeight()/2 -

    1);

    texture = new Texture(pixmap);

    //It's the textures responsibility now... get rid of the pixmappixmap.dispose();

    sprite = new Sprite(texture);}

    @Override

    public void dispose() {

    batch.dispose();

    texture.dispose();

    }

    @Override

    public void render() {

    Gdx.gl.glClearColor(0, 0, 0, 1);

    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    batch.begin();

    sprite.setPosition(0, 0);

    sprite.draw(batch);

    sprite.setPosition(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2);

    sprite.draw(batch);

    batch.end();

    }

    @Override

    public void resize(int width, int height) {

    }

    @Override

    public void pause() {

    }

    @Override

  • 8/10/2019 LibGDX Tutorial 1

    29/45

    public void resume() {}

    }

    Once again, the code is remarkably similar to our prior example. The biggest difference is instead of loading thetextures image data from file, we create one dynamically using a Pixmap. At the simplest, a pixmap can be

    thought of as a grid of pixel data in memory. It contains a number of graphical functions, many of which we

    demoed above. The drawing code is pretty well commented in terms of what it does, so I wont go into details

    here. One very important detail though, in the modern GPU driven world, these kinds of per pixel operations are

    REALLY REALLY SLOW. Generally you want to avoid them as much as possible.

    The only other thing of note in this example is the changes in the render() method. Notice how the same sprite is

    drawn twice to the sprite batch? Well this behaviour is perfectly OK, and has minimal performance overhead in

    doing so. Sprites setPosition method is used to position a sprite, once again, (0,0) is the lower left hand corner

    of the screen by default. The only other new code here is the Gdx.graphics.getWidth() and getHeight() method

    calls. These return the windows ( or Canvas in the case of HTML5 ) dimensions. Of course in production code

    you would probably cache them locally instead of retrieving them every pass through the render loop.

    TextureAtlas

    Quite often you want to deal with a sprite sheet, which is a number of sprites combined together into a single

    image. Such functionality is built into LibGdx. The first thing you are going to need is a directory of images that

    are going to be combined into a sprite sheet. Like this:

  • 8/10/2019 LibGDX Tutorial 1

    30/45

    Open a command line or terminal window and run the following command:

    java -cp gdx.jar;extensions/gdx-tools/gdx-tools.jar com.badlogic.gdx.tools.imagepacker.TexturePacker2 c:\tmp

    c:\tmp spritesheettmp

    It looks more unwieldy than it is. Basically you are running the TexturePacker2 class inside the gdx-tools

    jar. The first parameter is the source directory, the second parameter is the destination direction and the final

    parameter is the filename to use. It will automatically add the required file extensions. This process will create

    two files, a .atlas file and a .png. The atlas file is a text file describing how the sprites are laid out in the

    spritesheet image, with the images filename used as the key ( minus extension ), like so:

    spritesheet.atlas:

    spritesheet.png

    format: RGBA8888

    filter: Nearest,Nearest

    repeat: none

    0001

    http://www.gamefromscratch.com/image.axd?picture=image_1022.png
  • 8/10/2019 LibGDX Tutorial 1

    31/45

    rotate: false

    xy: 1, 651

    size: 192, 128

    orig: 192, 128

    offset: 0, 0

    index: -10002

    rotate: false

    While the sprite sheet itself looks like this:

    The spritepacker tool automatically pads the image out to be a power of 2 in size. Ive only scratched the very

    surface of what this tool can do. You can set it to run as part of your build process, run if from code or within

    Eclipse or even run it at program run time. There are a wealth of options you can configure. You can read

    muchmore about it right here.

    So how do you actually use a texture atlas then? Its very simple, first copy the generated png and atlas file to

    your assets. The following code shows how to use a TextureAtlas:

    package com.gamefromscratch.graphicsdemo;

    import com.badlogic.gdx.ApplicationListener;

    import com.badlogic.gdx.Gdx;

    import com.badlogic.gdx.graphics.GL10;

    import com.badlogic.gdx.graphics.g2d.Sprite;import com.badlogic.gdx.graphics.g2d.SpriteBatch;

    https://code.google.com/p/libgdx/wiki/TexturePackerhttps://code.google.com/p/libgdx/wiki/TexturePackerhttps://code.google.com/p/libgdx/wiki/TexturePackerhttp://www.gamefromscratch.com/image.axd?picture=spritesheet_1.pnghttps://code.google.com/p/libgdx/wiki/TexturePacker
  • 8/10/2019 LibGDX Tutorial 1

    32/45

    import com.badlogic.gdx.graphics.g2d.TextureAtlas;import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;

    import com.badlogic.gdx.utils.Timer;

    import com.badlogic.gdx.utils.Timer.Task;

    public class GraphicsDemo implements ApplicationListener {

    private SpriteBatch batch;private TextureAtlas textureAtlas;

    private Sprite sprite;

    private int currentFrame = 1;private String currentAtlasKey = new String("0001");

    @Override

    public void create() {

    batch = new SpriteBatch();

    textureAtlas = new TextureAtlas(Gdx.files.internal("data/spritesheet.atlas"));

    AtlasRegion region = textureAtlas.findRegion("0001");

    sprite = new Sprite(region);

    sprite.setPosition(120, 100);

    sprite.scale(2.5f);

    Timer.schedule(new Task(){@Override

    public void run() {

    currentFrame++;

    if(currentFrame > 20)

    currentFrame = 1;

    // ATTENTION! String.format() doesnt work under GWT for god knows

    why...

    currentAtlasKey = String.format("%04d", currentFrame);

    sprite.setRegion(textureAtlas.findRegion(currentAtlasKey));

    }}

    ,0,1/30.0f);

    }

    @Overridepublic void dispose() {

    batch.dispose();

    textureAtlas.dispose();

    }

    @Overridepublic void render() {

    Gdx.gl.glClearColor(0, 0, 0, 1);

    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    batch.begin();sprite.draw(batch);

    batch.end();

    }

    @Override

    public void resize(int width, int height) {

    }

    @Override

    public void pause() {

    }

    @Override

    public void resume() {

    }

    }

  • 8/10/2019 LibGDX Tutorial 1

    33/45

    Here is the HTML5 version of the above code:

    As you can see, its remarkably consistent. The majority of the code above is actually part of the demo related,

    as opposed to being part of using a TextureAtlas. Instead the only import new code is:

    batch = new SpriteBatch();

    textureAtlas = new TextureAtlas(Gdx.files.internal("data/spritesheet.atlas"));

    AtlasRegion region = textureAtlas.findRegion("0001");

    sprite = new Sprite(region);

    Just like working with a texture, but instead you load a TextureAtlas. Then instead of assign the texture to the

    sprite, you use an AtlasRegion, which describes the coordinates of the individual sprite within the

    spritesheet. You get the region by name by calling the findRegion() method and passing the key. Remember

    this value is set by the file names of the source images. The TextureAtlas needs to be dispose()d or you will

    leak memory.

    As you can see by the call:

    sprite.setRegion(textureAtlas.findRegion(currentAtlasKey));

    You can change the region within the sprite sheet that the sprite will refer to by calling setRegion().

    The rest of the code simply positions and scales the sprite up 2.5x times. We then schedule a Task using

    Timer.schedule(). This task will be called ever 30th of a second. It simply changes the key we will use within the

    TextureAtlas. In this case the files were named 0001.png, 0002.png, etc so we want a value between 0001

    and 0020. We then use this value to update the region the sprite refers to. As a result every 30th of a second,

    the sprite moves on to the next frame of animation, rolling over when it gets to the end.

    EDIT: I should state for the record, this is NOT how you would use a TextureAtlas to perform animation, this code

    was simply for demonstration purposes. There are dedicated animation classes and we will cover them later on.

    Be warned though, if you try to run this under GWT, you will see:

    http://www.gamefromscratch.com/image.axd?picture=image_1023.png
  • 8/10/2019 LibGDX Tutorial 1

    34/45

    This is because the GWT compiler ( this has nothing to do with LibGDX ) doesnt support String.format() for some

    reason. If you want to run this example in a browser you can simply replace

    currentAtlasKey = String.format("%04d", currentFrame);

    With:

    String base = new String();

    if(currentFrame >= 10)

    base = "00";

    else

    base = "000";

    currentAtlasKey = base + currentFrame;

    Now the HTML target should run just fine.

    In the next part we will take a look at controlling input in LibGDX.

    Configuring LibGDX to use GL 2

    It was brought to my attention byMario Zechnerthat LibGDX is not limited to power of 2 texture sizes. That

    instead is an artefact of OpenGL ES 1. If you run using OpenGL ES2 it will work fine. That said, OpenGL and

    the underlying hardware still perform better if you stick to power of two. If you want to use GL2, you set it during

    as part of the configuration process, we discussed briefly in theHello World tutorial. Simply set the useGL20

    value to true in the configuration you pass in to your application listener. Here for example is Main from thedesktop project configured to use GL 2.

    public class Main {public static void main(String[] args) {

    LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();cfg.title = "graphicsdemo";

    cfg.useGL20 = true;

    cfg.width = 480;

    cfg.height = 320;

    new LwjglApplication(new GraphicsDemo(), cfg);

    }}

    Remember of course to configure this for all targets you are supporting.

    LibGDX Tutorial 3B: Simple Animation9. December 20139 Comments

    Previous Part Table Of Contents Next Part

    Back inTutorial 3I created a simple animation using a Timer and setting the frame manually from a

    TextureAtlas. This is not the ideal way to perform animation using LibGDX and was done to illustrate how to use

    https://twitter.com/badlogicgameshttps://twitter.com/badlogicgameshttps://twitter.com/badlogicgameshttp://www.gamefromscratch.com/post/2013/09/26/LibGDX-Tutorial-2-Hello-World.aspxhttp://www.gamefromscratch.com/post/2013/09/26/LibGDX-Tutorial-2-Hello-World.aspxhttp://www.gamefromscratch.com/post/2013/09/26/LibGDX-Tutorial-2-Hello-World.aspxhttp://www.gamefromscratch.com/post/2013/12/09/LibGDX-Tutorial-3B-Simple-Animation.aspxhttp://www.gamefromscratch.com/post/2013/12/09/LibGDX-Tutorial-3B-Simple-Animation.aspxhttp://www.gamefromscratch.com/post.aspx?id=5d7b25e9-cec2-4416-bed8-5470b8c0444b#disqus_threadhttp://www.gamefromscratch.com/post.aspx?id=5d7b25e9-cec2-4416-bed8-5470b8c0444b#disqus_threadhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/post/2013/10/15/LibGDX-Tutorial-4-Handling-the-mouse-and-keyboard.aspxhttp://www.gamefromscratch.com/post/2013/10/15/LibGDX-Tutorial-4-Handling-the-mouse-and-keyboard.aspxhttp://www.gamefromscratch.com/post/2013/10/15/LibGDX-Tutorial-4-Handling-the-mouse-and-keyboard.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post/2013/10/15/LibGDX-Tutorial-4-Handling-the-mouse-and-keyboard.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post.aspx?id=5d7b25e9-cec2-4416-bed8-5470b8c0444b#disqus_threadhttp://www.gamefromscratch.com/post/2013/12/09/LibGDX-Tutorial-3B-Simple-Animation.aspxhttp://www.gamefromscratch.com/post/2013/09/26/LibGDX-Tutorial-2-Hello-World.aspxhttps://twitter.com/badlogicgames
  • 8/10/2019 LibGDX Tutorial 1

    35/45

    a TextureAtlas, not how to perform animation. Instead the better way to perform animations is using

    theAnimationclass. Here is an example using the same spritesheet fromtutorial 3,remember you need to add it

    to the Android project assets folder.

    package com.gamefromscratch;

    import com.badlogic.gdx.ApplicationListener;

    import com.badlogic.gdx.Gdx;

    import com.badlogic.gdx.graphics.GL10;

    import com.badlogic.gdx.graphics.g2d.Animation;

    import com.badlogic.gdx.graphics.g2d.SpriteBatch;import com.badlogic.gdx.graphics.g2d.TextureAtlas;

    public class AnimationDemo implements ApplicationListener {

    private SpriteBatch batch;

    private TextureAtlas textureAtlas;

    private Animation animation;private float elapsedTime = 0;

    @Override

    public void create() {

    batch = new SpriteBatch();

    textureAtlas = new TextureAtlas(Gdx.files.internal("data/spritesheet.atlas"));

    animation = new Animation(1/15f, textureAtlas.getRegions());

    }

    @Override

    public void dispose() {batch.dispose();

    textureAtlas.dispose();

    }

    @Override

    public void render() {Gdx.gl.glClearColor(0, 0, 0, 1);

    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    batch.begin();

    //sprite.draw(batch);elapsedTime += Gdx.graphics.getDeltaTime();

    batch.draw(animation.getKeyFrame(elapsedTime, true), 0, 0);

    batch.end();

    }

    @Override

    public void resize(int width, int height) {

    }

    @Override

    public void pause() {}

    @Override

    public void resume() {

    }

    }

    When you run it, you should see:

    http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Animation.htmlhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Animation.htmlhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Animation.htmlhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://www.gamefromscratch.com/post/2013/10/02/LibGDX-Tutorial-3-Basic-graphics.aspxhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Animation.html
  • 8/10/2019 LibGDX Tutorial 1

    36/45

    The key here is the Animation, created here:

    animation = newAnimation(1/15f, textureAtlas.getRegions());

    When creating an animation you pass in the amount of time per frame ( 15 frames per second in this case ) and

    an array of TextureRegions. These represent the individual frames of animation within the TextureAtlas. In this

    particular example we are simply using all of the frames available within the Atlas as a single animation. The

    next key change is:

    elapsedTime += Gdx.graphics.getDeltaTime();

    batch.draw(animation.getKeyFrame(elapsedTime, true), 0, 0);Here we are simply drawing the current frame from the animation to the screen. We pass in the amount of time

    that has elapsed so the animation knows where it is in the sequence. The true parameter is telling it to loop the

    animation.

    Of course, you can have multiple animations from a single texture Atlas. Consider the spritesheet we are

    currently working with. If you take a look at the .atlas file, you will see each individual frame is named:

    http://www.gamefromscratch.com/image.axd?picture=Animation.gif
  • 8/10/2019 LibGDX Tutorial 1

    37/45

    Looking at the spritesheet, you will see the animations are organized like such:

    http://www.gamefromscratch.com/image.axd?picture=image_1065.png
  • 8/10/2019 LibGDX Tutorial 1

    38/45

    http://www.gamefromscratch.com/image.axd?picture=spritesheet_2.png
  • 8/10/2019 LibGDX Tutorial 1

    39/45

    What we want to do is treat this as two sepeate animations. Frames 1 through 10 represent an upward roll, while

    11-20 are a downward roll. Lets take a look at how we do that:

    public void create() {

    batch = new SpriteBatch();textureAtlas = new TextureAtlas(Gdx.files.internal("data/spritesheet.atlas"));

    TextureRegion[] rotateUpFrames = new TextureRegion[10];

    // Rotate Up Animation

    // Create an array of TextureRegions

    rotateUpFrames[0] = (textureAtlas.findRegion("0001"));

    rotateUpFrames[1] = (textureAtlas.findRegion("0002"));

    rotateUpFrames[2] = (textureAtlas.findRegion("0003"));rotateUpFrames[3] = (textureAtlas.findRegion("0004"));

    rotateUpFrames[4] = (textureAtlas.findRegion("0005"));

    rotateUpFrames[5] = (textureAtlas.findRegion("0006"));

    rotateUpFrames[6] = (textureAtlas.findRegion("0007"));

    rotateUpFrames[7] = (textureAtlas.findRegion("0008"));rotateUpFrames[8] = (textureAtlas.findRegion("0009"));rotateUpFrames[9] = (textureAtlas.findRegion("0010"));

    rotateUpAnimation = new Animation(0.1f,rotateUpFrames);

    // Rotate Down Animation// Or you can just pass in all of the regions to the Animation constructor

    rotateDownAnimation = new Animation(0.1f,

    (textureAtlas.findRegion("0011")),

    (textureAtlas.findRegion("0012")),

    (textureAtlas.findRegion("0013")),

    (textureAtlas.findRegion("0014")),(textureAtlas.findRegion("0015")),

    (textureAtlas.findRegion("0016")),(textureAtlas.findRegion("0017")),

    (textureAtlas.findRegion("0018")),

    (textureAtlas.findRegion("0019")),(textureAtlas.findRegion("0020")));

    Gdx.input.setInputProcessor(this);

    }

    As you can see, its easy to create multiple animations from a single TextureAtlas. Keep in mind, when creating

    a TextureAtlas using TexturePacker, it was the filename that you passed in that created the region names. So

    what you would generally do is name your separate animations accordingly, such as WalkLeft, WalkRight, etc.

    LibGDX Tutorial 4: Handling Input -- The mouse and keyboard15. October 201311 Comments

    Previous Part Table Of Contents Next Part

    In this part we are going to look at how you handle mouse and keyboard input in LibGDX. There are two ways to

    go about handling input, by polling for it ( as in Has anything happened yet? No, ok What about now? No,

    ok Now? Yes! Handle it ) or by handling events ( Hey, you, Iv got this event for you! ). Which you go with

    generally depends on the way you structure your code. Polling tends to be a bit more resource intensive but at

    the end of the day that is mostly a non-factor.

    http://www.gamefromscratch.com/post/2013/10/15/LibGDX-Tutorial-4-Handling-the-mouse-and-keyboard.aspxhttp://www.gamefromscratch.com/post/2013/10/15/LibGDX-Tutorial-4-Handling-the-mouse-and-keyboard.aspxhttp://www.gamefromscratch.com/post.aspx?id=33b4499e-958c-434e-a43a-237659675d58#disqus_threadhttp://www.gamefromscratch.com/post.aspx?id=33b4499e-958c-434e-a43a-237659675d58#disqus_threadhttp://www.gamefromscratch.com/post/2013/12/09/LibGDX-Tutorial-3B-Simple-Animation.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/post/2013/10/24/LibGDX-Tutorial-5-Handling-Input-Touch-and-gestures.aspxhttp://www.gamefromscratch.com/post/2013/10/24/LibGDX-Tutorial-5-Handling-Input-Touch-and-gestures.aspxhttp://www.gamefromscratch.com/post/2013/10/24/LibGDX-Tutorial-5-Handling-Input-Touch-and-gestures.aspxhttp://www.gamefromscratch.com/post/2013/10/24/LibGDX-Tutorial-5-Handling-Input-Touch-and-gestures.aspxhttp://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspxhttp://www.gamefromscratch.com/post/2013/12/09/LibGDX-Tutorial-3B-Simple-Animation.aspxhttp://www.gamefromscratch.com/post.aspx?id=33b4499e-958c-434e-a43a-237659675d58#disqus_threadhttp://www.gamefromscratch.com/post/2013/10/15/LibGDX-Tutorial-4-Handling-the-mouse-and-keyboard.aspx
  • 8/10/2019 LibGDX Tutorial 1

    40/45

    Polling the keyboard for input

    Lets jumpright in and look at how you poll the keyboard for input. Here is the code:

    package input.gamefromscratch.com;

    import com.badlogic.gdx.ApplicationListener;

    import com.badlogic.gdx.Gdx;

    import com.badlogic.gdx.Input;

    import com.badlogic.gdx.graphics.GL10;import com.badlogic.gdx.graphics.Texture;

    import com.badlogic.gdx.graphics.g2d.Sprite;

    import com.badlogic.gdx.graphics.g2d.SpriteBatch;

    public class InputDemo implements ApplicationListener {

    private SpriteBatch batch;private Texture texture;

    private Sprite sprite;

    @Overridepublic void create() {

    float w = Gdx.graphics.getWidth();

    float h = Gdx.graphics.getHeight();

    batch = new SpriteBatch();

    texture = new Texture(Gdx.files.internal("data/0001.png"));

    sprite = new Sprite(texture);sprite.setPosition(w/2 -sprite.getWidth()/2, h/2 - sprite.getHeight()/2);

    }

    @Override

    public void dispose() {batch.dispose();

    texture.dispose();}

    @Override

    public void render() {Gdx.gl.glClearColor(1, 1, 1, 1);

    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){

    if(Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT))

    sprite.translateX(-1f);

    else

    sprite.translateX(-10.0f);

    }

    if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){if(Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT))

    sprite.translateX(1f);

    else

    sprite.translateX(10.0f);

    }

    batch.begin();sprite.draw(batch);

    batch.end();

    }

    @Overridepublic void resize(int width, int height) {

    }

    @Override

    public void pause() {

  • 8/10/2019 LibGDX Tutorial 1

    41/45

    }

    @Override

    public void resume() {

    }

    }

    Other than the highlighted bit and the translateX method, everything here we have seen before. Basically we

    draw a simple sprite centered to the screen and each frame we check to see if the user has pressed the LEFT or

    RIGHT arrow. If they have, we check if they also have the left control key held. If so, we move slowly to the left

    or right. If they dont have Control pressed, we move instead by 10 pixels.

    Here is the app, you need to click it first to give it keyboard focus:

    If it doesnt work in an frame,click here.

    Just use the left and right arrows to move the jet. Hold down control to move slowly. There is no clipping so the

    sprite can fly way off screen.

    In terms of what the new code is doing, the Sprite.translateX method is pretty self explanatory. It moves the

    sprite by a certain amount of pixels along the X axis. There is a translateY method as well, as well as a more

    general translate method. The key method in this example is isKeyPressed() member function of the input

    instance of the global Gdx object. We used a similar instance member when we accessed Gdx.files. These are

    public static references to the various sub-systems GDX depends on,you can read more here. isKeyPressed is

    passed a Key value defined in theKeys objectand returns true if that key is currently pressed. As you can see

    when we later tested if the Control key is also pressed, multiple keys can be pressed at the same time.

    Polling the Mouse for input

    Now lets take a look at how you poll the mouse for input. To save space, this code is identical to the last

    example, with only the render() method replaced.

    public void render() {

    Gdx.gl.glClearColor(1, 1, 1, 1);Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    if(Gdx.input.isButtonPressed(Input.Buttons.LEFT)){sprite.setPosition(Gdx.input.getX() - sprite.getWidth()/2,

    Gdx.graphics.getHeight() - Gdx.input.getY() - sprite.getHeight()/2);}

    if(Gdx.input.isButtonPressed(Input.Buttons.RIGHT)){

    sprite.setPosition(Gdx.graphics.getWidth()/2 -sprite.getWidth()/2,

    Gdx.graphics.getHeight()/2 - sprite.getHeight()/2);

    }

    batch.begin();sprite.draw(batch);

    batch.end();

    }

    Here we instead are checking if a mouse button has been pressed using isButtonPressed passing in a button

    value defined in the Buttons object. If the left button is pressed, get then poll the mouse position using

    http://www.gamefromscratch.com/downloads/GDX/input1/index.htmlhttp://www.gamefromscratch.com/downloads/GDX/input1/index.htmlhttp://www.gamefromscratch.com/downloads/GDX/input1/index.htmlhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Gdx.htmlhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Gdx.htmlhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Gdx.htmlhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Input.Keys.htmlhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Input.Keys.htmlhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Input.Keys.htmlhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Input.Keys.htmlhttp://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Gdx.htmlhttp://www.gamefromscratch.com/downloads/GDX/input1/index.html
  • 8/10/2019 LibGDX Tutorial 1

    42/45

    Gdx.input.getX() and Gdx.input.getY() and set the sprites location to that position. The math may look a bit

    overly complicated, why didnt we simply set the location to the values returned by getX/Y? There are two

    reasons. First, our sprites coordinate is relative to its bottom left corner. so if we want to center the sprite, we

    need to take half the sprites width and height into consideration. The next complication comes from the fact that

    LibGDX sets the origin at the bottom left corner, but mouse positions are relative to the top left corner. Simply

    subtracting the position from the screen height gives you the location of the mouse in screen coordinates. Wealso check to see if the user as hit the right mouse button, and if they have we reposition the jet sprite at the

    center of the window.

    If it doesnt work in an frame,click here.

    Once again, you need to click within above before it will start receiving mouse events ( depending on your

    browser ). Left click and the sprite should move to the location you clicked. Right click to return to default ( in

    theory ), right click behaviour is a bit random in web browsers.

    Event driven keyboard and mouse handling

    Now we will look at handling the functionality of both of the above examples ( as a single example ), but this time

    using an event driven approach.

    package input.gamefromscratch.com;

    import com.badlogic.gdx.ApplicationListener;

    import com.badlogic.gdx.Gdx;

    import com.badlogic.gdx.Input.Buttons;

    import com.badlogic.gdx.Input.Keys;

    import com.badlogic.gdx.InputProcessor;

    import com.badlogic.gdx.graphics.GL10;import com.badlogic.gdx.graphics.Texture;

    import com.badlogic.gdx.graphics.g2d.Sprite;

    import com.badlogic.gdx.graphics.g2d.SpriteBatch;

    public class InputDemo implements ApplicationListener, InputProcessor {private SpriteBatch batch;

    private Texture texture;

    private Sprite sprite;

    private float posX, posY;

    @Overridepublic void create() {

    float w = Gdx.graphics.getWidth();

    float h = Gdx.graphics.getHeight();

    batch = new SpriteBatch();

    texture = new Texture(Gdx.files.internal("data/0001.png"));

    sprite = new Sprite(texture);

    posX = w/2 - sprite.getWidth()/2;

    posY = h/2 - sprite.getHeight()/2;

    sprite.setPosition(posX,posY);

    Gdx.input.setInputProcessor(this);

    }

    @Override

    public void dispose() {batch.dispose();

    texture.dispose();}

    http://www.gamefromscratch.com/downloads/GDX/input2/index.htmlhttp://www.gamefromscratch.com/downloads/GDX/input2/index.htmlhttp://www.gamefromscratch.com/downloads/GDX/input2/index.htmlhttp://www.gamefromscratch.com/downloads/GDX/input2/index.html
  • 8/10/2019 LibGDX Tutorial 1

    43/45

    @Override

    public void render() {

    Gdx.gl.glClearColor(1, 1, 1, 1);

    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    sprite.setPosition(posX,posY);batch.begin();

    sprite.draw(batch);

    batch.end();}

    @Override

    public void resize(int width, int height) {

    }

    @Override

    public void pause() {

    }

    @Overridepublic void resume() {

    }

    @Override

    public boolean keyDown(int keycode) {

    float moveAmount = 1.0f;if(Gdx.input.isKeyPressed(Keys.CONTROL_LEFT))

    moveAmount = 10.0f;

    if(keycode == Keys.LEFT)

    posX-=moveAmount;if(keycode == Keys.RIGHT)

    posX+=moveAmount;

    return true;}

    @Override

    public boolean keyUp(int keycode) {

    return false;

    }

    @Overridepublic boolean keyTyped(char character) {

    return false;

    }

    @Overridepublic boolean touchDown(int screenX, int screenY, int pointer, int button) {

    if(button == Buttons.LEFT){

    posX = screenX - sprite.getWidth()/2;

    posY = Gdx.graphics.getHeight() - screenY - sprite.getHeight()/2;

    }

    if(button == Buttons.RIGHT){

    posX = Gdx.graphics.getWidth()/2 - sprite.getWidth()/2;

    posY = Gdx.graphics.getHeight()/2 - sprite.getHeight()/2;

    }

    return false;

    }

    @Override

    public boolean touchUp(int screenX, int screenY, int pointer, int button) {

    return false;

    }

  • 8/10/2019 LibGDX Tutorial 1

    44/45

    @Overridepublic boolean touchDragged(int screenX, int screenY, int pointer) {

    return false;

    }

    @Override

    public boolean mouseMoved(int screenX, int screenY) {return false;

    }

    @Override

    public boolean scrolled(int amount) {

    return false;

    }

    }

    And here it is running:

    If it doesnt work in an frame,click here.

    The code is structured quite a bit differently from when we polled for input. The most immediate thing to be

    aware of is our class declaration:

    public class InputDemo implementsApplicationListener, InputProcessor {

    We are implementing another interface, InputProcessor, which as you can see adds a number of overrides to our

    code. The most important ones we are dealing with here are keyDown and touchDown. Touch you say? Yeah,

    LibGDX treats the mouse and touch input as the same thing. We will look at this in a bit more detail later on. In

    addition to implementing the various methods of our interface, we also need to register our InputProcessor with

    the global input instance, this is done here:

    Gdx.input.setInputProcessor(this);

    At this point, our various event handlers will now be called whenever an event occurs. keyDown will be fired

    when a key is pressed ( while keyUp is fired when it is released, and keyTyped is fired after it has been fired and

    released ). The parameter is the value of the key pressed. Once again, these values are available in the Keys

    object. One thing you may have noticed is that we still poll to see if the Control key is pressed. The alternative

    would be to set a flag when the control key is pressed and clear it when it is released. It is important to realize

    that a keyDown event will be fired for each individual key fired, so if you want to handle multiple simutanious key

    presses, this may not be the best way to approach the subject. Another thing you might notice is that you have to

    hit the key multiple times to move. This is because a key press generates only a single event ( as does itsrelease ). If you want to have the old behavior that holding down the key will move the character continously, you

    will need to implement the logic yourself. Once again, this can simply be done by setting a flag in your code on

    keyDown and toggle it when the keyUp event is called.

    The touchDown event on the other hand is much more straight forward. It can be a bit confusing handling

    mouse events called touches, but it makes sense. Generally the logic you handle for both would be exactly

    the same, so no sense treating them differently. The parameters passed in to touchDown are the x and y

    coordinates of the touch/click location, the pointer and button clicked. On a mobile device the Button value will

    always be Buttons.LEFT. Once again, screen coordinates and image coordiantes arent the same, so we need to

    deal with that in our positioning. Notice how I glossed over just what exactly pointer is? Well, pointer is a bit

    oddly named in my opinion. TouchIndex would probably have made more sense, especially with pointer having a

    pair of very well defined meanings already. The pointer value is value between 0 and n ( defined as 20 in

    http://www.gamefromscratch.com/downloads/GDX/input3/index.htmlhttp://www.gamefromscratch.com/downloads/GDX/input3/index.htmlhttp://www.gamefromscratch.com/downloads/GDX/input3/index.htmlhttp://www.gamefromscratch.com/downloads/GDX/input3/index.html
  • 8/10/2019 LibGDX Tutorial 1

    45/45

    LibGDX, in reality much lower ) that represents the ORDER in which the touch event occurred in the event of

    multiple simultaneous touches. Therefore if you have multiple fingers touching, a pointer value of 0 would

    indicate that this touch event represents the first finger to touch the screen, while a value of 3 would be the fourth

    finger to touch the screen. Dont worry, we will talk about this later when we deal specifically with touch.