Python 如何使对象永久地粘在窗口中而不在Pygame中刷新?
我正在尝试使用Pygame重新创建Atari突破。我遇到了一个问题,我把所有三行的瓷砖放在三个列表中,我想打印它们,让它们在球击中它们之前留在原来的位置 代码如下: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
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()