Если игрок удерживает клавишу , корабль должен двигаться вправо до тех пор, пока клавиша не будет отпущена. Чтобы узнать, когда клавиша будет отпущена, наша игра отслеживает событие pygame.KEYUP; таким образом, реализация непрерывного движения будет основана на отслеживании событий KEYDOWN и KEYUP в сочетании с флагом moving_right.

В неподвижном состоянии корабля флаг moving_right равен False. При нажатии клавиши флагу присваивается значение True, а когда клавиша будет отпущена, флаг возвращается в состояние False.

Класс Ship управляет всеми атрибутами корабля, и мы добавим в него атрибут с именем moving_right и метод update() для проверки состояния флага moving_right. Метод update() изменяет позицию корабля, если флаг содержит значение True. Этот метод будет вызываться каждый раз, когда вы хотите обновить позицию корабля.

Ниже приведены изменения в классе Ship:

ship.py

class Ship():

def __init__(self, screen):

...

# Каждый новый корабль появляется у нижнего края экрана.

self.rect.centerx = self.screen_rect.centerx

self.rect.bottom = self.screen_rect.bottom

. . . .# Флаг перемещения

(1) . . . .self.moving_right = False

(2) . .def update(self):

. . . ."""Обновляет позицию корабля с учетом флага."""

. . . .if self.moving_right:

. . . . . .self.rect.centerx += 1

. .def blitme(self):

. . . ....

Мы добавляем атрибут self.moving_right в методе __init__() и инициализируем его значением False (1) . Затем вызывается метод update(), который перемещает корабль вправо, если флаг равен True (2).

Теперь внесем изменения в check_events(), чтобы при нажатии клавиши moving_right присваивалось значение True, а при ее отпускании — False:

game_functions.py

def check_events(ship):

"""Обрабатывает нажатия клавиш и события мыши."""

for event in pygame.event.get():

...

elif event.type == pygame.KEYDOWN:

if event.key == pygame.K_RIGHT:

(1) . . . . . . . .ship.moving_right = True

(2) . . . .elif event.type == pygame.KEYUP:

. . . . . .if event.key == pygame.K_RIGHT:

. . . . . . . .ship.moving_right = False

В точке (1) изменяется реакция игры при нажатии клавиши ; вместо непосредственного изменения позиции корабля программа просто присваивает moving_right значение True. В точке (2) добавляется новый блок elif, реагирующий на события KEYUP. Когда игрок отпускает клавишу (K_RIGHT), moving_right присваивается значение False.

Остается изменить цикл while в alien_invasion.py, чтобы при каждом проходе цикла вызывался метод update() корабля:

alien_invasion.py

# Запуск основного цикла игры.

while True:

gf.check_events(ship)

. . . .ship.update()

gf.update_screen(ai_settings, screen, ship)

Позиция корабля будет обновляться после проверки событий клавиатуры, но перед обновлением экрана. Таким образом, позиция корабля обновляется в ответ на действия пользователя и будет использоваться при перерисовке корабля на экране.

Если запустить alien_invasion.py и удерживать клавишу , корабль непрерывно двигается вправо, пока клавиша не будет отпущена.

<p>Перемещение влево и вправо</p>

Теперь, когда мы реализовали непрерывное движение вправо, добавить движение влево относительно несложно. Для этого нужно снова изменить класс Ship и функцию check_events(). Ниже приведены необходимые изменения в __init__() и update() в классе Ship:

ship.py

def __init__(self, screen):

...

. . . .# Флаги перемещения

self.moving_right = False

. . . .self.moving_left = False

. . . .

def update(self):

. . . ."""Обновляет позицию корабля с учетом флагов."""

if self.moving_right:

self.rect.centerx += 1

. . . .if self.moving_left:

. . . . . .self.rect.centerx -= 1

В методе __init__() добавляется флаг self.moving_left. В update() используются два отдельных блока if вместо elif, чтобы при нажатии обеих клавиш со стрелками атрибут rect.centerx сначала увеличивался, а потом уменьшался. В результате корабль остается на месте. Если бы для движения влево использовался блок elif, то клавиша всегда имела бы приоритет. Такая реализация повышает точность перемещения при переключении направления, когда игрок может ненадолго удерживать нажатыми обе клавиши.

В check_events() необходимо внести два изменения:

game_functions.py

def check_events(ship):

"""Обрабатывает нажатия клавиш и события мыши."""

for event in pygame.event.get():

...

elif event.type == pygame.KEYDOWN:

if event.key == pygame.K_RIGHT:

ship.moving_right = True

. . . . . .elif event.key == pygame.K_LEFT:

. . . . . . . .ship.moving_left = True

elif event.type == pygame.KEYUP:

if event.key == pygame.K_RIGHT:

ship.moving_right = False

. . . . . .elif event.key == pygame.K_LEFT:

. . . . . . . .ship.moving_left = False

Если событие KEYDOWN происходит для события K_LEFT, то moving_left присваивается True. Если событие KEYUP происходит для события K_LEFT, то moving_left присваивается False. Здесь возможно использовать блоки elif, потому что каждое событие связано только с одной клавишей. Если же игрок нажимает обе клавиши одновременно, то программа обнаруживает два разных события.

Перейти на страницу:

Все книги серии Библиотека программиста

Похожие книги