Greenfoot
(Doplnění isKeyDown()) |
(Přidání ukázky: Game over! s textovým aktérem.) |
||
(Není zobrazeno 16 mezilehlých verzí od 1 uživatele.) | |||
Řádka 3: | Řádka 3: | ||
== Co je to Greenfoot? == | == Co je to Greenfoot? == | ||
− | |||
− | |||
+ | Greenfoot je framework pro tvorbu jednoduchých 2D her, postavený na programovacích jazycích Java a Stride (my zde využíváme jazyk Java). | ||
− | + | ; Princip funkce | |
* 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 19: | Řádka 19: | ||
− | |||
− | |||
− | |||
− | |||
− | + | == Vytváření aktérů == | |
− | == Vytváření | + | ; Příprava instance aktéra |
− | ; Příprava instance | + | |
* 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>. | ||
* Jejich instance vytváříme stejně jako vždy v Javě: operátorem <code>new</code>. | * Jejich instance vytváříme stejně jako vždy v Javě: operátorem <code>new</code>. | ||
− | ;Umístění instance na plochu: | + | ;Umístění instance aktéra na plochu: |
* Metoda <code>World.addObject(Actor actor, int x, int y)</code>. | * Metoda <code>World.addObject(Actor actor, int x, int y)</code>. | ||
− | * Umístí | + | * Umístí aktéra na pozici (x, y) |
− | ; Odstranění | + | ; Odstranění aktéra z plochy |
* Metoda <code>World.removeObject(Actor actor)</code>. | * Metoda <code>World.removeObject(Actor actor)</code>. | ||
+ | |||
+ | <div class="Priklad"> | ||
+ | Příklad — Vytvoření aktéra třídy <code>Panacek</code> a umístění na souřadnice (200, 150). | ||
+ | public class MojeHra extends World { | ||
+ | ... | ||
+ | public void MojeHra() { | ||
+ | ... | ||
+ | Panacek panacek = new Panacek(); | ||
+ | this.addObject(panacek, 200, 150); | ||
+ | ... | ||
+ | } | ||
+ | </div> | ||
+ | |||
Řádka 61: | Řádka 69: | ||
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); | ||
+ | } | ||
+ | // ... | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | === Aktér s textovým popisem === | ||
+ | Pokud chceme místo obrázku aktéra zobrazit text, využijeme alternativní konstruktor třídy <code>GreenfootImage</code>: | ||
+ | GreenfootImage imgVlevo = new GreenfootImage("Vlevo!", 50, Color.RED, Color.YELLOW); | ||
+ | Zbytek kódu zůstává stejný. Jen potřebujeme navíc do hlavičky (úplně na začátek kódu třídy aktéra) doplnit k importu tříd knihovny <code>Greenfoot</code> i import třídy <code>java.awt.Color</code>: | ||
+ | import Greenfoot.*; | ||
+ | '''import java.awt.Color;''' | ||
+ | ... | ||
+ | |||
+ | <div class="Priklad"> | ||
+ | ; Příklad — „Game over!“ | ||
+ | * Připravme si hlášení „Game over!“, které zobrazíme na konci hry. | ||
+ | |||
+ | Třída GameOver: | ||
+ | |||
+ | import Greenfoot.*; | ||
+ | import java.awt.Color; | ||
+ | |||
+ | /** Třída GameOver bude reprezentovat aktéra, který bude fungovat jako | ||
+ | * textové hlášení. | ||
+ | */ | ||
+ | public class GameOver { | ||
+ | public GameOver() { | ||
+ | GreenfootImage imgGameOver = new GreenfootImage("Vlevo!", 50, Color.YELLOW, Color.BLUE); | ||
+ | this.setImage(imgGameOver); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | Ukončení hry: | ||
+ | |||
+ | import Greenfoot.*; | ||
+ | |||
+ | /** Třída Panáček - po srážce s kamenem ukončí hru. */ | ||
+ | public class Panacek { | ||
+ | public void act() { | ||
+ | if (this.isTouching(Kamen.class)) { | ||
+ | World svet = this.getWorld(); | ||
+ | ''// Přidej hlášení "Game over!"'' | ||
+ | svet.addObject('''new GameOver()''', svet.getWidth()/2, svet.getHeight/2); | ||
+ | ''// Ukonči hru:'' | ||
+ | '''Greenfoot.stop();''' | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Samozřejmě panáček toho může dělat víc a třídy se můžou jmenovat jinak. | ||
+ | </div> | ||
+ | |||
Řádka 97: | Řádka 178: | ||
* Takto lze detekovat stisk více kláves zároveň, nemusí to však být tak spolehlivé. | * Takto lze detekovat stisk více kláves zároveň, nemusí to však být tak spolehlivé. | ||
+ | === Funkční klávesy === | ||
+ | * Tímto způsobem můžeme detekovat i stisk funkčních kláves ''Control'' a ''Shift''. | ||
+ | * Kódy pro tyto klávesy jsou <code>"control"</code> a <code>"shift"</code>. | ||
+ | * Pokud tedy chceme detekovat kombinaci <code><Ctrl>+<Shift>+<S></code>, pak píšeme: | ||
+ | String pismeno = Greenfoot.getKey(); | ||
+ | if (Greenfoot.isKeyDown("control") && Greenfoot.isKeyDown("shift") && "s".equals(pismeno)) { | ||
+ | ''... co se má stát ... '' | ||
+ | } | ||
− | == Náhodná čísla == | + | === Jak detekovat pouze písmena a čísla? === |
+ | * Občas bychom chtěli reagovat pouze na alfanumerické znaky (písmena a čísla). | ||
+ | * K tomu můžete použít jednoduchý trik — většina funkčních kláves má totiž kódy z více písmen. Můžeme tedy využít toho, že když je funkční kód klávesy jen jedno písmeno, považujeme ho za alfanumerický znak: | ||
+ | String pismeno = Greenfoot.getKey(); | ||
+ | if (pismeno.lenght() == 1) { | ||
+ | ''... co se má stát ... '' | ||
+ | } | ||
+ | |||
+ | == Zjištění pozice myši == | ||
+ | <code>MouseInfo Greenfoot.getMouseInfo()</code> | ||
+ | * Vrací instanci třídy <code>MouseInfo</code>. | ||
+ | * <code>MouseInfo</code> nese informace o: | ||
+ | ** Pozici X a Y kurzoru: <code>int MouseInfo.getX()</code>, <code>int MouseInfo.getY()</code> | ||
+ | ** Stisku tlačítek,... | ||
+ | |||
+ | ; Příklad: Pohyb aktéra za myší | ||
+ | public void act() { | ||
+ | MouseInfo mi = Greenfoot.getMouseInfo(); | ||
+ | int x = mi.getX(); | ||
+ | int y = mi.getY(); | ||
+ | int vzdalenost = (int) Math.sqrt(Math.pow(x-this.getX(),2)+Math.pow(y-this.getY(),2)); | ||
+ | |||
+ | if (vzdalenost > 0) { | ||
+ | this.turnTowards(x, y); | ||
+ | this.move(Math.min(vzdalenost, 5)); | ||
+ | this.setRotation(0); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | == Další tipy == | ||
+ | |||
+ | === Náhodná čísla === | ||
; Standardní řešení Javy: | ; Standardní řešení Javy: | ||
* <code>Math.random()</code> ... vrací čísla z intervalu <0, 1) | * <code>Math.random()</code> ... vrací čísla z intervalu <0, 1) | ||
Řádka 106: | Řádka 228: | ||
** Vrací čísla z množiny {0, 1, ..., limit-1}. | ** Vrací čísla z množiny {0, 1, ..., limit-1}. | ||
− | == | + | === Okraj obrazovky === |
+ | * Pro detekci, zda je aktér na okraji obrazovky, můžeme použít metodu <code>isAtEdge()</code>. | ||
+ | if (this.isAtEdge()) { | ||
+ | this.turn(180); | ||
+ | } | ||
− | * | + | === Objekty mimo obrazovku === |
− | + | * Pokud v konstruktoru světa (třída <code>World</code>) použijete volitelný parametr, můžete povolit umístění objektů mimo obrazovku. | |
+ | public class MyWorld extends World | ||
+ | { | ||
+ | public MyWorld() | ||
+ | { | ||
+ | super(600, 400, 1, '''false'''); | ||
+ | } | ||
+ | } | ||
− | ; Výběr třídy | + | == Zjištění kolize aktérů ve hře == |
− | * Pokud zadáte parametr typu <tt>class</tt>, bere v potaz pouze objekty zadaného typu. Pokud zadáme <code>null</code>, berou se v potaz všechny objekty. | + | * Ke zjištění kolizí slouží metody ve třídě <tt>Actor</tt>, které se jmenují <code>get''XXX''Object''YYY''</code>. |
− | + | * Metod je hodně, ale chovají se podobně: | |
+ | '''get'''OneIntersecting'''Object'''(class) | ||
+ | * Vrátí jeden kolidující objekt. | ||
+ | * Řeší kolizi jen objektů té třídy, kterou zadáme jako parametr. | ||
+ | * Pokud chceme, aby řešil kolize s objekty libovolné třídy, zadáme jako parametr <code>null</code>. | ||
+ | '''get'''Intersecting'''Object'''s(class) | ||
+ | * Vrátí seznam všech objektů, kolidujících s aktérem. | ||
+ | '''get'''One'''Object'''AtOffset(int dx, int dy, class) | ||
+ | * Vrátí jednoho aktéra z aktérů vzdálených nejvýše (dx, dy)(viz dále). | ||
+ | ... | ||
+ | |||
+ | ; Výběr třídy objektů | ||
+ | * Pokud zadáte parametr typu <tt>class</tt>, bere v potaz pouze objekty zadaného typu. Pokud zadáme <code>null</code>, berou se v potaz všechny objekty. | ||
+ | |||
+ | Příklad: | ||
List<Actor> seznam = this.getIntersectingObjects(null); | List<Actor> seznam = this.getIntersectingObjects(null); | ||
− | * | + | * Bere v potaz všechny typy aktérů. Může se jednat o aktéry různých typů (instance různých tříd). |
− | List< | + | List<Jablko> seznam = this.getIntersectingObjects(Jablko.class); |
+ | * Detekuje pouze kolidující aktéry třídy <code>Jablko</code>, všechny ostatní objekty ignoruje! | ||
; Návratová hodnota | ; Návratová hodnota | ||
− | * | + | Tyto metody vrací buď: |
− | + | * první kolidující objekt daného typu nebo <code>null</code> když nekoliduje žádný objekt daného typu: | |
− | + | ||
− | + | ||
private void vyresKolidujici() { | private void vyresKolidujici() { | ||
− | + | Predmet predmet = (Predmet) this.getOneIntersectingObject(Predmet.class); | |
− | + | if (predmet != null) { | |
− | + | ''... Co se má dít, třeba: ...'' | |
+ | this.getWorld().removeObject(predmet); | ||
} | } | ||
} | } | ||
− | + | * nebo seznam (může být prázdný) všech kolidujících objektů daného typu: | |
− | + | private void vyresKolidujici() { | |
− | * | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | private void | + | |
− | + | ||
List<Actor> seznam = this.getIntersectingObjects(null); | List<Actor> seznam = this.getIntersectingObjects(null); | ||
for (Actor prvek : seznam) { | for (Actor prvek : seznam) { | ||
prvek.aplikuj(this); | prvek.aplikuj(this); | ||
− | |||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | = | + | <div class="Poznamka"> |
+ | Pokud vrací metoda seznam kolidujících objektů, pak musíme importovat třídu <code>java.util.List</code> tím, že napíšeme úplně na začátek: | ||
− | + | import java.util.List; | |
− | + | </div> | |
− | + | ||
− | + | ; 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 | ||
− | + | == Práce s prostředím hry (World) == | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | === | + | === Nastavení pozadí hrací plochy === |
+ | * Obrázek na pozadí prostředí/světa změníme metodou: | ||
+ | World.setBackground(GreenfootImage obrazek) | ||
+ | * Tuto metodu můžeme zavolat například v konstruktoru našeho potomka třídy <code>World</code>. | ||
− | + | === Přepínání prostředí/světů v Greenfootu === | |
− | + | * Pokud potřebujete přepnout hru do jiného prostředí (světa), máte k dispozici metodu: | |
− | public class | + | Greenfoot.setWorld(World ''novySvet'') |
+ | <div class="Priklad"> | ||
+ | Příklad: | ||
+ | 1. krok: Upravte třídu MyWorld: | ||
+ | public class MyWorld extends World | ||
{ | { | ||
− | + | int citac = 0; | |
− | + | int konec = 300; | |
− | + | public MyWorld() | |
− | + | { | |
− | + | super(600, 400, 1); | |
− | + | } | |
− | + | public void act() { | |
− | + | System.out.println("Zbývá: "+(this.konec-this.citac)); | |
− | + | this.citac++; | |
− | + | if (this.citac > this.konec) | |
− | + | { | |
− | + | Greenfoot.setWorld(new DruhySvet()); | |
− | + | } | |
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
} | } | ||
− | + | 2. krok: Vytvořte druhou instanci třídy World, které nastavte jako pozadí některý obrázek ze záložky Backgrounds: | |
− | + | public class DruhySvet extends World | |
− | + | { | |
− | public | + | public MyWorld() |
− | + | { | |
− | + | super(600, 400, 1); | |
− | + | } | |
} | } | ||
+ | Po spuštění hry by hra měla chvíli čekat a pak by se mělo změnit pozadí — dojde ke změně prostředí hry (world). | ||
+ | </div> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
Řádka 243: | Řádka 345: | ||
− | == | + | == Související stránky == |
+ | * [[Greenfoot: Řešení častých úloh]] | ||
* Máte-li probém se spouštěním aplikací na webu Greenfoot.org, zkuste: [[Spouštění appletů]]. | * Máte-li probém se spouštěním aplikací na webu Greenfoot.org, zkuste: [[Spouštění appletů]]. | ||
+ | |||
+ | |||
+ | |||
+ | == Zdroje == | ||
+ | * Existují velmi rozsáhlá fóra (v angličtině), popisující řešení problémů v Greenfootu. Zkuste ve vyhledávači najít: <code>greenfoot ''téma-které-hledáte''</code>. | ||
+ | * Dokumentaci tříd najdete na adrese [http://www.greenfoot.org/files/javadoc/ Greenfoot.org → Javadoc] |
Aktuální verze z 18. 5. 2020, 09:08
Obsah |
Co je to Greenfoot?
Greenfoot je framework pro tvorbu jednoduchých 2D her, postavený na programovacích jazycích Java a Stride (my zde využíváme jazyk Java).
- Princip funkce
- 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
Vytváření aktérů
- Příprava instance aktéra
- 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 aktéra na plochu
- Metoda
World.addObject(Actor actor, int x, int y)
. - Umístí aktéra na pozici (x, y)
- Odstranění aktéra z plochy
- Metoda
World.removeObject(Actor actor)
.
Příklad — Vytvoření aktéra třídy Panacek
a umístění na souřadnice (200, 150).
public class MojeHra extends World { ... public void MojeHra() { ... Panacek panacek = new Panacek(); this.addObject(panacek, 200, 150); ... }
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); } // ... } }
Aktér s textovým popisem
Pokud chceme místo obrázku aktéra zobrazit text, využijeme alternativní konstruktor třídy GreenfootImage
:
GreenfootImage imgVlevo = new GreenfootImage("Vlevo!", 50, Color.RED, Color.YELLOW);
Zbytek kódu zůstává stejný. Jen potřebujeme navíc do hlavičky (úplně na začátek kódu třídy aktéra) doplnit k importu tříd knihovny Greenfoot
i import třídy java.awt.Color
:
import Greenfoot.*; import java.awt.Color; ...
- Příklad — „Game over!“
- Připravme si hlášení „Game over!“, které zobrazíme na konci hry.
Třída GameOver:
import Greenfoot.*; import java.awt.Color; /** Třída GameOver bude reprezentovat aktéra, který bude fungovat jako * textové hlášení. */ public class GameOver { public GameOver() { GreenfootImage imgGameOver = new GreenfootImage("Vlevo!", 50, Color.YELLOW, Color.BLUE); this.setImage(imgGameOver); } }
Ukončení hry:
import Greenfoot.*; /** Třída Panáček - po srážce s kamenem ukončí hru. */ public class Panacek { public void act() { if (this.isTouching(Kamen.class)) { World svet = this.getWorld(); // Přidej hlášení "Game over!" svet.addObject(new GameOver(), svet.getWidth()/2, svet.getHeight/2); // Ukonči hru: Greenfoot.stop(); } } }
Samozřejmě panáček toho může dělat víc a třídy se můžou jmenovat jinak.
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é.
Funkční klávesy
- Tímto způsobem můžeme detekovat i stisk funkčních kláves Control a Shift.
- Kódy pro tyto klávesy jsou
"control"
a"shift"
. - Pokud tedy chceme detekovat kombinaci
<Ctrl>+<Shift>+<S>
, pak píšeme:
String pismeno = Greenfoot.getKey(); if (Greenfoot.isKeyDown("control") && Greenfoot.isKeyDown("shift") && "s".equals(pismeno)) { ... co se má stát ... }
Jak detekovat pouze písmena a čísla?
- Občas bychom chtěli reagovat pouze na alfanumerické znaky (písmena a čísla).
- K tomu můžete použít jednoduchý trik — většina funkčních kláves má totiž kódy z více písmen. Můžeme tedy využít toho, že když je funkční kód klávesy jen jedno písmeno, považujeme ho za alfanumerický znak:
String pismeno = Greenfoot.getKey(); if (pismeno.lenght() == 1) { ... co se má stát ... }
Zjištění pozice myši
MouseInfo Greenfoot.getMouseInfo()
- Vrací instanci třídy
MouseInfo
. -
MouseInfo
nese informace o:- Pozici X a Y kurzoru:
int MouseInfo.getX()
,int MouseInfo.getY()
- Stisku tlačítek,...
- Pozici X a Y kurzoru:
- Příklad
- Pohyb aktéra za myší
public void act() { MouseInfo mi = Greenfoot.getMouseInfo(); int x = mi.getX(); int y = mi.getY(); int vzdalenost = (int) Math.sqrt(Math.pow(x-this.getX(),2)+Math.pow(y-this.getY(),2)); if (vzdalenost > 0) { this.turnTowards(x, y); this.move(Math.min(vzdalenost, 5)); this.setRotation(0); } }
Další tipy
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}.
Okraj obrazovky
- Pro detekci, zda je aktér na okraji obrazovky, můžeme použít metodu
isAtEdge()
.
if (this.isAtEdge()) { this.turn(180); }
Objekty mimo obrazovku
- Pokud v konstruktoru světa (třída
World
) použijete volitelný parametr, můžete povolit umístění objektů mimo obrazovku.
public class MyWorld extends World { public MyWorld() { super(600, 400, 1, false); } }
Zjištění kolize aktérů ve hře
- Ke zjištění kolizí slouží metody ve třídě Actor, které se jmenují
getXXXObjectYYY
. - Metod je hodně, ale chovají se podobně:
getOneIntersectingObject(class)
- Vrátí jeden kolidující objekt.
- Řeší kolizi jen objektů té třídy, kterou zadáme jako parametr.
- Pokud chceme, aby řešil kolize s objekty libovolné třídy, zadáme jako parametr
null
.
getIntersectingObjects(class)
- Vrátí seznam všech objektů, kolidujících s aktérem.
getOneObjectAtOffset(int dx, int dy, class)
- Vrátí jednoho aktéra z aktérů vzdálených nejvýše (dx, dy)(viz dále).
...
- Výběr třídy objektů
- 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.
Příklad:
List<Actor> seznam = this.getIntersectingObjects(null);
- Bere v potaz všechny typy aktérů. Může se jednat o aktéry různých typů (instance různých tříd).
List<Jablko> seznam = this.getIntersectingObjects(Jablko.class);
- Detekuje pouze kolidující aktéry třídy
Jablko
, všechny ostatní objekty ignoruje!
- Návratová hodnota
Tyto metody vrací buď:
- první kolidující objekt daného typu nebo
null
když nekoliduje žádný objekt daného typu:
private void vyresKolidujici() { Predmet predmet = (Predmet) this.getOneIntersectingObject(Predmet.class); if (predmet != null) { ... Co se má dít, třeba: ... this.getWorld().removeObject(predmet); } }
- nebo seznam (může být prázdný) všech kolidujících objektů daného typu:
private void vyresKolidujici() { List<Actor> seznam = this.getIntersectingObjects(null); for (Actor prvek : seznam) { prvek.aplikuj(this); } }
Pokud vrací metoda seznam kolidujících objektů, pak musíme importovat třídu java.util.List
tím, že napíšeme úplně na začátek:
import java.util.List;
- 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
Práce s prostředím hry (World)
Nastavení pozadí hrací plochy
- Obrázek na pozadí prostředí/světa změníme metodou:
World.setBackground(GreenfootImage obrazek)
- Tuto metodu můžeme zavolat například v konstruktoru našeho potomka třídy
World
.
Přepínání prostředí/světů v Greenfootu
- Pokud potřebujete přepnout hru do jiného prostředí (světa), máte k dispozici metodu:
Greenfoot.setWorld(World novySvet)
Příklad: 1. krok: Upravte třídu MyWorld:
public class MyWorld extends World { int citac = 0; int konec = 300; public MyWorld() { super(600, 400, 1); } public void act() { System.out.println("Zbývá: "+(this.konec-this.citac)); this.citac++; if (this.citac > this.konec) { Greenfoot.setWorld(new DruhySvet()); } } }
2. krok: Vytvořte druhou instanci třídy World, které nastavte jako pozadí některý obrázek ze záložky Backgrounds:
public class DruhySvet extends World { public MyWorld() { super(600, 400, 1); } }
Po spuštění hry by hra měla chvíli čekat a pak by se mělo změnit pozadí — dojde ke změně prostředí hry (world).
Ú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.
Související stránky
- Greenfoot: Řešení častých úloh
- Máte-li probém se spouštěním aplikací na webu Greenfoot.org, zkuste: Spouštění appletů.
Zdroje
- Existují velmi rozsáhlá fóra (v angličtině), popisující řešení problémů v Greenfootu. Zkuste ve vyhledávači najít:
greenfoot téma-které-hledáte
. - Dokumentaci tříd najdete na adrese Greenfoot.org → Javadoc