Python 从组中删除精灵

Python 从组中删除精灵,python,pygame,sprite,Python,Pygame,Sprite,我正在用pygame做一个游戏,到目前为止,这个角色可以跳、跑、用剑和弓攻击,我可以在他两侧产卵蛇来追赶他。现在我希望玩家能够攻击一条蛇并让它死亡/消失。我制作了一个精灵(攻击区域),玩家在攻击的同时进行攻击。每一帧蛇都会检查它们是否与攻击区域发生碰撞。 该错误发生在检测到碰撞后,以及我想从列表中删除蛇时 这是一个错误的例子,发生在我生了两条蛇,其中一条与攻击区域相撞之后 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 03:37:03) [MSC v.1900 6

我正在用pygame做一个游戏,到目前为止,这个角色可以跳、跑、用剑和弓攻击,我可以在他两侧产卵蛇来追赶他。现在我希望玩家能够攻击一条蛇并让它死亡/消失。我制作了一个精灵(攻击区域),玩家在攻击的同时进行攻击。每一帧蛇都会检查它们是否与攻击区域发生碰撞。 该错误发生在检测到碰撞后,以及我想从列表中删除蛇时

这是一个错误的例子,发生在我生了两条蛇,其中一条与攻击区域相撞之后

3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 03:37:03) [MSC v.1900 64 bit (AMD64)]
Python Type "help", "copyright", "credits" or "license" for more information.
[evaluate game_v1.2 (Debug).py]
Traceback (most recent call last):
  File "C:/Users/Haig/Desktop/game_v1.2 (Debug).py", line 167, in <module>
    sanke_list.update()
  File "C:\Program Files\Python36\Lib\site-packages\pygame\sprite.py", line 462, in update
    s.update(*args)
  File "C:/Users/Haig/Desktop/game_v1.2 (Debug).py", line 88, in <module>
    sanke_list.remove(self)
  File "C:\Program Files\Python36\Lib\site-packages\pygame\sprite.py", line 398, in remove
    sprite.remove_internal(self)
  File "C:\Program Files\Python36\Lib\site-packages\pygame\sprite.py", line 166, in remove_internal
    del self.__g[group]
builtins.KeyError: <Group(1 sprites)>
由于我的游戏长度超过1000行,所以我删除了所有与此错误无关的内容,现在不到200行(同样的错误仍然存在)。缩短的程序只允许用户在屏幕两侧产卵蛇,它们朝着x 900移动。当它们与始终处于x 600的攻击区域碰撞时,会发生错误

这是整个节目

import pygame
SCREEN_SIZE = (1280, 720)
SNAKE_SPEED = 2

# Define some colors
BLACK    = (   0,   0,   0)
WHITE    = ( 255, 255, 255)

#CREATE LIST:
snake_list = pygame.sprite.Group()

#SANKE SLITHER animation
animation_index_snake = 0
animation_frame_snake = 0

# Initialize the game engine
pygame.init()

#Create Screen
screen = pygame.display.set_mode(SCREEN_SIZE)

#LOAD IMAGES AS VARIABLES:
background_image = pygame.image.load("game/gamefolder/images/backgrounds/background_1.png").convert()
#snakes
snake_left_1 = pygame.image.load("game/gamefolder/images/enemies/sanke/sanke_left_1.png").convert_alpha()
snake_left_2 = pygame.image.load("game/gamefolder/images/enemies/sanke/sanke_left_2.png").convert_alpha()
snake_right_1 = pygame.image.load("game/gamefolder/images/enemies/sanke/sanke_right_1.png").convert_alpha()
snake_right_2 = pygame.image.load("game/gamefolder/images/enemies/sanke/sanke_right_2.png").convert_alpha()

#MAKE SNAKE CLASS
class Snake(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.change_x = 0
        self.change_y = 0
        #transitions from 0 to 1:
        self.frame = 0
        #direction snake is facing
        self.direction = "left"
        self.image = snake_left_1
        self.rect = self.image.get_rect()   

    def update(self):
        super().__init__()        
        sanke_dimensions = self.image.get_rect()     
        #y coord so snake is on ground
        self.rect.y = 472    
        #Move the snake
        #if the snake is to the left of x 900 then
        if self.rect.x <= 900:
            #move right
            self.change_x = SNAKE_SPEED
            #face right
            self.direction = "right"
        #if the snake is to the right of x 900 then
        if self.rect.x > 900:
            #move left
            self.change_x = -1*SNAKE_SPEED
            #face left
            self.direction = "left"

        #UPDATE
        self.rect.x += self.change_x
        self.rect.y += self.change_y

        #set sprite according to direction and frame
        if self.direction == "left":
            if animation_index_snake == 0:
                self.image = snake_left_1
            if animation_index_snake == 1:
                self.image = snake_left_2
        if self.direction == "right":
            if animation_index_snake == 0:
                self.image = snake_right_1
            if animation_index_snake == 1:
                self.image = snake_right_2

        #check if any snakes were hurt    
        col = pygame.sprite.collide_rect(self, attack_area)
        if col == True:
            #BUG OCCURS HERE
            snake_list.remove(self)

class Attack_area(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        #make a surface
        self.image = pygame.Surface([72, 118])
        self.image.fill(WHITE) 
        self.rect = self.image.get_rect()

    def move(self):
        #move surface to center of screen (simplified for debugging)
        self.rect.x = 600
        self.rect.y = 472

#--------main program----------                
attack_area = Attack_area()

# Loop until the user clicks the close button.
done = False

# Used to manage how fast the screen updates
clock = pygame.time.Clock()

# -------- Main Program Loop ---------------------------------------------------
while not done: 
    # --- Main event loop-------------------------------------------------------
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done = True # Flag that we are done so we exit this loop
        # User pressed down on a key
        elif event.type == pygame.KEYDOWN:

            #spawn enemy snake (either side of screen:)
            if event.key == pygame.K_LEFT:
                #make snake instance on left side of screen facing right
                snake = Snake()
                snake.rect.x = -96
                snake.rect.y = 0
                snake.direction = "right"
                snake.frame = 0
                snake.change_x = 0
                snake.change_y = 0   
                snake.sprite = "snake_right_1"
                #add to snake list
                snake_list.add(snake)


            elif event.key == pygame.K_RIGHT:
                #make snake instance on right side of screen facing left
                snake = Snake()
                snake.rect.x = 1376
                snake.rect.y = 0
                snake.direction = "left"
                snake.frame = 0
                snake.change_x = 0
                snake.change_y = 0    
                snake.sprite = "sanke_left_1"
                #add to snake list
                snake_list.add(snake)                 
            elif event.key == pygame.K_w:
                print(snake_list.sprites())
    # --- Game logic --------------------------------------------- 


    #move attack in actual program this method would be more complex/useful
    attack_area.move()

    # --- Drawing code -------------------------------------------
    screen.fill(BLACK)

    #blit background 
    screen.blit(background_image, [0, 0])
    #move/update all snakes in list
    snake_list.update()
    #draw all snakes in list
    snake_list.draw(screen)

    # --- Go ahead and update the screen with what we've drawn------------------
    pygame.display.flip()

    # --- Clock Work------------------------------------------------------------
    #Limit to 60 frames per second
    clock.tick(60)
    #one frame passed:
    animation_frame_snake += 1
    #(18 is how many frames the animation frame should be shown for)
    if animation_frame_snake >= 18:
        #reset
        animation_frame_snake = 0
        #alternate index between 0 & 1
        if animation_index_snake == 0:
            animation_index_snake = 1
        elif animation_index_snake == 1:
            animation_index_snake = 0

#now left main program loop (because user pressed X), so quit
pygame.quit()
导入pygame
屏幕大小=(1280720)
蛇行速度=2
#定义一些颜色
黑色=(0,0,0)
白色=(255,255,255)
#创建列表:
snake\u list=pygame.sprite.Group()
#三科滑翔动画
动画索引=0
动画\帧\蛇=0
#初始化游戏引擎
pygame.init()
#创建屏幕
screen=pygame.display.set_模式(屏幕大小)
#将图像作为变量加载:
background\u image=pygame.image.load(“game/gamefolder/images/backgrounds/background\u 1.png”).convert()
#蛇
snake_left_1=pygame.image.load(“game/gamefolder/images/friends/sanke/sanke_left_1.png”)。convert_alpha()
snake_left_2=pygame.image.load(“game/gamefolder/images/friends/sanke/sanke_left_2.png”)。convert_alpha()
snake\u right\u 1=pygame.image.load(“game/gamefolder/images/friends/sanke/sanke\u right\u 1.png”)。convert\u alpha()
snake_right_2=pygame.image.load(“game/gamefolder/images/friends/sanke/sanke_right_2.png”)。convert_alpha()
#做蛇类
蛇类(pygame.sprite.sprite):
定义初始化(自):
super()。\uuuu init\uuuuu()
self.change_x=0
self.change_y=0
#从0到1的转换:
self.frame=0
#蛇所面对的方向
self.direction=“左”
self.image=snake\u left\u 1
self.rect=self.image.get_rect()
def更新(自我):
super()。\uuuu init\uuuuu()
sanke_dimensions=self.image.get_rect()
#所以蛇在地上
自校正y=472
#移开蛇
#如果蛇在x 900的左边,那么
如果self.rect.x 900:
#向左移动
self.change\u x=-1*蛇行速度
#面朝左
self.direction=“左”
#更新
self.rect.x+=self.change\u x
self.rect.y+=self.change\u y
#根据方向和帧设置精灵
如果self.direction==“left”:
如果动画索引=0:
self.image=snake\u left\u 1
如果动画索引=1:
self.image=snake\u left\u 2
如果self.direction==“right”:
如果动画索引=0:
self.image=snake\u right\u 1
如果动画索引=1:
self.image=snake\u right\u 2
#检查是否有蛇受伤
col=pygame.sprite.collide\u rect(自我攻击区)
如果col==True:
#错误发生在这里
snake_列表。删除(自身)
职业攻击区(pygame.sprite.sprite):
定义初始化(自):
super()。\uuuu init\uuuuu()
#浮出水面
self.image=pygame.Surface([72118])
self.image.fill(白色)
self.rect=self.image.get_rect()
def移动(自我):
#将表面移动到屏幕中心(简化调试)
自校正x=600
自校正y=472
#--------主程序--------
攻击面积=攻击面积()
#循环,直到用户单击关闭按钮。
完成=错误
#用于管理屏幕更新的速度
clock=pygame.time.clock()
#-----主程序循环---------------------------------------------------
虽然没有这样做:
#---主事件循环-------------------------------------------------------
对于pygame.event.get()中的事件:#用户执行了某些操作
if event.type==pygame.QUIT:#如果用户单击关闭
done=True#标记我们已完成,因此我们退出此循环
#用户按下一个键
elif event.type==pygame.KEYDOWN:
#产卵敌人蛇(屏幕两侧:)
如果event.key==pygame.K_左:
#使屏幕左侧的snake实例面向右侧
蛇
snake.rect.x=-96
snake.rect.y=0
snake.direction=“right”
snake.frame=0
snake.change_x=0
snake.change_y=0
snake.sprite=“snake\u right\u 1”
#添加到snake列表
snake_列表。添加(snake)
elif event.key==pygame.K_RIGHT:
#使屏幕右侧的snake实例面向左侧
蛇
snake.rect.x=1376
snake.rect.y=0
snake.direction=“左”
snake.frame=0
snake.change_x=0
snake.change_y=0
snake.sprite=“sanke_left_1”
#添加到snake列表
snake_列表。添加(snake)
elif event.key==pygame.K_w:
打印(snake\u list.sprites())
#---游戏逻辑------------------------------------------
#实际程序中的移动攻击这种方法更为复杂/有用
攻击_区域。移动()
#---图纸代码-------------------------------------------
屏幕填充(黑色)
#闪电背景
blit(背景图像,[0,0])
#移动/更新列表中的所有蛇
import pygame
SCREEN_SIZE = (1280, 720)
SNAKE_SPEED = 2

# Define some colors
BLACK    = (   0,   0,   0)
WHITE    = ( 255, 255, 255)

#CREATE LIST:
snake_list = pygame.sprite.Group()

#SANKE SLITHER animation
animation_index_snake = 0
animation_frame_snake = 0

# Initialize the game engine
pygame.init()

#Create Screen
screen = pygame.display.set_mode(SCREEN_SIZE)

#LOAD IMAGES AS VARIABLES:
background_image = pygame.image.load("game/gamefolder/images/backgrounds/background_1.png").convert()
#snakes
snake_left_1 = pygame.image.load("game/gamefolder/images/enemies/sanke/sanke_left_1.png").convert_alpha()
snake_left_2 = pygame.image.load("game/gamefolder/images/enemies/sanke/sanke_left_2.png").convert_alpha()
snake_right_1 = pygame.image.load("game/gamefolder/images/enemies/sanke/sanke_right_1.png").convert_alpha()
snake_right_2 = pygame.image.load("game/gamefolder/images/enemies/sanke/sanke_right_2.png").convert_alpha()

#MAKE SNAKE CLASS
class Snake(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.change_x = 0
        self.change_y = 0
        #transitions from 0 to 1:
        self.frame = 0
        #direction snake is facing
        self.direction = "left"
        self.image = snake_left_1
        self.rect = self.image.get_rect()   

    def update(self):
        super().__init__()        
        sanke_dimensions = self.image.get_rect()     
        #y coord so snake is on ground
        self.rect.y = 472    
        #Move the snake
        #if the snake is to the left of x 900 then
        if self.rect.x <= 900:
            #move right
            self.change_x = SNAKE_SPEED
            #face right
            self.direction = "right"
        #if the snake is to the right of x 900 then
        if self.rect.x > 900:
            #move left
            self.change_x = -1*SNAKE_SPEED
            #face left
            self.direction = "left"

        #UPDATE
        self.rect.x += self.change_x
        self.rect.y += self.change_y

        #set sprite according to direction and frame
        if self.direction == "left":
            if animation_index_snake == 0:
                self.image = snake_left_1
            if animation_index_snake == 1:
                self.image = snake_left_2
        if self.direction == "right":
            if animation_index_snake == 0:
                self.image = snake_right_1
            if animation_index_snake == 1:
                self.image = snake_right_2

        #check if any snakes were hurt    
        col = pygame.sprite.collide_rect(self, attack_area)
        if col == True:
            #BUG OCCURS HERE
            snake_list.remove(self)

class Attack_area(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        #make a surface
        self.image = pygame.Surface([72, 118])
        self.image.fill(WHITE) 
        self.rect = self.image.get_rect()

    def move(self):
        #move surface to center of screen (simplified for debugging)
        self.rect.x = 600
        self.rect.y = 472

#--------main program----------                
attack_area = Attack_area()

# Loop until the user clicks the close button.
done = False

# Used to manage how fast the screen updates
clock = pygame.time.Clock()

# -------- Main Program Loop ---------------------------------------------------
while not done: 
    # --- Main event loop-------------------------------------------------------
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done = True # Flag that we are done so we exit this loop
        # User pressed down on a key
        elif event.type == pygame.KEYDOWN:

            #spawn enemy snake (either side of screen:)
            if event.key == pygame.K_LEFT:
                #make snake instance on left side of screen facing right
                snake = Snake()
                snake.rect.x = -96
                snake.rect.y = 0
                snake.direction = "right"
                snake.frame = 0
                snake.change_x = 0
                snake.change_y = 0   
                snake.sprite = "snake_right_1"
                #add to snake list
                snake_list.add(snake)


            elif event.key == pygame.K_RIGHT:
                #make snake instance on right side of screen facing left
                snake = Snake()
                snake.rect.x = 1376
                snake.rect.y = 0
                snake.direction = "left"
                snake.frame = 0
                snake.change_x = 0
                snake.change_y = 0    
                snake.sprite = "sanke_left_1"
                #add to snake list
                snake_list.add(snake)                 
            elif event.key == pygame.K_w:
                print(snake_list.sprites())
    # --- Game logic --------------------------------------------- 


    #move attack in actual program this method would be more complex/useful
    attack_area.move()

    # --- Drawing code -------------------------------------------
    screen.fill(BLACK)

    #blit background 
    screen.blit(background_image, [0, 0])
    #move/update all snakes in list
    snake_list.update()
    #draw all snakes in list
    snake_list.draw(screen)

    # --- Go ahead and update the screen with what we've drawn------------------
    pygame.display.flip()

    # --- Clock Work------------------------------------------------------------
    #Limit to 60 frames per second
    clock.tick(60)
    #one frame passed:
    animation_frame_snake += 1
    #(18 is how many frames the animation frame should be shown for)
    if animation_frame_snake >= 18:
        #reset
        animation_frame_snake = 0
        #alternate index between 0 & 1
        if animation_index_snake == 0:
            animation_index_snake = 1
        elif animation_index_snake == 1:
            animation_index_snake = 0

#now left main program loop (because user pressed X), so quit
pygame.quit()
builtins.KeyError: <Group(1 sprites)>