Skip to content

Instantly share code, notes, and snippets.

@avianey
Last active October 3, 2017 13:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avianey/4cbdf5e9c953dd714417 to your computer and use it in GitHub Desktop.
Save avianey/4cbdf5e9c953dd714417 to your computer and use it in GitHub Desktop.
Generates LibGDX BitmapFont and TextureAtlas at build time with Gradle
buildscript {
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
jcenter()
mavenLocal()
}
dependencies {
classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
classpath 'com.android.tools.build:gradle:1.5.0'
classpath('fr.avianey.androidsvgdrawable:gradle-plugin:3.0.0') {
// should be excluded to avoid conflict
exclude group: 'xerces'
}
}
}
buildscript {
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
jcenter()
mavenLocal()
}
dependencies {
classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
classpath 'com.android.tools.build:gradle:1.5.0'
classpath "com.badlogicgames.gdx:gdx-tools:1.7.3-SNAPSHOT"
classpath "com.badlogicgames.gdx:gdx-tools:1.7.3-SNAPSHOT:distribution"
classpath "com.badlogicgames.gdx:gdx:1.7.3-SNAPSHOT"
classpath "com.badlogicgames.gdx:gdx-platform:1.7.3-SNAPSHOT:natives-desktop"
classpath "com.badlogicgames.gdx:gdx-freetype:1.7.3-SNAPSHOT"
classpath "com.badlogicgames.gdx:gdx-freetype-platform:1.7.3-SNAPSHOT:natives-desktop"
classpath('fr.avianey.androidsvgdrawable:gradle-plugin:3.0.0') {
// should be excluded to avoid conflict
exclude group: 'xerces'
}
}
}
compileJava.dependsOn generateATLAS
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="90px" height="140px" viewBox="0 0 90 140"
version="1.1">
<rect
style="fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-opacity:1"
width="90" height="140" x="0" y="0" rx="8" ry="8" />
<image x="26" y="82" width="38" height="38" xlink:href="#{suit_.*}" />
<image x="22" y="16" width="46" height="46" xlink:href="#{rank_.*}" />
<path
style="fill:#000000;fill-opacity:0.1254902;stroke:none;stroke-opacity:1"
d="M 45 0 L 45 140 L 82 140 C 86.432 140 90 136.432 90 132 L 90 8 C 90 3.568 86.432 4.9515947e-17 82 0 L 45 0 z " />
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="90px" height="140px" viewBox="0 0 90 140"
version="1.1">
<defs>
<image id="suit" x="25" y="50" width="40" height="40" xlink:href="#{suit_.*}" />
<image id="rank" x="7" y="7" width="30" height="30" xlink:href="#{rank_.*}" />
</defs>
<rect
style="fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-opacity:1"
width="90" height="140" rx="8" ry="8" x="0" y="0" />
<use xlink:href="#suit" />
<use xlink:href="#rank" />
<use xlink:href="#rank" transform="translate(60, 110) rotate(180, 15, 15)"/>
<path
style="fill:#000000;fill-opacity:0.1254902;stroke:none;stroke-opacity:1"
d="M 45 0 L 45 140 L 82 140 C 86.432 140 90 136.432 90 132 L 90 8 C 90 3.568 86.432 4.9515947e-17 82 0 L 45 0 z " />
</svg>
import com.badlogic.gdx.tools.texturepacker.TexturePacker
task generateATLAS(dependsOn: [generatePNG, generateFONT]) {
ext.inputDir = file("${rootProject.projectDir}/android/build/generated/assets")
ext.outputDir = file("${rootProject.projectDir}/android/assets/")
inputs.file inputDir
outputs.dir outputDir
doLast {
TexturePacker.process(inputDir.getAbsolutePath(), outputDir.getAbsolutePath(), "skin")
}
}
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
import com.badlogic.gdx.backends.lwjgl.LwjglFiles
import com.badlogic.gdx.backends.lwjgl.LwjglGraphics
import com.badlogic.gdx.backends.lwjgl.LwjglInput
import com.badlogic.gdx.backends.lwjgl.LwjglNativesLoader
import com.badlogic.gdx.backends.lwjgl.LwjglNet
import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.g2d.PixmapPacker
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator
import com.badlogic.gdx.tools.bmfont.BitmapFontWriter
task generateFONT(dependsOn: [initHeadlessLibGDX]) {
ext.inputFont = file("${rootProject.projectDir}/resources/font/Cantarell-Regular.ttf")
ext.outputPNGDir = file("${rootProject.projectDir}/android/build/generated/assets/")
ext.outputPNGName = "cantarell.png"
ext.outputFNT = file("${rootProject.projectDir}/android/assets/cantarell.fnt")
ext.padding = 3
inputs.file inputFont
outputs.files files(new File(outputPNGDir, outputPNGName), outputFNT)
doLast {
outputPNGDir.mkdirs();
// from https://github.com/libgdx/libgdx/wiki/Hiero#bitmapfontwriter
FreeTypeFontGenerator.FreeTypeFontParameter param = new FreeTypeFontGenerator.FreeTypeFontParameter();
param.characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890." /* Hiero.EXTENDED_CHARS */;
param.size = 32;
param.color = new Color(1, 1, 1, 1f);
param.borderWidth = (padding - 1);
param.borderColor = new Color(0, 0, 0, 1f);
param.renderCount = 3;
param.packer = new PixmapPacker(512, 512, Pixmap.Format.RGBA8888, padding, false, new PixmapPacker.SkylineStrategy());
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(new FileHandle(inputFont.getAbsolutePath()));
FreeTypeFontGenerator.FreeTypeBitmapFontData data = generator.generateData(param);
BitmapFontWriter.FontInfo info = new BitmapFontWriter.FontInfo();
info.padding = new BitmapFontWriter.Padding(padding, padding, padding, padding);
BitmapFontWriter.writeFont(data, (String[]) [outputPNGName], new FileHandle(outputFNT.getAbsolutePath()), info, 512, 512);
BitmapFontWriter.writePixmaps(param.packer.getPages(), new FileHandle(outputPNGDir.getAbsolutePath()), "cantarell");
}
}
task generatePNG(type: fr.avianey.androidsvgdrawable.gradle.SvgDrawableTask) {
from = files("${rootProject.projectDir}/resources/svg/svg")
to = file("${rootProject.projectDir}/android/build/generated/assets")
createMissingDirectories = true
overwriteMode = "ifModified"
outputFormat = "PNG"
outputType = "raw"
svgMaskFiles = files("${rootProject.projectDir}/resources/svg/mask")
svgMaskResourceFiles = files("${rootProject.projectDir}/resources/svg/masked")
svgMaskedSvgOutputDirectory = file("${rootProject.projectDir}/android/build/generated/svg")
}
task initHeadlessLibGDX {
LwjglNativesLoader.load();
Gdx.graphics = new LwjglGraphics(new LwjglApplicationConfiguration());
Gdx.files = new LwjglFiles();
Gdx.input = new LwjglInput();
Gdx.net = new LwjglNet();
}
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.SpriteDrawable;
import com.badlogic.gdx.utils.Scaling;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
public class CardDeckApplication implements ApplicationListener {
private static final String[] RANKS = new String [] {"ace", "king", "queen", "jack", "ten", "nine", "eight", "seven", "six", "five", "four", "three", "two"};
private static final String[] SUITS = new String [] {"spade", "heart", "diamond", "club"};
private static final int BACKGROUND = 0x0A6B0DFF;
private static final float r = ((BACKGROUND >> 24) & 0xFF) / ((float) 0xFF);
private static final float g = ((BACKGROUND >> 16) & 0xFF) / ((float) 0xFF);
private static final float b = ((BACKGROUND >> 8) & 0xFF) / ((float) 0xFF);
private Skin skin;
private Stage stage;
private TextureAtlas atlas;
private AssetManager manager;
private boolean initialized = false;
@Override
public void create () {
manager = new AssetManager();
manager.load("skin.json", Skin.class);
manager.load("skin.atlas", TextureAtlas.class);
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
}
@Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
@Override
public void render() {
Gdx.gl.glClearColor(r, g, b, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (!manager.update()) {
// still loading
return;
} else if (!initialized) {
// loading done
initializeAssets();
initialized = true;
}
stage.act(Gdx.graphics.getRawDeltaTime());
stage.draw();
}
@Override
public void pause() {}
@Override
public void resume() {}
@Override
public void dispose() {
initialized = false;
stage.dispose();
manager.dispose();
}
private void initializeAssets() {
skin = manager.get("skin.json", Skin.class);
atlas = manager.get("skin.atlas", TextureAtlas.class);
// layout
Table table = new Table();
table.pad(10);
table.defaults().space(10);
table.setFillParent(true);
// header
table.row();
table.add(new Label("LibGDX Card Deck", skin, "cantarell")).colspan(RANKS.length);
// deck
for (String suit : SUITS) {
table.row();
for (String rank : RANKS) {
table.add(
new Image(
new SpriteDrawable(atlas.createSprite(String.format("card_suit_%s_rank_%s", suit, rank))),
Scaling.fit));
}
}
stage.addActor(table);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment