【问题标题】:Python PyGame draw rectangles using for loopPython PyGame 使用 for 循环绘制矩形
【发布时间】:2014-12-23 22:02:46
【问题描述】:

我是 PyGame 的新手,我正在学习使用 Python 和 PyGame 开始游戏开发这本书。有一个示例(清单 4-9),作者说脚本将在 PyGame 屏幕上绘制十个随机放置、随机着色的矩形。这是书中的代码:

import pygame 
from pygame.locals import *
from sys import exit
from random import *

pygame.init()

screen = pygame.display.set_mode((640, 480), 0,32)
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
    screen.lock()
    for count in range(10):
        random_color = (randint(0,255), randint(0,255), randint(0,255))
        random_pos = (randint(0,639), randint(0,479))
        random_size = (639-randint(random_pos[0], 639), 479-randint(random_pos[1],479))
        pygame.draw.rect(screen, random_color, Rect(random_pos, random_size))
    screen.unlock()
    pygame.display.update()

当我这样做时会发生什么(这是我在逻辑上期望发生的)是它绘制了无限多的矩形。它只是继续执行 for 循环,因为 while 循环始终为 True。我已经在网上搜索过这个,我尝试移动显示更新,但这些东西没有用。它快把我逼疯了!

谢谢!

【问题讨论】:

  • 这解决了你的问题吗?
  • 代码确实无限运行。但是,内部循环确实创建了 10 个矩形。所以从技术上讲,该脚本确实绘制了十个随机放置、随机着色的矩形。它只是做了无数次。

标签: python pygame


【解决方案1】:

看起来你已经知道为什么它用矩形绘制无限了。

我猜你想一次绘制 10 个随机大小、位置和颜色的随机矩形。

那么你可以这样做:

import pygame 
from pygame.locals import *
from sys import exit
from random import *

pygame.init()

screen = pygame.display.set_mode((640, 480), 0,32)

class Rectangle:
    def __init__(self, pos, color, size):
        self.pos = pos
        self.color = color
        self.size = size
    def draw(self):
        pygame.draw.rect(screen, self.color, Rect(self.pos, self.size))

rectangles = []     

for count in range(10):
    random_color = (randint(0,255), randint(0,255), randint(0,255))
    random_pos = (randint(0,639), randint(0,479))
    random_size = (639-randint(random_pos[0], 639), 479-randint(random_pos[1],479))

    rectangles.append(Rectangle(random_pos, random_color, random_size))



while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
    screen.lock()
    for rectangle in rectangles:
        rectangle.draw()
    screen.unlock()
    pygame.display.update()

【讨论】:

    【解决方案2】:

    代码确实无限运行。 但是,内部循环确实创建了 10 个矩形。 所以从技术上讲,该脚本确实绘制了十个随机放置、随机着色的矩形。 它只是无限次地这样做。

    注意:这是绘制十个随机放置、随机着色的矩形的部分。

    for count in range(10):
            random_color = (randint(0,255), randint(0,255), randint(0,255))
            random_pos = (randint(0,639), randint(0,479))
            random_size = (639-randint(random_pos[0], 639), 479-randint(random_pos[1],479))
            pygame.draw.rect(screen, random_color, Rect(random_pos, random_size))
    

    【讨论】:

      【解决方案3】:

      它会画很多矩形,而且是无穷无尽的。它没有画10次,因为除了-sys exit-没有参数说打破while循环。所以你必须为此定义一个变量。

      event 语句中通常应该有一个 if 语句,它将 while 的布尔值更改为 False em> 它将停止循环。

      您只需将代码更改为:

      import pygame 
      from pygame.locals import *
      from sys import exit
      from random import *
      
      pygame.init()
      
      screen = pygame.display.set_mode((640, 480), 0,32)
      count=0 #new variable for stop the loop
      while count<10: #new limit
          for event in pygame.event.get():
              if event.type == QUIT:
                  exit()
          screen.lock()
      
          random_color = (randint(0,255), randint(0,255), randint(0,255))
          random_pos = (randint(0,639), randint(0,479))
          random_size = (639-randint(random_pos[0], 639), 479-randint(random_pos[1],479))
          pygame.draw.rect(screen, random_color, Rect(random_pos, random_size))
          count+=1 #variable updating after drawing each rectangle
      
          screen.unlock()
          pygame.display.update()
      

      我不知道这可能是书中的错误输入,但该循环是无限的,因此您可以将其更改为:)

      【讨论】:

      • 有一个 if 语句:if event.type == QUIT: 我同意这个例子写得不好,但它没有坏。
      【解决方案4】:

      是的,这是一个写得很糟糕的例子,但它并没有“损坏”。到目前为止大家都忽略了这一点:

      for event in pygame.event.get():
          if event.type == QUIT:
              exit()
      

      PyGame 包含处理事件的概念。第一行获取您的游戏可以访问的所有事件,并查看每个事件。如果其中一个是“QUIT”事件,则直接调用exit()(通常称为sys.exit(0)),立即结束应用程序。

      当您退出应用程序时会生成“QUIT”类型的事件,例如通过单击红色 X。可能还有其他结束应用程序的方法也会生成此事件,但我不确定它们是什么.还有一些方法可以结束不会生成此事件的应用程序。所以是的,如果你从不退出应用程序,它将永远运行。

      编写此功能的更好方法如下:

      done = False
      while not done:
          for event in pygame.event.get():
              if event.type == QUIT: # or other types of events
                  done = True
          //do other game logic and drawing stuff after this
          pygame.display.update()
      

      这样可以确保循环处理一致,并且退出点始终在同一个位置:循环的顶部。如果只有一个地方可以退出循环,那么您可以更轻松地了解有多少代码正在运行(全部)。它还允许您有一些更复杂的方法来决定何时以及是否结束循环。

      但是,即使这将是一个非常令人困惑的“示例”,因为(就像您和 @user3679917 指出的那样)它似乎做了一些与描述不同的事情。 似乎它只是永远地绘制随机矩形。让我们看看我们是否可以让它更可预测......

      //pre-roll the random numbers before the while loop
      random_attributes = []
      for count in range(10):
          random_color = (randint(0,255), randint(0,255), randint(0,255))
          random_pos = (randint(0,639), randint(0,479))
          random_size = (639-randint(random_pos[0], 639), 479-randint(random_pos[1],479))
          random_attributes.append(random_color, random_pos, random_size)
      
      //then when you draw, just draw what you already rolled each time, without rolling new stats
      done = False
      while not done:
          for event in pygame.event.get():
              if event.type == QUIT: # or other types of events
                  done = True
          //do other game logic and drawing stuff after this
          for color, position, size in random_attributes:
              pygame.draw.rect(screen, color, Rect(position, size))
          pygame.display.update()
      

      这将无限绘制相同的东西,直到您关闭应用程序。顺便说一句,这也是(几乎)所有视觉应用程序一直在做的事情,即每次都绘制所有内容。并不是说你可以在屏幕上画一次就留下来。每次绘制屏幕时,屏幕都会询问每个人“好吧,伙计们,现在屏幕上发生了什么”,除非您的应用程序说“绘制这些东西”,否则它不会被绘制,即使它是上次绘制的.

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-21
        相关资源
        最近更新 更多