Функция ввода с клавиатуры из pygame не работает - PullRequest
0 голосов
/ 19 марта 2019

Я искал причину около 3 часов, но не смог найти никакого решения.

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

Кроме того, я не думаю, что понял, как работают event.key и pygame.event.get ().Я был бы очень признателен, если бы кто-нибудь объяснил мне это.

И это код из моей игры для Ascii, и это только начало кода, который я до сих пор делал.

    class maingame:

    def __init__(self):
        exit = False

    def processkey(self):
        global hotkey,crazy

        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == K_SPACE:
                    crazy = 1
                if event.key == K_DOWN:
                    dir = 's'
                    y_option -= 1
                    hotkey  = 2
                if event.key == pygame.K_w:
                    dir = 'w'
                    y_option += 1
                    hotkey = 1
                if event.key == K_LEFT:
                    dir = 'a'

                if event.key == K_RIGHT:
                    dir = 'd'
            else:
                    hotkey = 1
                    y_option = 0
                    crazy = 0

    def displaymanu(self,hotkey):
        print(">" if hotkey == 1 else " ","play")
        print(">" if hotkey == 2 else " ","quit")
        if hotkey == 1 and crazy == 1:
            self.play()     
        elif hotkey == 2 and crazy == 1:
            exit = True
if __name__ == '__main__':
        while not quit:
            displayee = maingame()
            os.system('cls')
            displayee.processkey()
            displayee.processkey()
            displayee.displaymanu(hotkey)

Ответы [ 2 ]

1 голос
/ 20 марта 2019

PyGame не будет работать без экрана / окна . Таким образом, ваш код должен сначала инициализировать PyGame, а затем открыть окно (или полноэкранное отображение).

Исходя из моего понимания вашего кода, похоже, что должно отображаться меню:

> Play
  Quit

Где нажатие / (или w / s ) перемещает курсор > между вариантами, а затем пробел запускает опцию.

Одной из проблем вашего кода является ваша попытка интерпретировать нажатия клавиш внутри функции displaymanu(). Лучше, чтобы функция выполняла особые вещи, поэтому вся обработка клавиш в processkey() и только при рисовании экрана displaymanu().

Я исправил ваш код до того места, где он работает. Это включало изменение класса так, чтобы он инициализировал отображение PyGame. Меню должно было отображаться в окне, поэтому вместо print() были добавлены вызовы новой функции drawTextAt(). Многие переменные-члены класса Maingame имели проблемы с областью видимости, но простое указание self. имя-переменной (что делало их членами класса) исправило их.

Я также добавил состояние игры, чтобы показать, как должна меняться обработка клавиш в зависимости от того, в какой фазе находится игра в данный момент. Она начинается в меню, где «Вверх / Вниз» просто меняет пункт меню. Но потом во время игры Up / Down нужно сделать что-то совершенно другое.

import pygame
import os

# Window size
WINDOW_WIDTH  = 400
WINDOW_HEIGHT = 400
# colours
DARK    = (  50, 50, 50 )
RED     = ( 255, 50, 50 )


class Maingame:

    def __init__(self):
        # Initialise PyGame
        pygame.init()
        pygame.font.init()
        # Initialise a window
        pygame.display.set_caption("Main Game")
        self.screen = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), pygame.DOUBLEBUF )
        # menu font
        self.font   = pygame.font.SysFont(None, 20)

        self.hotkey     = 1
        self.crazy      = 0
        self.y_option   = 0
        self.game_state = 0  # state=0 -> show menu, 1 => Game, 2-> Game Over

    def processkey(self):
        # no key pressed yet
        self.crazy = 0
        dir_code   = ''  
        exit       = False

        # Detect keys pressed
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    dir_code = ' '
                    self.crazy = 1
                elif event.key == pygame.K_s or event.key == pygame.K_DOWN:
                    dir_code = 's'
                    self.y_option -= 1
                    self.hotkey  = 2
                elif event.key == pygame.K_w or event.key == pygame.K_UP:
                    dir_code = 'w'
                    self.y_option += 1
                    self.hotkey = 1
                elif event.key == pygame.K_LEFT:
                    dir_code = 'a'
                elif event.key == pygame.K_RIGHT:
                    dir_code = 'd'
                else:
                    self.hotkey = 1
                    self.y_option = 0
                    self.crazy = 0
                print( "DEBUG - game_state=[%d], dir_code is [%s], hotkey is [%d], crazy=[%d]" % ( self.game_state, dir_code, self.hotkey, self.crazy ) )

                # Act on the keys pressed (if any)
                if self.game_state == 0:  # menu mode
                    if self.hotkey == 1 and self.crazy == 1:
                        self.game_state = 1 # start the game
                    elif self.hotkey == 2 and self.crazy == 1:
                        exit = True
                elif self.game_state == 1:  # game mode
                    pass  # TODO
                elif self.game_state == 2:  # game-over mode
                    pass  # TODO

        return exit

    def drawTextAt( self, text, coord, foreground_colour=(255,255,255) ):
        """ Convert the specified text into a font-bitmap, and draw it
            onto the screen at the given co-ordinates """
        text_bitmap = self.font.render( text, True, foreground_colour )
        self.screen.blit( text_bitmap, coord )

    def displaymanu( self ):
        """ Draw the Menu """
        # MENU
        self.screen.fill( DARK )
        # Draw the menu options
        prefix = [ "  ", "  " ]
        prefix[ self.hotkey-1 ] = "> "
        self.drawTextAt( prefix[0] + "Play", ( 30, 100 ) )
        self.drawTextAt( prefix[1] + "Quit", ( 30, 150 ) )


    def displaygame( self ):
        """ Draw the Game Screen """
        # GAME SCREEN
        self.screen.fill( RED )
        self.drawTextAt( "GAME - #TODO", ( 30, 180 ) )

    def displaygameover( self ):
        """ Draw the Game-Over Screen """
        # GAME OVER SCREEN
        self.screen.fill( RED )
        self.drawTextAt( "* GAME OVER *", ( 30, 180 ) )

if __name__ == '__main__':
    # Initialise PyGame and the window

    displayee = Maingame()
    quit = False
    while not quit:
        #os.system('cls')
        # Draw the correct display for the state
        if displayee.game_state == 0:
            displayee.displaymanu()
        elif displayee.game_state == 1:
            displayee.displaygame()
        elif displayee.game_state == 2:
            displayee.displaygameover()
        # Push all drawing to the screen
        pygame.display.flip()
        # Handle keys
        quit = displayee.processkey()
0 голосов
/ 19 марта 2019

Похоже, вы не поместили pygame. перед некоторыми переменными здесь:

if event.key == K_SPACE: # Does not have pygame prefix
    crazy = 1
if event.key == K_DOWN: # Does not have pygame prefix
    dir = 's'
    y_option -= 1
    hotkey  = 2
if event.key == pygame.K_w: # Does have pygame prefix
    dir = 'w'
    y_option += 1
    hotkey = 1
if event.key == K_LEFT: # Does not have pygame prefix
    dir = 'a'

if event.key == K_RIGHT: # Does not have pygame prefix
    dir = 'd'

Добавьте pygame. к тем, и он должен обнаружить после этого. Странно, как он не вытащил исключение NameError во время работы.

...