Stage ja Actorite süsteem¶
Stage¶
Scene2D
on mängu UI, mis luuakse kas SpriteBatchi
ja/või Stage
ja Actor
-ite süsteemiga. Ühele Screen
-ile võib panna mitu Stage
-i. Hallates Screen
-e abstraktse Game
-klassi kaudu, seatakse vaid 1 Screen
ja selle Stage
/Stage
-id korraga aktiivseks. See võimaldab Sreen
-i ja ta Stage
-ide haldust teha Screen
-i klassis. Kui Game
klassi asemel tegeleb Screen
-ide vahetusega ApplicationListener
või ApplicationAdapter
, tuleb Screen
-ide ja Stage
-ide haldus teha ka nende klasside sees ning ka ise Screen
-ide aktiviseerumise ja inaktiveeruse loogikat ise läbi viia.
Screen-i kasutamine ilma Stage-ita:¶
Peab ise haldama
sprite
-ide joonistamist, asukohta ja kustutamist.Animatsioonide tegemiseks tuleb kasutada
Animation
-klassi.Kasutaja sisendi jaoks tuleb laiendada
InputProcessor
-it ja ka ise sisendi halduse loogika paika panna.
Stage-i kasutamise eelised:¶
Sprite
-id saab asendadaActor
-itega.Actor
-ite positsiooni määravad vanemadWidgetGroup
-is, sestWidgetGroup
implementeeribLayout
liidest.Animatsioone saab teha
Actions
-klassi abil.Stage
-ile saab kergelt lisadaInputProcessor
-i (Gdx.input.setInputProcessor(stage)
), jaActor
-itele lisadaListener
-e, määramaks, kas sisendit haldab vanem või lapseActor
kunaActor
-itel on hierarhiline süsteem.
Actorile InputListener andmine:¶
actor.setBounds(0, 0, texture.getWidth(), texture.getHeight());
actor.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("down");
return true;
}
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("up");
}
});
Tüüpilisel mängul on mängimise-ekraanil 3 kihti:
Taust – Staatiline või dünaamiline taust, mis pole interaktiivne.
Mänguobjektid – Tegelased, objektid ja klikitavad elemendid.
HUD
– Ekraani servadel asuv statistika (näiteks mängija punktid) ja nupud (näiteks pausinupp).
Sellise kihilise struktuuri loomiseks kasutatakse üldiselt kahte moodust:
Kasutades ühte
Stage
-i ja jaotadesActor
-id kolmeGroup
-i, kusStage
renderdab neid vastavalt z-indeksi järjekorras.Tehes kolm eraldi
Stage
-i (backgroundStage
,gameStage
,hudStage
) ning joonistades neid eraldi (backgroundStage.draw()
).
Stage-i asemel saab samu tulemusi kasutades SpriteBatch
-i, BitmapFont
-i ja InputProcessor
-i. Samuti võib AI olla eraldi Stage
-ist. Kui aga kasutada mõlemat samal Screen
-il korraga ehk Stage
-i koos Actor
-itega kui ka SpriteBatch
-iga, mis ei asu Stage
-i peal, peab arvestama, et Stage
-il ja Camera
'l on erinev Viewport
.
Camera ja Stage'i Viewport¶
// Camera viewport:
private Viewport viewport;
private Camera camera;
public void create() {
camera = new PerspectiveCamera();
viewport = new FitViewport(800, 480, camera);
}
// Stage viewport:
private Stage stage;
public void create() {
stage = new Stage(new StretchViewport(width, height));
}
Mitme erisuuruse ViewPort
-i puhul on ka Camera
'l ja Stage
-il erinev strateegia:
// Camera viewport:
viewport1.apply();
viewport1.draw
viewport2.apply();
viewport2.draw()()
// Stage viewport
stage1.getViewport().apply();
stage1.draw();
stage2.getViewport().apply();
stage2.draw();
Kasutades aga Camera
't ja Stage
-i koos:
public void create() {
Viewport viewport = new FitViewport(worldWidth, worldHeight);
SpriteBatch spriteBatch = new SpriteBatch();
Stage stage = new Stage(new FitViewport(worldWidth, worldHeight));
stage.getViewport().getCamera().position.setZero(); // (valikuline) kaamera keskele panek
}
public void render() {
viewport.apply();
spriteBatch.setProjectionMatrix(viewport.getCamera().combined);
spriteBatch.begin();
// spriteBatch.draw() sisendparameetritega
spriteBatch.end();
stage.getViewport().apply();
stage.draw();
}
Actor¶
Kõik Stage
-i elemendid on tavaliselt esindatud Actor
-itena. Stage
joonistab, uuendab ja eemaldab enda peal olevad Actor
-id automaatselt. Kui Actor
ei panda Stage
-i peale, peab Actor
-it ise haldama.
Actorite omadused:¶
Positsioon – vasaku alumise nurga kaugus oma vanemast, kui
Actor
kuulubGroup
-i. Ka animatsiooni saab selle omadusi järgi lisada (asukoha muutusele lisaks anda aja-parameeter), kasutadesAction
-it.Suurus – ristkülikukujuline kuju.
Vanem – kui
Actor
kuulubGroup
-i, siis kes on tema vanem.Skaleerimisvõime – suuruse muutmise võime, millele saab ka aja-parameetri kaasa anda
Action
-it kasutades.Pööramisvõime – millele saab ka aja-parameetri kaasa anda, et sujuvust muuta,
Action
-it kasutades.Z-indeks – kas
Actor
asub teiste peal või all.Värv – värvus ja läbipaistvus, millele saab ka aja-parameetri kaasa anda
Action
-it kasutades.
Actor
-itel on olemas erinevad Listener
-id, kuid keerukamate Event
-ide jaoks on vaja Actor
-eid laiendada või Listener
-e kohandada.
Actor
-i alamtüübil Widget
-il on juba sisseehitatud kasutaja sisendi haldamine ning lisaks kasutab Widget
Layout
liidest.
WidgetGroup
koosneb mitmest Widget
-ist ehk peale Actor
-i on WidgetGroup
ka Group
-i alamtüüp.
Actorite hierarhia:¶
Actor
│
├── Layout Widgetid: määravad widgetite paigutuse Stage'il.
│ ├── WidgetGroup: kui Widgetil on lapsed
│ │ ├── ScrollPane: keritavus
│ │ ├── SplitPane
│ │ ├── Tree
│ │ ├── HorizontalGroup
│ │ ├── VerticalGroup
│ │ └── Stack: Actorid pannakse üksteise peale
│ ├── Table: Saab vanemaks panna terve Stagei (setFillParent(true))
│ ├── Container:
│ └── Window: UI-aknad
│ └── Dialog
│
├── Widgetid: kasutaja sisendi jaoks
│ ├── Label
│ ├── Button
│ │ ├── TextButton
│ │ ├── ImageButton
│ │ └── CheckBox
│ ├── ProgressBar
│ │ ├── Slider
│ │ └── ProgressBar
│ ├── List
│ ├── SelectBox: Rippmenüü
│ ├── TextField
│ ├── TextArea: Mitmerealine tekstiväli
│ └── Touchpad
│
├── Image (`TextureRegioniga` või `Drawable`)
└── CustomActor
Widget
-it ja WidgetGroup
-i saab luua ka Stage
-ita, rakendades mõlemale pack
meetodit ning kasutades SpriteBatch
-i Widget
-i joonistamiseks.
Label ja Table ilma Stage'ita¶
private SpriteBatch batch;
private Label label;
private Skin skin;
private Table table;
public void create() {
batch = new SpriteBatch();
skin = new Skin(Gdx.files.internal("uiskin.json"));
label = new Label("Hello!", skin);
label.pack();
label.setPosition(100, 100);
table = new Table();
table.add(label);
table.pack();
}
public void render() {
batch.begin();
label.draw(batch, 1);
batch.end();
}