gpt4 book ai didi

python - 从组中删除 Sprite

转载 作者:太空宇宙 更新时间:2023-11-04 04:35:37 26 4
gpt4 key购买 nike

我正在用 pygame 制作游戏,到目前为止角色可以跳跃、奔跑、用剑和弓攻击,我可以在他的两边生成蛇来追他。现在我希望玩家能够攻击蛇并让它死亡/消失。我通过在玩家攻击时生成一个 Sprite (attack_area) 来做到这一点。每一帧蛇都会检查它们是否与攻击区域发生碰撞。错误发生在检测到碰撞之后以及我想从列表中删除蛇时。

这是一个错误示例,发生在我生成了两条蛇并且其中一条与 attack_area 相撞之后。

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)>

错误发生的地方:

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

由于我的游戏超过 1000 行,我删除了所有与此错误无关的内容,现在它不到 200 行,(同样的错误仍然发生)。缩短的程序只允许用户在屏幕的任一侧生成蛇,它们向 x 900 移动。当它们与始终位于 x 600 的 attack_area 发生碰撞时,错误就会发生。

这是整个程序

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)>

最佳答案

问题是您在 update 方法中的每一帧都调用了 super().__init__()。只需删除这一行,程序就会正常运行。

当您调用 super().__init__() 时, Sprite 的 _Sprite__g 属性(包含 Sprite 的 Sprite 组字典)将被设置为空字典,即使它仍在 snake_list 中。所以,snake_list 组仍然包含 Sprite ,但 Sprite 认为它不在任何组中。

现在当你调用snake_list.remove(self)时, Sprite 组调用带有self的 Sprite 的remove_internal方法(组) 作为一个参数,这样 Sprite 就可以通过删除其组字典 del self.__g[group] 中的那个键来将自己从该组中删除,但是字典是空的,因此出现 KeyError 被提升。

这是 sprite module如果您想查看源代码。

关于python - 从组中删除 Sprite ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51803236/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com