If you are using the Gradle Kotlin DSL, see README-kotlin
GdxPlugin is a Gradle plugin that adds a few libGDX related tasks to:
- create Texture Packs (a.k.a. Texture Atlases) using TexturePacker
- create Bitmap Fonts using Hiero
- create Nine Patches
- create Distance Fields from single images using DistanceFieldGenerator
This plugin requires Gradle 6.4 or higher.
- Getting started
- PackTextures task
- BitmapFont task
- NinePatch task
- DistanceField task
- General
- Changelog
Add the plugin to your project:
plugins {
id "com.github.blueboxware.gdx" version "1.3.3"
}
Creating a packTextures task:
packTextures {
// The directory which contains the images to pack
from 'textures/'
// The target directory: 'pack.atlas' is placed in this directory
into 'assets/'
settings {
// Settings for TexturePacker
filterMin = "MipMapLinearNearest"
filterMag = "MipMap"
}
}
Run the task (or just do a build):
gradlew.bat packTextures
To create a Bitmap Font:
bitmapFonts {
// We name the font 'text': this creates a task called 'generateTextFont'
text {
inputFont = file("fonts/roboto.ttf")
outputFile = file("assets/textFont.fnt")
// Create the font in 2 sizes. The created fonts will be put in "textFont32px.fnt" and "textFont64px.fnt"
sizes = [32, 48]
// The settings to use for the fonts
settings {
bold = true
// The effects to apply
effects = [
color {
color = color("#ff0000")
},
shadow {
opacity = 0.4
xDistance = 4
yDistance = 4
}
]
}
}
}
Run the task (or just do a build):
gradlew.bat generateTextFont
To create Nine Patches:
ninePatch {
// Creates a task called generateRectangleNinePatch
rectangle {
image = file('textures/rect.png')
output = file('assets/rect.9.png')
// The insets, as number of pixels from the left/right/top/bottom of the image
left = 2
right = 2
top = 4
bottom = 4
}
// Creates a task called generateBorderNinePatch
border {
image = file('textures/border.png')
output = file('assets/border.9.png')
left = 2
right = 2
top = 4
bottom = 4
// The paddings
// If you don't specify any padding, no padding is included in the ninepatch
paddingLeft = 4
paddingRight = 4
paddingTop = 4
paddingBottom = 4
}
}
To create all the ninepatches, run the createAllNinePatches
task.
To create Distance Fields from single images:
distanceFields {
// Creates a task called generateLogoDistanceField
logo {
inputFile = file('textures/logo.png')
downscale = 8
spread = 32
outputFile = file('assets/logo-df.png')
}
// Creates a task called generateTitleDistanceField
title {
inputFile = file('textures/title.jpg')
downscale = 4
spread = 16
color = 'ff0000'
outputFile = file('assets/title-df.png')
}
}
Settings for Texture Packer are specified in a settings { }
block. See the libGDX Wiki
for a list of available settings, their default values and descriptions. To get a quick overview of the available settings you can run the
texturePackerSettingsHelp
Gradle task.
For reference, these are the most important settings and their default values, as of libGDX 1.10.0:
settings {
pot = true
multipleOfFour = false
paddingX = 2
paddingY = 2
edgePadding = true
duplicatePadding = false
rotation = false
minWidth = 16
minHeight = 16
maxWidth = 1024
maxHeight = 1024
square = false
stripWhitespaceX = false
stripWhitespaceY = false
alphaThreshold = 0
filterMin = "Nearest"
filterMag = "Nearest"
wrapX = "ClampToEdge"
wrapY = "ClampToEdge"
format = "RGBA8888"
alias = true
outputFormat = "png"
jpegQuality = 0.9
ignoreBlankImages = true
fast = false
debug = false
silent = false
combineSubdirectories = false
ignore = false
flattenPaths = false
premultiplyAlpha = false
useIndexes = true
bleed = true
bleedIterations = 2
limitMemory = true
grid = false
scale = [1.0]
scaleSuffix = [""]
scaleResampling = ["bicubic"]
atlasExtension = ".atlas"
prettyPrint = true
legacyOutput = true
}
If you want to create multiple texture packs, you can use a texturePacks { }
block.
The following example creates 3 tasks: packGameTextures, packMenuTextures and packGameOverTextures:
texturePacks {
// Creates "game.atlas"
game {
from 'textures/game'
into 'assets'
}
// Creates "menu.atlas"
menu {
from 'textures/menu'
into 'assets'
settings {
filterMin = 'MipMapLinearNearest'
filterMag = 'Nearest'
}
}
gameOver {
from 'textures/gameOver'
into 'assets'
// Name the pack "end.atlas" instead of the default "gameOver.atlas"
packFileName = 'end.atlas'
}
}
Sometimes you want a few simple solid color rectangular textures in your atlas, like a single white pixel. Instead of creating these yourself, you can have
the plugin generate them for you with the solid { }
directive:
packTextures {
into 'assets/'
from 'textures/'
// Adds a single white pixel named "white"
solid {
name = "white"
}
// Adds a 3x4 red texture named "red"
solid {
name = "red"
color = color("#ff0000") // default: #ffffffff
width = 3 // default: 1
height = 4 // default: 1
}
}
If some of the textures which have to be packed are generated by a bitmap font task or distance field task, you have make sure these tasks are run first, so that the input for the texture pack is available and up to date. You can do this by making the texture pack task depended on those other tasks using Gradle's dependsOn mechanism:
bitmapFonts {
roboto {
// ...
}
}
distanceFields {
logo {
// ...
}
}
packTextures {
from 'textures/'
into 'assets/'
dependsOn(generateRobotoFont, generateLogoDistanceField)
}
To reuse settings for multiple texture packs, you can define settings objects with packSettings { }
(packSettings
has to be
imported from dsl.Utils
):
import static com.github.blueboxware.gdxplugin.dsl.Utils.*
// Create base settings
def baseSettings = packSettings {
filterMin = 'MipMapLinearNearest'
filterMag = 'Nearest'
maxWidth = 2048
maxHeight = 2048
}
// Create settings for scaled texture packs, based on the base settings
def scaledPackSettings = packSettings(baseSettings) {
scale = [1, 2]
scaleSuffix = ["Normal", "Scaled"]
scaleResampling = ["bicubic", "bicubic"]
}
texturePacks {
game {
from 'textures/game'
into 'assets'
settings = baseSettings
}
menu {
from 'textures/menu'
into 'assets'
settings = scaledPackSettings
}
gameOver {
from 'textures/gameOver'
into 'assets'
// Use packSettings, but change outputFormat to jpg
settings = packSettings(baseSettings) {
outputFormat = "jpg"
}
}
}
Pack Textures tasks implement Gradle's CopySpec, so you can specify multiple input directories, and filter and rename files:
packTextures {
into 'assets'
from('textures/ui') {
exclude 'test*'
}
from('textures/menu') {
include '*.png'
rename('menu_(.*)', '$1')
}
}
Normally any pack.json
files in the input directories (and any subdirectories) are ignored. If you want to load the texture packer settings from a
pack.json file instead of defining them in the build file, you can use the settingsFile
argument:
packTextures {
from 'textures/'
into 'assets/'
settingsFile = file('textures/pack.json')
}
If you want TexturePacker to use pack.json files found in the input directories and any subdirectories, set usePackJson
to true:
packTextures {
from 'textures/'
into 'assets/'
usePackJson = true
}
Note that if you specify multiple input directories (see above), and more than one of the top level directories contain
pack.json files, only one of these is used. Use the settingsFile
parameter to specify which one.
The plugin provides the PackTextures
task type which can be used to create custom tasks:
import com.github.blueboxware.gdxplugin.tasks.PackTextures
task('myPackTask', type: PackTextures) {
description = 'Pack things'
into 'assets'
from 'textures'
settings {
atlasExtension = ".pack"
filterMin = "MipMapLinearLinear"
}
doLast {
println 'Done!'
}
}
The input font is specified by the inputFont
parameter. It can be set to a File, which should be a TTF-file. It can also be set to a String, in which
case it should be the name of a system font which will be used to generate the bitmap font. If you don't specify an input font, the system font "Arial"
is used (assuming a font with that name is available).
The characters
parameter is used to specify a string which contains all the characters to include in the font. The following predefined constants are available:
NEHE
(DEFAULT): "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz1234567890"!`?'.,;:()[]{}<>|/@^$-%+=#_&~*\u007f", the same as Hiero's NEHE character setCOMMON
: same asNEHE
ASCII
: all ASCII characters from ord(33) to ord(255) inclusive, the same as Hiero's ASCII character setEXTENDED
: a larger collection of characters, the same as Hiero's Extended character set
The space and null characters are always added.
Use the outputFile
argument to specify the filename for the bitmap font. If you specify multiple sizes, the sizes will be appended to the specified
name (for example: arial16px.fnt
, arial32px.fnt
, etc.). If you don't specify an output file, the task name will be used and the font will be written
to the top level directory of the project.
You can also specify custom names for specific sizes:
bitmapFonts {
text {
inputFont = file("fonts/roboto.ttf")
// Default output name
outputFile = "assets/textFont.fnt"
// Create textFont16px.fnt and textFont24px.fnt
sizes = [16, 24]
// Also create a 32 px font in assets/big.fnt
size 32, "assets/big.fnt"
// And a 64 px font in assets/toobig.fnt
size 64, file("assets/toobig.fnt")
}
}
The settings for the font are specified using a settings { }
block. It supports the same settings as Hiero and has the same defaults, except that
the default renderType
is Java instead of FreeType. Here are the available settings with their defaults:
settings {
bold = false
italic = false
mono = false
gamma = 1.8f
paddingTop = 1
paddingLeft = 1
paddingBottom = 1
paddingRight = 1
paddingAdvanceX = -2
paddingAdvanceY = -2
glyphPageWidth = 512
glyphPageHeight = 512
// "Java", "FreeType" or "Native"
renderType = "Java"
// The effects to apply
effects = [
color {
color = color("#ffffff")
}
]
}
The effects from Hiero are available, and a list of effects to apply can be used with the effects
parameter of the settings to
specify which effects to use and their settings. The effects have the same parameters and defaults as in Hiero. Here are the
available effects and their defaults:
color {
color = color("#ffffff")
}
gradient {
topColor = color("#00ffff")
bottomColor = color("#0000ff")
offset = 0
scale = 1f
cyclic = false
}
shadow {
color = color("#000000")
opacity = 0.6f
xDistance = 2f
yDistance = 2f
blurKernelSize = 0
blurPasses = 1
}
outline {
width = 2f
color = color("#000000")
join = JoinBevel // JoinBevel, JoinMiter or JoinRound
stroke = null // See java.awt.Stroke
}
wobble {
width = 2f
color = color("#000000")
detail = 1f
amplitude = 1f
}
zigzag {
width = 2f
color = color("#000000")
amplitude = 1f
wavelength = 3f
join = JoinBevel // JoinBevel, JoinMiter or JoinRound
}
distanceField {
color = color("#ffffff")
scale = 1
spread = 1f
}
The arguments for NinePatch tasks with their defaults:
ninePatch {
taskName {
// Input image
image = file('textures/rect.png')
// By default the output image is put in the same directory as the input image
// and has the same name but with the extension ".9.png"
output = file('textures/rect.9.png')
// Insets
// These are the number of pixels from the left/right/top/bottom of the image where the center stretch region starts
left = 0
right = 0
top = 0
bottom = 0
// Padding
// Padding is only generated if you specify at least one of the below
paddingLeft = same as left inset
paddingRight = same as right inset
paddingTop = same as top inset
paddingBottom = same as bottom inset
// When true, tries to determine the insets automatically. See next section.
auto = false
fuzziness = 0f
centerX = image.width / 2
centerY = image.height / 2
}
}
If your image is fairly simple, you can have the plugin try to determine the insets automatically. Whether this will actually work depends on the image.
To do this, specify auto = true
and all insets you don't specify yourself will be automatically set.
When determining the insets, the plugin scans outward from the center of the image. If the center of the image is not
actually part of the center stretchable region, the results will be wrong. You can specify an alternative starting
location with the centerX
and/or centerY
arguments (the origin is top left).
The fuzziness
parameter determines how strict or loose the rows and columns of the image are compared. It should be
a float between 0 (inclusive) and 100 (inclusive). 0 means: the center region should be completely even - any difference
in row or column will be taken as the border of the center region. 100 means: all differences will be ignored and the
center region will contain the entire image. The default is 0. A value between 50 and 70 often seems to work when the
center region has a color gradient.
The arguments for the distance field task:
inputFile
: The input file (type: File)outputFile
: The output file (type: File, default: inputFileWithoutExtension + "-df." + outputFormat)color
: The color of the output image (type: String, default: "ffffff")downscale
: The downscale factor (type: int, default: 1)spread
: The edge scan distance (type: float, default: 1.0)outputFormat
: The output format (type: String, default: The extension ofoutputFile
. IfoutputFile
is not specified: "png")
The plugin comes with a bundled version of libGDX, which is used for packing etc. To see the libGDX version used by the
plugin (this is not the version used by your project itself), run the gdxVersion
task:
> gradlew.bat -q gdxVersion
1.10.0
If you want the plugin to use a different version, you can force this in the buildscript
block. For example, to use version 1.9.5:
buildscript {
ext {
gdxVersion = "1.9.5"
}
repositories {
mavenCentral()
// ... other repositories
}
dependencies {
// ... other dependencies
classpath("com.badlogicgames.gdx:gdx-tools:$gdxVersion") {
force = true
}
classpath("com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion") {
force = true
}
classpath("com.badlogicgames.gdx:gdx-platform:$gdxVersion") {
force = true
}
}
}
Use the gdxVersion
task again to check:
> gradlew.bat -q gdxVersion
1.9.5 (default: 1.10.0)
- Prepare for Gradle 8.0
- Minimum Gradle version is now 6.4
- Update to libGDX 1.10.0
- Fix warnings about property annotations in tasks
- Update to libGDX 1.9.11
- Display informative error when trying to create a jpeg with alpha when using OpenJDK
- Fix BitmapFont task
- Fix backward compatibility, down to Gradle 3.5
- Added NinePatch task
- It's no longer necessary to add custom tasks as dependencies to the build task
- Added
solid
directive to texture pack tasks to add simple solid colored textures
- Fix BitmapFont task
- Added task for creating Bitmap Fonts
- Added
createAllAssets
task which runs all the tasks of the plugin
- Added
createAllTexturePacks
task which runs all texture pack tasks - Added
createAllDistanceFields
task which runs all distance fields tasks - Use
packSettings()
instead ofPackTextures.createSettings()
to create texture packer settings objects - Made the plugin more Gradle Kotlin DSL-friendly. See README-kotlin.md