Greenfoot: Řešení častých úloh
(Přidán kód pro omezení pohybu zdí.) |
(→Rušení aktérů: Varování - po vyjmutí aktéra ze světa nelze volat getX) |
||
| Řádka 18: | Řádka 18: | ||
World svet = this.getWorld(); | World svet = this.getWorld(); | ||
if (svet != null) { | if (svet != null) { | ||
| − | + | getWorld().removeObject(this); | |
} | } | ||
} | } | ||
} | } | ||
| + | <div class="Varovani"> | ||
| + | Pokud vyjmete aktéra ze světa, nelze už volat metody, které jsou závislé na poloze aktéra ve světě. Volání metod <code>getX()</code>, <code>getY()</code>, <code>getWorld()</code>, <code>isAtEdge()</code> a dalších už nyní způsobí chybu! | ||
| + | |||
| + | Doporučujeme proto volat <code>removeObject(...)</code> jako poslední příkaz metody <code>act()</code>. | ||
| + | </div> | ||
== Aktér se objeví a zmizí == | == Aktér se objeví a zmizí == | ||
Verze z 17. 7. 2024, 07:30
Obsah |
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) {
getWorld().removeObject(this);
}
}
}
Pokud vyjmete aktéra ze světa, nelze už volat metody, které jsou závislé na poloze aktéra ve světě. Volání metod getX(), getY(), getWorld(), isAtEdge() a dalších už nyní způsobí chybu!
Doporučujeme proto volat removeObject(...) jako poslední příkaz metody act().
Aktér se objeví a zmizí
Pokud chceme aktéra, který se objeví na nějakou dobu a pak zmizí, stačí si v atributu počítá, kolikrát byla zavolána metoda act():
int jakDlouhoZiji = 0;
public void act()
{
this.jakDlouhoZiji++;
if (this.jakDlouhoZiji >= 200) {
World svet = this.getWorld();
int x = Greenfoot.getRandomNumber(svet.getWidth());
int y = Greenfoot.getRandomNumber(svet.getHeight());
this.setLocation(x, y);
this.jakDlouhoZiji = 0;
}
}
Hlášení ve hře
Někdy potřebujeme hráče upozornit na nějakou událost ve hře vyskakovacím hlášením. V Greenfootu je to nejjednodušší tak, že vyrobíte aktéra, který bude mít místo obrázku text. Tohoto aktéra potom přidáte do světa.
Třída aktéra:
public class Hlaseni
{
public Hlaseni()
{
GreenfootImage banner = new GreenfootImage("Text", 30, Color.YELLOW, Color.RED);
this.setImage(banner);
}
}
Umístění aktéra do světa:
... this.setPaintOrder(Hlaseni.class); // Zařídí, že se hlášení objeví nahoře nad všemi ostatními aktéry. this.getWorld().addObject(new Hlaseni(), 300, 200); ...
Počítadlo bodů, výpis stavu hry
- Podobně jako vyskakovací hlášení můžeme realizovat i zobrazení počítadla bodů. I tady vytváříme nového speciálního „actora“ (aktéra hry).
- 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 (Pocitadlo.prvniHrac == null) {
Pocitadlo.prvniHrac = new Pocitadlo();
}
return Pocitadlo.prvniHrac;
}
// A zbytek kódu:
private int stav;
private Pocitadlo() { // private kvůli Jedináčkovi
this.reset();
}
public int getStav() {
return this.stav;
}
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);
}
public void reset() {
this.setStav(0);
}
}
- Přidání počitadla na plochu
- Přidání počitadla na plochu provedeme v konstruktoru světa (třída
MyWorldči jiná podle toho, jak si ji pojmenujeme).
public MyWorld() {
...
this.addObject(Pocitadlo.getInstance(), 50, 30);
Pocitadlo.getInstance().reset(); // Vynulování počítadla
// Pokud se na stejném místě jako počítadlo objeví jiný objekt, bude vždy pod počitadlem:
this.setPaintOrder(Pocitadlo.class);
}
- Zjištění aktuálního skóre
- Ve kterékoli třídě pak můžeme vyvolat zjištění skóre:
... int skore = Pocitadlo.getInstance().getStav();
- Změnu skóre provedeme
... Pocitadlo.getInstance().setStav(10); // Nastaví nový stav na 10 bodů - bez ohledu na předchozí stav. ...
nebo
... Pocitadlo.getInstance().zmenStav(-2); // Sníží stav počítadla o 2 body oproti předchozímu stavu. ...
Zdi
Pokud chceme aktérovi zakázat pohyb skrz zdi, můžeme v každém kroku ověřit, jestli by se tímto krokem nedostal do zdi. Pohyb povolíme pouze v případě, kdy na cílových souřadnicích zeď není.
public class Panacek extends Actor
{
private int rychlost = 3;
private int okrajAkteraX = getImage().getWidth()/2;
private int okrajAkteraY = getImage().getHeight()/2;
private void pohybMimoZdi()
{
int offsetX = 0, offsetY = 0;
int smer = 0;
if (Greenfoot.isKeyDown("left"))
{
smer = -1;
offsetX = rychlost;
}
if (Greenfoot.isKeyDown("right"))
{
smer = 1;
offsetX = rychlost;
}
if (Greenfoot.isKeyDown("down"))
{
smer = 1;
offsetY = rychlost;
}
if (Greenfoot.isKeyDown("up"))
{
smer = -1;
offsetY = rychlost;
}
if (
getObjectsAtOffset(
smer*(offsetX+okrajAkteraX),
smer*(offsetY+okrajAkteraY),
Zed.class).size() == 0
)
{
setLocation(getX()+smer*offsetX, getY()+smer*offsetY);
}
}
public void act()
{
pohybMimoZdi();
}
}