Skip to content

Adding Images and Sounds

Almas Baimagambetov edited this page Nov 13, 2017 · 4 revisions

This tutorial builds on previous Basic Game Example. Please complete it first if you haven't done so.

Tutorial Brief

Works with fxgl

  1. Replace player view by an image.
  2. Add an image to the game UI.
  3. Play a sound when pixels moved is divisible by 100.

By end of this tutorial you will have:

Preparation

Using the previous tutorial's project, create the assets directory in:

  • If you use Maven/Gradle: src/main/resources/
  • If you use uber-jar (as external library): src/

Note: you can read more on the standard Directory Structure.

Create textures and sounds directories in assets. I will use this image and this sound. To download, click on the link and then click "Download". You can use your own or download these ones. Then place the image and the sound you want to use in your game in textures and sounds respectively.

Feature 1 (Player Image)

First we will replace the blue rectangle that is the player with an image of your choice. It is very easy to do with the fluent API. In fact, there is only one line of code (commented out below) we will replace from the previous tutorial:

@Override
protected void initGame() {
    player = Entities.builder()
            .at(300, 300)
            //.viewFromNode(new Rectangle(25, 25, Color.BLUE))
            .viewFromTexture("brick.png")
            .buildAndAttach(getGameWorld());
}

The image file that I've used is called brick.png and is located in assets/textures/. Hence, FXGL knows that it is a texture and so we can simply use just the name. If your file is named differently, then you will use that name instead.

You should now be able to move the player (who is now represented by a brick image, rather than a blue rectangle). Wasn't too hard, was it? 👍

Feature 2 (UI Image)

Remember where we put UI code? Yes, it's in initUI()! Let's add the following:

Texture brickTexture = getAssetLoader().loadTexture("brick.png");
brickTexture.setTranslateX(50);
brickTexture.setTranslateY(450);

getGameScene().addUINode(brickTexture);

It should pretty straightforward just by reading the code. We can load any asset by calling getAssetLoader().load .... We are loading from textures/, so it's loadTexture(). You can find the full list of asset types that FXGL supports in Assets.

Note: a Texture is also a JavaFX Node, so you can easily use in UI and call UI methods, such as setTranslate(). Almost done 😃

Feature 3 (Sound)

We want to play a sound but we want to do it when the number of pixels moved by the player is divisible by 100. You know, just to keep things interesting. We could do it the old school way and keep checking how far the player's travelled in the update loop. However, the modern approach, which is listening for the changes, is much neater. In initGame() we can do:

getGameState().<Integer>addListener("pixelsMoved", (prev, now) -> {
    // code here gets called whenever "pixelsMoved" global variable changes
});

You can listen for changes in any global variable. Better still you also get the previous value in your callback (as can be seen above). Right, the final piece of the puzzle is:

getGameState().<Integer>addListener("pixelsMoved", (prev, now) -> {
    if (now % 100 == 0) {
        getAudioPlayer().playSound("drop.wav");
    }
});

As discussed, we check if current value of pixelsMoved (accessed via now) is divisible by 100. If it is, then play the sound file, which in my case is called drop.wav. We could, as with Texture, call getAssetLoader().loadSound("drop.wav"), apply some settings and then play it. However, if you just want to play a sound once with default settings, then getAudioPlayer().playSound("drop.wav") is much more concise.

You now know how to add images and sounds to your game. Yay!

Link to the full source code of this tutorial. Enjoy!

Want some more? Follow a more complex video tutorial. Explore Core Features, or experiment with pre-made games.

Clone this wiki locally