Событие Pygame: запуск события key up без отпускания ключа - PullRequest
1 голос
/ 25 апреля 2020

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

   def set_keyboard_dirs(cur_block, width, height, events): # events stores pygame.event.get() as I use it multiple times in my code
        global move_timer # only moves block one time per set number of frames
        cur_block.reset_collisions(height)
        for event in events:
            if event.type == pygame.KEYDOWN:  # sets magnitude and direction of movement
                if event.key == pygame.K_RIGHT:
                    cur_block.dir = (cur_block.length, 0)
                elif event.key == pygame.K_LEFT:
                    cur_block.dir = (-cur_block.length, 0)
                elif event.key == pygame.K_DOWN:
                    cur_block.dir = (0, cur_block.length)
                elif event.key == pygame.K_UP:
                    cur_block.rotate(height, width)
                elif event.key == pygame.K_SPACE: # just moves the block instantly to the bottom of the screen by equating it to a 'projection' already there. 
                    cur_block.shape = deepcopy(cur_block.projection)
            elif event.type == pygame.KEYUP:  # stops block from moving
                print(event.key) # I called this to see what's happening, and event.key is printed event when I didn't release the key. 
                cur_block.dir = (0, 0)

        cur_block.move()

Из-за вышеизложенного блок перемещается по одному шагу за раз, а не непрерывно (до тех пор, пока они его удерживают), как я хочу. Как я могу это исправить, пожалуйста? Остальная часть игры работает, поэтому я очень хочу, чтобы это тоже сработало. Заранее большое спасибо.

РЕДАКТИРОВАТЬ: Я также пытался установить элементы управления с помощью pygame.key.get_pressed () следующим образом:

def set_keyboard_dirs(cur_block, width, height):
    global move_timer, keys
    cur_block.reset_collisions(height)
    cur_block.dir = (0, 0)
    if keys[pygame.K_UP] or keys[pygame.K_w]:
        cur_block.rotate(height, width)
    elif keys[pygame.K_SPACE]:
        cur_block.shape = deepcopy(cur_block.projection)
    elif (keys[pygame.K_DOWN] or keys[pygame.K_s]) and 2 not in cur_block.collisions: # 1, 2, 3 are collisions in left, down and right directions
        cur_block.dir = (0, cur_block.length)
    elif (keys[pygame.K_RIGHT] or keys[pygame.K_d]) and 1 not in cur_block.collisions:
        cur_block.dir = (cur_block.length, 0)
    elif (keys[pygame.K_LEFT] or keys[pygame.K_a]) and 3 not in cur_block.collisions:
        cur_block.dir = (-cur_block.length, 0)
    else:
        print('ran reset') # this statement print even as i'm holding down a key for some reason
        cur_block.dir = (0, 0)
    if cur_block.dir != (0, 0) and move_timer == 0:
        cur_block.move()
        move_timer = 7

в первом случае, если я удаляю KEYUP событие и в последнем случае, если я удаляю оператор else, блок перемещается непрерывно (но не может остановиться), что также показывает, что именно эти операторы являются причиной проблемы, я думаю. И это единственное место, где находится мой код, где я также определяю свой cur_block.dir.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2020

В вашем коде движение блока отменяется, если отпущен какой-либо ключ, а не если отпущен специальный ключ. Вам придется реализовать особые случаи, если отпущено только одно из клавиш курсора:

elif event.type == pygame.KEYUP:
    if event.key == pygame.K_RIGHT:
        # [...]
    elif event.key == pygame.K_LEFT:
        # [...]
    # [...]

Я рекомендую установить направление движения в зависимости от состояний клавиш, которые возвращаются pygame.key.get_pressed()* 1006. *:

def set_keyboard_dirs(cur_block, width, height, events):
    global move_timer
    cur_block.reset_collisions(height)

    keys = pygame.key.get_pressed()

    cur_block = [0, 0]
    if key[pygame.K_RIGHT]:
        cur_block.dir[0] += cur_block.length
    if key[pygame.K_LEFT]:
        cur_block.dir[0] -= cur_block.length
    if key[pygame.K_DOWN]:
        cur_block.dir[1] += cur_block.length
    if key[pygame.K_UP]:
        cur_block.rotate(height, width)
    if key[pygame.K_SPACE]:
        cur_block.shape = deepcopy(cur_block.projection)

    cur_block.move()
0 голосов
/ 25 апреля 2020

Вероятно, это потому, что ваш for l oop запускается 1 раз за кадр, поэтому, если вы удерживаете нажатой кнопку, она засчитывается, когда вы нажимали ее 1 раз в указанном c кадре, то же самое с событиями KEYUP. Вы можете попробовать сделать две переменные вне mainl oop left = False и right = False И за пределами вашего текущего значения для l oop, вы проверяете, нажата ли какая-либо кнопка.

#these are outside of the mainloop
left=False
right=False



keys = pygame.key.get_pressed()  # checks for key events (put this outside of the for loop, but still be inside your mainloop)
if keys[pygame.K_LEFT]:
    right = False
    left = True
elif keys[pygame.K_RIGHT]:
    left = False
    right = True

# if none of those buttons pressed, it sets the values back to False
else:
    right = False
    left = False

# using the left value, if its true, it will do your action every frame, 
#(you can adjust the speed of your block later)

if left:
    #  do something
    cur_block.dir = (-cur_block.length, 0)
if right:
    # do something else


, а затем например, если вы нажмете клавишу «ВЛЕВО», значение Left будет истинным, а затем вы сможете проверить: если какое-либо из этих значений true> что-то сделать.

На основании вашего примера кода это единственное, что Я могу придумать. Я надеюсь, что это работает.

...