1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
---
title: Жизни
slug: Games/Tutorials/2D_breakout_game_Phaser/Extra_lives
translation_of: Games/Tutorials/2D_breakout_game_Phaser/Extra_lives
original_slug: Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Жизни
---
<div>{{GamesSidebar}}</div>
<div>{{IncludeSubnav("/ru/docs")}}</div>
<p>{{PreviousNext("Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Победа", "Games/Tutorials/Создание_2D_Breakout_игры_на_Phaser/Анимация")}}</p>
<div class="summary">
<p>Это <strong>12 </strong>из 16 уроков <a href="https://developer.mozilla.org/ru/docs/Games/Tutorials/%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_2D_Breakout_%D0%B8%D0%B3%D1%80%D1%8B_%D0%BD%D0%B0_Phaser">руководства разработки игры с помощью Phaser</a>. Исходный код этого урока вы можете найти здесь: <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson13.html">Gamedev-Phaser-Content-Kit/demos/lesson13.html</a>.</p>
</div>
<p><span class="seoSummary">Мы можем растянуть удовольствие от игры, добавив жизни. Это позволит игроку сделать несколько попыток, а не одну.</span></p>
<h2 id="Новый_переменные">Новый переменные</h2>
<p>Добавьте следующие переменные сразу после всех наших текущих определений переменных:</p>
<pre class="brush: js">var lives = 3;
var livesText;
var lifeLostText;
</pre>
<p>Эти переменные хранят, соответственно, количество жизней, надпись с количеством оставшихся жизней, и надпись, которая выведется на экран, если игрок потеряет жизнь.</p>
<h2 id="Определяем_новые_надписи">Определяем новые надписи</h2>
<p>Надписи мы уже определяли, когда реализовывали систему <a href="https://developer.mozilla.org/ru/docs/Games/Tutorials/%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_2D_Breakout_%D0%B8%D0%B3%D1%80%D1%8B_%D0%BD%D0%B0_Phaser/%D0%9E%D1%87%D0%BA%D0%B8">очков</a>. Добавьте следующие строки кода в после определения надписи <code>scoreText</code> в функции <code>create()</code>:</p>
<pre class="brush: js">livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, { font: '18px Arial', fill: '#0095DD' });
livesText.anchor.set(1,0);
lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', { font: '18px Arial', fill: '#0095DD' });
lifeLostText.anchor.set(0.5);
lifeLostText.visible = false;
</pre>
<p>Объекты <code>livesText</code> и<code>lifeLostText</code> очень похожи на <code>scoreText</code> — они определяют положение на экране, текст надписи и стилизацию шрифта. Чтобы всё выглядело должным образом, надпись с жизнями мы закрепляем в правом верхнем углу, а надпись о потере жизни, мы выводим в центре экрана. И всё это при помощи функции <code>anchor.set()</code>.</p>
<p>Надпись <code>lifeLostText</code> появится только при потере жизни, поэтому её видимость мы выставляем в <code>false</code>.</p>
<h3 id="Чистим_код_стилизирующий_надписи">Чистим код, стилизирующий надписи</h3>
<p>Как вы могли заметить, мы используем одинаковые стили для всех надписей: <code>scoreText</code>, <code>livesText</code> и <code>lifeLostText</code>. Однако, налицо копирование кода и если мы, когда-либо, захотим изменить размер шрифта или цвет, то нам придётся делать это в нескольких местах. Чтобы избежать этого, мы вынесем стиль в отдельную переменную. Напишите следующую строку сразу после всех наших текущих определений переменных:</p>
<pre class="brush: js">var textStyle = { font: '18px Arial', fill: '#0095DD' };
</pre>
<p>Теперь мы можем использовать эту переменную для нашего текста — обновите ваш код и замените повторяющиеся участки со стилем текста на переменную.</p>
<pre class="brush: js">scoreText = game.add.text(5, 5, 'Points: 0', textStyle);
livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, textStyle);
livesText.anchor.set(1,0);
lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', textStyle);
lifeLostText.anchor.set(0.5);
lifeLostText.visible = false;
</pre>
<p>Теперь, чтобы изменить стиль всего текста в игре, достаточно изменить только эту переменную.</p>
<h2 id="Код_обработки_жизни">Код обработки жизни</h2>
<p>Чтобы реализовать жизнь в нашей игре, давайте сначала изменим функцию шара, связанную с событием <code>onOutOfBounds</code>. Вместо того, чтобы выполнять анонимную функцию и сразу показывать сообщение:</p>
<pre class="brush: js"><s>ball.events.onOutOfBounds.add(function(){
alert('Game over!');
location.reload();
}, this);</s>
</pre>
<p>Мы объявим новую функцию <code>ballLeaveScreen</code>; Удалим предыдущий обработчик (зачёркнутый код сверху) и заменим его следующей линией:</p>
<pre class="brush: js">ball.events.onOutOfBounds.add(ballLeaveScreen, this);
</pre>
<p>Мы будем уменьшать количество жизней каждый раз, когда шар выйдет за пределы окна Canvas. Добавьте функцию <code>ballLeaveScreen()</code> в конец кода:</p>
<pre class="brush: js">function ballLeaveScreen() {
lives--;
if(lives) {
livesText.setText('Lives: '+lives);
lifeLostText.visible = true;
ball.reset(game.world.width*0.5, game.world.height-25);
paddle.reset(game.world.width*0.5, game.world.height-5);
game.input.onDown.addOnce(function(){
lifeLostText.visible = false;
ball.body.velocity.set(150, -150);
}, this);
}
else {
alert('You lost, game over!');
location.reload();
}
}
</pre>
<p>Вместо того, чтобы сразу вызывать сообщение, когда мяч выходит за пределы Canvas, мы сначала вычитаем одну жизнь из текущего числа и проверяем, не равно ли оно нулю. Если не равно, то у игрока все ещё осталось несколько жизней, и он может продолжать играть - он увидит сообщение о потере жизни, позиции мяча и платформы будут сброшены и при следующем клике мышью сообщение будет скрыто и мяч снова начнёт двигаться.</p>
<p>Когда количество жизней достигнет нуля игра заканчивается, а игроку показывается соответствующее сообщение.</p>
<h2 id="События">События</h2>
<p>Скорее всего вы заметили вызов методов <code>add()</code> и <code>addOnce()</code> в двух блоках кода выше и хотите знать, чем они отличаются. Разница в том, что метод <code>add()</code> и привязанная к нему функция выполняется каждый раз, когда выполняется событие, тогда как метод <code>addOnce() </code>полезен, когда вы хотите, чтобы связанная с ним функция выполнилась единожды и не повторялась снова. В нашем случае при каждом событии <code>outOfBounds</code> будет выполняться <code>ballLeaveScreen</code>, но когда мяч покидает экран, сообщение с экрана удалится единожды.</p>
<h2 id="Проверь_свой_код">Проверь свой код</h2>
<p>Вы можете проверить готовый код этого урока в его демо-версии и поиграть с ним чтобы лучше понять, как он работает:</p>
<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/yk1c5n0b/","","400")}}</p>
<h2 id="Следующий_шаг">Следующий шаг</h2>
<p>Жизни делают игру более казуальной — даже если вы проиграете единожды, у вас будут ещё 2 жизни и вы сможете продолжить игру. Теперь мы можем поработать над внешним видом игры, сделать её более красивой, добавив <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens">анимацию и эффекты </a>.</p>
<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Win_the_game", "Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens")}}</p>
|