有人会修复我的 Pygame 碰撞代码吗?

Would someone fix my Pygame collision code?

我有一个 Pygame 寒假期间的学校项目,作为总结。我制作了游戏的基础(Flappy Bird),但问题是碰撞不正常。问题是它把通过管道算作碰撞。

你们可以检查我的代码并修复它吗?

import pygame
import sys
import math
import random
from pygame.locals import *
a=320

b=240
da=1
db=0
x=25
y=25
e=50
da2=0
c=200
d=10
c_change=0
d_change=0
clock = pygame.time.Clock()
bg=(36,38,82)
wood=(253,197,136)
green=(79, 255, 101)
pipe=(152,228,86)
end=(137, 226, 57)
bg1=(40,42,86)
gold=(219,178,58)
golden=(254, 197, 34)
golder=(255, 206, 63)
black=(0,0,0)
red=(255, 47, 47)
white=(255,255,255)
pygame.init()
screen = pygame.display.set_mode((1400,700))
class Wall(pygame.sprite.Sprite):

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


        self.image = pygame.Surface([width, height])
        self.image.fill(GREY)


        self.rect = self.image.get_rect()
        self.rect.y = y
        self.rect.x = x

crashFlag=0

done = False
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        if event.type==pygame.KEYDOWN:
            if event.key==pygame.K_SPACE:
                c_change=-1
                d_change=1
        if event.type==pygame.KEYUP:
            if event.key==pygame.K_SPACE:
                c_change=1
        if event.type==pygame.KEYDOWN:
            crashFlag==0


    c+=c_change
    d+=d_change

    screen.fill(bg)
    pygame.draw.rect(screen,bg1, (0,350,1400,350), 0)


    pygame.draw.circle(screen,white, (d,c),5)
    #for f in range(195, 390 ,5):
    if d>200 and d<275:
        if c>340:
            crashFlag=1

    pygame.draw.rect(screen,end, (195,300,80,40), 0)
    pygame.draw.rect(screen,pipe, (200,0,70,300), 0)
    pygame.draw.rect(screen,pipe, (350,0,70,450), 0)
    pygame.draw.rect(screen,end, (345,420,80,40), 0)
    pygame.draw.rect(screen,pipe, (490,0,70,480), 0)
    pygame.draw.rect(screen,end, (485,480,80,40), 0)
    pygame.draw.rect(screen,pipe, (630,0,70,450), 0)
    pygame.draw.rect(screen,end, (625,450,80,40), 0)
    pygame.draw.rect(screen,pipe, (770,0,70,430), 0)
    pygame.draw.rect(screen,end, (765,420,80,40), 0)
    pygame.draw.rect(screen,pipe, (910,0,70,400), 0)
    pygame.draw.rect(screen,end, (905,400,80,40), 0)
    pygame.draw.rect(screen,pipe, (1050,0,70,470), 0)
    pygame.draw.rect(screen,end, (1045,470,80,40), 0)
    pygame.draw.rect(screen,pipe, (1190,0,70,430), 0)
    pygame.draw.rect(screen,end, (1185,430,80,40), 0)
    pygame.draw.rect(screen,gold, (1330,0,70,410), 0)
    pygame.draw.rect(screen,golder, (1350,0,70,410), 0)
    pygame.draw.rect(screen,golden, (1325,410,80,40), 0)
    pygame.draw.rect(screen,pipe, (200,400,70,240), 0)
    #lower pipes
    pygame.draw.rect(screen,end, (195,400,80,40), 0)
    pygame.draw.rect(screen,pipe, (350,520,70,500), 0)
    pygame.draw.rect(screen,end, (345,515,80,40), 0)
    pygame.draw.rect(screen,pipe, (490,570,70,100), 0)
    pygame.draw.rect(screen,end, (485,570,80,40), 0)
    pygame.draw.rect(screen,pipe, (630,570,70,100), 0)
    pygame.draw.rect(screen,end, (625,540,80,40), 0)
    pygame.draw.rect(screen,pipe, (770,550,70,120), 0)
    pygame.draw.rect(screen,end, (765,510,80,40), 0)
    pygame.draw.rect(screen,pipe, (910,530,70,220), 0)
    pygame.draw.rect(screen,end, (905,490,80,40), 0)
    pygame.draw.rect(screen,pipe, (1050,560,70,220), 0)
    pygame.draw.rect(screen,end, (1045,560,80,40), 0)
    pygame.draw.rect(screen,pipe, (1190,530,70,220), 0)
    pygame.draw.rect(screen,end, (1185,530,80,40), 0)
    pygame.draw.rect(screen,gold, (1330,530,70,220), 0)
    pygame.draw.rect(screen,golder, (1350,530,70,220), 0)
    pygame.draw.rect(screen,golden, (1325,510,80,40), 0)
    pygame.draw.rect(screen, wood, (0,650,1400,50), 0)
    pygame.draw.rect(screen,green, (0,640,1400,10), 0)

    if crashFlag==1:
        pygame.draw.rect(screen,white, (0,0,1400,700), 0)
        font = pygame.font.SysFont("Berlin Sans FB Demi", 100, True, False)

        text = font.render("You Lost", True, black)
        screen.blit(text, (500, 100))
        pygame.draw.rect(screen,green, (600,400,190,60), 0)
        font = pygame.font.SysFont("Aharoni", 50, True, False)

        text = font.render("RESET", True, white)
        screen.blit(text, (630, 410))



    pygame.display.update()
    clock.tick(150)
pygame.quit()

变化太多无法全部描述。

我将列表 all_pipes 中的所有管道都保留为 (END, pygame.Rect(195,300,80,40)),然后我可以使用 for 循环来绘制它们

    for pipe_color, pipe_rect in all_pipes:
        pygame.draw.rect(screen, pipe_color, pipe_rect, 0)

并检查与玩家的碰撞。

    for pipe_color, pipe_rect in all_pipes:
        if pipe_rect.collidepoint(player_x, player_y):
            state = STATE_GAMEOVER
            break # no need to check other

完整代码

import pygame

# --- constants --- (UPPER_CASE_NAMES)

# - colors -

BACKGROUND_0 = (36, 38, 82)
BACKGROUND_1 = (40, 42, 86)

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 47, 47)
GREEN = (79, 255, 101)

WOOD = (253, 197, 136)
PIPE = (152, 228, 86)
END = (137, 226, 57)
GOLD = (219, 178, 58)
GOLDEN = (254, 197, 34)
GOLDER = (255, 206, 63)

# - states -

STATE_INTRO    = 1
STATE_GAME     = 2
STATE_GAMEOVER = 3

# --- classes --- (CamelCaseNames)

#class Wall(pygame.sprite.Sprite):
#
#   def __init__(self, x, y, width, height):
#        super().__init__()
#
#        self.image = pygame.Surface((width, height))
#        self.image.fill(GREY)
#
#        self.rect = self.image.get_rect()
#        self.rect.y = y
#        self.rect.x = x

# --- functions --- (lower_case_names)

# empty

# --- main ---

# - init -

pygame.init()
screen = pygame.display.set_mode((1400,700))

font1 = pygame.font.SysFont("Berlin Sans FB Demi", 100, True, False)
text1 = font1.render("You Lost", True, BLACK)
font2 = pygame.font.SysFont("Aharoni", 50, True, False)
text2 = font2.render("RESET", True, WHITE)

# - objects -

player_y = 200
player_x = 10

x_change = 5
y_change = 0

all_pipes = [
    #upper pipes
    (END, pygame.Rect(195,300,80,40)), 
    (PIPE, pygame.Rect(200,0,70,300)), 
    (PIPE, pygame.Rect(350,0,70,450)), 
    (END, pygame.Rect(345,420,80,40)), 
    (PIPE, pygame.Rect(490,0,70,480)), 
    (END, pygame.Rect(485,480,80,40)), 
    (PIPE, pygame.Rect(630,0,70,450)), 
    (END, pygame.Rect(625,450,80,40)), 
    (PIPE, pygame.Rect(770,0,70,430)), 
    (END, pygame.Rect(765,420,80,40)), 
    (PIPE, pygame.Rect(910,0,70,400)), 
    (END, pygame.Rect(905,400,80,40)), 
    (PIPE, pygame.Rect(1050,0,70,470)), 
    (END, pygame.Rect(1045,470,80,40)), 
    (PIPE, pygame.Rect(1190,0,70,430)), 
    (END, pygame.Rect(1185,430,80,40)), 
    (GOLD, pygame.Rect(1330,0,70,410)), 
    (GOLDER, pygame.Rect(1350,0,70,410)), 
    (GOLDEN, pygame.Rect(1325,410,80,40)), 
    (PIPE, pygame.Rect(200,400,70,240)), 
    #lower pipes
    (END, pygame.Rect(195,400,80,40)), 
    (PIPE, pygame.Rect(350,520,70,500)), 
    (END, pygame.Rect(345,515,80,40)), 
    (PIPE, pygame.Rect(490,570,70,100)), 
    (END, pygame.Rect(485,570,80,40)), 
    (PIPE, pygame.Rect(630,570,70,100)), 
    (END, pygame.Rect(625,540,80,40)), 
    (PIPE, pygame.Rect(770,550,70,120)), 
    (END, pygame.Rect(765,510,80,40)), 
    (PIPE, pygame.Rect(910,530,70,220)), 
    (END, pygame.Rect(905,490,80,40)), 
    (PIPE, pygame.Rect(1050,560,70,220)), 
    (END, pygame.Rect(1045,560,80,40)), 
    (PIPE, pygame.Rect(1190,530,70,220)), 
    (END, pygame.Rect(1185,530,80,40)), 
    (GOLD, pygame.Rect(1330,530,70,220)), 
    (GOLDER, pygame.Rect(1350,530,70,220)), 
    (GOLDEN, pygame.Rect(1325,510,80,40)), 
    (WOOD, pygame.Rect(0,650,1400,50)), 
    (GREEN, pygame.Rect(0,640,1400,10)), 
]

# - mainloop -

state = STATE_INTRO # STATE_GAME, STATE_GAMEOVER

clock = pygame.time.Clock()
done = False

while not done:

    # - events -

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

        if state == STATE_INTRO:
            if event.type == pygame.KEYDOWN:
               state = STATE_GAME

        elif state == STATE_GAME:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    y_change = -5
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_SPACE:
                    y_change = 5

        elif state == STATE_GAMEOVER:
            if event.type == pygame.KEYDOWN:
               state = STATE_INTRO
               player_y = 200
               player_x = 10

    # - updates (without draws) -

    if state == STATE_GAME:
        player_x += x_change
        player_y += y_change

        # check collisions with all pipes

        for pipe_color, pipe_rect in all_pipes:
            if pipe_rect.collidepoint(player_x, player_y):
                state = STATE_GAMEOVER
                break # no need to check other

    # - draws (without updates) -

    if state in (STATE_INTRO, STATE_GAME):
        screen.fill(BACKGROUND_0)
        pygame.draw.rect(screen, BACKGROUND_1, (0, 350, 1400, 350), 0)

        # draw all pipes

        for pipe_color, pipe_rect in all_pipes:
            pygame.draw.rect(screen, pipe_color, pipe_rect, 0)

        pygame.draw.circle(screen, WHITE, (player_x, player_y), 5)

    if state == STATE_GAMEOVER:
        screen.fill(WHITE)
        screen.blit(text1, (500, 100))
        pygame.draw.rect(screen, GREEN, (600, 400, 190, 60), 0)
        screen.blit(text2, (630, 410))

    pygame.display.update()
    clock.tick(25)

# - end -

pygame.quit()