JavaFX je multiplatformní GUI toolkit pro Java a je nástupcem knihovny Java Swing. V tomto kurzu budeme zkoumat funkce JavaFX, které je snadno ovladatelný, jak začít programovat hry v Javě.
Tento kurz předpokládá, že už víte, jak se kód v jazyce Java. Pokud ne, podívejte se na další Java pro Android, Úvod do programování počítače s Java: 101 a 201, hlava první Java, Greenfoot nebo naučit Java tvrdý způsob, jak začít.
Instalace
Pokud jste již vyvíjet aplikace Java, pravděpodobně nebudete muset vůbec nic stahovat: JavaFX byla součástí standardní sady JDK (Java Development Kit) od JDK verze 7u6 (srpen 2012). Pokud jste neaktualizovali své instalace Javy ve chvíli, zamiřte do Java stáhnout webové stránky pro nejnovější verzi.
Základní rámec tříd
Vytvoření programu JavaFX začíná třída aplikace, z něhož jsou rozšířeny všechny aplikace JavaFX. Hlavní třída by měla zavolat metodu launch(), která pak zavolá metodu init() a poté vyčkejte na dokončení aplikace metodu start() a poté zavolejte metodu stop(). Z těchto metod metoda start() je abstraktní a musí být přepsána.
Třída Stage je nejvyšší úroveň JavaFX kontejner. Když se spustí aplikace, počáteční fázi je vytvořen a předán do aplikace start metody. Fáze řízení základní okno Vlastnosti, například titul, ikony, viditelnost, resizability, celoobrazovkový režim a dekorace; Ta je nakonfigurován pomocí StageStyle. Další fází může být vytvořena podle potřeby. Po fázi je nakonfigurován a přidávání obsahu, je volána metoda show().
Věděl to všechno, můžeme napsat minimální příklad, který otevře okno v JavaFX:
1
importjavafx.application.Application;
2
importjavafx.stage.Stage;
3
4
publicclassExample1extendsApplication
5
{
6
publicstaticvoidmain(String[]args)
7
{
8
launch(args);
9
}
10
11
publicvoidstart(StagetheStage)
12
{
13
theStage.setTitle("Hello, World!");
14
theStage.show();
15
}
16
}
Strukturování obsahu
Obsah v JavaFX (např. text, obrázky a UI prvky) je uspořádán pomocí stromu jako datové struktury známé jako grafu scény, která seskupí a uspořádá prvky grafické scény.
Znázornění grafu JavaFX scény.
Obecným prvkem graf scény v JavaFX se nazývá uzel. Každý uzel ve stromu má jeden "nadřazený" uzel, s výjimkou speciální uzel, označené jako "root". Skupina je uzel, který může mít mnoho prvky uzlu "dítě". Grafické transformace (překlady, rotace a měřítko) a efekty, které aplikujete na skupinu platí také pro jeho děti. Uzly může být navržen pomocí JavaFX kaskádových stylů (CSS), podobně jako CSS pro formátování dokumentů HTML.
Třída Scene obsahuje veškerý obsah pro graf scény a vyžaduje kořenový uzel nastavit (v praxi to je často skupina). Můžete nastavit velikost scény konkrétně; jinak velikost scény bude automaticky vypočtou na základě jeho obsahu. Scénu objekt musí být předán do fáze (metodou setScene()) Chcete-li zobrazit.
Vykreslování grafiky
Vykreslování grafiky je obzvlášť důležité programátorům her! V JavaFX plátno objekt je obrázek na kterém získáme text, tvary a obrázky, pomocí jeho přidruženého objektu GraphicsContext. (Pro ty vývojáři, kteří znají Java Swing toolkit, to je obdobou Graphics objektu předaný metodě paint() třídy JFrame.)
Objekt GraphicsContext obsahuje spoustu vlastních úprav schopnosti. Chcete-li vybrat barvy pro kreslení text a tvary, můžete nastavit výplň (interiér) a tah (hranice) barvy, které jsou objekty, malování: to může být jediný plnou barvou, přechodovou definované uživatelem (LinearGradient nebo RadialGradient) nebo dokonce ImagePattern. Můžete také použít jeden nebo více účinek styl objektů, například osvětlení, stín nebo GaussianBlur a změnit výchozí písma pomocí třídy písmo.
Image třída usnadňuje načítat obrázky z různých formátů souborů a jejich kreslení pomocí třídy GraphicsContext. Je to snadné konstrukci procedurálně generované obrazy pomocí třídy WritableImage spolu s PixelReader a PixelWriter třídy.
Pomocí těchto tříd, můžeme napsat mnohem více hoden "Hello, World"-styl příklad následovně. Pro stručnost, uvedeme jen metodu start() (budeme přeskočit příkazy pro import a main() metody); Nicméně kompletní funkční zdrojový kód naleznete v GitHub repo, který doprovází tento návod.
1
publicvoidstart(StagetheStage)
2
{
3
theStage.setTitle("Canvas Example");
4
5
Grouproot=newGroup();
6
ScenetheScene=newScene(root);
7
theStage.setScene(theScene);
8
9
Canvascanvas=newCanvas(400,200);
10
root.getChildren().add(canvas);
11
12
GraphicsContextgc=canvas.getGraphicsContext2D();
13
14
gc.setFill(Color.RED);
15
gc.setStroke(Color.BLACK);
16
gc.setLineWidth(2);
17
FonttheFont=Font.font("Times New Roman",FontWeight.BOLD,48);
18
gc.setFont(theFont);
19
gc.fillText("Hello, World!",60,50);
20
gc.strokeText("Hello, World!",60,50);
21
22
Imageearth=newImage("earth.png");
23
gc.drawImage(earth,180,100);
24
25
theStage.show();
26
}
Herní smyčky
Dále potřebujeme, aby naše programy dynamické, což znamená, že v průběhu času mění stav hry. Jsme budete implementovat herní smyčky: nekonečnou smyčku, která aktualizuje herní objekty a vykresluje scénu na obrazovku, v ideálním případě ve výši 60 krát za sekundu.
Nejjednodušší způsob, jak dosáhnout tohoto v JavaFX používá AnimationTimer třídy, kde metoda (pojmenované handle()) může zapisovat, který bude volat ve výši 60 krát za sekundu, nebo jako blízko k této sazbě jako je možné. (Tato třída nemusí být použity výhradně pro účely animací, dokáže mnohem víc.)
Pomocí třídy AnimationTimer je trochu složitější: protože to je abstraktní třída, nelze vytvořit přímo – třída musí být prodloužena dříve, než mohou být vytvořena instance. Však naše jednoduché příklady, jsme se rozšířit třídu napsáním anonymní vnitřní třídy. Tato vnitřní třída musí definovat abstraktní metodu handle(), který bude předán jeden argument: aktuální systémový čas v nanosekundách. Po definování vnitřní třída, jsme okamžitě vyvolat metodu start(), která začíná smyčku. (Smyčky může být zastavena voláním metody stop().)
Pomocí těchto tříd můžeme upravit náš příklad "Hello, World" vytváření animace sestávající z zemi obíhající kolem slunce proti hvězdné pozadí obrazu.
Existují alternativní způsoby, jak implementovat herní smyčky v JavaFX. Trochu delší (ale pružnější) přístup zahrnuje třída časové osy, která je animační sekvence sestávající z řady objektů, klíčový snímek. Chcete-li vytvořit herní smyčky, je třeba nastavit časové osy na opakovalo, a jen jediný klíčový snímek je požadováno, s jeho trvání nastavena na 0.016 sekund (k dosažení 60 cyklů za sekundu). Tato implementace lze nalézt v souboru Example3T.java v GitHub repo.
Založené na rámečku animace
Další běžně potřebné herní programování komponenta je založené na rámečku animace: zobrazení pořadí snímků v rychlém sledu k vytvoření iluze pohybu.
Za předpokladu, že všechny animace opakovat a všechny snímky zobrazovat stejný počet sekund, základní provedení by mohlo být stejně jednoduché následovně:
Chcete-li integrovat tuto třídu do předchozího příkladu, bychom mohli vytvořit animovaný UFO, inicializaci objektu pomocí kódu:
1
AnimatedImageufo=newAnimatedImage();
2
Image[]imageArray=newImage[6];
3
for(inti=0;i<6;i++)
4
imageArray[i]=newImage("ufo_"+i+".png");
5
ufo.frames=imageArray;
6
ufo.duration=0.100;
... a v rámci AnimationTimer, přidáním jednoho řádku kódu:
1
gc.drawImage(ufo.getFrame(t),450,25);
.. .at příhodné místo. Kompletní příklad pracovní kódu naleznete v souboru Example3AI.java v GitHub repo.
Zpracování vstupu uživatele
Zjišťování a zpracování vstupu uživatele v JavaFX je jednoduché. Uživatelské akce, které mohou být detekovány v systému, například stisknutí kláves a klepnutí myší, se nazývají události. V JavaFX tyto akce automaticky způsobit generování objektů (například KeyEvent a MouseEvent), které ukládají přidružená data (například skutečný klíč stisknutí nebo umístění ukazatele myši). JavaFX třídy, která implementuje EventTarget třídy, například scénu, může "poslouchat" události a zpracování v následujících příkladech vám ukážeme, jak nastavit scénu zpracovat různé události.
Pohlédl přes dokumentaci pro třídu scénu, existuje mnoho metod, které naslouchání pro zpracování různých typů vstupů z různých zdrojů. Například metodu setOnKeyPressed() můžete přiřadit EventHandler, která se aktivuje při stisknutí klávesy, setOnMouseClicked() Metoda přiřadit EventHandler, který se aktivuje, když je stisknuto tlačítko myši, a tak dále. EventHandler třída slouží jednomu účelu: k zapouzdření metoda (tzv. handle()), který se nazývá při výskytu příslušné události.
Při vytváření EventHandler, je nutné zadat typ události, která zpracovává: můžete deklarovat EventHandler<KeyEvent> nebo EventHandler<MouseEvent>, například.</MouseEvent> </KeyEvent> Také obslužné rutiny jsou často vytvořeny jako anonymní vnitřní třídy, jako jsou obvykle použity pouze jednou (když jsou předávány jako argument do jedné z výše uvedených způsobů).
Zpracování události klávesnice
Vstup uživatele je často zpracovány do hlavní herní smyčky, a tedy musí být vedeny záznamy, které klávesy jsou momentálně aktivní. Jedním ze způsobů jak toho dosáhnout je tím, že vytvoří ArrayList String objektů. Když zpočátku stisknutí klávesy, přidáme řetězcovou reprezentaci KeyEvent KeyCode do seznamu; Když klíč je propuštěn, odstraníme ji ze seznamu.
V následujícím příkladu plátna obsahuje dva obrazy klávesy se šipkami; při každém stisknutí klávesy odpovídající obraz se zabarví zeleně.
Zdrojový kód je obsažen v souboru Example4K.java v GitHub repo.
1
publicvoidstart(StagetheStage)
2
{
3
theStage.setTitle("Keyboard Example");
4
5
Grouproot=newGroup();
6
ScenetheScene=newScene(root);
7
theStage.setScene(theScene);
8
9
Canvascanvas=newCanvas(512-64,256);
10
root.getChildren().add(canvas);
11
12
ArrayList<String>input=newArrayList<String>();
13
14
theScene.setOnKeyPressed(
15
newEventHandler<KeyEvent>()
16
{
17
publicvoidhandle(KeyEvente)
18
{
19
Stringcode=e.getCode().toString();
20
21
// only add once... prevent duplicates
22
if(!input.contains(code))
23
input.add(code);
24
}
25
});
26
27
theScene.setOnKeyReleased(
28
newEventHandler<KeyEvent>()
29
{
30
publicvoidhandle(KeyEvente)
31
{
32
Stringcode=e.getCode().toString();
33
input.remove(code);
34
}
35
});
36
37
GraphicsContextgc=canvas.getGraphicsContext2D();
38
39
Imageleft=newImage("left.png");
40
ImageleftG=newImage("leftG.png");
41
42
Imageright=newImage("right.png");
43
ImagerightG=newImage("rightG.png");
44
45
newAnimationTimer()
46
{
47
publicvoidhandle(longcurrentNanoTime)
48
{
49
// Clear the canvas
50
gc.clearRect(0,0,512,512);
51
52
if(input.contains("LEFT"))
53
gc.drawImage(leftG,64,64);
54
else
55
gc.drawImage(left,64,64);
56
57
if(input.contains("RIGHT"))
58
gc.drawImage(rightG,256,64);
59
else
60
gc.drawImage(right,256,64);
61
}
62
}.start();
63
64
theStage.show();
65
}
Zpracování událostí myši
Nyní Podívejme se na příklad, který se zaměřuje na třídy MouseEvent spíše než KeyEvent třídy. V této minihře hráč nasbírá bod při každém klepnutí na cíl.
Vzhledem k tomu, obslužné rutiny jsou vnitřní třídy, musí být proměnné, které používají finále nebo "efektivně finální", což znamená, že proměnné nemůže být reinicializována. V předchozím příkladu byla data předána EventHandler prostřednictvím ArrayList, jejichž hodnoty mohou být změněny bez reinitializing (prostřednictvím metody add() a remove()).
Nicméně v případě základní datové typy, hodnoty nelze změnit jednou inicializována. Pokud chcete EventHandler pro přístup k základní datové typy, které jsou změněny jinde v programu, můžete vytvořit souhrnný třídu, která obsahuje veřejné proměnné nebo vlastnosti getter/setter metody. (V následujícím příkladu IntValue je třída, která obsahuje veřejné int proměnnou s názvem hodnotu.)
Úplný zdrojový kód je obsažen v GitHub repo; Hlavní třída je Example4M.java.
Vytvoření třídy základní Sprite s JavaFX
Ve videohrách sprite je termín pro jeden vizuální celek. Níže je příklad třídy Sprite, který ukládá obraz a postavení, stejně jako rychlost informace (pro mobilní entity) a šířky/výšky informace při výpočtu ohraničovací rámečky pro účely detekce kolizí. Máme také standardní vlastnosti getter/setter metody pro většinu těchto dat (vynechán pro stručnost) a některých standardních metod potřebných ve vývoji her:
Update(): vypočítá novou pozici na základě Sprite je rychlost.
Render(): kreslí přidružit obraz na plátno (přes třídu GraphicsContext) pomocí umístění jako souřadnice.
getBoundary(): vrátí JavaFX Rectangle2D objekt, který je užitečný při detekci kolizí vzhledem k jeho protíná metoda.
intersects(): Určuje, zda ohraničovacího rámečku tohoto Sprite protíná s tím jiného pohyblivého symbolu.
Úplný zdrojový kód je součástí Sprite.java v GitHub repo.
Pomocí třídy Sprite
S pomocí třídy Sprite, můžeme snadno vytvořit jednoduchý sběr hra v JavaFX. V této hře můžete převzít roli vnímající aktovky, jehož cílem je shromáždit mnoho pytle s penězi, které byly ponechány ležící kolem neopatrný předchozí majitel. Kláves se šipkami přesuňte hráč po obrazovce.
Tento kód výrazně čerpá z předchozích příkladů: nastavení písma zobrazit skóre, tvorbě tříd obálky pro jednoduché hodnoty, které musí být změněny během ukládání vstup z klávesnice s ArrayList a implementace herní smyčku AnimationTimer herní smyčky.
Jeden segment kódu zvláštního zájmu zahrnuje vytvoření objektu Sprite pro hráče (Aktovky) a ArrayList Sprite objektů pro sběratelství (pytle s penězi):
Další segment kódu zájmu je vytvoření AnimationTimer, který je pověřen:
Výpočet doby, která uplynula od poslední aktualizace
nastavení přehrávače rychlost v závislosti na aktuálně stisknutí kláves
detekci střetu mezi přehrávačem a sběratelství a aktualizace skóre a seznam sběratelství, pokud k tomu dojde (iterace se používá spíše než ArrayList přímo k vyhnout souběžné modifikaci výjimku při odstraňování objektů z seznam)
Jako obvykle kompletní kód naleznete v přiloženém kodexu souboru (Example5.java) v GitHub repo.
Další kroky
Zde je sbírka úvodní tutoriály na webu Oracle, který vám pomůže naučit se běžné úkoly JavaFX: Začínáme s JavaFX ukázkové aplikace.
Může být zájem o učení, jak používat Scene Builder, vizuální rozložení prostředí pro návrh uživatelského rozhraní. Tento program generuje FXML, což je jazyk založený na XML, který lze použít k definování uživatelského rozhraní programu JavaFX. Za to, viz JavaFX Scene Builder: Začínáme.
FX je vynikající blog, pravidelně aktualizován, která obsahuje informace a ukázkové projekty v zájmu JavaFX vývojáři. Mnozí z uvedeny ukázky jsou velmi inspirující!
José Pereda má vynikající příklady pokročilejší her s JavaFX v jeho úložiště GitHub.
Projekt JFxtras je tvořena skupina vývojářů, které vytvořily zvláštní JavaFX součásti, které poskytují běžně potřebné funkce, které jsou v současné době chybí od JavaFX.
JavaFXPorts projektu umožňuje balíček JavaFX aplikace pro nasazení na iOS a Android.
Oficiální odkazy by záložku pro JavaFX, zejména společnosti Oracle JavaFX guide a dokumentace API.
Některé dobře hodnocené knihy o JavaFX patří 8 Pro JavaFX, JavaFX 8 - Úvod příkladem a zvláštního zájmu pro vývojáře her, vývoj hry Java 8 začátek.
Závěr
V tomto kurzu já jsem představil JavaFX tříd, které jsou užitečné při programování her. Pracovali jsme přes řadu příkladů z rostoucí složitosti, vyvrcholilo sprite-based collection styl hry. Teď jsi připraven buď prozkoumáme některé z prostředků uvedených výše, nebo ponořit a začít vytvářet vlastní hru. Hodně štěstí ve vašem snažení!