# Създаване на космическа игра, част 5: Точки и животи ## Тест преди лекцията [Тест преди лекцията](https://ff-quizzes.netlify.app/web/quiz/37) В този урок ще научите как да добавите точки към играта и как да изчислявате животи. ## Рисуване на текст на екрана За да можете да показвате резултата от играта на екрана, трябва да знаете как да поставите текст върху него. Отговорът е използването на метода `fillText()` на обекта canvas. Можете също така да контролирате други аспекти като шрифта, цвета на текста и дори подравняването му (ляво, дясно, център). По-долу е даден код, който рисува текст на екрана. ```javascript ctx.font = "30px Arial"; ctx.fillStyle = "red"; ctx.textAlign = "right"; ctx.fillText("show this on the screen", 0, 0); ``` ✅ Прочетете повече за [как да добавите текст към canvas](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) и не се колебайте да направите вашия текст по-стилен! ## Животът като концепция в игрите Концепцията за живот в играта е просто число. В контекста на космическа игра е обичайно да се задават определен брой животи, които се намаляват един по един, когато вашият кораб понася щети. Ще е хубаво, ако можете да покажете графично представяне на това, например миникорабчета или сърца, вместо просто число. ## Какво да изградите Нека добавим следното към вашата игра: - **Резултат от играта**: За всеки унищожен вражески кораб, героят трябва да получава точки. Предлагаме 100 точки на кораб. Резултатът от играта трябва да се показва в долния ляв ъгъл. - **Живот**: Вашият кораб има три живота. Губите живот всеки път, когато вражески кораб се сблъска с вас. Броят на животите трябва да се показва в долния десен ъгъл и да бъде представен с графика като тази: ![изображение на живот](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.bg.png). ## Препоръчителни стъпки Намерете файловете, които са създадени за вас в подпапката `your-work`. Тя трябва да съдържа следното: ```bash -| assets -| enemyShip.png -| player.png -| laserRed.png -| index.html -| app.js -| package.json ``` Започнете проекта си в папката `your_work`, като напишете: ```bash cd your-work npm start ``` Горната команда ще стартира HTTP сървър на адрес `http://localhost:5000`. Отворете браузър и въведете този адрес. В момента трябва да виждате героя и всички врагове, а когато натискате стрелките наляво и надясно, героят се движи и може да стреля по враговете. ### Добавяне на код 1. **Копирайте необходимите ресурси** от папката `solution/assets/` в папката `your-work`. Ще добавите ресурса `life.png`. Добавете lifeImg към функцията window.onload: ```javascript lifeImg = await loadTexture("assets/life.png"); ``` 1. Добавете `lifeImg` към списъка с ресурси: ```javascript let heroImg, ... lifeImg, ... eventEmitter = new EventEmitter(); ``` 2. **Добавете променливи**. Добавете код, който представлява общия резултат (0) и оставащите животи (3), и ги покажете на екрана. 3. **Разширете функцията `updateGameObjects()`**. Разширете функцията `updateGameObjects()`, за да обработва сблъсъци с врагове: ```javascript enemies.forEach(enemy => { const heroRect = hero.rectFromGameObject(); if (intersectRect(heroRect, enemy.rectFromGameObject())) { eventEmitter.emit(Messages.COLLISION_ENEMY_HERO, { enemy }); } }) ``` 4. **Добавете `life` и `points`**. 1. **Инициализирайте променливи**. Под `this.cooldown = 0` в класа `Hero` задайте life и points: ```javascript this.life = 3; this.points = 0; ``` 1. **Рисувайте променливите на екрана**. Покажете тези стойности на екрана: ```javascript function drawLife() { // TODO, 35, 27 const START_POS = canvas.width - 180; for(let i=0; i < hero.life; i++ ) { ctx.drawImage( lifeImg, START_POS + (45 * (i+1) ), canvas.height - 37); } } function drawPoints() { ctx.font = "30px Arial"; ctx.fillStyle = "red"; ctx.textAlign = "left"; drawText("Points: " + hero.points, 10, canvas.height-20); } function drawText(message, x, y) { ctx.fillText(message, x, y); } ``` 1. **Добавете методи към игровия цикъл**. Уверете се, че добавяте тези функции към функцията window.onload под `updateGameObjects()`: ```javascript drawPoints(); drawLife(); ``` 1. **Реализирайте правилата на играта**. Реализирайте следните правила: 1. **За всеки сблъсък между героя и враг** изваждайте един живот. Разширете класа `Hero`, за да направите това изваждане: ```javascript decrementLife() { this.life--; if (this.life === 0) { this.dead = true; } } ``` 2. **За всеки лазер, който удари враг**, увеличавайте резултата от играта със 100 точки. Разширете класа `Hero`, за да направите това увеличение: ```javascript incrementPoints() { this.points += 100; } ``` Добавете тези функции към вашите Collision Event Emitters: ```javascript eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { first.dead = true; second.dead = true; hero.incrementPoints(); }) eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => { enemy.dead = true; hero.decrementLife(); }); ``` ✅ Направете малко проучване, за да откриете други игри, създадени с JavaScript/Canvas. Какви са техните общи черти? След като завършите тази работа, трябва да виждате малките "живот" кораби в долния десен ъгъл, точките в долния ляв ъгъл и да виждате как броят на животите намалява при сблъсък с врагове, а точките се увеличават, когато стреляте по врагове. Браво! Вашата игра е почти завършена. --- ## 🚀 Предизвикателство Вашият код е почти завършен. Можете ли да си представите следващите стъпки? ## Тест след лекцията [Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/38) ## Преглед и самостоятелно обучение Проучете начини за увеличаване и намаляване на резултатите и животите в игрите. Съществуват интересни игрови енджини като [PlayFab](https://playfab.com). Как използването на такъв енджин би подобрило вашата игра? ## Задача [Създайте игра с точки](assignment.md) --- **Отказ от отговорност**: Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.