Python Snake游戏中碰撞的实现问题

Python Snake游戏中碰撞的实现问题,python,pygame,Python,Pygame,我正在尝试实现一个循环,检查蛇头(由列表snake_parts的头部表示)是否与蛇身体的任何部分碰撞,这些部分是构成列表其余部分的rect对象。但一旦蛇的身体伸展,两个物体之间就会不断发生碰撞。考虑到蛇身是如何实现的,我看不出它们是如何相交的,所以我不确定是什么导致了碰撞 import pygame from pygame.locals import * import random import sys pygame.init() FPS = 30 fpsClock = pygame.ti

我正在尝试实现一个循环,检查蛇头(由列表snake_parts的头部表示)是否与蛇身体的任何部分碰撞,这些部分是构成列表其余部分的rect对象。但一旦蛇的身体伸展,两个物体之间就会不断发生碰撞。考虑到蛇身是如何实现的,我看不出它们是如何相交的,所以我不确定是什么导致了碰撞

import pygame
from pygame.locals import *
import random
import sys


pygame.init()

FPS = 30
fpsClock = pygame.time.Clock()

WIN_WIDTH = 680 #width of window
WIN_HEIGHT = 500 #height of window

DISPLAY = (WIN_WIDTH, WIN_HEIGHT) #variable for screen display
DEPTH = 32 #standard
FLAGS = 0 #standard
BLACK = (0, 0, 0) #black
RED = (255, 0, 0) #red
GOLD = (255, 215, 0)
LOL = (14, 18, 194)

screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
pygame.display.set_caption('Snaek')                                      

snake_parts = [1]
Score = 0
speed = 10
snakex = 125
snakey = 70
size = 20


# --- classes ---
class Snake(pygame.Rect):
    def __init__(self, x, y, screen, size, colour):
        pygame.Rect.__init__(self, x, y, size, 20)
        self.screen = screen
        self.colour = colour
        self.x = x
        self.y = y


    def draw(self, screen):
        pygame.draw.rect(self.screen, self.colour, self)

    def coordinates(self):
        return self.x, self.y

class Food(pygame.Rect):
    def __init__(self, x, y, screen):
        pygame.Rect.__init__(self, x, y, 20, 20)
        self.screen = screen

    def draw(self, screen):
        pygame.draw.rect(self.screen, GOLD, self)

class Barrier(pygame.Rect):

    def __init__(self, x, y, screen):
        pygame.Rect.__init__(self, x, y, 40, 20)
        self.screen = screen 
    def draw(self, screen):
        pygame.draw.rect(self.screen, LOL, self)


# --- functions ---
def get_food_pos(WIN_WIDTH, WIN_HEIGHT):
    WIN_WIDTH = random.randint(100, WIN_WIDTH-150)
    WIN_HEIGHT = random.randint(100, WIN_HEIGHT-150)
    return WIN_WIDTH, WIN_HEIGHT

eaten = True
pressed_right = True
pressed_left = False
pressed_up = False
pressed_down = False
pygame.key.set_repeat(10,10)

level = [
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP", 
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
]


while True:
    screen.fill(BLACK)

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        elif event.type == pygame.KEYDOWN:          # check for key presses          
            if event.key == pygame.K_LEFT:
                if pressed_right:
                    pressed_right = True# left arrow turns left
                else:
                    pressed_left = True
                    pressed_right = False
                    pressed_up = False
                    pressed_down = False
            elif event.key == pygame.K_RIGHT:
                if pressed_left:
                    pressed_left = True# right arrow turns right
                else: 
                    pressed_right = True
                    pressed_left = False
                    pressed_up = False
                    pressed_down = False
            elif event.key == pygame.K_UP:
                if pressed_down:# up arrow goes up
                    pressed_down = True
                else:
                    pressed_up = True
                    pressed_right = False
                    pressed_left = False
                    pressed_down = False
            elif event.key == pygame.K_DOWN:
                if pressed_up:
                    pressed_up = False
                else:
                    pressed_down = True
                    pressed_right = False
                    pressed_up = False
                    pressed_left = False

    x = snakex
    y = snakey




    if pressed_left:
        snakex -= speed
    elif pressed_right:
        snakex += speed
    elif pressed_up:
        snakey -= speed
    elif pressed_down:
        snakey += speed

    snake_parts[0] = Snake(snakex, snakey, screen, int(size), RED)
    snake_parts[0].draw(screen)



    if eaten:
        foodx, foody = get_food_pos(WIN_WIDTH, WIN_HEIGHT)
        eaten = False

    my_food = Food(foodx, foody, screen)
    my_food.draw(screen)

    if snake_parts[0].colliderect(my_food):
        eaten = True
        screen.fill(BLACK)
        a_snake = Snake(snakex, snakey, screen, int(size), RED)
        snake_parts.append(a_snake)


    for i in range(1, len(snake_parts)):
        tempx, tempy = snake_parts[i].coordinates()
        snake_parts[i] = Snake(x, y, screen, int(size), RED)
        if snake_parts[0].colliderect(snake_parts[i]):
            print("Self collision")
        snake_parts[i].draw(screen)
        x, y = tempx, tempy



    platform_x = 0
    platform_y = 0

    for row in level:
        for col in row:
            if col == "P":
                col = Barrier(platform_x, platform_y, screen)
                col.draw(screen)
                if snake_parts[0].colliderect(col):
                    print("Barrier collision")

            platform_x += 15
        platform_y += 20
        platform_x = 0        



    pygame.display.update()
    fpsClock.tick(FPS)     

调试这样的程序非常困难,正如@WillemVanOnsem所说的,我们无法快速理解您的代码。但根据我所看到的,我可以给你一些建议,让你以更稳健的方式改写游戏:

  • 您的电路板段可以位于二维阵列中。在这个二维数组中,您的蛇可以表示为坐标列表。您可以在移动时检测碰撞,即即将弹出snake列表的最后一个元素并将下一个元素附加到列表的前面。我敢肯定,几年前我已经成功地使用这种方法,用不到30行代码编写了一个最小的snake游戏
  • 做一些单元测试。以编程方式将您的蛇放在您知道会导致意外碰撞的特定位置,并尝试了解发生了什么。如果问题没有弄清楚,那就再问一次

  • 如果我正确地阅读了规则,您不应该转储整个程序,而应该转储更多相关部分以寻求帮助。我已经运行了您的程序,看起来您确实遇到了冲突问题。我们不是来调试您的整个程序以查找问题的。你需要知道你需要帮助的是什么。如果你不知道是什么原因导致了这个问题,你必须先分解你的程序,直到你找到了一个合理的少量导致这个错误的代码。阅读和了解更多信息。