为什么这个pygame代码不起作用?

时间:2017-05-04 02:32:11

标签: python pygame collision-detection

有人可以帮助我使用此代码吗?我似乎拥有使桨叶移动所需的一切。另外,在第146-149行中,我已经注释掉了一个碰撞检查器,它在运行时会返回错误。该错误表示' Paddle对象没有属性sprite'。有人请帮忙。谢谢。

import pygame
import random
from pygame import *

pygame.init()
#COLORS
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
ORANGE = (255, 117, 26)
YELLOW = (255, 255, 0)
GREEN = (51, 204, 51)
BLUE = (0, 102, 255)
PURPLE = (153, 0, 204)
#INT
size = (800, 600)
paddlesize = (100, 15)
blockx = 20
blocky = 75
paddlex = 350
paddley = 565
ballx = 396
bally = 553
x_coord = 100
y_coord = 100
x_speed = 0
y_speed = 0
colorlistnum = 0
BALLSIZE = 5
#OTHER
paddle_dir = ''
font = pygame.font.SysFont("Calibri", 25, True, False)

colorlist = [RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE]

pygame.display.set_caption("Breakout")
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()

class Paddle(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface(paddlesize)
        self.image.fill(WHITE)
        self.rect = self.image.get_rect()
        self.rect.x = paddlex
        self.rect.y = paddley
        self.change_x = 0
        self.change_y = 0
    def update(self):
        self.rect.x += self.change_x
        self.rect.y += self.change_y

class Block(pygame.sprite.Sprite):
    def __init__(self, color):
        super().__init__()
        self.image = pygame.Surface([60, 20])
        self.image.fill(color)
        self.rect = self.image.get_rect()

class Ball(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((12, 12))
        self.image.fill(WHITE)
        self.rect = self.image.get_rect()
        self.x = 396
        self.y = 553
        self.width = 10
        self.height = 10
        self.change_x = 0
        self.change_y = 0

all_sprites_list = pygame.sprite.Group()

block_list = pygame.sprite.Group()

bullet_list = pygame.sprite.Group()

for i in range(72):
    block = Block(colorlist[colorlistnum])

    block.rect.x = blockx
    block.rect.y = blocky
    block_list.add(block)
    all_sprites_list.add(block)
    blockx += 70
    if colorlistnum == 5 and blockx >= 730:
        break
    if blockx > 774:
        colorlistnum += 1
        blocky += 30
        blockx = 20

def make_ball():
        ball = Ball()

        ball.change_x = random.randrange(-2, 3)
        ball.change_y = random.randrange(-2, 3)

        return ball

ball = make_ball()
ball_list = []
ball_list.append(ball)

paddle = Paddle()
ball = Ball()
all_sprites_list.add(ball)
all_sprites_list.add(paddle)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_speed = -4
                paddle_dir = 'left'
            elif event.key == pygame.K_RIGHT:
                x_speed = 4
                paddle_dir = 'right'
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                if paddle_dir == 'left':
                    paddle_dir = ''
                    x_speed = 0
            if event.key == pygame.K_RIGHT:
                if paddle_dir == 'right':
                    paddle_dir = ''
                    x_speed = 0
    # LOGIC
    x_coord += x_speed
    y_coord += y_speed
    for ball in ball_list:
        # Move the ball's center
        ball.x += ball.change_x
        ball.y += ball.change_y

        # Bounce the ball if needed
        if ball.y > 600 - BALLSIZE or ball.y < BALLSIZE:
            ball.change_y *= -1
        if ball.x > 800 - BALLSIZE or ball.x < BALLSIZE:
            ball.change_x *= -1
        #if pygame.sprite.spritecollide(ball, paddle, True):
        #    ball.change_y *= -1
        #if pygame.sprite.spritecollide(ball, block_list, True):
        #    ball.change_y *= -1
    # GRAPHIC AND DRAWING
    screen.fill(BLACK)
    for ball in ball_list:
        pygame.draw.circle(screen, WHITE, [ball.x, ball.y], BALLSIZE)
    all_sprites_list.draw(screen)
    pygame.display.update()
    clock.tick(100)
pygame.quit()

2 个答案:

答案 0 :(得分:1)

这是因为spritecollide()需要一个精灵,一个组和一个碰撞的条件。这对于block_list是可以的,因为这是一组精灵,但是paddle isn&t; t。尝试使用collide_rect()代替两个精灵&#39;碰撞的rect属性。

答案 1 :(得分:0)

您似乎正处于向班级过渡的过程中。 x_coordy_coordx_speedx_speed变量已过时,可以删除。仅更新rect和球的paddle属性。您还需要在while循环中调用all_sprites_list.update()来更新球拍。

正如Joe D所提到的,您需要将划桨冲突检查更改为if ball.rect.colliderect(paddle.rect):

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                paddle_dir = 'left'
                paddle.change_x = -4
            elif event.key == pygame.K_RIGHT:
                paddle_dir = 'right'
                paddle.change_x = 4
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                if paddle_dir == 'left':
                    paddle_dir = ''
                    paddle.change_x = 0
            if event.key == pygame.K_RIGHT:
                if paddle_dir == 'right':
                    paddle_dir = ''
                    paddle.change_x = 0
    # LOGIC
    all_sprites_list.update()
    for ball in ball_list:
        # Move the ball's rect.
        ball.rect.x += ball.change_x
        ball.rect.y += ball.change_y

        # Bounce the ball if needed.
        if ball.rect.y > 600 - BALLSIZE or ball.rect.y < 0:
            ball.change_y *= -1
        if ball.rect.x > 800 - BALLSIZE or ball.rect.x < 0:
            ball.change_x *= -1
        if ball.rect.colliderect(paddle.rect):
            ball.change_y *= -1
        if pygame.sprite.spritecollide(ball, block_list, True):
            ball.change_y *= -1
    # GRAPHIC AND DRAWING
    screen.fill(BLACK)
    for ball in ball_list:
        pygame.draw.circle(screen, WHITE, ball.rect.center, BALLSIZE)