尝试从列表中删除单个项目时,列表中的许多项目都会被删除

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

在这个pygame程序中,我正在尝试制作一个slither.io游戏,在slither.io中,当蛇接触其中一个球体时,球体应该被蛇吃掉并消失,但由于某种原因几乎当蛇只触及其中一个球体时,列表中的所有球体都会被删除。

这是代码的一部分。

for snake in snake_group:
    snake.head_tail_length = 0
    for ele in [x for x in blob_list if 620 > x[1] > 0 and 620 > x[2] > 0 \
        and 0 < abs(snake.head_segment[0] - x[1]) < 20 and 0 < abs(snake.head_segment[1] - x[2]) < 20]:
        blob_list.remove(ele)
    pygame.display.update()

但这是完整的代码:

import pygame
import math
import random

pygame.init()

screen = pygame.display.set_mode((620, 620))
screen.fill((20, 20, 20))
pygame.display.set_caption("Slither IO")
clock = pygame.time.Clock()
font = pygame.font.Font('freesansbold.ttf', 32)

run = True
temp_speed = 0.3
snake_x_change = 0
snake_y_change = 0
ult_diff = 0
piece_grp = []
cob_list = []
player_x_coords, player_y_coords = 310, 310
div = 0

CYAN = (0, 200, 200)
GREEN = (50, 255, 50)
YELLOW = (200,200,0)
ORANGE = (255,165,0)
RED = (255, 100, 100)
MAGENTA = (255,0,255)

color_list = [CYAN, GREEN, YELLOW, ORANGE, RED, MAGENTA]
blob_list = []
blob_rect_list = []

for i in range(250):
    blob_list.append([random.choice(color_list), random.randrange(0, 5000) + snake_x_change,\
         random.randrange(0, 5000) + snake_y_change, random.randrange(8, 15)])

class Snake:
    def __init__(self, x_coord, y_coord, size):
        self.x_coord = x_coord
        self.y_coord = y_coord
        self.size = size
        self.segments = [[self.x_coord, self.y_coord]] * size
        self.head_segment = None
        self.cursor_head_length = None
        self.head_tail_length = 0
        self.head_rect = pygame.Rect(self.x_coord, self.y_coord, 40, 40)

    def movement(self, current_x, current_y, target_x, target_y, speed):
        global length
        length = math.sqrt((target_x - current_x) ** 2 + (target_y - current_y) ** 2)

        new_x = current_x + ((target_x - current_x) / length) * speed
        new_y = current_y + ((target_y - current_y) / length) * speed
        return [new_x, new_y]


for i in range(len(blob_list)):
    cob_list.append((blob_list[i][1], blob_list[i][2]))
    blob_rect_list.append(pygame.Rect(blob_list[i][1], blob_list[i][2], blob_list[i][3] * 2, blob_list[i][3] * 2))

snake_group = []
player_snake = Snake(310, 310, 15)
snake_group.append(player_snake)

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

    for i in range(len(blob_list)):
            blob_list[i][1] = cob_list[i][0] - snake_group[0].x_coord - 310
            blob_list[i][2] = cob_list[i][1] - snake_group[0].y_coord - 310   
            blob_rect_list[i][0] = cob_list[i][0] - snake_group[0].x_coord - 310
            blob_rect_list[i][1] = cob_list[i][0] - snake_group[0].x_coord - 310
    cursor_pos = pygame.mouse.get_pos()

    prev_diff_x, prev_diff_y = snake_group[0].x_coord - 310, snake_group[0].y_coord - 310

    player_x_coords, player_y_coords = player_snake.movement(
            player_x_coords, player_y_coords, cursor_pos[0], cursor_pos[1], 0.003
        ) 
    if round(length) == 0:
        player_x_coords, player_y_coords = 310, 310

    for snake in snake_group:
        snake.head_segment = snake.movement(
            snake.x_coord, snake.y_coord, cursor_pos[0], cursor_pos[1], 0.3
        ) 

        snake.segments[0] = snake.head_segment
        head_rect = pygame.Rect(snake.head_segment[0], snake.head_segment[1], 40, 40)
        snake.cursor_head_length = math.sqrt(
            (cursor_pos[0] - snake.x_coord) ** 2 + (cursor_pos[1] - snake.y_coord) ** 2
        )

    for snake in snake_group:
        for i in range(1, snake.size):
            snake.head_tail_length += math.sqrt(
                (snake.segments[i - 1][0] - snake.segments[i][0]) ** 2 +
                (snake.segments[i - 1][1] - snake.segments[i][1]) ** 2
            )

    screen.fill((20, 20, 20))

    for i in range(len(blob_list)):
        blob_list[i][1] -= (player_x_coords - 310) * 50
        blob_list[i][2] -= (player_y_coords - 310) * 50

        pygame.draw.circle(screen, blob_list[i][0], (blob_list[i][1], blob_list[i][2]), blob_list[i][3])
    
    for snake in snake_group:
        ult_diff = [snake.head_segment[0] - 310, \
        snake.head_segment[1] - 310]
        for piece in snake.segments:
            piece[0] -= ult_diff[0] 
            piece[1] -= ult_diff[1] 
        
    for snake in snake_group:
        pygame.draw.circle(
            screen, (255, 255, 255), (int(snake.head_segment[0]), int(snake.head_segment[1])), 20, 20
        )
        snake.x_coord, snake.y_coord = snake.head_segment

    for snake in snake_group:
        if round(snake.cursor_head_length) != 0:
            for i in range(1, snake.size):
                if snake.head_tail_length < 15 * snake.size:
                    temp_speed -= 0.01
                elif snake.head_tail_length > 15 * snake.size:
                    temp_speed += 0.01

                other_segment = snake.movement(
                    snake.segments[i][0], snake.segments[i][1],
                    snake.segments[i - 1][0], snake.segments[i - 1][1], temp_speed
                )
                pygame.draw.circle(
                    screen, (255, 255, 255), (int(other_segment[0]), int(other_segment[1])), 20, 20
                )
                snake.segments[i] = other_segment
        else:
            for segment in snake.segments:
                pygame.draw.circle(
                    screen, (255, 255, 255), (int(segment[0]), int(segment[1])), 20, 20
                )

    temp_speed = 0.3

    for snake in snake_group:
        snake.head_tail_length = 0
        for ele in [x for x in blob_list if 620 > x[1] > 0 and 620 > x[2] > 0 \
            and 0 < abs(snake.head_segment[0] - x[1]) < 20 and 0 < abs(snake.head_segment[1] - x[2]) < 20]:
            blob_list.remove(ele)
    pygame.display.update()

我尝试了 pygame 中内置的不同碰撞函数,但它们似乎不起作用, 我也尝试使用“pop”而不是“remove”。

python list pygame
1个回答
0
投票

迭代时从列表中删除元素可能会带来惊喜。

我建议将您的代码调整为:

for snake in snake_group:
    snake.head_tail_length = 0
    new_blob_list = []
    for ele in blob_list:
        if 620 > ele[1] > 0 and 620 > ele[2] > 0 and 0 < abs(snake.head_segment[0] - ele[1]) < 20 and 0 < abs(snake.head_segment[1] - ele[2]) < 20:
            # Blob is eaten, do not add to new_blob_list
            continue
        new_blob_list.append(ele)
    blob_list = new_blob_list
    pygame.display.update()
© www.soinside.com 2019 - 2024. All rights reserved.