16 KiB
Създаване на космическа игра, част 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);
Как да изстреляме лазер
Изстрелването на лазер означава да реагираме на събитие от клавиатурата и да създадем обект, който се движи в определена посока. Затова трябва да изпълним следните стъпки:
- Създаване на обект лазер: от върха на кораба на героя, който започва да се движи нагоре към горната част на екрана веднага след създаването.
- Прикачване на код към събитие от клавиатурата: трябва да изберем клавиш на клавиатурата, който да представлява стрелбата на лазера от играча.
- Създаване на обект в играта, който изглежда като лазер, когато клавишът е натиснат.
Забавяне при стрелба с лазер
Лазерът трябва да се изстрелва всеки път, когато натиснете клавиш, например space. За да предотвратим играта да създава твърде много лазери за кратко време, трябва да поправим това. Решението е чрез реализиране на така нареченото забавяне, таймер, който гарантира, че лазерът може да се изстрелва само през определен интервал. Можете да го реализирате по следния начин:
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 ); }
-
Добавете способност за стрелба с лазер
-
Добавете съобщение за събитие от клавиш. Клавишът space трябва да създава лазер точно над кораба на героя. Добавете три константи в обекта Messages:
KEY_EVENT_SPACE: "KEY_EVENT_SPACE", COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER", COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
-
Обработете клавиша space. Редактирайте функцията
window.addEventListener
за keyup, за да обработва space:} else if(evt.keyCode === 32) { eventEmitter.emit(Messages.KEY_EVENT_SPACE); }
-
Добавете слушатели. Редактирайте функцията
initGame()
, за да гарантирате, че героят може да стреля, когато клавишът space е натиснат: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 и враговете изчезват, когато ги ударите. Браво!
🚀 Предизвикателство
Добавете експлозия! Разгледайте ресурсите за играта в репото Space Art и опитайте да добавите експлозия, когато лазер удари извънземно.
Финален тест
Преглед и самостоятелно обучение
Експериментирайте с интервалите във вашата игра досега. Какво се случва, когато ги промените? Прочетете повече за събития за време в JavaScript.
Задание
Отказ от отговорност:
Този документ е преведен с помощта на AI услуга за превод Co-op Translator. Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.