pygame中的重复绘图

问题描述 投票:1回答:1

我正在使用pygame制作BrickBreaker / Breakout游戏。我希望我的游戏创建一排排砖块,直到一排砖块击中桨,但我不知道该怎么做。目前,它仅创建1排砖。我还想使砖块在球撞击时消失。目前,当打砖时,它们只是移出屏幕,但我希望将它们永久删除。

谢谢!

我当前的代码:

# Brick Breaker Game

import pygame
import random

# Initialize the pygame
pygame.init()

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

# background
background = pygame.image.load("realBackground.png")

# Title and Icon
pygame.display.set_caption("Brick Breaker")
icon = pygame.image.load("Brick Breaker Icon.png")
pygame.display.set_icon(icon)

# Paddle
paddleImage = pygame.image.load("scaledPaddle.png")
paddleX = 335
paddleY = 550
paddleX_change = 0

# BrickCoordinates
brickX = []
brickY = []
brickX_change = []
brickY_change = []
numOfBricks = 6

brickXValue = 15
for i in range(numOfBricks):
    brickX.append(brickXValue)
    brickY.append(0)
    brickX_change.append(0.3)
    brickY_change.append(0)
    # Add 120 if thick lines in middle bricks
    # Add 110 if uniform thickness
    brickXValue += 130


#Bricks
yellowBrickImage = pygame.image.load("yellowBrick.png")
greenBrickImage = pygame.image.load("greenBrick.png")
blueBrickImage = pygame.image.load("blueBrick.png")
pinkBrickImage = pygame.image.load("pinkBrick.png")

# ball
ballImage = pygame.image.load("Ball.png")
ballX = 380
ballY = 280
ballX_change = 1.5
ballY_change = 1.5

#Score
scoreValue = 0
font = pygame.font.Font("Neufreit-ExtraBold.otf",24)
textX = 10
textY = 10

def showScore(x,y):
    score = font.render("Score : " + str(scoreValue), True, (255,255,255))
    screen.blit(score,(x,y))

def paddle(x, y):
    screen.blit(paddleImage, (x, y))

def yellowBrick(x, y, i):
    screen.blit(yellowBrickImage, (x, y))

def greenBrick(x, y, i):
    screen.blit(greenBrickImage, (x, y))

def blueBrick(x, y, i):
    screen.blit(blueBrickImage, (x, y))

def pinkBrick(x, y, i):
    screen.blit(pinkBrickImage, (x, y))

def ball(x, y):
    screen.blit(ballImage, (x, y))

#To pick random brick colours
colourOfBrick = []
for i in range(numOfBricks):
    colourOfBrick.append(random.randint(1,4))



# Game Loop (makes sure game is always running)
running = True

while running:
    # To change background colour
    screen.fill((128, 128, 128))
    # background image
    screen.blit(background, (0, 0))

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

        # If keystroke is pressed check whether left or right
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                paddleX_change = -5
            if event.key == pygame.K_RIGHT:
                paddleX_change = 5
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                paddleX_change = 0

    # Checking boudries of paddle
    paddleX += paddleX_change

    if paddleX <= 0:
        paddleX = 0
    elif paddleX >= 669:
        paddleX = 669

    #Draw Rectangles around bricks
    brickRect = []
    for i in range(numOfBricks):
        brickRect.append(pygame.draw.rect(screen, (0, 0, 0), (brickX[i], brickY[i], 120, 42),1))

    # Brick Movement
    for i in range(numOfBricks):
        brickY[i] += brickY_change[i]
        if brickY[i] <= 0:
            brickY_change[i] = 0.3
        elif brickY[i] >= 500:
            brickY_change[i] = -0.3
        # Makes brick show up on screen
        if colourOfBrick[i] == 1:
            yellowBrick(brickX[i], brickY[i], i)
        elif colourOfBrick[i] == 2:
            greenBrick(brickX[i], brickY[i], i)
        elif colourOfBrick[i] == 3:
            blueBrick(brickX[i], brickY[i], i)
        elif colourOfBrick[i] == 4:
            pinkBrick(brickX[i], brickY[i], i)

    # Ball Movement and boundary checking
    ballX += ballX_change

    if ballX <= 0:
        ballX_change *= -1
    elif ballX >= 760:
        ballX_change *= -1

    ballY += ballY_change

    if ballY <= 0:
        ballY_change *= -1
    elif ballY >= 560:
        ballX = 380
        ballY = 280


    # Paddle and Ball Collision
    if ballY > 530 and ballY < 535 and (ballX+20) < paddleX + 131 and (ballX+20) > paddleX:
        ballY_change *= -1

    paddle(paddleX, paddleY)
    ballCircle = pygame.draw.circle(screen, (255,0,0), (int(ballX+20),int(ballY+20)) ,20)
    ball(ballX, ballY)

    #Ball and Brick Collision
    for i in range (numOfBricks):
        if ballCircle.colliderect(brickRect[i]):
            if abs(ballCircle.top - brickRect[i].bottom < 10) and ballY_change < 0:
                brickX[i] = -400
                ballY_change *= -1
                scoreValue += 1

    showScore(textX,textY)
    pygame.display.update()

python pygame drawing
1个回答
1
投票

在您的代码中,所有积木都有brickY.append(0),因此所有积木都排成一排。您必须创建具有不同Y值的积木才能创建其他行。

您可能需要嵌套for循环-像这样

row_number = 3

brickYValue = 0

for row in range(row_number):

    brickXValue = 15

    for column in range(numOfBricks):
        brickX.append(brickXValue)

        brickY.append(brickYValue)

        brickX_change.append(0.3)
        brickY_change.append(0)
        brickXValue += 130

    # after `for column`    
    brickYValue += 15  # row height

但是它将创建比numOfBricks更多的积木-您将拥有numOfBricks*row_number积木,因此您将不得不更改其他for循环并使用range(numOfBricks*row_number)而不是range(numOfBricks)

或者您应该学习如何在没有for的情况下使用range()循环

brickRect = []

for x, y in zip(brickX, brickY):
    brickRect.append(pygame.draw.rect(screen, (0, 0, 0), x, y, 120, 42),1))

BTW:您还应该学习如何使用pygame.Rect()来保持砖块,球拍和球的大小和位置。 Rect()有检查冲突的方法,您不需要很长的时间if ... and ... and ...


EDIT:我在这段代码中添加了行,但是我进行了许多其他更改,因此它可能不是一个很好的示例。

我绘制表面而不是加载图像,所以每个人都可以在没有图像的情况下运行它。

import pygame
import random

# --- classes ---

class Brick():

    def __init__(self, x, y, image):
        self.image = image
        self.rect = self.image.get_rect(x=x, y=y)
        self.x = x
        self.y = y
        self.x_change = 0
        self.y_change = 1

    def draw(self, screen):
        self.rect.x = int(self.x)
        self.rect.y = int(self.y)
        screen.blit(self.image, self.rect)
        pygame.draw.rect(screen, (0, 0, 0), self.rect, 1)

    def update(self):
        self.y += self.y_change
        self.rect.y = int(self.y)

        if self.rect.y <= 0:
            self.y_change = 1
        elif self.rect.y >= 500:
            self.y_change = -1

class Ball():

    def __init__(self):
        #self.image = pygame.image.load("Ball.png")

        self.image = pygame.Surface((16, 16)).convert_alpha()
        self.image.fill((0,0,0,0)) # transparent background
        pygame.draw.circle(self.image, (255,255,255), (8, 8), 8)

        self.rect = self.image.get_rect(centerx=380, centery=280)
        self.x = 380
        self.y = 280
        self.x_change = 3
        self.y_change = 3

    def reset(self):
        self.x = 380
        self.y = 280

    def draw(self, screen):
        self.rect.centerx = int(self.x)
        self.rect.centery = int(self.y)
        screen.blit(self.image, self.rect)

    def update(self):
        # Ball Movement and boundary checking
        self.x += self.x_change
        self.rect.centerx = int(self.x)

        if self.rect.left <= 0:
            self.x_change *= -1
        elif self.rect.right >= 800:
            self.x_change *= -1

        self.y += self.y_change
        self.rect.centery = int(self.y)

        if self.rect.top <= 0:
            self.y_change *= -1
        elif self.rect.bottom >= 600:
            self.reset()

class Paddle():

    def __init__(self):
        #self.image = pygame.image.load("scaledPaddle.png")
        self.image = pygame.Surface((100, 30))
        self.image.fill((255,0,0))

        self.rect = self.image.get_rect(x=335, y=550)
        self.x_change = 0
        self.y_change = 0

    def reset(self):
        self.rect.x = 335
        self.rect.y = 550

    def draw(self, screen):
        screen.blit(self.image, self.rect)

    def update(self):
        # Checking boudries of paddle
        self.rect.x += self.x_change

        if self.rect.left <= 0:
            self.rect.left = 0
        elif self.rect.right >= 800:
            self.rect.right = 800

class Score():

    def __init__(self):
        #self.font = pygame.font.Font("Neufreit-ExtraBold.otf", 24)
        self.font = pygame.font.SysFont(None, 24)
        self.value = 0
        self.x = 10
        self.y = 10

    def reset(self):
        self.value = 0

    def draw(self, screen):
        self.image = self.font.render("Score : " + str(self.value), True, (255,255,255))
        self.rect = self.image.get_rect(x=self.x, y=self.y)
        screen.blit(self.image, self.rect)

# --- functions ---

# empty

# --- main ---

pygame.init()
screen = pygame.display.set_mode((800, 600))

pygame.display.set_caption("Brick Breaker")
#icon = pygame.image.load("Brick Breaker Icon.png")
#pygame.display.set_icon(icon)

# Background Image

#background_image = pygame.image.load("realBackground.png")

background_image = pygame.Surface((800,600))
for y in range(5, 600, 25):
    for x in range(5, 800, 25):
        color = random.choice([(255,128,128), (128,255,128), (128,128,255)])
        background_image.fill(color, [x,y,15,15])

# Brick Images

#brick_images = [
#    pygame.image.load("yellowBrick.png"),
#    pygame.image.load("greenBrick.png"),
#    pygame.image.load("blueBrick.png"),
#    pygame.image.load("pinkBrick.png"),
#]

brick_images = [
    pygame.Surface((100, 30)),
    pygame.Surface((100, 30)),
    pygame.Surface((100, 30)),
    pygame.Surface((100, 30)),
    pygame.Surface((100, 30)),
    pygame.Surface((100, 30)),
]    

brick_images[0].fill((255,0,0))
brick_images[1].fill((0,255,0))
brick_images[2].fill((0,0,255))
brick_images[3].fill((255,255,0))
brick_images[4].fill((255,0,255))
brick_images[5].fill((0,255,255))

# Objects

paddle = Paddle()
ball   = Ball()
score  = Score()

# bricks
rows_number = 5
cols_number = 7

all_bricks = []

y = 0
for row in range(rows_number):
    x = 50
    for col in range(cols_number):
        color_image = random.choice(brick_images)
        brick = Brick(x, y, color_image)
        all_bricks.append(brick)
        x += 100
    y += 30

# Game Loop

clock = pygame.time.Clock()
running = True

while running:

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

        # If keystroke is pressed check whether left or right
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                paddle.x_change = -5
            if event.key == pygame.K_RIGHT:
                paddle.x_change = 5
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                paddle.x_change = 0

    # --- updates ---

    paddle.update()
    ball.update()

    # Bricks Update
    for brick in all_bricks:
        brick.update()

    # Ball and Paddle Collision
    if ball.rect.colliderect(paddle):
        ball.y_change *= -1

    # Ball and Bricks Collision
    for brick in all_bricks:
        if ball.rect.colliderect(brick):
            brick.x = -400
            ball.y_change *= -1
            score.value += 1

    # --- draws ---

    # To change background colour
    # screen.fill((128, 128, 128)) # you don't need it if background fill all screen

    # background image
    screen.blit(background_image, (0, 0))

    for brick in all_bricks:
        brick.draw(screen)

    paddle.draw(screen)
    ball.draw(screen)

    score.draw(screen)

    pygame.display.flip()

    clock.tick(60) # 60 FPS (Frames Per Second) on all computers

# --- end ---

pygame.quit() 

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.