|
3 weeks ago | |
---|---|---|
.. | ||
solution | 4 weeks ago | |
your-work | 4 weeks ago | |
README.md | 3 weeks ago | |
assignment.md | 4 weeks ago |
README.md
Budowanie gry kosmicznej, część 4: Dodawanie lasera i wykrywanie kolizji
Quiz przed lekcją
W tej lekcji nauczysz się strzelać laserami za pomocą JavaScriptu! Dodamy dwie rzeczy do naszej gry:
- Laser: laser wystrzeliwany z statku bohatera, poruszający się pionowo w górę
- Wykrywanie kolizji, jako część implementacji możliwości strzelania, dodamy również kilka zasad gry:
- Laser trafia w przeciwnika: Przeciwnik ginie, jeśli zostanie trafiony laserem
- Laser trafia w górną część ekranu: Laser zostaje zniszczony, jeśli trafi w górną część ekranu
- Kolizja przeciwnika z bohaterem: Przeciwnik i bohater giną, jeśli zderzą się ze sobą
- Przeciwnik trafia w dolną część ekranu: Przeciwnik i bohater giną, jeśli przeciwnik dotrze do dolnej części ekranu
Krótko mówiąc, Ty -- bohater -- musisz zestrzelić wszystkich przeciwników laserem, zanim dotrą do dolnej części ekranu.
✅ Zrób małe badania na temat pierwszej gry komputerowej, jaka kiedykolwiek została napisana. Jakie miała funkcje?
Bądźmy razem bohaterami!
Wykrywanie kolizji
Jak wykrywać kolizje? Musimy traktować nasze obiekty w grze jako poruszające się prostokąty. Dlaczego? Ponieważ obraz używany do rysowania obiektu gry to prostokąt: ma x
, y
, szerokość
i wysokość
.
Jeśli dwa prostokąty, np. bohater i przeciwnik, przecinają się, mamy kolizję. Co powinno się wtedy wydarzyć, zależy od zasad gry. Aby zaimplementować wykrywanie kolizji, potrzebujesz:
-
Sposobu na uzyskanie reprezentacji prostokąta obiektu gry, coś takiego:
rectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y + this.height, right: this.x + this.width } }
-
Funkcji porównującej, która może wyglądać tak:
function intersectRect(r1, r2) { return !(r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top); }
Jak niszczyć obiekty
Aby niszczyć obiekty w grze, musisz poinformować grę, że nie powinna już rysować tego elementu w pętli gry, która uruchamia się w określonych odstępach czasu. Można to zrobić, oznaczając obiekt gry jako martwy, gdy coś się wydarzy, na przykład tak:
// collision happened
enemy.dead = true
Następnie możesz przefiltrować martwe obiekty przed ponownym narysowaniem ekranu, na przykład tak:
gameObjects = gameObject.filter(go => !go.dead);
Jak wystrzelić laser
Wystrzelenie lasera oznacza reakcję na zdarzenie klawisza i stworzenie obiektu, który porusza się w określonym kierunku. Musimy wykonać następujące kroki:
- Stworzyć obiekt lasera: z górnej części statku bohatera, który po utworzeniu zaczyna poruszać się w górę, w kierunku górnej części ekranu.
- Podłączyć kod do zdarzenia klawisza: musimy wybrać klawisz na klawiaturze, który będzie reprezentował strzał laserem przez gracza.
- Stworzyć obiekt gry, który wygląda jak laser, gdy klawisz zostanie naciśnięty.
Czas odnowienia lasera
Laser musi być wystrzeliwany za każdym razem, gdy naciśniesz klawisz, na przykład spację. Aby zapobiec generowaniu zbyt wielu laserów w krótkim czasie, musimy to naprawić. Rozwiązaniem jest zaimplementowanie tzw. czasu odnowienia, czyli timera, który zapewnia, że laser może być wystrzeliwany tylko co jakiś czas. Możesz to zaimplementować w następujący sposób:
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.
}
}
}
✅ Przypomnij sobie lekcję 1 z serii o grze kosmicznej, aby przypomnieć sobie, czym jest czas odnowienia.
Co zbudować
Weźmiesz istniejący kod (który powinieneś już uporządkować i zrefaktoryzować) z poprzedniej lekcji i rozszerzysz go. Możesz zacząć od kodu z części II lub użyć kodu z Część III - starter.
wskazówka: laser, nad którym będziesz pracować, znajduje się już w folderze z zasobami i jest referencjonowany przez Twój kod
- Dodaj wykrywanie kolizji, gdy laser zderzy się z czymś, powinny obowiązywać następujące zasady:
- Laser trafia w przeciwnika: przeciwnik ginie, jeśli zostanie trafiony laserem
- Laser trafia w górną część ekranu: laser zostaje zniszczony, jeśli trafi w górną część ekranu
- Kolizja przeciwnika z bohaterem: przeciwnik i bohater giną, jeśli zderzą się ze sobą
- Przeciwnik trafia w dolną część ekranu: przeciwnik i bohater giną, jeśli przeciwnik dotrze do dolnej części ekranu
Zalecane kroki
Znajdź pliki, które zostały dla Ciebie utworzone w podfolderze your-work
. Powinny zawierać:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| index.html
-| app.js
-| package.json
Rozpocznij swój projekt w folderze your_work
, wpisując:
cd your-work
npm start
Powyższe uruchomi serwer HTTP pod adresem http://localhost:5000
. Otwórz przeglądarkę i wpisz ten adres, obecnie powinien renderować bohatera i wszystkich przeciwników, nic się jeszcze nie porusza :).
Dodaj kod
-
Ustaw reprezentację prostokąta dla swojego obiektu gry, aby obsłużyć kolizję. Poniższy kod pozwala uzyskać reprezentację prostokąta dla
GameObject
. Edytuj klasę GameObject, aby ją rozszerzyć:rectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y + this.height, right: this.x + this.width, }; }
-
Dodaj kod sprawdzający kolizję. To będzie nowa funkcja testująca, czy dwa prostokąty się przecinają:
function intersectRect(r1, r2) { return !( r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top ); }
-
Dodaj możliwość wystrzeliwania lasera
-
Dodaj komunikat o zdarzeniu klawisza. Klawisz spacja powinien tworzyć laser tuż nad statkiem bohatera. Dodaj trzy stałe w obiekcie Messages:
KEY_EVENT_SPACE: "KEY_EVENT_SPACE", COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER", COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
-
Obsłuż klawisz spacji. Edytuj funkcję
window.addEventListener
dla zdarzenia keyup, aby obsłużyć spację:} else if(evt.keyCode === 32) { eventEmitter.emit(Messages.KEY_EVENT_SPACE); }
-
Dodaj nasłuchy. Edytuj funkcję
initGame()
, aby upewnić się, że bohater może strzelać, gdy naciśnięty zostanie klawisz spacji:eventEmitter.on(Messages.KEY_EVENT_SPACE, () => { if (hero.canFire()) { hero.fire(); }
i dodaj nową funkcję
eventEmitter.on()
, aby zapewnić odpowiednie zachowanie, gdy przeciwnik zderzy się z laserem:eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { first.dead = true; second.dead = true; })
-
Porusz obiektem, Upewnij się, że laser stopniowo porusza się w górę ekranu. Stworzysz nową klasę Laser, która rozszerza
GameObject
, tak jak wcześniej: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) } }
-
Obsłuż kolizje, Zaimplementuj zasady kolizji dla lasera. Dodaj funkcję
updateGameObjects()
, która testuje zderzające się obiekty pod kątem trafień: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); }
Upewnij się, że dodasz
updateGameObjects()
do swojej pętli gry wwindow.onload
. -
Zaimplementuj czas odnowienia dla lasera, aby mógł być wystrzeliwany tylko co jakiś czas.
Na koniec edytuj klasę Hero, aby mogła obsłużyć czas odnowienia:
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; } }
-
Na tym etapie Twoja gra ma już pewną funkcjonalność! Możesz poruszać się za pomocą klawiszy strzałek, strzelać laserem za pomocą klawisza spacji, a przeciwnicy znikają, gdy ich trafisz. Brawo!
🚀 Wyzwanie
Dodaj eksplozję! Sprawdź zasoby gry w repozytorium Space Art i spróbuj dodać eksplozję, gdy laser trafi w obcego.
Quiz po lekcji
Przegląd i samodzielna nauka
Eksperymentuj z interwałami w swojej grze. Co się stanie, gdy je zmienisz? Przeczytaj więcej o zdarzeniach czasowych w JavaScript.
Zadanie
Zastrzeżenie:
Ten dokument został przetłumaczony za pomocą usługi tłumaczenia AI Co-op Translator. Chociaż staramy się zapewnić dokładność, prosimy pamiętać, że automatyczne tłumaczenia mogą zawierać błędy lub nieścisłości. Oryginalny dokument w jego rodzimym języku powinien być uznawany za wiarygodne źródło. W przypadku informacji krytycznych zaleca się skorzystanie z profesjonalnego tłumaczenia wykonanego przez człowieka. Nie ponosimy odpowiedzialności za jakiekolwiek nieporozumienia lub błędne interpretacje wynikające z użycia tego tłumaczenia.