Python 如何使对象永久地粘在窗口中而不在Pygame中刷新?

Python 如何使对象永久地粘在窗口中而不在Pygame中刷新?,python,python-3.x,pygame,Python,Python 3.x,Pygame,我正在尝试使用Pygame重新创建Atari突破。我遇到了一个问题,我把所有三行的瓷砖放在三个列表中,我想打印它们,让它们在球击中它们之前留在原来的位置 代码如下: import pygame import random pygame.init() screenWidth = 1200 screenHeight = 700 window = pygame.display.set_mode((screenWidth,screenHeight)) pygame.display.set_capt

我正在尝试使用Pygame重新创建Atari突破。我遇到了一个问题,我把所有三行的瓷砖放在三个列表中,我想打印它们,让它们在球击中它们之前留在原来的位置

代码如下:

import pygame
import random

pygame.init()

screenWidth = 1200
screenHeight = 700

window = pygame.display.set_mode((screenWidth,screenHeight))
pygame.display.set_caption('Atari Breakout')

pygame.mouse.set_pos(-500,650)


class Plate():

    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 5

    def draw_plate(self):
        pygame.mouse.set_visible(True)
        pos = pygame.mouse.get_pos()
        self.x = pos[0]-100

        pygame.draw.rect(window, (00,00,255), (self.x, self.y ,self.width, self.height))


class Circle():

    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius
        self.vel_x = 5
        self.vel_y = 5


class Tiles():

    def __init__(self, x, y, width, height, color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.color = color

    def draw(self):
        if self.color == 'red':
            pygame.draw.rect(window, (255,0,0), (self.x, self.y, self.width, self.height))
        elif self.color == 'green':
            pygame.draw.rect(window, (44,176,55), (self.x, self.y, self.width, self.height))
        elif self.color == 'blue':
            pygame.draw.rect(window, (0,191,255), (self.x, self.y, self.width, self.height))
        pygame.display.update()


def draw_titles():
    first_row = []
    second_row = []
    third_row = []
    preset_width1 = [70, 120, 200, 30, 240, 140, 130, 120, 80]                       # nine elements
    preset_width2 = [70, 120, 200, 30, 240, 140, 130, 120, 80]
    preset_width3 = [70, 120, 200, 30, 240, 140, 130, 120, 80]
    random.shuffle(preset_width1)
    random.shuffle(preset_width2)
    random.shuffle(preset_width3)
    #print(f'preset_width1 is: {preset_width1}')
    put_width1 = []
    put_width2 = []
    put_width3 = []

    for t in range(1,10):

        if t==1:
            width = preset_width1.pop(0)
            put_width1.append(width)
            #print(f'put_width1 is: {put_width1}')


        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width1)
            #print(f'add is: {add}')
            x = t*5 + add
            #print(f'x is: {x}')

        if t>1:
            width = preset_width1.pop(0)
            put_width1.append(width)
            #print(f'put_width1 is: {put_width1}')

        y = 125

        height = 35


        first_row.append(Tiles(x,y,width,height,'red'))

        if t == 9:
            break

    for t in range(1,10):

        if t==1:
            width = preset_width2.pop(0)
            put_width2.append(width)

        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width2)
            x = t*5 + add

        if t>1:
            width = preset_width2.pop(0)
            put_width2.append(width)

        y = 170

        height = 35

        second_row.append(Tiles(x,y,width,height,'green'))

        if t == 9:
            break

    for t in range(1,10):

        if t==1:
            width = preset_width3.pop(0)
            put_width3.append(width)

        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width3)
            x = t*5 + add

        if t>1:
            width = preset_width3.pop(0)
            put_width3.append(width)

        y = 215

        height = 35

        third_row.append(Tiles(x,y,width,height,'blue'))

        if t == 9:
            break


    for num in range(0,9):
        first_row[num].draw()

    for num in range(0,9):
        second_row[num].draw()

    for num in range(0,9):
        third_row[num].draw()

    keys = pygame.key.get_pressed()
    if keys[pygame.K_BACKSPACE]:
        run = False







# main loop
plate = Plate(10,650,200,40)
ball = Circle(600,300,10)
run = True
start = False
bounds = pygame.Rect(0, 0, 1200, 700)


while run:
    pygame.time.Clock().tick(120)

    for event in pygame.event.get():
        if event == pygame.QUIT:
            run = False


    plate.draw_plate()



    keys = pygame.key.get_pressed()


    # bounce algorithem 
    if keys[pygame.K_SPACE]:
        start = True

    if start:
        ball.y -= ball.vel_y        
        ball.x += ball.vel_x

        if ball.x - ball.radius < bounds.left or ball.x + ball.radius > bounds.right:
            ball.vel_x *= -1 
        if ball.y - ball.radius < bounds.top or ball.y + ball.radius > bounds.bottom:
            ball.vel_y *= -1 

    pygame.draw.rect(window, (0, 0, 0), bounds, 1)
    pygame.draw.circle(window, (44,176,55), (ball.x, ball.y), ball.radius)
    #pygame.display.update()


    draw_titles()



    # close call
    if keys[pygame.K_BACKSPACE]:
        run = False
        break





    window.fill((0,0,0))
    pygame.display.update()




pygame.quit()
导入pygame
随机输入
pygame.init()
屏幕宽度=1200
屏幕高度=700
window=pygame.display.set_模式((屏幕宽度、屏幕高度))
pygame.display.set_标题('Atari Breakout'))
pygame.mouse.set_pos(-500650)
类板():
定义初始值(自、x、y、宽度、高度):
self.x=x
self.y=y
self.width=宽度
自我高度=高度
self.vel=5
def牵引板(自):
pygame.mouse.set_可见(True)
pos=pygame.mouse.get_pos()
self.x=位置[0]-100
pygame.draw.rect(窗口,(00,00255),(self.x,self.y,self.width,self.height))
类圆():
定义初始(自、x、y、半径):
self.x=x
self.y=y
自半径=半径
self.vel_x=5
self.vel_y=5
类Tiles():
定义初始值(自、x、y、宽度、高度、颜色):
self.x=x
self.y=y
self.width=宽度
自我高度=高度
self.color=颜色
def牵引(自):
如果self.color==“红色”:
pygame.draw.rect(窗口,(255,0,0),(self.x,self.y,self.width,self.height))
elif self.color==“绿色”:
pygame.draw.rect(窗口,(44176,55),(self.x,self.y,self.width,self.height))
elif self.color==“蓝色”:
pygame.draw.rect(窗口,(0191255),(self.x,self.y,self.width,self.height))
pygame.display.update()
def draw_titles():
第一行=[]
第二行=[]
第三行=[]
预设宽度1=[70、120、200、30、240、140、130、120、80]#九个元素
预设宽度2=[70、120、200、30、240、140、130、120、80]
预设宽度3=[70、120、200、30、240、140、130、120、80]
随机洗牌(预设宽度1)
随机洗牌(预设宽度2)
随机洗牌(预设宽度3)
#打印(f'preset_width1为:{preset_width1}')
放置宽度1=[]
放置宽度2=[]
放置宽度3=[]
对于范围(1,10)内的t:
如果t==1:
宽度=预设宽度1.pop(0)
put_width1.追加(宽度)
#打印(f'put_width1为:{put_width1}')
如果t==1:
x=0+5
其他:
加法=总和(1)
#打印(f'add为:{add}')
x=t*5+相加
#打印(f'x为:{x}')
如果t>1:
宽度=预设宽度1.pop(0)
put_width1.追加(宽度)
#打印(f'put_width1为:{put_width1}')
y=125
高度=35
第一行。追加(平铺(x,y,宽度,高度,'red'))
如果t==9:
打破
对于范围(1,10)内的t:
如果t==1:
宽度=预设宽度2.pop(0)
put_width2.追加(宽度)
如果t==1:
x=0+5
其他:
加法=总和(2)
x=t*5+相加
如果t>1:
宽度=预设宽度2.pop(0)
put_width2.追加(宽度)
y=170
高度=35
第二行。追加(平铺(x,y,宽度,高度,'green'))
如果t==9:
打破
对于范围(1,10)内的t:
如果t==1:
宽度=预设宽度3.弹出(0)
放置宽度3.追加(宽度)
如果t==1:
x=0+5
其他:
加法=总和(3)
x=t*5+相加
如果t>1:
宽度=预设宽度3.弹出(0)
放置宽度3.追加(宽度)
y=215
高度=35
第三行。追加(平铺(x,y,宽度,高度,'blue'))
如果t==9:
打破
对于范围(0,9)中的num:
第一行[num].draw()
对于范围(0,9)中的num:
第二行[num].draw()
对于范围(0,9)中的num:
第三行[num].draw()
keys=pygame.key.get_pressed()
如果键[pygame.K_BACKSPACE]:
运行=错误
#主回路
板=板(10650200,40)
球=圆(600300,10)
运行=真
开始=错误
bounds=pygame.Rect(0,0,1200,700)
运行时:
pygame.time.Clock().tick(120)
对于pygame.event.get()中的事件:
如果event==pygame.QUIT:
运行=错误
板。绘制板()
keys=pygame.key.get_pressed()
#反弹算法
如果键[pygame.K_SPACE]:
开始=真
如果启动:
ball.y-=ball.vel_y
ball.x+=ball.vel_x
如果ball.x-ball.radiusbounds.right:
ball.vel_x*=-1
如果ball.y-ball.radiusbounds.bottom:
ball.vel_y*=-1
pygame.draw.rect(窗口,(0,0,0),边界,1)
pygame.draw.circle(窗口,(44176,55),(ball.x,ball.y),ball.radius)
#pygame.display.update()
绘制标题()
#势均力敌
如果键[pygame.K_BACKSPACE]:
运行=错误
打破
窗口填充((0,0,0))
pygame.display.update()
pygame.quit()
这是理想的情况:

但相反,它像疯了一样清新。我知道问题在于我将
draw\u titles()
函数放在主While循环中。但我相信是我编写
draw\u tiles()
函数的方式使它无法工作。如果我将
draw_titles()
放在循环之前,瓷砖将出现并立即消失,球和板都不会显示

我在网上做了一些研究,看到了关于文本和图像的教程。对于图像,他们使用
.blit()
,但我相信这只适用于图像

我尝试了许多变体来解决这个问题,但都没有用。请帮忙

谢谢。

这里有一个快速解决方案:

import pygame
import random

pygame.init()

screenWidth = 1200
screenHeight = 700

window = pygame.display.set_mode((screenWidth,screenHeight))
pygame.display.set_caption('Atari Breakout')

pygame.mouse.set_pos(-500,650)


class Plate():

    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 5

    def draw_plate(self):
        pygame.mouse.set_visible(True)
        pos = pygame.mouse.get_pos()
        self.x = pos[0]-100

        pygame.draw.rect(window, (00,00,255), (self.x, self.y ,self.width, self.height))


class Circle():

    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius
        self.vel_x = 5
        self.vel_y = 5


class Tiles():

    def __init__(self, x, y, width, height, color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.color = color

    def draw(self):
        if self.color == 'red':
            pygame.draw.rect(window, (255,0,0), (self.x, self.y, self.width, self.height))
        elif self.color == 'green':
            pygame.draw.rect(window, (44,176,55), (self.x, self.y, self.width, self.height))
        elif self.color == 'blue':
            pygame.draw.rect(window, (0,191,255), (self.x, self.y, self.width, self.height))

first_row = []
second_row = []
third_row = []

def create_titles():
    preset_width1 = [70, 120, 200, 30, 240, 140, 130, 120, 80]                       # nine elements
    preset_width2 = [70, 120, 200, 30, 240, 140, 130, 120, 80]
    preset_width3 = [70, 120, 200, 30, 240, 140, 130, 120, 80]
    random.shuffle(preset_width1)
    random.shuffle(preset_width2)
    random.shuffle(preset_width3)
    #print(f'preset_width1 is: {preset_width1}')
    put_width1 = []
    put_width2 = []
    put_width3 = []

    for t in range(1,10):

        if t==1:
            width = preset_width1.pop(0)
            put_width1.append(width)
            #print(f'put_width1 is: {put_width1}')


        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width1)
            #print(f'add is: {add}')
            x = t*5 + add
            #print(f'x is: {x}')

        if t>1:
            width = preset_width1.pop(0)
            put_width1.append(width)
            #print(f'put_width1 is: {put_width1}')

        y = 125

        height = 35


        first_row.append(Tiles(x,y,width,height,'red'))

        if t == 9:
            break

    for t in range(1,10):

        if t==1:
            width = preset_width2.pop(0)
            put_width2.append(width)

        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width2)
            x = t*5 + add

        if t>1:
            width = preset_width2.pop(0)
            put_width2.append(width)

        y = 170

        height = 35

        second_row.append(Tiles(x,y,width,height,'green'))

        if t == 9:
            break

    for t in range(1,10):

        if t==1:
            width = preset_width3.pop(0)
            put_width3.append(width)

        if t==1:
            x = 0 + 5
        else:
            add = sum(put_width3)
            x = t*5 + add

        if t>1:
            width = preset_width3.pop(0)
            put_width3.append(width)

        y = 215

        height = 35

        third_row.append(Tiles(x,y,width,height,'blue'))

        if t == 9:
            break

# main loop
plate = Plate(10,650,200,40)
ball = Circle(600,300,10)
run = True
start = False
bounds = pygame.Rect(0, 0, 1200, 700)

create_titles()

while run:
    pygame.time.Clock().tick(120)

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

    keys = pygame.key.get_pressed()
    # bounce algorithem 
    if keys[pygame.K_SPACE]:
        start = True
    # close call
    if keys[pygame.K_BACKSPACE]:
        run = False
        break

    if start:
        ball.y -= ball.vel_y        
        ball.x += ball.vel_x

        if ball.x - ball.radius < bounds.left or ball.x + ball.radius > bounds.right:
            ball.vel_x *= -1 
        if ball.y - ball.radius < bounds.top or ball.y + ball.radius > bounds.bottom:
            ball.vel_y *= -1 

    window.fill((0,0,0))
    plate.draw_plate()
    pygame.draw.rect(window, (0, 0, 0), bounds, 1)
    pygame.draw.circle(window, (44,176,55), (ball.x, ball.y), ball.radius)
    for tile in first_row:
        tile.draw()
    for tile in second_row:
        tile.draw()
    for tile in third_row:
        tile.draw()

    pygame.display.update()

pygame.quit()
请注意,所有与绘图相关的内容是如何放在一个地方的。这样,它更清晰,更容易混淆

您应该确保只调用pygame.display
.flip()
(或
.upda
    ...
    window.fill((0,0,0))
    plate.draw_plate()
    pygame.draw.rect(window, (0, 0, 0), bounds, 1)
    pygame.draw.circle(window, (44,176,55), (ball.x, ball.y), ball.radius)
    for tile in first_row:
        tile.draw()
    for tile in second_row:
        tile.draw()
    for tile in third_row:
        tile.draw() 
    ...
import pygame
import random

class Paddle(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height, bounds, *grps):
        super().__init__(*grps)
        self.image = pygame.Surface((width, height))
        self.image.fill((0,0,255))
        self.rect = self.image.get_rect(topleft=(x, y))
        self.bounds = bounds

    def update(self, dt):
        pos = pygame.mouse.get_pos()
        self.rect.centerx = pos[0]
        self.rect.clamp_ip(self.bounds)

class Circle(pygame.sprite.Sprite):

    def __init__(self, x, y, radius, bounds, *grps):
        super().__init__(*grps)
        self.image = pygame.Surface((radius, radius))
        self.image.set_colorkey((1, 2, 3))
        self.image.fill((1, 2, 3))
        self.rect = self.image.get_rect(topleft=(x, y))
        pygame.draw.circle(self.image, (44,176,55), (radius//2, radius//2), 5)
        self.vel = pygame.Vector2((5, 5))
        self.pos = self.rect.center
        self.bounds = bounds

    def update(self, dt):
        self.pos += self.vel * min(dt/15, 10)
        self.rect.center = self.pos

        if self.rect.left < self.bounds.left or self.rect.right > self.bounds.right:
            self.vel.x *= -1
        if self.rect.top < self.bounds.top or self.rect.bottom > self.bounds.bottom:
            self.vel.y *= -1

        self.rect.clamp_ip(self.bounds)

    def bounce(self, sprite):
        if self.rect.top <= sprite.rect.top or sprite.rect.bottom >= sprite.rect.bottom:
            self.vel.y *= -1
        elif self.rect.left <= sprite.rect.left or sprite.rect.right >= sprite.rect.right:
            self.vel.x *= -1


class Tiles(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height, color,  *grps):
        super().__init__(*grps)
        self.image = pygame.Surface((width, height))
        self.image.fill(color)
        self.rect = self.image.get_rect(topleft=(x, y))

    def hit(self):
        self.kill()

def main():
    pygame.init()
    screen = pygame.display.set_mode((1200, 700))
    screen_rect = screen.get_rect()
    pygame.display.set_caption('Atari Breakout')

    sprites = pygame.sprite.Group()
    tiles = pygame.sprite.Group()
    paddle = Paddle(10,650,200,40, screen_rect, sprites)
    ball = Circle(600,300,10, screen_rect, sprites)

    preset = [70, 120, 200, 30, 240, 140, 130, 120, 80]
    y = 215
    for color in ['blue', 'green', 'red']:
        x = 5
        line = preset[:]
        random.shuffle(line)
        for width in line:
            Tiles(x, y, width, 35, pygame.Color(color), sprites, tiles)
            x += width + 5
        y -= 45

    dt = 0
    clock = pygame.time.Clock()
    while True:
        pygame.time.Clock().tick(120)

        # events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_BACKSPACE:
                    return

        # game logic
        tile = pygame.sprite.spritecollideany(ball, tiles)
        if tile:
            tile.hit()
            ball.bounce(tile)

        if pygame.sprite.collide_rect(paddle, ball):
            ball.bounce(paddle)

        sprites.update(dt)

        # drawing
        screen.fill((0,0,0))
        sprites.draw(screen)
        pygame.draw.rect(screen, (0, 0, 0), screen_rect, 1)

        pygame.display.update()
        dt = clock.tick(120)

    pygame.quit()

if __name__ == '__main__':
    main()