Greenfoot
(→Řešení situací: Změna obrázku přesunuta do teorie.) |
(Vrácení změny obrázku aktéra jako samostatné kapitoly) |
||
Řádka 9: | Řádka 9: | ||
== Princip == | == Princip == | ||
* Vzhled hry popisuje třída, která musí být potomkem třídy <code>World</code>. Předpokládejme, že se bude jmenovat <code>HraWorld</code>, ale název si můžeme vymyslet. | * Vzhled hry popisuje třída, která musí být potomkem třídy <code>World</code>. Předpokládejme, že se bude jmenovat <code>HraWorld</code>, ale název si můžeme vymyslet. | ||
− | * Na hrací ploše jsou aktéři, | + | * Na hrací ploše jsou aktéři (''actor''). |
+ | * Chování aktérů je popsáno třídami, které jsou potomky třídy <code>Actor</code>. | ||
* Aktéři jsou vizuálně zastoupeni obrázkem, který vybíráme při vytvoření třídy aktéra. | * Aktéři jsou vizuálně zastoupeni obrázkem, který vybíráme při vytvoření třídy aktéra. | ||
; Průběh hry: | ; Průběh hry: | ||
Řádka 25: | Řádka 26: | ||
− | == Vytváření | + | == Vytváření aktérů == |
; Příprava instance actora | ; Příprava instance actora | ||
* Prvky ve hře (postavy atd.) jsou třídy, které jsou potomky třídy <code>Actor</code>. | * Prvky ve hře (postavy atd.) jsou třídy, které jsou potomky třídy <code>Actor</code>. | ||
Řádka 61: | Řádka 62: | ||
this.setLocation(cilX, cilY); | this.setLocation(cilX, cilY); | ||
} | } | ||
+ | |||
+ | |||
+ | == Změna obrázku aktéra == | ||
+ | Ke změně obrázku slouží metody: | ||
+ | Actor.setImage(GreenfootImage novyObrazek) | ||
+ | Actor.setImage(String cestaKNovemuObrazku) | ||
+ | |||
+ | Pokud zadáme cestu k obrázku, obrázek se hledá v podsložce <tt>images</tt> složky s projektem. | ||
+ | |||
+ | ; Příklad 1) Otočení vlevo či vpravo | ||
+ | class Panacek extends Actor | ||
+ | GreenfootImage imgVlevo = new GreenfootImage("imgVlevo.png"); | ||
+ | // ... | ||
+ | public void act() { | ||
+ | // ... | ||
+ | if (Greenfoot.isKeyDown("left")) { | ||
+ | this.setLocation(this.getX()-1, this.getY()); | ||
+ | this.setImage(imgVlevo); | ||
+ | } | ||
+ | // ... | ||
+ | } | ||
+ | } | ||
Řádka 106: | Řádka 129: | ||
** Vrací čísla z množiny {0, 1, ..., limit-1}. | ** Vrací čísla z množiny {0, 1, ..., limit-1}. | ||
− | |||
+ | == Zjištění kolize prvků ve hře == | ||
* Ke zjištění kolizí slouží metody ve třídě <tt>Actor</tt>, které se jmenují <code>get...Object...</code>. | * Ke zjištění kolizí slouží metody ve třídě <tt>Actor</tt>, které se jmenují <code>get...Object...</code>. | ||
* Metod je hodně, ale chovají se podobně. | * Metod je hodně, ale chovají se podobně. | ||
Řádka 133: | Řádka 156: | ||
* intersecting objects ... objekty, které se prolínají se stávajícím (došlo ke kolizi) | * intersecting objects ... objekty, které se prolínají se stávajícím (došlo ke kolizi) | ||
* objects at offset ... objekty, které jsou v dané vzdálenosti (dx, dy) od stávajícího objektu | * objects at offset ... objekty, které jsou v dané vzdálenosti (dx, dy) od stávajícího objektu | ||
+ | |||
== Řešení typických situací == | == Řešení typických situací == | ||
− | |||
=== Rušení aktérů === | === Rušení aktérů === | ||
; Příklad 1) Zrušení kolidujících actorů | ; Příklad 1) Zrušení kolidujících actorů | ||
Řádka 159: | Řádka 182: | ||
=== Výpis stavu hry, hlášky === | === Výpis stavu hry, hlášky === | ||
− | |||
Pro výpis skóre vytváříme nového speciálního „actora“ (objekt). Protože bude počitadlo pro celý projekt nejspíš jedno (nebo třeba jedno pro každého hráče), využijeme s výhodou [[Návrhové vzory#Jedináček|návrhový vzor Jedináček (Singleton)]]. | Pro výpis skóre vytváříme nového speciálního „actora“ (objekt). Protože bude počitadlo pro celý projekt nejspíš jedno (nebo třeba jedno pro každého hráče), využijeme s výhodou [[Návrhové vzory#Jedináček|návrhový vzor Jedináček (Singleton)]]. | ||
Řádka 209: | Řádka 231: | ||
Lze samozřejmě do počitadla přidat informaci o aktuálním počtu bodů a tu pak zvyšovat nebo snižovat dle potřeby. | Lze samozřejmě do počitadla přidat informaci o aktuálním počtu bodů a tu pak zvyšovat nebo snižovat dle potřeby. | ||
+ | |||
+ | === Zdi === | ||
+ | |||
== Úkol: Zkuste si vytvořit hru! == | == Úkol: Zkuste si vytvořit hru! == |
Verze z 20. 10. 2015, 07:15
Obsah |
Co je to Greenfoot?
Dokumentaci tříd najdete na adrese:
Princip
- Vzhled hry popisuje třída, která musí být potomkem třídy
World
. Předpokládejme, že se bude jmenovatHraWorld
, ale název si můžeme vymyslet. - Na hrací ploše jsou aktéři (actor).
- Chování aktérů je popsáno třídami, které jsou potomky třídy
Actor
. - Aktéři jsou vizuálně zastoupeni obrázkem, který vybíráme při vytvoření třídy aktéra.
- Průběh hry
- Vytvoří se instance třídy
HraWorld
(resp. jak jsme nazvali svého potomka třídyWorld
). - Spustí se konstruktor třídy
HraWorld
. - A dále se opakuje:
- Zavolá se metoda
act()
na svět (potomka třídyHraWorld
). - Zavolá se metoda
act()
pro všechny aktéry.
- Zavolá se metoda
Nastavení parametrů světa
- Nastavení pozadí hrací plochy
- Například v konstruktoru našeho potomka třídy World můžeme zavolat:
World.setBackground(GreenfootImage obrazek)
Vytváření aktérů
- Příprava instance actora
- Prvky ve hře (postavy atd.) jsou třídy, které jsou potomky třídy
Actor
. - Jejich instance vytváříme stejně jako vždy v Javě: operátorem
new
.
- Umístění instance na plochu
- Metoda
World.addObject(Actor actor, int x, int y)
. - Umístí actora na pozici (x, y)
- Odstranění actora z plochy
- Metoda
World.removeObject(Actor actor)
.
Nastavení pozice aktéra
Máme dvě varianty ovládání prvku (actora):
- Relativní pozicování
-
turn(int oKolik)
... otáčí o daný počet stupňů ve směru hodinových ručiček -
move(int delka)
... pokročí vpřed o daný počet dílků ve směru, do kterého je otočen -
setRotation(int uhel)
... natočí prvek do daného směru (0 je směr vpravo, po směru hodinových ručiček) -
turnTowards(int x, int y)
... natočí prvek směrem k zadaným souřadnicím.
- Absolutní pozicování
-
setLocation(int x, int y)
- přesune prvek na zadané souřadnice
- obvykle je třeba uložit si souřadnice.
- Příklad
- vytvoření metody
move(int dx, int dy)
public void act() { this.move(3,-1); } private void move(int dx, int dy) { int cilX = this.getX()+dx; int cilY = this.getY()+dy; this.turnTowards(cilX, cilY); this.setLocation(cilX, cilY); }
Změna obrázku aktéra
Ke změně obrázku slouží metody:
Actor.setImage(GreenfootImage novyObrazek) Actor.setImage(String cestaKNovemuObrazku)
Pokud zadáme cestu k obrázku, obrázek se hledá v podsložce images složky s projektem.
- Příklad 1) Otočení vlevo či vpravo
class Panacek extends Actor GreenfootImage imgVlevo = new GreenfootImage("imgVlevo.png"); // ... public void act() { // ... if (Greenfoot.isKeyDown("left")) { this.setLocation(this.getX()-1, this.getY()); this.setImage(imgVlevo); } // ... } }
Reakce na klávesy
Stisk klávesy (napsání písmenka)
String Greenfoot.getKey()
- Vrací
null
, když nebyla stisknuta žádná klávesa. - Odpovídá tomu, jak píše písmenka textový editor.
- Pokud uživatel drží stisknutou klávesu déle, pak:
- Pošle se jedno písmeno,
- nějakou dobu se počká a neposílá se nic,
- pak se začne opakovaně vysílat písmeno, dokud uživatel klávesu nepustí, nebo
- Speciální klávesy:
-
"space"
... mezerník -
"up"
,"down"
,"right"
,"left"
... šipky -
"F1"
,... funkční klávesy
-
- Příklad
- Pohyb podle kláves
String vstup = Greenfoot.getKey(); if (vstup != null) { if (vstup.equals("right")) { this.setRotation(0); } else if (vstup.equals("left")) { this.setRotation(180); } else if (vstup.equals("up")) { this.setRotation(-90); } else if (vstup.equals("down")) { this.setRotation(90); } this.move(1); }
Detekce, zda uživatel drží klávesu
boolean Greenfoot.isKeyDown(String klavesa)
- Pokud uživatel drží klávesu delší dobu, zůstane platná pořád.
- Takto lze detekovat stisk více kláves zároveň, nemusí to však být tak spolehlivé.
Náhodná čísla
- Standardní řešení Javy
-
Math.random()
... vrací čísla z intervalu <0, 1)
- Řešení Greenfootu
- Pro hry je často potřeba generovat celá čísla. Pro zjednodušení je tedy v Greenfootu metoda:
-
Greenfoot.getRandomNumber(int limit)
- Vrací čísla z množiny {0, 1, ..., limit-1}.
Zjištění kolize prvků ve hře
- Ke zjištění kolizí slouží metody ve třídě Actor, které se jmenují
get...Object...
. - Metod je hodně, ale chovají se podobně.
- Výběr třídy
- Pokud zadáte parametr typu class, bere v potaz pouze objekty zadaného typu. Pokud zadáme
null
, berou se v potaz všechny objekty. - Všechny objekty:
List<Actor> seznam = this.getIntersectingObjects(null);
- Jen objekty zvoleného typu:
List<Zradlo> seznam = this.getIntersectingObjects(Zradlo.class);
- Návratová hodnota
- Vrací buď první kolidující objekt nebo
null
když nekoliduje:
getOneIntersectingObject(class) getOneObjectAtOffset(int dx, int dy, class)
- ... nebo seznam všech vyhovujících objektů.
private void vyresKolidujici() { List<Actor> seznam = this.getIntersectingObjects(null); for (Actor prvek : seznam) { prvek.aplikuj(this); } }
- Filtr
- intersecting objects ... objekty, které se prolínají se stávajícím (došlo ke kolizi)
- objects at offset ... objekty, které jsou v dané vzdálenosti (dx, dy) od stávajícího objektu
Řešení typických situací
Rušení aktérů
- Příklad 1) Zrušení kolidujících actorů
private void act() { // ... World svet = this.getWorld(); List<Actor> seznam = this.getIntersectingObjects(null); for (Actor prvek : seznam) { prvek.aplikuj(this); svet.removeObject(prvek); }
- Příklad 2) Zrušení aktéra, který vyjel mimo obrazovku na levém okraji
public void act() { // ... if (this.getX() < 1) { World svet = this.getWorld(); if (svet != null) { this.getWorld().removeObject(this); } } }
Výpis stavu hry, hlášky
Pro výpis skóre vytváříme nového speciálního „actora“ (objekt). Protože bude počitadlo pro celý projekt nejspíš jedno (nebo třeba jedno pro každého hráče), využijeme s výhodou návrhový vzor Jedináček (Singleton).
public class Pocitadlo extends Actor { // Implementace Jedináčka: private static Pocitadlo prvniHrac = null; public static Pocitadlo getInstance() { if (this.prvniHrac == null) this.prvniHrac = new Pocitadlo(); } return this.prvniHrac; } // A zbytek kódu: private int stav; private Pocitadlo() { // private kvůli Jedináčkovi this.setStav(0); } public void setStav(int stav) { this.stav = stav; String text = "Skóre: "+this.stav; GreenfootImage obrazek = new GreenfootImage(text, 20, Color.yellow, Color.gray); this.setImage(obrazek); } public void zmenStav(int zmena) { this.setStav(this.stav+zmena); } }
Na plochu počítadlo přidáme:
public HraWorld() { ... this.addObject(Pocitadlo.getInstance(), 20, 20); ... }
Změnu skóre pak kdekoli v projektu můžeme vyvolat:
... Pocitadlo.getInstance().setStav(10); ...
nebo
... Pocitadlo.getInstance().zmenStav(-2); ...
Lze samozřejmě do počitadla přidat informaci o aktuálním počtu bodů a tu pak zvyšovat nebo snižovat dle potřeby.
Zdi
Úkol: Zkuste si vytvořit hru!
- Vytvořte hru, na které ukážete ty prvky práce v Greenfootu, které jsme si ukázali výše.
Přikládám pár nápadů pro inspiraci z projektů řešených na Obchodní akademii Uherské Hradiště - obor Informační technologie.
Další stránky
- Máte-li probém se spouštěním aplikací na webu Greenfoot.org, zkuste: Spouštění appletů.