Atlas-fail¶
Atlas-fail on failiformaat, mis võimaldab koondada erinevaid pildifaile (PNG, JPEG, BMP, GIF, TIFF, WEBP) üheks suureks Texture’iks. Atlas-faili eri formaatidega faile pannes muudetakse kõik need staatilisteks (PNG/JPEG). Tasub küll tähele panna, et GIF-failid salvestatakse ainult ühe kaadrina.
Texture sisaldab pildi metaandmeid ning üht Texture'it laaditakse arvutimällu ainult ühe korra, initsialiseerimise ajal. Kui kõigil failidel on oma Texture, tuleb iga Texture vahetamisel (näiteks animatsioonides või ühte pilti teisega asendades) siduda Texture CPU-ga ehk bind'ida.
Lisaks kasutatakse Texture’i joonistamiseks kas SpriteBatch'i (mitme pildi korraga joonistamine) või Sprite’i (üksiku pildi joonistamine), mis ka vajavad igal joonistamisel bind'imist.
Atlas-fail võimaldab efektiivsemat mälukasutust ning teeb ka failihalduse lihtsamaks.
Mitmest pildifailist Atlas-faili loomine¶
Aseta kõik failid, mida soovid atlas-faili koondada, ühte kausta (näites
powerupFlykaust).
Leia
build.gradlefaillwjgl3projektist ning lisatasks.registermeetodite juurde järgmised read:
tasks.register("runTexturePacker", JavaExec) {
main = "tools.TexturePackerTool"
classpath = sourceSets.main.runtimeClasspath
args = []
}
Kontrolli, et järgmine dependency oleks olemas – kui seda pole, lisa see dependencies alla:
dependencies {
implementation "com.badlogicgames.gdx:gdx-tools:$gdxVersion"
}
PS! Vanem JDK versioon eelistab
task runTexturePacker(type: JavaExec) {
main = "tools.TexturePackerTool"
classpath = sourceSets.main.runtimeClasspath
args = []
}
3. Loo klass TexturePackerTool package-is tools ja kopeeri sinna järgnev kood, kus asenda soovi korral:
- assets/powerupFly oma pildikausta nimega.
- assets/packed soovitud pildikausta nimega.
- packFileName soovitud atlas-faili nimega.
NB! tools paketti ei ole vaja käsitsi luua – see tuleb automaatselt koos gdx-tools dependencyga.
package tools;
import com.badlogic.gdx.tools.texturepacker.TexturePacker;
public class TexturePackerTool {
public static void main(String[] args) throws Exception {
String inputDir = "assets/powerupFly";
String outputDir = "assets/packed";
String packFileName = "powerupFly";
TexturePacker.process(inputDir, outputDir, packFileName);
}
}
Jooksuta
TexturePackerToolklassi.Sulle tekib
packedkaust (kus on.atlasja.pnglaiendusega failid). PNG-faili on koondatud kõik pildid ning atlas-failis on info, mis koordinaatidel eri PNG-failid asuvad.
|
|
Järgnev kood näitab, kuidas otsida atlas-faili abil kindel piirkond (näites ämbri PNG ehk bucket) ning kuidas (näites tingimuslikult) muuta bucketSprite’i pilt.
Loome enne konstruktorit kaks uut muutujat:
boolean canFly = false;float canFlyTimer = 0;
canFly väärtuse muudame trueks kui bucket välgunoolega kokku puutub.
input meetodis määrame kolmanda vajaliku muutuja ning see on ka meetod, kus määrame, mis klaviatuuri klahvidega on võimalik bucket-it liigutada.
float delta = Gdx.graphics.getDeltaTime();
logic meetodis paneme canFly muutuja sõltuma canFlyTimer-ist ning canFlyTimer-i sõltuma delta muutujast. Siin meetodis anname bucket muutujale võime ka liikuda vertikaalselt ehk input meetodis saab mängija klaviatuuril kahte nuppu lisaks vajutada. Me ei anna seda võimet aga igaveseks vaid kaheks sekundiks ning canFlyTimer peab järge aja möödumise üle. Kui canFlyTimer nulli jõuab, siis määrame canFly oleku jälle false-iks. delta muutuja tagastab meile kui palju aega möödus viimase kaadri renderdamisest.
public class Main implements ApplicationListener {
private SpriteBatch spriteBatch;
private TextureAtlas textureFlyAtlas;
private Rectangle bucketRectangle;
private Sprite bucketSprite;
private TextureAtlas.AtlasRegion bucketRegion;
private float canFlyTimer = 0;
private boolean canFly = false;
@Override
public void create() {
textureFlyAtlas = new TextureAtlas("assets/packed/powerupFly.atlas");
bucketRegion = textureFlyAtlas.findRegion("bucket");
bucketSprite = new Sprite(bucketRegion);
bucketSprite.setSize(1, 1);
bucketSprite.setPosition(42, 0);
bucketRectangle = new Rectangle();
}
private void logic() {
if (canFly) {
canFlyTimer -= delta;
if (canFlyTimer <= 0) {
bucketSprite.setRegion(bucketRegion);
}
}
}
@Override
public void dispose() {
textureFlyAtlas.dispose();
spriteBatch.dispose();
}
}
Mitmest pildifailist animatsiooni loomine TextureAtlasega¶
Aseta kõik failid, mida soovid atlas-failiga animatsiooniks teha, ühte kausta.
Leia
build.gradlefaillwjgl3projektist ning lisatasks.registermeetodite juurde järgmised read:
tasks.register(runTexturePacker, JavaExec) {
main = tools.TexturePackerTool
classpath = sourceSets.main.runtimeClasspath
args = []
}
3.Uuenda TexturePackerTool klassi, asendades:
assets/bucketsoma pildikausta nimega.assets/packedAnimationssoovitud pildikausta nimega.packFileNamesoovitud atlas-faili nimega.
Jooksuta
TexturePackerToolklassi.Sulle tekib
packedAnimationskaust (kus on.atlasja.pnglaiendusega failid). PNG-faili on koondatud kõik animatsiooni kaadrid ning atlas-failis on info, mis koordinaatidel eri PNG-failid asuvad.
Järgnev kood näitab, kuidas otsida atlas-faili abil kindel piirkond (animatsiooni kaadrid) ning kuidas seda rakendada bucketSprite’il (näites tingimusel, kui ämber on alla kukkumas).
public class Main implements ApplicationListener {
private TextureAtlas.AtlasRegion bucketRegion;
private TextureAtlas textureAnimationAtlas;
private Array<TextureAtlas.AtlasRegion> bucketAnimationFrames;
private Rectangle bucketRectangle;
private Sprite bucketSprite;
private float animationTimer;
private int currentFrameIndex;
boolean isFalling = false;
float fallSpeed = 0;
float fallEndY = 0;
@Override
public void create() {
textureAnimationAtlas = new TextureAtlas("assets/packedAnimation/animation.atlas");
bucketAnimationFrames = new Array<>();
for (int i = 1; i <= 8; i++) {
String frameName = "bucket" + i;
bucketAnimationFrames.add(textureAnimationAtlas.findRegion(frameName));
bucketSprite = new Sprite(bucketRegion);
bucketSprite.setSize(1, 1);
bucketSprite.setPosition(42, 0);
bucketRectangle = new Rectangle();
}
@Override
public void render() {
input();
logic();
draw();
}
private void logic() {
if (isFalling) {
animationTimer += delta;
if (animationTimer >= 0.1f) {
currentFrameIndex++;
if (currentFrameIndex >= bucketAnimationFrames.size) {
currentFrameIndex = 0;
}
animationTimer = 0;
bucketSprite.setRegion(bucketAnimationFrames.get(currentFrameIndex));
}
bucketSprite.translateY(-fallSpeed * delta);
if (bucketSprite.getY() <= fallEndY) {
bucketSprite.setY(fallEndY);
isFalling = false;
bucketSprite.setRegion(bucketRegion);
}
}
}
@Override
public void dispose() {
textureFlyAtlas.dispose();
spriteBatch.dispose();
}
}