|
3 weeks ago | |
---|---|---|
.. | ||
solution | 3 weeks ago | |
your-work | 3 weeks ago | |
README.md | 3 weeks ago | |
assignment.md | 3 weeks ago |
README.md
Vytvořte vesmírnou hru, část 4: Přidání laseru a detekce kolizí
Kvíz před lekcí
V této lekci se naučíte střílet lasery pomocí JavaScriptu! Do naší hry přidáme dvě věci:
- Laser: tento laser bude vystřelen z lodi vašeho hrdiny a bude se pohybovat vertikálně nahoru
- Detekce kolizí, jako součást implementace schopnosti střílet přidáme také několik herních pravidel:
- Laser zasáhne nepřítele: Nepřítel zemře, pokud ho zasáhne laser
- Laser zasáhne horní část obrazovky: Laser bude zničen, pokud zasáhne horní část obrazovky
- Kolize nepřítele a hrdiny: Nepřítel i hrdina budou zničeni, pokud do sebe narazí
- Nepřítel zasáhne spodní část obrazovky: Nepřítel i hrdina budou zničeni, pokud nepřítel zasáhne spodní část obrazovky
Stručně řečeno, vy -- hrdina -- musíte zasáhnout všechny nepřátele laserem, než se dostanou na spodní část obrazovky.
✅ Udělejte si malý průzkum o úplně první počítačové hře, která byla kdy napsána. Jaká byla její funkčnost?
Buďme hrdinové společně!
Detekce kolizí
Jak provádíme detekci kolizí? Musíme si představit herní objekty jako obdélníky, které se pohybují. Proč? Protože obrázek použitý k vykreslení herního objektu je obdélník: má x
, y
, šířku
a výšku
.
Pokud se dva obdélníky, například hrdina a nepřítel, protnou, dojde ke kolizi. Co by se mělo stát, záleží na pravidlech hry. K implementaci detekce kolizí tedy potřebujete následující:
-
Způsob, jak získat obdélníkové vyjádření herního objektu, například takto:
rectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y + this.height, right: this.x + this.width } }
-
Porovnávací funkci, která může vypadat takto:
function intersectRect(r1, r2) { return !(r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top); }
Jak ničíme objekty
Abychom mohli ve hře něco zničit, musíme hře sdělit, že tento objekt již nemá být vykreslen v herní smyčce, která se spouští v určitém intervalu. Jedním ze způsobů je označit herní objekt jako mrtvý, když se něco stane, například takto:
// collision happened
enemy.dead = true
Poté můžete mrtvé objekty odstranit před opětovným vykreslením obrazovky, například takto:
gameObjects = gameObject.filter(go => !go.dead);
Jak vystřelit laser
Vystřelení laseru znamená reagovat na klávesovou událost a vytvořit objekt, který se pohybuje určitým směrem. Musíme tedy provést následující kroky:
- Vytvořit laserový objekt: z horní části lodi našeho hrdiny, který se po vytvoření začne pohybovat směrem nahoru k horní části obrazovky.
- Přiřadit kód ke klávesové události: musíme vybrat klávesu na klávesnici, která bude představovat střelbu laseru hráčem.
- Vytvořit herní objekt, který vypadá jako laser, když je klávesa stisknuta.
Časový limit pro laser
Laser musí být vystřelen pokaždé, když stisknete klávesu, například mezerník. Aby hra nevytvářela příliš mnoho laserů v krátkém čase, musíme to opravit. Řešením je implementace tzv. časového limitu, časovače, který zajistí, že laser může být vystřelen jen v určitých intervalech. To můžete implementovat následujícím způsobem:
class Cooldown {
constructor(time) {
this.cool = false;
setTimeout(() => {
this.cool = true;
}, time)
}
}
class Weapon {
constructor {
}
fire() {
if (!this.cooldown || this.cooldown.cool) {
// produce a laser
this.cooldown = new Cooldown(500);
} else {
// do nothing - it hasn't cooled down yet.
}
}
}
✅ Podívejte se na lekci 1 v sérii vesmírných her, abyste si připomněli, jak fungují časové limity.
Co vytvořit
Vezmete stávající kód (který byste měli vyčistit a refaktorovat) z předchozí lekce a rozšíříte ho. Buď začněte s kódem z části II, nebo použijte kód z části III - startovací.
tip: laser, se kterým budete pracovat, je již ve vaší složce s prostředky a je odkazován vaším kódem
- Přidejte detekci kolizí, když laser narazí na něco, měla by platit následující pravidla:
- Laser zasáhne nepřítele: nepřítel zemře, pokud ho zasáhne laser
- Laser zasáhne horní část obrazovky: laser bude zničen, pokud zasáhne horní část obrazovky
- Kolize nepřítele a hrdiny: nepřítel i hrdina budou zničeni, pokud do sebe narazí
- Nepřítel zasáhne spodní část obrazovky: nepřítel i hrdina budou zničeni, pokud nepřítel zasáhne spodní část obrazovky
Doporučené kroky
Najděte soubory, které byly pro vás vytvořeny ve složce your-work
. Měla by obsahovat následující:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| index.html
-| app.js
-| package.json
Spusťte svůj projekt ve složce your_work
zadáním:
cd your-work
npm start
Tím se spustí HTTP server na adrese http://localhost:5000
. Otevřete prohlížeč a zadejte tuto adresu, aktuálně by se měl zobrazit hrdina a všichni nepřátelé, nic se však zatím nehýbe :).
Přidání kódu
-
Nastavte obdélníkové vyjádření svého herního objektu pro zpracování kolizí. Následující kód umožňuje získat obdélníkové vyjádření
GameObject
. Upravte svou třídu GameObject, aby ji rozšířila:rectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y + this.height, right: this.x + this.width, }; }
-
Přidejte kód, který kontroluje kolize. Toto bude nová funkce, která testuje, zda se dva obdélníky protínají:
function intersectRect(r1, r2) { return !( r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top ); }
-
Přidejte schopnost střílet laser
-
Přidejte zprávu pro klávesovou událost. Klávesa mezerník by měla vytvořit laser těsně nad lodí hrdiny. Přidejte tři konstanty do objektu Messages:
KEY_EVENT_SPACE: "KEY_EVENT_SPACE", COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER", COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
-
Zpracujte klávesu mezerník. Upravte funkci
window.addEventListener
pro událost keyup, aby zpracovávala mezerník:} else if(evt.keyCode === 32) { eventEmitter.emit(Messages.KEY_EVENT_SPACE); }
-
Přidejte posluchače. Upravte funkci
initGame()
, aby hrdina mohl střílet, když je stisknut mezerník:eventEmitter.on(Messages.KEY_EVENT_SPACE, () => { if (hero.canFire()) { hero.fire(); }
a přidejte novou funkci
eventEmitter.on()
, aby se zajistilo chování, když nepřítel narazí na laser:eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { first.dead = true; second.dead = true; })
-
Pohyb objektu, zajistěte, aby se laser postupně pohyboval k horní části obrazovky. Vytvoříte novou třídu Laser, která rozšiřuje
GameObject
, stejně jako dříve:class Laser extends GameObject { constructor(x, y) { super(x,y); (this.width = 9), (this.height = 33); this.type = 'Laser'; this.img = laserImg; let id = setInterval(() => { if (this.y > 0) { this.y -= 15; } else { this.dead = true; clearInterval(id); } }, 100) } }
-
Zpracování kolizí, implementujte pravidla kolizí pro laser. Přidejte funkci
updateGameObjects()
, která testuje kolidující objekty:function updateGameObjects() { const enemies = gameObjects.filter(go => go.type === 'Enemy'); const lasers = gameObjects.filter((go) => go.type === "Laser"); // laser hit something lasers.forEach((l) => { enemies.forEach((m) => { if (intersectRect(l.rectFromGameObject(), m.rectFromGameObject())) { eventEmitter.emit(Messages.COLLISION_ENEMY_LASER, { first: l, second: m, }); } }); }); gameObjects = gameObjects.filter(go => !go.dead); }
Ujistěte se, že jste přidali
updateGameObjects()
do herní smyčky vwindow.onload
. -
Implementujte časový limit pro laser, aby mohl být vystřelen jen v určitých intervalech.
Nakonec upravte třídu Hero, aby mohla používat časový limit:
class Hero extends GameObject { constructor(x, y) { super(x, y); (this.width = 99), (this.height = 75); this.type = "Hero"; this.speed = { x: 0, y: 0 }; this.cooldown = 0; } fire() { gameObjects.push(new Laser(this.x + 45, this.y - 10)); this.cooldown = 500; let id = setInterval(() => { if (this.cooldown > 0) { this.cooldown -= 100; } else { clearInterval(id); } }, 200); } canFire() { return this.cooldown === 0; } }
-
V tomto bodě má vaše hra určitou funkčnost! Můžete se pohybovat pomocí šipek, střílet laser mezerníkem a nepřátelé zmizí, když je zasáhnete. Skvělá práce!
🚀 Výzva
Přidejte explozi! Podívejte se na herní prostředky v repozitáři Space Art a zkuste přidat explozi, když laser zasáhne mimozemšťana.
Kvíz po lekci
Přehled a samostudium
Experimentujte s intervaly ve své hře. Co se stane, když je změníte? Přečtěte si více o časových událostech v JavaScriptu.
Zadání
Prohlášení:
Tento dokument byl přeložen pomocí služby pro automatický překlad Co-op Translator. Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.