如何停止用户输入和在Pygame上显示之间的滞后

发布于 2025-01-27 18:31:39 字数 2045 浏览 1 评论 0原文

我是Pygame社区和Python的新手。对于我的计算机分配,我们必须制作一个视频游戏。即时通讯尝试做的是通过获取用户输入开始,然后将用户输入进行循环,然后根据该输入显示新视图。我试图制作一个主菜单屏幕,用户可以在其中按上下箭头以在屏幕上选择选项。但是,当我运行它时,它非常笨拙,响应用户输入的速度很慢。只有当您将其放下时,它才会移动,但它一直进入第四个选项。

while Loop_2 == True:
    pygame.time.delay(75)
    #Checks what keys have been pressed
    keys = pygame.key.get_pressed()
   
    #Checks if player has pressed the exit button
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

    #Checks if the player has pressed escape and will end python        
    if keys[pygame.K_ESCAPE]:
     pygame.quit()

    #The second main menu if statements for moving the curser and selecting
    if keys[pygame.K_DOWN] and Position < 4:
        #If the player presses the down arrow to move the pointer and its not in the 4th position at the bottom. it will move down
        Position = Position + 1
    else:
        if keys[pygame.K_UP] and Position > 1:
            #If the player presses the up arrow to move the pointer and its not in the 1st position at the top. it will move up
            Position = Position - 1
        else:
            if keys[pygame.K_LSHIFT]:
                Loop_3 = True

                if Position == 1:
                    Play_Menu()
                elif Position == 2:
                    Saves_Menu()
                elif Position == 3:
                    Settings_Menu()
                elif Position == 4:
                    Quit_Menu()
       
           
    #Loads the second main Menu
    window.blit(main_menu_2,(0,0))

    if Position == 1:
        window.blit(main_menu_pointer,(650,-525))
       
    elif Position == 2:
        window.blit(main_menu_pointer,(650,-385))
       
    elif Position == 3:
        window.blit(main_menu_pointer,(650,-240))
       
    elif Position == 4:
        window.blit(main_menu_pointer,(650,-100))
       
   
   


    pygame.display.update()

我已经尝试将pygame.delay更改为不同的值,它将使其响应迅速或无反应。我只想要它,以便我可以向下或向上,当它释放时,它将移至下一个选项上,而不是一直向下底部。我在此网站上找不到有关此的信息。谢谢

Im a newbie in the pygame community and python in general. For my computers assignment we have to make a video game. What Im trying to do is have a loop where it starts off by getting user input, then it takes that user input and then displays a new view based on that. Im trying to make a main menu screen where the user can press the up and down arrows to select options on the screen. However, when I run it, its very glitchy and its slow to respond to user input. Only when you hold it down it will move, but it goes all the way to the 4th option.

while Loop_2 == True:
    pygame.time.delay(75)
    #Checks what keys have been pressed
    keys = pygame.key.get_pressed()
   
    #Checks if player has pressed the exit button
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

    #Checks if the player has pressed escape and will end python        
    if keys[pygame.K_ESCAPE]:
     pygame.quit()

    #The second main menu if statements for moving the curser and selecting
    if keys[pygame.K_DOWN] and Position < 4:
        #If the player presses the down arrow to move the pointer and its not in the 4th position at the bottom. it will move down
        Position = Position + 1
    else:
        if keys[pygame.K_UP] and Position > 1:
            #If the player presses the up arrow to move the pointer and its not in the 1st position at the top. it will move up
            Position = Position - 1
        else:
            if keys[pygame.K_LSHIFT]:
                Loop_3 = True

                if Position == 1:
                    Play_Menu()
                elif Position == 2:
                    Saves_Menu()
                elif Position == 3:
                    Settings_Menu()
                elif Position == 4:
                    Quit_Menu()
       
           
    #Loads the second main Menu
    window.blit(main_menu_2,(0,0))

    if Position == 1:
        window.blit(main_menu_pointer,(650,-525))
       
    elif Position == 2:
        window.blit(main_menu_pointer,(650,-385))
       
    elif Position == 3:
        window.blit(main_menu_pointer,(650,-240))
       
    elif Position == 4:
        window.blit(main_menu_pointer,(650,-100))
       
   
   


    pygame.display.update()

I’ve tried changing the pygame.delay to different values and it will either make it too responsive or non-responsive. I just want it so that I can press down or up and when its released it will move onto the next option, not all the way down the bottom. I cant find anything about this on this website here. Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮萍、无处依 2025-02-03 18:31:39

核心问题是,您希望能够循环浏览菜单选项,而不会对普通人过于快速。

目前,代码延迟整个程序以保持速度。但是,这里真正需要的是对选择下一个项目之间的时间限制。

这样做的一种方法是查看当选择“事件”发生时。也就是说,用户什么时候突出显示菜单项。时间的方便函数是.get_ticks(),它返回一个毫秒相对时间。

# user just changed selection
time_now = pygame.time.get_ticks()

这使我们能够创建一个未来的时间,然后允许新的选择。

# user just changed selection
time_now = pygame.time.get_ticks()
next_allowed  = time_now + 300       # 300 milliseconds in the future

现在,当用户试图更改选择时,直到当前时间已经过去,才允许它。以我们的示例,这将不适合另外300毫秒(这很慢)。

# user has tried to change selection
time_now = pygame.time.get_ticks()
if ( time_now > next_allowed ):
    # ( TODO - menu selection change code )
    next_allowed = time_now + 300   # future time next change allowed

当然,我们应该为时间延迟设置一个常数,因此它很容易更改,而无需浏览常数的代码,

MENU_DELAY = 300

...

next_allowed = time_now + MENU_DELAY   # future time next change allowed

这是一些实现此类菜单的示例代码:

”

import pygame

WIDTH = 500
HEIGHT= 500
FPS   = 60

MENU_DELAY = 200

BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)
GREEN = ( 20, 180,  20)

pygame.init()
screen = pygame.display.set_mode( ( WIDTH, HEIGHT ) )
pygame.display.set_caption( "Menuosity" )

font  = pygame.font.Font( None, 32 )  # font used to make menu Items
                

class MenuItem:
    """ Simple sprite-like object representing a Menu Button """
    def __init__( self, label ):
        super().__init__()
        self.image    = pygame.Surface( ( 200, 50 ) )   # long rectangle
        self.rect     = self.image.get_rect()
        self.label    = label.strip().capitalize()
        self.selected = False
        self.fore     = BLACK
        self.back     = WHITE
        self.makeImage( self.fore, self.back )

    def makeImage( self, foreground, background ):
        """ Make the image used for the menu item, in the given colour """
        self.image.fill( background )
        pygame.draw.rect( self.image, foreground, [0, 0, self.image.get_width(), self.image.get_height()], 3 )

        # centred text for Label
        text = font.render( self.label, True, foreground )
        text_centre_rect = text.get_rect( center = self.image.get_rect().center )
        self.image.blit( text, text_centre_rect )

    def moveTo( self, x, y ):
        """ Reposition the menu item """
        self.rect.x = x
        self.rect.y = y

    def makeSelected( self, selected=True ):
        """ If the button is selected, invert it's colours """
        if ( self.selected != selected ):
            # Only re-generate if different
            if ( selected ):
                self.makeImage( self.back, self.fore )  # inverted colours on selection
            else:
                self.makeImage( self.fore, self.back )  # non-selected, normal colours
        self.selected = selected

    def draw( self, surface ):
        """ Paint the item on the given surface """
        surface.blit( self.image, self.rect )



### Create a Menu of Items
menu = []
menu.append( MenuItem( "First Item" ) )
menu.append( MenuItem( "Second Item" ) )
menu.append( MenuItem( "Third Item" ) )
menu.append( MenuItem( "Fourth Item" ) )

### Highlight the first item
current_option = 0
menu[0].makeSelected()

### Lay-out the menu
for i,item in enumerate( menu ):
    item.moveTo( 150, 50 + ( i * 80 ) )   # spread out in a single column

### Used to slow down the UI Changes
clock = pygame.time.Clock()
next_change_time = 0  

###
### MAIN
###
while True:
    time_now = pygame.time.get_ticks()   # milliseconds elapsed time 

    # Handle events
    keys = pygame.key.get_pressed()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    # if the user pressed [space]
    if ( keys[pygame.K_SPACE] ):
        # When space is pushed move to the next item, but not more than every 300ms
        # So, has enough time elapsed since the last keypress?
        if ( time_now > next_change_time ):
            # enough time elapsed, un-select the current, and select the next menu-item
            menu[current_option].makeSelected( False )    
            current_option += 1
            if ( current_option >= len( menu ) ):
                current_option = 0
            menu[current_option].makeSelected( True )
            next_change_time = time_now + MENU_DELAY  # remember the time of the change

    # paint the screen
    screen.fill( GREEN )  # paint background

    # Paint the menu
    for item in menu:
        item.draw( screen );

    pygame.display.flip()
    clock.tick( FPS )       # keep a sane frame-rate

The core issue is that you want to be able to cycle through menu options without it being too-fast for a normal human.

Currently the code is delaying the entire program to maintain a speed. But what is really needed here is a restriction on the time between selecting a next item.

One way of doing this is looking at the Pygame Time when the selection "event" happens. That is, at what time did the user highlight the menu item. A handy function of the time is .get_ticks(), which returns a millisecond relative time.

# user just changed selection
time_now = pygame.time.get_ticks()

This allows us to create a future-time, after which a new selection is allowed.

# user just changed selection
time_now = pygame.time.get_ticks()
next_allowed  = time_now + 300       # 300 milliseconds in the future

Now when the user attempts to change the selection, don't allow it until the current time is past this time in the future. By our example, that wont be for another 300 milliseconds (which is quite slow).

# user has tried to change selection
time_now = pygame.time.get_ticks()
if ( time_now > next_allowed ):
    # ( TODO - menu selection change code )
    next_allowed = time_now + 300   # future time next change allowed

Of course, we should set a constant for the time delay, so it's easily changed without having to hunt through the code for constants

MENU_DELAY = 300

...

next_allowed = time_now + MENU_DELAY   # future time next change allowed

Here's some example code which implements such a menu:

menu screen shot

import pygame

WIDTH = 500
HEIGHT= 500
FPS   = 60

MENU_DELAY = 200

BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)
GREEN = ( 20, 180,  20)

pygame.init()
screen = pygame.display.set_mode( ( WIDTH, HEIGHT ) )
pygame.display.set_caption( "Menuosity" )

font  = pygame.font.Font( None, 32 )  # font used to make menu Items
                

class MenuItem:
    """ Simple sprite-like object representing a Menu Button """
    def __init__( self, label ):
        super().__init__()
        self.image    = pygame.Surface( ( 200, 50 ) )   # long rectangle
        self.rect     = self.image.get_rect()
        self.label    = label.strip().capitalize()
        self.selected = False
        self.fore     = BLACK
        self.back     = WHITE
        self.makeImage( self.fore, self.back )

    def makeImage( self, foreground, background ):
        """ Make the image used for the menu item, in the given colour """
        self.image.fill( background )
        pygame.draw.rect( self.image, foreground, [0, 0, self.image.get_width(), self.image.get_height()], 3 )

        # centred text for Label
        text = font.render( self.label, True, foreground )
        text_centre_rect = text.get_rect( center = self.image.get_rect().center )
        self.image.blit( text, text_centre_rect )

    def moveTo( self, x, y ):
        """ Reposition the menu item """
        self.rect.x = x
        self.rect.y = y

    def makeSelected( self, selected=True ):
        """ If the button is selected, invert it's colours """
        if ( self.selected != selected ):
            # Only re-generate if different
            if ( selected ):
                self.makeImage( self.back, self.fore )  # inverted colours on selection
            else:
                self.makeImage( self.fore, self.back )  # non-selected, normal colours
        self.selected = selected

    def draw( self, surface ):
        """ Paint the item on the given surface """
        surface.blit( self.image, self.rect )



### Create a Menu of Items
menu = []
menu.append( MenuItem( "First Item" ) )
menu.append( MenuItem( "Second Item" ) )
menu.append( MenuItem( "Third Item" ) )
menu.append( MenuItem( "Fourth Item" ) )

### Highlight the first item
current_option = 0
menu[0].makeSelected()

### Lay-out the menu
for i,item in enumerate( menu ):
    item.moveTo( 150, 50 + ( i * 80 ) )   # spread out in a single column

### Used to slow down the UI Changes
clock = pygame.time.Clock()
next_change_time = 0  

###
### MAIN
###
while True:
    time_now = pygame.time.get_ticks()   # milliseconds elapsed time 

    # Handle events
    keys = pygame.key.get_pressed()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    # if the user pressed [space]
    if ( keys[pygame.K_SPACE] ):
        # When space is pushed move to the next item, but not more than every 300ms
        # So, has enough time elapsed since the last keypress?
        if ( time_now > next_change_time ):
            # enough time elapsed, un-select the current, and select the next menu-item
            menu[current_option].makeSelected( False )    
            current_option += 1
            if ( current_option >= len( menu ) ):
                current_option = 0
            menu[current_option].makeSelected( True )
            next_change_time = time_now + MENU_DELAY  # remember the time of the change

    # paint the screen
    screen.fill( GREEN )  # paint background

    # Paint the menu
    for item in menu:
        item.draw( screen );

    pygame.display.flip()
    clock.tick( FPS )       # keep a sane frame-rate
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文