|
3 weeks ago | |
---|---|---|
.. | ||
solution | 3 weeks ago | |
your-work | 3 weeks ago | |
README.md | 3 weeks ago | |
assignment.md | 3 weeks ago |
README.md
Створення космічної гри, частина 4: Додавання лазера та виявлення зіткнень
Передлекційна вікторина
У цьому уроці ви навчитеся стріляти лазерами за допомогою JavaScript! Ми додамо до нашої гри дві речі:
- Лазер: цей лазер стріляє з корабля героя вертикально вгору.
- Виявлення зіткнень: у рамках реалізації можливості стріляти ми також додамо кілька цікавих правил гри:
- Лазер влучає в ворога: ворог знищується, якщо його вразив лазер.
- Лазер досягає верхньої частини екрану: лазер знищується, якщо досягає верхньої частини екрану.
- Зіткнення ворога та героя: ворог і герой знищуються, якщо стикаються.
- Ворог досягає нижньої частини екрану: ворог і герой знищуються, якщо ворог досягає нижньої частини екрану.
Коротко кажучи, ви — герой — повинні вразити всіх ворогів лазером, перш ніж вони досягнуть нижньої частини екрану.
✅ Проведіть невелике дослідження про першу комп'ютерну гру, яка була створена. Яка була її функціональність?
Давайте будемо героями разом!
Виявлення зіткнень
Як ми можемо виявляти зіткнення? Нам потрібно уявляти наші ігрові об'єкти як прямокутники, що рухаються. Чому саме так? Тому що зображення, яке використовується для відображення ігрового об'єкта, є прямокутником: воно має x
, y
, width
і height
.
Якщо два прямокутники, наприклад, герой і ворог, перетинаються, це означає зіткнення. Що має відбутися далі, залежить від правил гри. Для реалізації виявлення зіткнень вам потрібно наступне:
-
Спосіб отримати прямокутне представлення ігрового об'єкта, щось на кшталт цього:
rectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y + this.height, right: this.x + this.width } }
-
Функція порівняння, яка може виглядати так:
function intersectRect(r1, r2) { return !(r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top); }
Як знищувати об'єкти
Щоб знищити об'єкт у грі, потрібно повідомити грі, що цей об'єкт більше не потрібно відображати в ігровому циклі, який викликається через певний інтервал. Один із способів зробити це — позначити ігровий об'єкт як мертвий, коли щось відбувається, наприклад:
// collision happened
enemy.dead = true
Потім можна видалити мертві об'єкти перед повторним відображенням екрану, наприклад:
gameObjects = gameObject.filter(go => !go.dead);
Як стріляти лазером
Стрільба лазером означає реагування на подію натискання клавіші та створення об'єкта, який рухається в певному напрямку. Для цього потрібно виконати наступні кроки:
- Створити об'єкт лазера: з верхньої частини корабля героя, який після створення починає рухатися вгору до верхньої частини екрану.
- Прив'язати код до події натискання клавіші: потрібно вибрати клавішу на клавіатурі, яка буде відповідати за стрільбу лазером.
- Створити ігровий об'єкт, який виглядає як лазер, коли натискається клавіша.
Затримка для лазера
Лазер повинен стріляти щоразу, коли ви натискаєте клавішу, наприклад, пробіл. Щоб запобігти створенню занадто великої кількості лазерів за короткий час, потрібно це виправити. Виправлення полягає у впровадженні так званої затримки — таймера, який гарантує, що лазер можна стріляти лише через певний інтервал. Це можна реалізувати наступним чином:
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.
}
}
}
✅ Перегляньте урок 1 із серії про космічну гру, щоб нагадати собі про затримки.
Що створити
Ви візьмете існуючий код (який ви повинні були очистити та рефакторити) з попереднього уроку та розширите його. Або почніть із коду з частини II, або використовуйте код із Part III- starter.
підказка: лазер, з яким ви працюватимете, вже знаходиться у вашій папці з ресурсами та підключений до вашого коду.
- Додайте виявлення зіткнень, коли лазер стикається з чимось, повинні застосовуватися наступні правила:
- Лазер влучає в ворога: ворог знищується, якщо його вразив лазер.
- Лазер досягає верхньої частини екрану: лазер знищується, якщо досягає верхньої частини екрану.
- Зіткнення ворога та героя: ворог і герой знищуються, якщо стикаються.
- Ворог досягає нижньої частини екрану: ворог і герой знищуються, якщо ворог досягає нижньої частини екрану.
Рекомендовані кроки
Знайдіть файли, які були створені для вас у підпапці your-work
. Вона повинна містити наступне:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| index.html
-| app.js
-| package.json
Запустіть ваш проєкт у папці your_work
, ввівши:
cd your-work
npm start
Це запустить HTTP-сервер за адресою http://localhost:5000
. Відкрийте браузер і введіть цю адресу, зараз він повинен відображати героя та всіх ворогів, але нічого ще не рухається :).
Додайте код
-
Налаштуйте прямокутне представлення вашого ігрового об'єкта для обробки зіткнень. Наведений нижче код дозволяє отримати прямокутне представлення
GameObject
. Відредагуйте ваш клас GameObject, щоб розширити його:rectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y + this.height, right: this.x + this.width, }; }
-
Додайте код, який перевіряє зіткнення. Це буде нова функція, яка перевіряє, чи перетинаються два прямокутники:
function intersectRect(r1, r2) { return !( r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top ); }
-
Додайте можливість стріляти лазером
-
Додайте повідомлення про подію натискання клавіші. Клавіша пробіл повинна створювати лазер прямо над кораблем героя. Додайте три константи в об'єкт Messages:
KEY_EVENT_SPACE: "KEY_EVENT_SPACE", COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER", COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
-
Обробіть клавішу пробіл. Відредагуйте функцію
window.addEventListener
для обробки натискання пробілу:} else if(evt.keyCode === 32) { eventEmitter.emit(Messages.KEY_EVENT_SPACE); }
-
Додайте слухачі подій. Відредагуйте функцію
initGame()
, щоб герой міг стріляти, коли натискається пробіл:eventEmitter.on(Messages.KEY_EVENT_SPACE, () => { if (hero.canFire()) { hero.fire(); }
і додайте нову функцію
eventEmitter.on()
, щоб забезпечити поведінку, коли ворог стикається з лазером:eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { first.dead = true; second.dead = true; })
-
Рух об'єкта. Переконайтеся, що лазер поступово рухається до верхньої частини екрану. Ви створите новий клас Laser, який розширює
GameObject
, як ви робили раніше: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) } }
-
Обробіть зіткнення. Реалізуйте правила зіткнень для лазера. Додайте функцію
updateGameObjects()
, яка перевіряє об'єкти, що стикаються: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); }
Переконайтеся, що ви додали
updateGameObjects()
у ваш ігровий цикл уwindow.onload
. -
Реалізуйте затримку для лазера, щоб його можна було стріляти лише через певний інтервал.
Нарешті, відредагуйте клас Hero, щоб він міг мати затримку:
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; } }
-
На цьому етапі ваша гра має певну функціональність! Ви можете керувати героєм за допомогою стрілок, стріляти лазером за допомогою пробілу, і вороги зникають, коли ви їх вражаєте. Чудова робота!
🚀 Виклик
Додайте вибух! Перегляньте ігрові ресурси в репозиторії Space Art і спробуйте додати вибух, коли лазер влучає в прибульця.
Післялекційна вікторина
Огляд і самостійне навчання
Експериментуйте з інтервалами у вашій грі. Що відбувається, коли ви їх змінюєте? Читайте більше про таймінгові події в JavaScript.
Завдання
Відмова від відповідальності:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу Co-op Translator. Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.