【问题标题】:Allowing resizing window pyGame允许调整窗口大小 pyGame
【发布时间】:2012-07-22 19:11:42
【问题描述】:

我试图允许调整这个应用程序的大小,我设置了 RESIZABLE 标志,但是当我尝试调整大小时,它搞砸了!试试我的代码。

这是一个网格程序,当窗口调整大小时,我希望网格也调整大小/缩小。

import pygame,math
from pygame.locals import *
# Define some colors
black    = (   0,   0,   0)
white    = ( 255, 255, 255)
green    = (   0, 255,   0)
red      = ( 255,   0,   0)

# This sets the width and height of each grid location
width=50
height=20
size=[500,500]
# This sets the margin between each cell
margin=1


# Initialize pygame
pygame.init()

# Set the height and width of the screen

screen=pygame.display.set_mode(size,RESIZABLE)

# Set title of screen
pygame.display.set_caption("My Game")

#Loop until the user clicks the close button.
done=False

# Used to manage how fast the screen updates
clock=pygame.time.Clock()

# -------- Main Program Loop -----------
while done==False:
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done=True # Flag that we are done so we exit this loop
        if event.type == pygame.MOUSEBUTTONDOWN:
            height+=10

    # Set the screen background
    screen.fill(black)

    # Draw the grid
    for row in range(int(math.ceil(size[1]/height))+1):
        for column in range(int(math.ceil(size[0]/width))+1):
            color = white
            pygame.draw.rect(screen,color,[(margin+width)*column+margin,(margin+height)*row+margin,width,height])

    # Limit to 20 frames per second
    clock.tick(20)

    # Go ahead and update the screen with what we've drawn.
    pygame.display.flip()
# Be IDLE friendly. If you forget this line, the program will 'hang'
# on exit.
pygame.quit ()

请告诉我有什么问题,谢谢。

【问题讨论】:

    标签: python pygame


    【解决方案1】:

    这个问题的答案(允许 Pygame 窗口及其内部的表面调整大小)只是在用户更改其尺寸时重新创建具有更新大小的可调整大小的窗口(在 pygame.VIDEORESIZE 事件上完成)。

    >>> import pygame
    >>> help(pygame.display.set_mode)
    Help on built-in function set_mode in module pygame.display:
    
    set_mode(...)
        set_mode(size=(0, 0), flags=0, depth=0, display=0, vsync=0) -> Surface
        Initialize a window or screen for display
    >>> 
    

    删除了窗口表面上所有以前的内容,所以在下面
    有一个过程可以继续当前窗口内容。

    一些示例代码:

    import pygame, sys
    
    pygame.init()
    # Create the window, saving it to a variable.
    surface = pygame.display.set_mode((350, 250), pygame.RESIZABLE)
    pygame.display.set_caption("Example resizable window")
    
    while True:
        surface.fill((255,255,255))
    
        # Draw a red rectangle that resizes with the window.
        pygame.draw.rect(surface, (200,0,0), (surface.get_width()/3,
          surface.get_height()/3, surface.get_width()/3,
          surface.get_height()/3))
    
        pygame.display.update()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
    
            if event.type == pygame.VIDEORESIZE:
                # There's some code to add back window content here.
                surface = pygame.display.set_mode((event.w, event.h),
                                                  pygame.RESIZABLE)
    

    如何继续当前窗口内容:
    以下是添加回之前窗口内容的一些步骤:

    1. 创建第二个变量,设置为旧窗口表面变量的值。
    2. 创建新窗口,将其存储为旧变量。
    3. 在第一个表面(旧变量)上绘制第二个表面 - 使用 blit 函数。
    4. 使用此变量并删除新变量(可选,使用del)以不使用额外内存。

    上述步骤的一些示例代码(替换pygame.VIDEORESIZE event if 语句):

            if event.type == pygame.VIDEORESIZE:
                old_surface_saved = surface
                surface = pygame.display.set_mode((event.w, event.h),
                                                  pygame.RESIZABLE)
                # On the next line, if only part of the window
                # needs to be copied, there's some other options.
                surface.blit(old_surface_saved, (0,0))
                del old_surface_saved
    

    【讨论】:

    • 当我在第一个第二个窗口正确停止后运行上面的示例时,在中心绘制调整大小的矩形。
    • 我发现了this open pygame bug。很快:发送 VIDEORESIZE 事件适用于通过移动边缘调整大小,但在尝试移动角后失败。
    【解决方案2】:

    当窗口发生变化时,您不会更新宽度、高度或大小。

    来自文档:http://www.pygame.org/docs/ref/display.html

    如果显示设置了 pygame.RESIZABLE 标志, pygame.VIDEORESIZE 事件将在用户调整时发送 窗口尺寸。

    您可以从VIDEORESIZEhttp://www.pygame.org/docs/ref/event.html活动中获得新的size, w, h

    【讨论】:

      【解决方案3】:

      一个可调整大小的简单 Hello World 窗口,另外我还在玩类。
      分为两个文件,一个用于定义颜色常量。

      import pygame, sys
      from pygame.locals import *
      from colors import *
      
      
      # Data Definition
      class helloWorld:
          '''Create a resizable hello world window'''
          def __init__(self):
              pygame.init()
              self.width = 300
              self.height = 300
              DISPLAYSURF = pygame.display.set_mode((self.width,self.height), RESIZABLE)
              DISPLAYSURF.fill(WHITE)
      
          def run(self):
              while True:
                  for event in pygame.event.get():
                      if event.type == QUIT:
                          pygame.quit()
                          sys.exit()
                      elif event.type == VIDEORESIZE:
                          self.CreateWindow(event.w,event.h)
                  pygame.display.update()
      
          def CreateWindow(self,width,height):
              '''Updates the window width and height '''
              pygame.display.set_caption("Press ESC to quit")
              DISPLAYSURF = pygame.display.set_mode((width,height),RESIZABLE)
              DISPLAYSURF.fill(WHITE)
      
      
      if __name__ == '__main__':
          helloWorld().run()
      

      colors.py:

      BLACK  = (0, 0,0)
      WHITE  = (255, 255, 255)
      RED    = (255, 0, 0)
      YELLOW = (255, 255, 0)
      BLUE   = (0,0,255)
      
      GREEN = (0,255,0)
      

      【讨论】:

      • 代码有效,但您应该真正阅读 PEP 8 样式指南。您违反了很多约定,例如CreateWindow 不是一个类,helloWorldthat isDISPLAYSURF 这不是一个常量。另外,请避免在任何地方发送垃圾邮件 from ... import *,特别是因为您没有使用它们(无论如何您都在为所有 pygame 调用添加前缀)
      • @MestreLion,from pygame.locals import * 用于 QUITRESIZEABLEVIDEORESIZE。 pygame 调用不是该导入的一部分...我已提交了一个编辑,但您可能实际上正在查看此示例的早期版本,该版本与 pygame 的导入方式不同。
      【解决方案4】:

      我发现一个简单的方法是下面的代码sn-p

      # Imports
      from vars import *
      from pygame.locals import *
      
      # Main init
      pygame.init()
      
      # Basic vars
      run = True
      s_width = 1000
      s_height = 600
      
      # Making display screen. Don't forget the last tag!
      screen = pygame.display.set_mode((s_width, s_height), RESIZABLE)
      
      # Main loop
      while run:
          # event detection
          for event in pygame.event.get():
              if event.type == QUIT:
                  run = False
              # The part which matters for our purposes
              if event.type == WINDOWRESIZED:
                  s_width, s_height = screen.get_width(), screen.get_height()
              if event.type == KEYDOWN:
                  if event.key == K_ESCAPE:
                      run = False
          # Test line to see if the window resizing works properly
          pygame.draw.line(screen, (255, 255, 255), (int(0.3*s_width), int(0.25*s_height)), (int(0.8*s_width), int(0.25*s_height)))
          # Final flip
          pygame.display.flip()
      
      # Quit
      pygame.quit()
      

      这样做是允许调整 pygame 窗口的大小。但是由于您经常根据 s_width 和 s_height 来放置很多元素/精灵的位置和大小,因此它还会检测窗口大小何时更改并相应地调整尺寸。

      【讨论】:

        【解决方案5】:

        首先,您在重绘屏幕之前没有检测到新的窗口大小。

        在第 45 行添加 get_size() 方法就可以了:

        #--------------------------------------------------------------
        # Draw the grid
        size = pygame.display.get_surface().get_size() // size update
        for row in range(int(math.ceil(size[1]/height))+1):
        #---------------------------------------------------------
        

        然后您使用固定的单元格大小(50、20)并填充尽可能多的单元格。如果您想在调整窗口大小时扩大/缩小单元格,则必须定义每行/行的单元格数量,然后计算单元格大小,然后绘制它们。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-03-07
          • 1970-01-01
          • 2021-04-15
          • 1970-01-01
          • 2016-06-01
          • 2018-02-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多