玩家与精灵群体之间的Pygame中的碰撞检测mudballGroup
我正在关注如何检测类玩家与精灵群体MudballGroup之间的冲突。当在语句pg.sprite.spritecollide(Player,mudballGroup,False)中设置碰撞时,我得到错误类型对象'Player'没有属性'rect'。我从我的播放器精灵的代码显示rect在下面的语句中定义:self.rect = self.image.get_rect()。我不知道为什么我得到这个错误。请有人帮忙。玩家与精灵群体之间的Pygame中的碰撞检测mudballGroup
class Player(pg.sprite.Sprite):
def __init__(self, game):
pg.sprite.Sprite.__init__(self)
self.game = game
self.walking = False
self.jumping = False
self.current_frame = 0
self.last_update = 0
self.load_images()
self.image = self.girl_standing[0]
#Isn't this my rect attribute for Player?
self.rect = self.image.get_rect()
self.rect.center = (WIDTH/2, HEIGHT/2)
self.pos = vec(WIDTH/2, HEIGHT/2)
self.vel = vec(0, 0)
self.acc = vec(0, 0)
self.screen = pg.display.set_mode((WIDTH, HEIGHT))
self.clock = pg.time.Clock()
def shoot(self):
mudball = MUDBALL(self.rect.centerx, self.rect.centery)
print("SHOOT function")
self.game.all_sprites.add(mudball)
mudballGroup = pg.sprite.Group()
mudballGroup.add(mudball)
# Me attempting collision
hits = pg.sprite.spritecollide(self.player, mudballGroup, False)
if hits:
print("HITS!!!!!!!!", hits)
def hailing(self):
jets = JETS()
print("FLYOVER")
self.game.all_sprites.add(jets)
jetsGroup = pg.sprite.Group()
jetsGroup.add(jets)
class MUDBALL(pg.sprite.Sprite):
def __init__(self, x, y):
pg.sprite.Sprite.__init__(self)
self.image = pg.image.load("SLIMEballGREEN.png")
# self.mudballGroup = pg.sprite.Group()
self.rect = self.image.get_rect()
self.rect.bottom = y
self.rect.centerx = x
self.speedx = -30
def update(self):
self.rect.x += self.speedx
#kill if moves off screen
if self.rect.centerx < 0:
self.kill()
class JETS(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.image.load("JETSscaled.png")
#self.jetsGroup = pg.sprite.Group()
self.rect = self.image.get_rect()
self.rect.x = 1366
self.rect.y = 0
self.speedx = -70
def update(self):
self.rect.x += self.speedx
#kill if moves off screen
if self.rect.x + 848 < 0:
self.kill()
您使用的是Player
类的碰撞检测,但你必须使用这个类的一个实例来代替。
# Player is the class, but spritecollide needs an instance.
hits = pg.sprite.spritecollide(Player, mudballGroup, False)
要创建Player
类的一个实例,只写:
# Don't forget to pass the game instance to the `Player`s __init__ method.
player = Player(game)
它还看起来很奇怪,我认为你定义mudballGroup
的shoot
方法里面。这意味着这个小组只会包含一个模拟球,但是你也可以检查球员的反应和泥球是否碰撞:player.rect.colliderect(mudball.rect)
而不是spritecollide
。但是,如果你想多mudballs您需要将mudballGroup
存储为其他类的属性,在__init__
方法写:
self.mudballGroup = pg.sprite.Group()
编辑:好吧,你已经有了一个self.player
比如在你的游戏实例。我建议在Game
类别中定义mudballGroup
,然后将其传递给玩家的shoot
方法,并将其传递给all_sprites
组,以添加模糊球。碰撞检测可以在游戏的update
方法中完成。
class Game:
def new(self):
# Other code omitted ...
self.mudballGroup = pg.sprite.Group()
def update(self):
# Check if the player is shooting.
if self.player.shooting: # You have to add a `shooting` attribute to player.
# `shoot` just adds a mudball to these groups.
self.player.shoot(self.all_sprites, self.mudballGroup)
# Then detect collisions.
hits = pg.sprite.spritecollide(self.player, self.mudballGroup, False)
if hits:
print("HITS!!!!!!!!", hits)
class Player(pg.sprite.Sprite):
# Pass the sprite groups of the game to the shoot method.
def shoot(self, all_sprites, mudballGroup):
mudball = MUDBALL(self.player.centerx, self.player.centery)
# Add sprite to the passed groups.
all_sprites.add(mudball)
mudballGroup.add(mudball)
编辑2:这里的其他变种。在创建实例时(您不必传递完整的游戏实例)将两个需要的精灵组传递给玩家,然后将它们设置为玩家的属性。
class Game:
def new(self):
# Other code omitted ...
self.all_sprites = pg.sprite.Group()
self.mudballGroup = pg.sprite.Group()
self.player = Player(self.all_sprites, self.mudballGroup)
def update(self):
# Check if the player is shooting.
if self.player.shooting:
# `shoot` adds a mudball to self.all_sprites & self.mudballGroup.
self.player.shoot()
# Then detect collisions.
hits = pg.sprite.spritecollide(self.player, self.mudballGroup, False)
if hits:
print("HITS!!!!!!!!", hits)
class Player(pg.sprite.Sprite):
def __init__(self, all_sprites, mudballGroup):
# Other code omitted ...
# These two attributes are references to the groups
# that were defined in the Game class.
self.all_sprites = all_sprites
self.mudballGroup = mudballGroup
def shoot(self):
mudball = MUDBALL(self.player.centerx, self.player.centery)
# Add sprite to the passed groups.
self.all_sprites.add(mudball)
self.mudballGroup.add(mudball)
编辑3:好吧,忘记shooting
属性(也只是需要对播放器实例,以检查用户是否正在拍摄)。您也不需要在游戏类中调用特朗普的shoot
方法,因为您已经在他的update
方法中调用了它。所以这是更新后的代码:
class Game(pg.sprite.Sprite):
def new(self):
# Other code omitted ...
self.all_sprites = pg.sprite.Group()
self.mudballGroup = pg.sprite.Group()
# Pass the groups to trump during the instantiation.
# You don't have to pass the complete game instance (self).
self.trump = TRUMP(self.all_sprites, self.mudballGroup)
self.all_sprites.add(self.trump)
def update(self):
hits = pg.sprite.spritecollide(self.player, self.mudballGroup, False)
for collided_sprite in hits:
print("HIT", collided_sprite)
class TRUMP(pg.sprite.Sprite):
def __init__(self, all_sprites, mudballGroup):
# Now set the passed groups as attributes of the trump instance.
# These attributes are references to the same sprite groups as
# in the Game class.
self.all_sprites = all_sprites
self.mudballGroup = mudballGroup
def shoot(self):
print("SHOOT function")
mudball = MUDBALL(self.rect.centerx, self.rect.centery)
# Add the mudball to the groups.
self.all_sprites.add(mudball)
self.mudballGroup.add(mudball)
对不起,我是新手。为了简单起见,我宁愿使用spritecollide。我如何编码一个球员的实例?它是self.Player?如果我不在那里制造泥巴小组,那它应该去哪里?非常感谢您的帮助。 –
我编辑了答案,向您展示如何创建播放器实例/对象。此外,mudballGroup可能应该是其他类的属性,那么你可以继续使用'spritecollide'函数。 – skrx
我实际上猜测你已经有一个播放器实例,否则你的游戏根本无法工作。所以另一个类或者需要引用这个'player'实例,或者你需要将它作为参数传递给'shoot'方法。如果我能看到完整的代码,我可能会给你更多的建议,但Stack Overflow不是正确的代码审查网站。当您的代码正常工作时,您可以在http://codereview.stackexchange.com/上发布它以获取一些提示。 – skrx
''Player''是一类。你需要制作一个实例来实际使用它。程序。请参阅https://learnpythonthehardway.org/book/ex40.html –
我宁愿推荐程序街机游戏[关于类和精灵的章节](http://programarcadegames.com/index.php?chapter=introduction_to_classes&lang=de#section_12 )(12和13)。 – skrx
请记住,您应该在这里发布[完整但很少的示例](http://stackoverflow.com/help/mcve)。我们需要我们可以复制,粘贴和运行的代码。 – skrx