# Створення космічної гри, частина 2: Малюємо героя та монстрів на Canvas API Canvas — одна з найпотужніших функцій веб-розробки для створення динамічної, інтерактивної графіки прямо у вашому браузері. У цьому уроці ми перетворимо порожній HTML-елемент `` на ігровий світ, наповнений героями та монстрами. Уявіть Canvas як вашу цифрову дошку для малювання, де код стає візуальним. Ми продовжуємо те, що ви вивчили в попередньому уроці, і тепер заглибимося у візуальні аспекти. Ви навчитеся завантажувати та відображати ігрові спрайти, точно позиціонувати елементи та створювати візуальну основу для вашої космічної гри. Це з'єднує статичні веб-сторінки з динамічними, інтерактивними досвідами. До кінця цього уроку у вас буде повна ігрова сцена з правильно розташованим кораблем героя та формаціями ворогів, готовими до бою. Ви зрозумієте, як сучасні ігри рендерять графіку в браузерах, і здобудете навички для створення власних інтерактивних візуальних досвідів. Давайте дослідимо графіку Canvas і оживимо вашу космічну гру! ## Тест перед лекцією [Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/31) ## Canvas Що ж таке цей елемент ``? Це рішення HTML5 для створення динамічної графіки та анімації у веб-браузерах. На відміну від звичайних зображень чи відео, які є статичними, Canvas дає вам контроль над кожним пікселем на екрані. Це робить його ідеальним для ігор, візуалізації даних та інтерактивного мистецтва. Уявіть його як програмовану поверхню для малювання, де JavaScript стає вашим пензлем. За замовчуванням елемент Canvas виглядає як порожній, прозорий прямокутник на вашій сторінці. Але саме тут прихована його потенціальна сила! Його справжня потужність проявляється, коли ви використовуєте JavaScript для малювання форм, завантаження зображень, створення анімацій та забезпечення взаємодії з користувачем. Це схоже на те, як піонери комп'ютерної графіки в Bell Labs у 1960-х роках програмували кожен піксель для створення перших цифрових анімацій. ✅ Прочитайте [більше про Canvas API](https://developer.mozilla.org/docs/Web/API/Canvas_API) на MDN. Ось як зазвичай оголошується Canvas, як частина тіла сторінки: ```html ``` **Що робить цей код:** - **Встановлює** атрибут `id`, щоб ви могли звертатися до цього конкретного елемента Canvas у JavaScript - **Визначає** ширину в пікселях для контролю горизонтального розміру Canvas - **Встановлює** висоту в пікселях для визначення вертикальних розмірів Canvas ## Малювання простих геометричних форм Тепер, коли ви знаєте, що таке елемент Canvas, давайте дослідимо, як насправді малювати на ньому! Canvas використовує систему координат, яка може здатися знайомою з уроків математики, але є одна важлива особливість, специфічна для комп'ютерної графіки. Canvas використовує декартову систему координат з віссю x (горизонтальною) та віссю y (вертикальною) для позиціонування всього, що ви малюєте. Але є ключова відмінність: на відміну від системи координат з уроків математики, точка початку `(0,0)` знаходиться у верхньому лівому куті, причому значення x збільшуються, коли ви рухаєтеся вправо, а значення y збільшуються, коли ви рухаєтеся вниз. Такий підхід бере початок з ранніх комп'ютерних дисплеїв, де електронні промені сканували зверху вниз, роблячи верхній лівий кут природною точкою початку. ![сітка Canvas](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.uk.png) > Зображення з [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) Щоб малювати на елементі Canvas, ви будете слідувати тому ж триетапному процесу, який є основою всієї графіки Canvas. Як тільки ви зробите це кілька разів, це стане для вас природним: 1. **Отримайте посилання** на ваш елемент Canvas з DOM (так само, як і будь-який інший HTML-елемент) 2. **Отримайте контекст рендерингу 2D** – це забезпечує всі методи малювання 3. **Почніть малювати!** Використовуйте вбудовані методи контексту для створення вашої графіки Ось як це виглядає в коді: ```javascript // Step 1: Get the canvas element const canvas = document.getElementById("myCanvas"); // Step 2: Get the 2D rendering context const ctx = canvas.getContext("2d"); // Step 3: Set fill color and draw a rectangle ctx.fillStyle = 'red'; ctx.fillRect(0, 0, 200, 200); // x, y, width, height ``` **Давайте розберемо це крок за кроком:** - Ми **отримуємо** наш елемент Canvas за його ID і зберігаємо його у змінній - Ми **отримуємо** контекст рендерингу 2D – це наш набір інструментів для малювання - Ми **вказуємо** Canvas, що хочемо заповнити речі червоним кольором, використовуючи властивість `fillStyle` - Ми **малюємо** прямокутник, починаючи з верхнього лівого кута (0,0), шириною та висотою 200 пікселів ✅ API Canvas здебільшого зосереджений на 2D-формах, але ви також можете малювати 3D-елементи на веб-сайті; для цього можна використовувати [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API). На Canvas API можна малювати різноманітні речі, такі як: - **Геометричні форми**, ми вже показали, як намалювати прямокутник, але є багато іншого, що можна намалювати. - **Текст**, ви можете малювати текст будь-яким шрифтом і кольором, який вам подобається. - **Зображення**, ви можете малювати зображення на основі графічного файлу, наприклад .jpg або .png. ✅ Спробуйте! Ви знаєте, як намалювати прямокутник, чи можете ви намалювати коло на сторінці? Подивіться на деякі цікаві малюнки Canvas на CodePen. Ось [особливо вражаючий приклад](https://codepen.io/dissimulate/pen/KrAwx). ## Завантаження та малювання графічного ресурсу Малювання базових форм корисне для початку, але більшість ігор потребують реальних зображень! Спрайти, фони та текстури — це те, що надає іграм їхню візуальну привабливість. Завантаження та відображення зображень на Canvas працює інакше, ніж малювання геометричних форм, але це досить просто, якщо зрозуміти процес. Нам потрібно створити об'єкт `Image`, завантажити наш графічний файл (це відбувається асинхронно, тобто "у фоновому режимі"), а потім намалювати його на Canvas, коли він буде готовий. Такий підхід гарантує, що ваші зображення відображаються правильно, не блокуючи вашу програму під час завантаження. ### Базове завантаження зображень ```javascript const img = new Image(); img.src = 'path/to/my/image.png'; img.onload = () => { // Image loaded and ready to be used console.log('Image loaded successfully!'); }; ``` **Що відбувається в цьому коді:** - Ми **створюємо** абсолютно новий об'єкт Image для зберігання нашого спрайту або текстури - Ми **вказуємо**, який графічний файл завантажити, встановлюючи шлях до джерела - Ми **слухаємо** подію завантаження, щоб точно знати, коли зображення готове до використання ### Кращий спосіб завантаження зображень Ось більш надійний спосіб обробки завантаження зображень, який часто використовують професійні розробники. Ми обгорнемо завантаження зображень у функцію на основі Promise – цей підхід, популяризований, коли JavaScript Promises стали стандартом в ES6, робить ваш код більш організованим і дозволяє ефективно обробляти помилки: ```javascript function loadAsset(path) { return new Promise((resolve, reject) => { const img = new Image(); img.src = path; img.onload = () => { resolve(img); }; img.onerror = () => { reject(new Error(`Failed to load image: ${path}`)); }; }); } // Modern usage with async/await async function initializeGame() { try { const heroImg = await loadAsset('hero.png'); const monsterImg = await loadAsset('monster.png'); // Images are now ready to use } catch (error) { console.error('Failed to load game assets:', error); } } ``` **Що ми зробили тут:** - **Обгорнули** всю логіку завантаження зображень у Promise, щоб краще її обробляти - **Додали** обробку помилок, яка фактично повідомляє нам, коли щось пішло не так - **Використали** сучасний синтаксис async/await, тому що він набагато зрозуміліший - **Включили** блоки try/catch для плавного оброблення будь-яких проблем із завантаженням Коли ваші зображення завантажені, їх малювання на Canvas насправді досить просте: ```javascript async function renderGameScreen() { try { // Load game assets const heroImg = await loadAsset('hero.png'); const monsterImg = await loadAsset('monster.png'); // Get canvas and context const canvas = document.getElementById("myCanvas"); const ctx = canvas.getContext("2d"); // Draw images to specific positions ctx.drawImage(heroImg, canvas.width / 2, canvas.height / 2); ctx.drawImage(monsterImg, 0, 0); } catch (error) { console.error('Failed to render game screen:', error); } } ``` **Давайте розберемо це крок за кроком:** - Ми **завантажуємо** як зображення героя, так і монстра у фоновому режимі, використовуючи await - Ми **отримуємо** наш елемент Canvas і отримуємо необхідний контекст рендерингу 2D - Ми **позиціонуємо** зображення героя прямо в центрі, використовуючи швидку математику координат - Ми **розміщуємо** зображення монстра у верхньому лівому куті, щоб почати формування ворогів - Ми **обробляємо** будь-які помилки, які можуть виникнути під час завантаження або рендерингу ## Тепер час почати створювати вашу гру Тепер ми об'єднаємо все, щоб створити візуальну основу вашої космічної гри. Ви маєте міцне розуміння основ Canvas та технік завантаження зображень, тому цей практичний розділ допоможе вам створити повний ігровий екран із правильно розташованими спрайтами. ### Що створити Ви створите веб-сторінку з елементом Canvas. Вона повинна відображати чорний екран `1024*768`. Ми надали вам два зображення: - Корабель героя ![Корабель героя](../../../../translated_images/player.dd24c1afa8c71e9b82b2958946d4bad13308681392d4b5ddcc61a0e818ef8088.uk.png) - 5×5 монстрів ![Корабель монстра](../../../../translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.uk.png) ### Рекомендовані кроки для початку розробки Знайдіть стартові файли, які були створені для вас у підпапці `your-work`. Структура вашого проекту повинна містити: ```bash your-work/ ├── assets/ │ ├── enemyShip.png │ └── player.png ├── index.html ├── app.js └── package.json ``` **Що у вас є:** - **Ігрові спрайти** знаходяться в папці `assets/`, щоб усе залишалося організованим - **Ваш основний HTML-файл** налаштовує елемент Canvas і готує все до роботи - **Файл JavaScript**, у якому ви напишете весь ваш код для рендерингу гри - **Файл package.json**, який налаштовує сервер розробки, щоб ви могли тестувати локально Відкрийте цю папку у Visual Studio Code, щоб почати розробку. Вам знадобиться локальне середовище розробки з встановленими Visual Studio Code, NPM та Node.js. Якщо у вас не налаштований `npm` на комп'ютері, [ось як його встановити](https://www.npmjs.com/get-npm). Запустіть сервер розробки, перейшовши до папки `your-work`: ```bash cd your-work npm start ``` **Ця команда робить кілька крутих речей:** - **Запускає** локальний сервер на `http://localhost:5000`, щоб ви могли тестувати свою гру - **Слугує** всі ваші файли належним чином, щоб ваш браузер міг їх правильно завантажити - **Слідкує** за вашими файлами на предмет змін, щоб ви могли розробляти безперешкодно - **Надає вам** професійне середовище розробки для тестування всього > 💡 **Примітка**: Ваш браузер спочатку покаже порожню сторінку – це очікувано! Додавайте код і оновлюйте браузер, щоб побачити зміни. Такий підхід до розробки схожий на те, як NASA створювала комп'ютер Apollo – тестуючи кожен компонент перед інтеграцією в більшу систему. ### Додайте код Додайте необхідний код до `your-work/app.js`, щоб виконати наступні завдання: 1. **Намалюйте Canvas з чорним фоном** > 💡 **Як це зробити**: Знайдіть TODO у `/app.js` і додайте лише два рядки. Встановіть `ctx.fillStyle` на чорний, потім використовуйте `ctx.fillRect()`, починаючи з (0,0) з розмірами вашого Canvas. Легко! 2. **Завантажте текстури гри** > 💡 **Як це зробити**: Використовуйте `await loadAsset()` для завантаження зображень гравця та ворога. Збережіть їх у змінних, щоб використовувати пізніше. Пам'ятайте – вони не з'являться, поки ви їх не намалюєте! 3. **Намалюйте корабель героя в центрі внизу** > 💡 **Як це зробити**: Використовуйте `ctx.drawImage()`, щоб позиціонувати вашого героя. Для координати x спробуйте `canvas.width / 2 - 45`, щоб центрувати його, а для координати y використовуйте `canvas.height - canvas.height / 4`, щоб розмістити його в нижній частині. 4. **Намалюйте формацію ворогів 5×5** > 💡 **Як це зробити**: Знайдіть функцію `createEnemies` і налаштуйте вкладений цикл. Вам потрібно буде зробити деякі розрахунки для розташування та позиціонування, але не хвилюйтеся – я покажу вам, як саме! Спочатку встановіть константи для правильного розташування формації ворогів: ```javascript const ENEMY_TOTAL = 5; const ENEMY_SPACING = 98; const FORMATION_WIDTH = ENEMY_TOTAL * ENEMY_SPACING; const START_X = (canvas.width - FORMATION_WIDTH) / 2; const STOP_X = START_X + FORMATION_WIDTH; ``` **Давайте розберемо, що роблять ці константи:** - Ми **встановлюємо** 5 ворогів у рядку та колонці (гарна сітка 5×5) - Ми **визначаємо**, скільки простору залишити між ворогами, щоб вони не виглядали тісно - Ми **розраховуємо**, наскільки широка буде вся формація - Ми **знаходимо**, де почати і закінчити, щоб формація виглядала центрованою Потім створіть вкладені цикли для малювання формації ворогів: ```javascript for (let x = START_X; x < STOP_X; x += ENEMY_SPACING) { for (let y = 0; y < 50 * 5; y += 50) { ctx.drawImage(enemyImg, x, y); } } ``` **Що робить цей вкладений цикл:** - Зовнішній цикл **рухається** зліва направо через нашу формацію - Внутрішній цикл **проходить** зверху вниз, створюючи акуратні рядки - Ми **малюємо** кожен спрайт ворога на точних координатах x, y, які ми розрахували - Все залишається **рівномірно розташованим**, щоб виглядало професійно та організовано ## Результат Готовий результат має виглядати так: ![Чорний екран з героєм та формацією монстрів 5×5](../../../../translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.uk.png) ## Рішення Спробуйте спочатку вирішити самостійно, але якщо ви застрягли, подивіться [рішення](../../../../6-space-game/2-drawing-to-canvas/solution/app.js) --- ## Виклик GitHub Copilot Agent 🚀 Використовуйте режим Agent, щоб виконати наступний виклик: **Опис:** Покращіть Canvas вашої космічної гри, додавши візуальні ефекти та інтерактивні елементи, використовуючи техніки Canvas API, які ви вивчили. **Завдання:** Створіть новий файл під назвою `enhanced-canvas.html` з Canvas, який відображає анімовані зірки на фоні, пульсуючу шкалу здоров'я для корабля героя та ворогів, які повільно рухаються вниз. Включіть JavaScript-код, який малює мерехтливі зірки, використовуючи випадкові позиції та прозорість, реалізує шкалу здоров'я, яка змінює колір залежно від рівня здоров'я (зелений > жовтий > червоний --- **Відмова від відповідальності**: Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.