Pygame: как поместить управление с клавиатуры в отдельный модуль, не теряя при этом непрерывного движения - PullRequest
0 голосов
/ 10 июня 2018

Обзор Я создаю игру с космическим кораблем, который может двигаться во всех 4 направлениях.В игре while loop мой космический корабль может управляться с клавиатуры, как показано ниже.Для простоты я показал только часть своего кода и только ту часть, где я перемещаю свой космический корабль вправо.

Метод Как видно, я использую 'for loop' и модуль pygame для получения ввода с клавиатуры.И я использую метод flag , чтобы включить непрерывное перемещение.Я начинаю с установки всех флагов на False.Затем, в зависимости от нажатия на клавиатуру, он перемещается в другом направлении и снова устанавливается в False, когда клавиша поднимается.Все работает нормально ... Примечание: переменная surf_centerx является центром моего космического корабля, а screen.blit (surf, surf_rect), pygame.display.flip () в конце просто отображает космический корабль на экране и обновляетпоследние изменения в положении космического корабля, соответственно.

import pygame
# pygame initializing
pygame.init()

#create the screen surface
screen =  pygame.display.set_mode((400, 400))

#..snip...

speedfactor = 0.1
move_right = False
#..snip...
while True:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                move_right = True
#..snip...
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                move_right = False
#..snip...

    if move_right:
        surf_centerx += speedfactor

#..snip...

    screen.blit(surf, surf_rect)
    pygame.display.flip()

Рефакторинг кода - я думал Но так как мой цикл while продолжает расти, я хочу провести некоторый рефакторинг кода, я подумал: o)Таким образом, я поместил бы свою клавиатуру в отдельный модуль с функцией, которую я бы затем вызвал в цикле while.Я сохраняю значение из k_c.check_key_events () в переменной «return», и ниже значение распаковывается строкой «move_right = return».Мой цикл while теперь выглядит так (намного короче):

import keyboard_control as k_c
while True:
    returned = k_c.check_key_events()
    move_right = returned
    if move_right:
        surf_centerx += speedfactor
#..snip...

    screen.blit(surf, surf_rect)
    pygame.display.flip()

А боковой модуль, управляющий клавиатурой (keyboard_control):

import pygame

#necessary pygame initializing
pygame.init()

def check_key_events():
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                move_right = True
#..snip...
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                move_right = False
#..snip...
    return move_right

Теперь я вызываю модуль keyboard_control в'while цикл' в главном модуле и модуле keyboard_control теперь должен возвращать значение переменной 'move_right'.Помещение цикла for и т. Д. В собственный модуль эффективно упрощает основной модуль.

Проблема Но запуск моей программы теперь выдает ошибку: * return move_right UnboundLocalError: локальная переменная 'move_right', на которую ссылается перед присваиванием *

Проблема в том, что функция незнать переменную 'move_right', потому что она не определена в функции 'check_key_events ()'.И , если Я определяю это в начале функции, что-то вроде этого:

#..snip...
def check_key_events():
    move_right = False
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                move_right = True
#..snip...

Тогда моя проблема заключается в том, что я теряю непрерывное движение, потому что в каждом цикле цикла whileстрока 'return = k_c.check_key_events ()' вызывает функцию 'check_key_events ()', которая устанавливает переменную move_right в False, даже если я не отпустил клавишу 'Move Right'. Итак, мой вопрос как мне ловко обойти эту проблему ??Я просто не могу понять это.

1 Ответ

0 голосов
/ 10 июня 2018

Есть (по крайней мере) два способа исправить это, быстрый и грязный и правильный.

Быстрый и чистый: объявить ваш move_right из функции какглобальная переменная и поместите global move_right в начале функции.Это будет работать, но это довольно уродливо, потому что глобальные переменные являются злом .

Правильный способ - создать класс для вашего космического корабля и установить там свойство, сообщающее, в каком направлении выдвигаешьсяЭто довольно долгий путь, но определенно то, что вам нужно, потому что, возможно, позже вы захотите расширить объект космического корабля.

...