Понимание бесконечных циклов while в python - PullRequest
0 голосов
/ 29 апреля 2020

Вы можете сделать бесконечно продолжительное окно всплывающим, используя бесконечное время, пока l oop in python:

import pygame

#Game-loop

while True:

    # Initialize the pygame
    pygame.init()

    # create the screen
    screen = pygame.display.set_mode((800, 600))

    # Title and icon
    pygame.display.set_caption("RPS Pro")
    icon = pygame.image.load('icon.png')
    pygame.display.set_icon(icon)

Теперь этот код делает то, что мы хотим, и он также имеет смысл. Когда мы вводим наш код внутри бесконечного while-l oop, он работает вечно. Но я попробовал что-то другое:

import pygame

# Initialize the pygame
pygame.init()

#create the screen
screen = pygame.display.set_mode((800, 600))

#Title and icon
pygame.display.set_caption("RPS Pro")
icon = pygame.image.load('icon.png')
pygame.display.set_icon(icon)

#Game-loop
while True:
    pass

Удивительно, но это также может создать бесконечно продолжительное окно. Это странно Код не находится внутри цикла while; почему тогда он делает то, что мы хотим? Это правда, что while-l oop все еще бесконечно, но наш код не находится внутри while-l oop. Почему это работает тогда?

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Я попытаюсь дать вам общее представление:

Ваш код - не единственный код, работающий на вашем компьютере. Есть также вещи, называемые операционными системами, дисплеями дисплеев, драйверами устройств и многим другим.

Поэтому, когда вы звоните, например,

pygame.display.set_mode((800, 600))

, это не ваш код волшебным образом создает окно на вашем рабочем столе. Вы кодируете функции в модуле pygame, который, в свою очередь, вызывает функции библиотеки SDL, которая, в свою очередь, вызывает функции операционной системы (или диспетчера отображения в не Windows системах).

Так что, если вы включены Windows, вызывается функция CreateWindow, которая побуждает Windows к создать окно . Windows также создает очередь сообщений для потока ваших приложений, которая позволяет межпроцессное взаимодействие между вашим приложением, окном и операционной системой (или диспетчером отображения; на * 1038) * это dwm.exe).

Это называется Event-driven programming. Одна часть (окно, созданное и запускаемое диспетчером отображения) связывается с другой частью (вашим приложением python) через события. И это также причина, по которой вам нужно вызывать pygame.event.get() в вашем приложении: для обработки сообщения l oop. На не Windows системе это работает аналогично; на Linux вы, вероятно, используете Xlib для внутреннего использования.


Подумайте о том, что происходит при перемещении мыши: есть драйвер устройства, транслирующий сигналы с вашего оборудования в команды для диспетчера дисплея. Есть драйвер, который отвечает за рисование курсора мыши на экране. Диспетчер дисплеев управляет windows.

Поэтому, когда вы, наконец, нажмете перекрестную кнопку, менеджер дисплея поместит событие в очередь сообщений потока вашего приложения. Пока что ваш код не участвует ни в одной из этих вещей. Окно управляется и запускается диспетчером отображения.

Пока ваше приложение работает, окно будет оставаться открытым, поскольку оно связано с потоком вашего приложения.

0 голосов
/ 29 апреля 2020

Окно появляется, потому что вы не вышли из него, и пока l oop бесконечно l oop. Начиная с этого код выполняется до тех пор, пока вы не окажетесь внутри l oop. также попробуйте сделать движение объекта или анимацию, если вы заметите, что он не будет обновлен, потому что код не в том, как игра работает, когда мы делаем это правильно, тогда ? => Ваш код постоянно обновляется внутри l oop и все работает. (как это пример игры)

import pygame
import time
import numpy as np
gravity =0
pygame.init()
gamewin = pygame.display.set_mode((650,400))
pygame.display.set_caption("flappy bird ")

bg = pygame.image.load("background-day.png")
pipes = pygame.image.load("pipe-green.png")
flipped_pipes = pygame.transform.flip(pipes,1,1)
play = [pygame.image.load("bird.png"),pygame.image.load("bird2.png"),pygame.image.load("bird3.png"),pygame.image.load("bird.png"),pygame.image.load("bird2.png"),pygame.image.load("bird3.png"),pygame.image.load("bird.png"),pygame.image.load("bird2.png"),pygame.image.load("bird3.png")]

pipe = False

def text_objects(text, font):
    textSurface = font.render(text, True,(0,0,0))
    return textSurface, textSurface.get_rect()
def message_display(text):
    largeText = pygame.font.Font('freesansbold.ttf',70)
    TextSurf, TextRect = text_objects(text, largeText)
    TextRect.center = ((700/2),(400/2))
    gamewin.blit(TextSurf, TextRect)
    pygame.display.update()
    time.sleep(2)



def seecollisions(x1,y1,w1,h1,x2,y2,w2,h2):
    if(x2+w2>=x1>=x2 and y2+h2>=y1>=y2):
        return True
    elif(x2+w2>=x1+w1>=x2 and y2+h2>=y1>=y2):
        return True
    elif(x2+w2>=x1>=x2 and y2+h2>=y1+h1>=y2):
        return True
    elif(x2+w2>=x1+w1>=x2 and y2+h2>=y1+h1>=y2):
        return True
    else:
        return False


class birdy(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.pipe = False
        self.jumpcount= 0
        self.space = False
        self.hitbox= (self.x,self.y,self.width,self.height)
        self.rect = pygame.Rect(self.hitbox)

    def draw(self,win,obj):
        if self.jumpcount+1 > 27:
            self.jumpcount =0

        if self.space:

            win.blit(pygame.transform.rotate(obj[self.jumpcount//3],6%360),(self.x,self.y))
            #pygame.draw.rect(gamewin,(255,0,0),self.hitbox,2)



        else:

            win.blit(pygame.transform.rotate(obj[self.jumpcount//3],-6%360),(self.x,self.y))

            self.hitbox= (self.x,self.y,self.width,self.height)

            #pygame.draw.rect(gamewin,(255,0,0),self.hitbox,2)
            self.rect = pygame.Rect(self.hitbox)


        self.jumpcount +=1



class piper(pygame.sprite.Sprite):
    def __init__(self,box_x,box_y,bxuppery,width,height):
        self.width = width
        self.height = height
        self.box_x =box_x
        self.box_y = box_y
        self.bxuppery = bxuppery
        self.hitbox= (self.box_x,self.box_y,64,64)
        self.rect = pygame.Rect(self.hitbox)
        self.hitboxup= (self.box_x,self.box_y-self.bxuppery,self.width,self.height-180)



    def draw(self,win,obj,fobj):
        win.blit(obj,(self.box_x,self.box_y))
        self.hitbox= (self.box_x,self.box_y,self.width,self.height)
        self.hitboxup= (self.box_x,self.box_y-self.bxuppery,self.width,self.height-180)


        #pygame.draw.rect(gamewin,(255,0,0),self.hitbox,2)
        #pygame.draw.rect(gamewin,(255,0,0),self.hitboxup,2)

        self.rect = pygame.Rect(self.hitbox)


        win.blit(fobj,(self.box_x,self.box_y-self.bxuppery))



bird = birdy(20,200,34,26)

def redrawgame():

    gamewin.blit(bg,(0,0))
    bird.draw(gamewin,play)

    if pipe:
        pipspawn1.draw(gamewin,pipes,flipped_pipes)
        pipspawn2.draw(gamewin,pipes,flipped_pipes)
        pipspawn3.draw(gamewin,pipes,flipped_pipes)
        pipspawn4.draw(gamewin,pipes,flipped_pipes)




    pygame.display.update()


box_x = 740
box_x2 = box_x + 250
box_x3 = box_x2 + 250
box_x4 = box_x3 +250


rin = True 
upperboxy = 432

collidedpipe = False
box_y1 = np.random.randint(low=100,high=380)
box_y2 = np.random.randint(low=100,high=380)
box_y3 = np.random.randint(low=100,high=380)
box_y4 = np.random.randint(low=100,high=380)
pipspawn1=piper(box_x, box_y1,upperboxy,52,500)
pipspawn2=piper(box_x2, box_y2,upperboxy,52,500)
pipspawn3=piper(box_x3, box_y3,upperboxy,52,500)
pipspawn4=piper(box_x4, box_y4,upperboxy,52,500)
while rin:
    pygame.time.delay(30)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    keys = pygame.key.get_pressed()
    if keys[pygame.K_UP] :

        if collidedpipe == False:
            bird.y-= 25
            bird.space = True
            gravity = 7


    if bird.x < 220:
        bird.x+=2
    if collidedpipe == False:
        bird.y+=1/2 * gravity 
        pygame.time.delay(50)
        gravity +=1.3


    if bird.y > 380:
        collidedpipe = True

    if bird.x > 120:
        pipe = True
        if collidedpipe == False:
            pipspawn1.box_x -= 10
            pipspawn2.box_x -= 10
            pipspawn3.box_x -= 10
            pipspawn4.box_x -= 10

    if pipspawn1.box_x <- 80:   
        pipspawn1.box_x= 880
        pipspawn1.box_y =  np.random.randint(low=100,high=380)


    if pipspawn2.box_x <- 80:   
        pipspawn2.box_x= 880
        pipspawn2.box_y =  np.random.randint(low=100,high=380)


    if pipspawn3.box_x <- 80:   
        pipspawn3.box_x=880
        pipspawn3.box_y =  np.random.randint(low=100,high=380)

    if pipspawn4.box_x <- 80:   
        pipspawn4.box_x= 880
        pipspawn4.box_y =  np.random.randint(low=100,high=380)


    # if score>1:
    #   print("score is",score+1)
    #print(bird.hitbox[0],bird.hitbox[1],bird.hitbox[2],bird.hitbox[3])
    #print(pipspawn1.hitboxup[0],pipspawn1.hitboxup[1],pipspawn1.hitboxup[2],pipspawn1.hitboxup[3])
    collision1 = seecollisions(bird.hitbox[0],bird.hitbox[1],bird.hitbox[2],bird.hitbox[3],pipspawn1.hitboxup[0],pipspawn1.hitboxup[1],pipspawn1.hitboxup[2],pipspawn1.hitboxup[3])
    collision2 = seecollisions(bird.hitbox[0],bird.hitbox[1],bird.hitbox[2],bird.hitbox[3],pipspawn2.hitboxup[0],pipspawn2.hitboxup[1],pipspawn2.hitboxup[2],pipspawn2.hitboxup[3])
    collision3 = seecollisions(bird.hitbox[0],bird.hitbox[1],bird.hitbox[2],bird.hitbox[3],pipspawn3.hitboxup[0],pipspawn3.hitboxup[1],pipspawn3.hitboxup[2],pipspawn3.hitboxup[3])
    collision4 = seecollisions(bird.hitbox[0],bird.hitbox[1],bird.hitbox[2],bird.hitbox[3],pipspawn4.hitboxup[0],pipspawn4.hitboxup[1],pipspawn4.hitboxup[2],pipspawn4.hitboxup[3])
    #print(collision1,collision2,collision3,collision4)
    if(collision2 or collision1 or collision3 or collision4):
        collidedpipe= True
    if(pygame.sprite.collide_rect(bird,pipspawn1)):
        collidedpipe = True
    if(pygame.sprite.collide_rect(bird,pipspawn2)):
        collidedpipe = True
    if(pygame.sprite.collide_rect(bird,pipspawn3)):
        collidedpipe = True
    if(pygame.sprite.collide_rect(bird,pipspawn4)):
        collidedpipe = True
    if collidedpipe:
        message_display("Game over")
        box_y1 = np.random.randint(low=100,high=380)
        box_y2 = np.random.randint(low=100,high=380)
        box_y3 = np.random.randint(low=100,high=380)
        box_y4 = np.random.randint(low=100,high=380)
        pipspawn1=piper(box_x, box_y1,upperboxy,52,500)
        pipspawn2=piper(box_x2, box_y2,upperboxy,52,500)
        pipspawn3=piper(box_x3, box_y3,upperboxy,52,500)
        pipspawn4=piper(box_x4, box_y4,upperboxy,52,500)

        bird = birdy(20,200,34,26)
        collidedpipe = False

    redrawgame()
    bird.space = False

pygame.quit()

В примере вы можете видеть, что l oop содержит только те части, где экран должен быть обновлен. и это то, что нужно go, там вы можете использовать его только для вызова функции (которая обновляет экран), и она все равно будет работать нормально

...