TlačiťTlačiť Slovenčina English Hľadať RSS

© 2005 – 2024 Roman Horváth, všetky práva vyhradené. Dnes je 25. 4. 2024.

Stránka sa načítava, prosím čakajte…

Dátum: 7. 8. 2020, pred štyrmi rokmi

Táto jednoduchá ukážka má simulovať prekážky približujúce sa z jedného bodu v diaľke smerom dopredu k objektu ovládanému hráčom (uhýbačovi). Podrobnosti implementácie sa dajú prečítať zo zdrojových kódov tried.

 

obrázok 
Ukážka vzhľadu po spustení.

ikonaBalíček so zdrojovými súbormi na prevzatie. 2,03 kB (1,98 KiB), 7. 8. 2020

 

~

import knižnica.*;

public class Prekážka extends GRobot
{
	// Tento príznak je nastavený od štartu prekážky dovtedy, kým neklesne
	// pod určitú úroveň na ploche, kedy vyžiada vznik novej prekážky
	// a príznak vynuluje. (Pozri reakciu aktivita.)
	private boolean žiadajNovúPrekážku = true;

	public Prekážka()
	{
		zdvihniPero();
		pomer(0.8); // (Nastavenie pomeru tvaru obĺžnika.)
		gyroskop(90.0); // (O gyroskope sa píše v metóde koliduje nižšie.)

		// Zrýchlenie je nastavené tak, aby pred dosiahnutím spodného
		// okraja obrazovky nedosiahlo maximálnu povolenú rýchlosť (20 bodov
		// za tik). Napriek tomu sa zdá, že prekážka spomaľuje, pretože mení
		// svoju veľkosť podľa vertikálnej súradnice, aby vznikol dojem
		// perspektívy.
		zrýchlenie(0.25);
		maximálnaRýchlosť(20);
		reset();
	}

	public void reset()
	{
		// (Reset rýchlosti, polohy a cez aktivitu aj veľkosti.)
		rýchlosť(0, false);
		skočNa(0, Svet.najväčšieY());
		aktivita();

		// (Nastavenie nového cieľa zároveň prekážku aktivuje.)
		cieľ(Svet.náhodnéReálneČíslo(Svet.najmenšieX(), Svet.najväčšieX()),
			Svet.najmenšieY() * 4);
		žiadajNovúPrekážku = true;

		// (Presunieme prekážku na spodok kreslenia, aby pôsobila, že je za
		// ostatnými, ktoré sa mezitým posunuli na obrazovke nižšie.)
		naSpodok();
	}

	@Override public void kresliTvar()
	{
		hrúbkaČiary(veľkosť() / 8);
		farba(biela);
		vyplňObdĺžnik();
		farba(čierna);
		kresliObdĺžnik();
	}

	@Override public boolean koliduje(GRobot iný)
	{
		// Blok try-finally spolu s riadkom kódu pred ním slúžia na
		// zálohovanie a obnovenie uhla prekážky, pretože jej uhol sa musí
		// v čase detekcie kolízie rovnať 90°.
		//
		// Inak by detekcia bola odchýlená, pretože by porovnávala tvar
		// obdĺžnikovej oblasti orientovanej v skutočnom smere prekážky.
		//
		// Skutočný smer prekážky sa od kresleného smeru líši, pretože
		// prekážka má aktivovaný gyroskop. Gyroskop vždy pootočí tvar
		// kreslenia na zadaný uhol (v tomto prípade 90°).

		double uhol = uhol();
		try
		{
			uhol(90.0);
			return bodVObdĺžniku(iný);
		}
		finally
		{
			uhol(uhol);
		}
	}

	@Override public void aktivita()
	{
		if (žiadajNovúPrekážku && polohaY() < Svet.najväčšieY() / 2)
		{
			žiadajNovúPrekážku = false;

			// Vytvorenie novej prekážky na tomto mieste by spôsobilo zmeny
			// vo vnútornom zozname robotov. Tento zoznam by nikdy nemal byť
			// upravovaný v rámci „pracovných reakcií,“ preto je vytvorenie
			// odložené na spracovanie v čase nečinnosti.
			Svet.vykonaťNeskôr(() -> Uhýbač.nováPrekážka());
		}

		// (Automatická úprava veľkosti podľa vertikálnej súradnice.)
		veľkosť(
			(-polohaY() + Svet.najväčšieY()) * 100 /
			(Svet.najväčšieY() - Svet.najmenšieY()));
	}
}

~

import knižnica.*;

public class Uhýbač extends GRobot
{
	private final static Zoznam<Prekážka> prekážky = new Zoznam<>();

	private Uhýbač()
	{
		veľkosť(15);
		hrúbkaČiary(10);
		nováPrekážka();
	}

	public static void nováPrekážka()
	{
		// Buď nájde neaktívnu prekážku v zozname prekážok, …
		for (Prekážka prekážka : prekážky)
			if (prekážka.neaktívny())
			{
				prekážka.reset();
				return;
			}

		// … alebo vytvorí novú.
		prekážky.pridaj(new Prekážka());
	}

	@Override public void kresliTvar()
	{
		krúžok();
	}

	@Override public void pohybMyši()
	{
		skočNa(ÚdajeUdalostí.polohaMyšiX(), Svet.najmenšieY());
	}

	@Override public void tik()
	{
		for (Prekážka prekážka : prekážky)
		{
			if (prekážka.koliduje(this))
			{
				// (Kolízia s prekážkou zafarbí uhýbača načerveno.)
				farba(červená);
				return;
			}
		}

		farba(čierna);
	}

	public static void main(String[] args)
	{
		Svet.použiKonfiguráciu("Uhýbač.cfg");
		Svet.skry();
		Svet.nekresli();
		new Uhýbač();
		Svet.zbaľ();
		Svet.kresli();
		Svet.zobraz();
	}
}

Návrhy na zlepšenia

  • Upravte projekt tak, aby bol hráč nútený prechádzať z ľavej strany obrazovky na pravú a späť. (Napríklad striedavým pridávaním dlhých „vlajočiek“ k prekážkam zľava a sprava.)
  • Graficky zvýraznite kolízie uhýbača s prekážkami. (Napríklad farebným zablysnutím plochy.)
  • Zhustite premávku.