Welcome to a place of magic and wonder, the World Wide Web! Even though some folks say this Internet thing is “just a fad,” and we should keep using usenet and gopher, there’s at least one thing the WWW has that those technologies don’t:

libGDX Games

Html checkbox. The rest should be straightforward! BUT IT SOMETIMES ISN’T, AT FIRST gradlew html:superDev will be your main tool during development; it allows for a much-improved debugging experience and allows quickly reloading changes to the Java code. gradlew html:dist produces a fully-functioning web page that can be uploaded to a static web host (such as the free GitHub Pages service); it also optimizes the web page so the game in it will perform better, which makes dist take a little longer than superDev.

superDev

superDev allows you to debug your HTML5 application. This is not necessary in most cases: if there are problems in your core game, you can debug the desktop application. But sometimes, there are bugs only appearing when running on HTML5. You can debug the application with the following steps:

  • html:superdev Gradle task. It compiles the game and sets up a local HTTP server. When it is done, it will idle to keep the server running.
  • http://localhost:8080/index.html (current config) or http://localhost:8080/html/ (older Gradle configuration with Jetty plugin) - open the page with Chrome to debug
  • - build.gradle:
    1. gwt { // right below compiler.strict = true compiler.style = org.wisepersist.gradle.plugins.gwt.Style.DETAILED}

    dist Information

    html/build/dist/. You can delete the sourcemap files if you feel you won’t be debugging the dist; they’re usually a few MB in size and are in html/build/dist/WEB-INF/deploy/html/symbolMaps.

    Fullscreen Functionality

    Surprisingly, fullscreen functionality actually works on the HTML backend. To enable fullscreen, call the following method from within your core project:
    1. Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
    PR pending):
    1. class ResizeListener implements ResizeHandler { @Override public void onResize(ResizeEvent event) { if (Gdx.graphics.isFullscreen()) { Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); } else { int width = event.getWidth() - PADDING; int height = event.getHeight() - PADDING; getRootPanel().setWidth("" + width + "px"); getRootPanel().setHeight("" + height + "px"); getApplicationListener().resize(width, height); Gdx.graphics.setWindowedMode(width, height); } }}
    Don’t forget to also set the fullscreen orientation for mobile in the getConfig():
    1. cfg.fullscreenOrientation = GwtGraphics.OrientationLockType.LANDSCAPE;

    Resolution on mobiles

    config.usePhysicalPixels = true;. This will also affect HDPI and Retina screens on desktop, so maybe you want to use usePhysicalPixels = GwtApplication.isMobileDevice(). Check out this PR for detailed information.

    Changing the Load Screen Progress Bar

    As much as we love libGDX, the default loading progress bar when preparing the HTML game screams “newbie”. Impress your friends and bring honor to your family name by making a custom progress bar! Add the following to your HtmlLauncher class in your HTML project:
    1. @Overridepublic Preloader.PreloaderCallback getPreloaderCallback() { return createPreloaderPanel(GWT.getHostPageBaseURL() + "preloadlogo.png");}@Overrideprotected void adjustMeterPanel(Panel meterPanel, Style meterStyle) { meterPanel.setStyleName("gdx-meter"); meterPanel.addStyleName("nostripes"); meterStyle.setProperty("backgroundColor", "#ffffff"); meterStyle.setProperty("backgroundImage", "none");}
    “preloadlogo.png” is an image you place in the “webapp” folder in the HTML project for DIST builds. Place the image in your “war” folder as well for your SUPERDEV builds. Adjust your color to fit the theme of your game. Enjoy yourself.

    Speeding up preload process

    Speaking of the preloader: The HTML5 preloader is necessary, because usual gdx games rely on all assets being ready to access when needed. It prefetches every file in your asset directory. This may take some time and is not necessary if your game is a game that does not need all assets for presenting the startup screen. Think of all the people out there not having high speed internet connections. AssetFilter with your own AssetFilter on GWT and return false for all asset files that are not needed before game start. Make sure these files are only loaded via AssetManager, otherwise your game will freeze when using such assets.
    1. public class AssetFilter extends DefaultAssetFilter { @Override public boolean preload(String file) { return !file.endsWith(".png") || file.startsWith("data/hud/"); }}
    GdxDefinition.gwt.xml file:
    1. <set-configuration-property name="gdx.assetfilterclass" value="your.package.AssetFilter"/>
    See game source commit using the feature) an alternative backend.

    Preventing Keys From Triggering Scrolling and Other Browser Functions

    On a normal web page, if you press the down arrow on your keyboard, it will scroll the page up. That’s nice and all, but maybe you don’t want that to happen when players are trying to move the character in your game. To prevent this, you have to set libGDX to prevent the default actions of special keys by catching them:
    1. Gdx.input.setCatchKey(Input.Keys.SPACE, true);

    Preventing Right Click Context Menu

    Similarly to keyboard keys, the right click context menu can be prevented from interrupting your game. You’ll notice that there are already functions to prevent left click from doing anything unexpected. You just need to add an additional line to apply the fix to right click as well. The following must be added to the script block of your index.html in the “html/webapp” folder (dist) and “html/war” folder (superDev):
    1. // prevent right clickdocument.getElementById('embed-html').addEventListener('contextmenu', handleMouseDown, false);

    Sound and Music

    You will probably face some problems with sounds and music, especially on mobile platforms. It is not recommended to play sounds immediately on startup of the game as browsers probably will block this. check out this PR

    Differences Between GWT and Desktop Java

    Numbers

  • long.
  • int.
  • ints is much faster than math with longs on GWT, because any int is represented by a JavaScript Number and web browsers are used to working with Numbers all the time. On the other hand, any long is represented by a specific type of JavaScript Object that stores three Numbers to help ensure precision.
  • int, is almost the same as a double in Java, but it also allows bitwise operations to be used on it.
  • doubles, they don’t overflow, and can go higher than Integer.MAX_VALUE (2147483647) and lower than Integer.MIN_VALUE (-2147483648). Using any bitwise operation on them will bring any numbers that got too big back into the normal int range. If you encounter fishy numeric results that seem way too large for an int, try using this simple trick: int fishy = Integer.MAX_VALUE * 5; int fixed = (Integer.MAX_VALUE * 5) | 0; On desktop, adding | 0 won’t change anything, but it can correct numbers that got weird on GWT. Or, you can use a long.
  • long values on GWT is that they aren’t visible to reflection, so libGDX’s Json class won’t automatically write them or read them. You can work around this with Json’s handy custom serializer behavior, so it isn’t a huge issue.
  • MathUtils.isEqual().

    Other Known Limitations

  • -
  • this wiki page for more details. -
    • an alternative backend which is based on WebAudioAPI and supports it. -
  • -
  • draw it pixel by pixel or use FrameBuffer with a ShapeRenderer to achieve it.
    • -
  • -
  • https://github.com/intrigus/gdx-freetype-gwt

    Further Reading

    The original Super Dev Instructions from Mario How to speed up GWT compilation Building libGDX from source and adding new files to gdx.gwt.xml HTML5 - GWT Explained on YouTube