2014-12-23 2 views
1

Я новичок в PyGame, и я изучаю, используя книгу «Начало разработки игр с Python и PyGame». Существует пример (листинг 4-9), где автор говорит, что скрипт будет рисовать десять случайно размещенных, случайно окрашенных прямоугольников на экране PyGame. Вот код из книги:Python 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 всегда прав. Я искал в Интернете об этом, и я попробовал переместить обновление дисплея, но эти вещи не сработали. Это сводит меня с ума!

Спасибо!

+0

Решена ли ваша проблема? – GLHF

+0

Код действительно работает бесконечно. Однако внутренний цикл создает 10 прямоугольников. Так что технически сценарий рисует десять случайно расположенных, случайно окрашенных прямоугольников. Он просто делает это бесконечное количество раз. – c0deMonk3y

ответ

0

Он будет рисовать много прямоугольников, и его бесконечный да. Он не рисует 10 раз, потому что нет аргументов, говорит, что разрывает , а loop except -sys exit-. Поэтому вам нужно определить переменную для этого.

Обычно должен быть если заявления в событии заявления , что изменит булеву в то время как к ложным и остановит цикл.

Вы можете просто изменить свои коды:

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() 

Его, может быть, misstyping в книге я не знаю, но что цикл бесконечен, так что вы можете изменить его на это :)

+0

Существует инструкция if: 'if event.type == QUIT:' Я согласен, что пример плохо написан, но он не сломан. – Matt

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() 
1

Код мчит бесконечно. Однако внутренний цикл создает 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)) 
0

Да, это плохо написанный пример, но он не «сломан». Все до сих пор упускают из виду этот бит:

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() 

Это будет делать то же самое бесконечно, пока вы не закроете приложение. Кстати, это тоже то, что (почти) все визуальные приложения делают все время, т. Е. Рисуют все каждый раз. Это не так, как будто вы можете нарисовать его на экране один раз, и он остается. Каждый раз, когда экран рисуется, экран спрашивает всех «Хорошо, ребята, что происходит на экране прямо сейчас», и если ваше приложение не говорит «нарисуйте это», тогда это не получится, даже если оно было нарисовано в последний раз ,

Надеюсь, это поможет.

Смежные вопросы