Python-pygame 如何在精灵之间进行光环碰撞? [英] Python-pygame How to make an aura collision between sprites?
问题描述
所以,当精灵玩家绕过(而不是越过)另一个精灵时,我试图得到一个反应.
so, Im trying to get a reaction when the sprite player pass around (not over) another sprite.
到目前为止,我的想法是这样的:
So far my idea is something like:
if (sprite.x +100) > player.x > (sprite.x -100) and (sprite.y +100) > player.y > (sprite.y -100):
print("hit")
# Sprite.x and y are the position of the rect, not the whole image
这行得通,但有什么方法可以简化它吗?我也在想如何摆脱 100 像素
This works but there is some way to simplify it? Also Im thinking how to get rid of the 100 pixels
推荐答案
如果您想使用缩放的 rect 进行碰撞检测,您可以扩大您的原始 rect(或创建一个新的)并将其分配为单独的属性到你的精灵(我称之为 hitbox
在这里).原始的 rect
将仅用于存储位置.
If you want to use a scaled rect for the collision detection, you can inflate your original rect (or create a new one) and assign it as a separate attribute to your sprite (I call it hitbox
here). The original rect
will only be used to store the position.
创建一个自定义碰撞检测函数,该函数必须作为 collided
参数传递给 pygame.sprite.spritecollide
或 groupcollide
.在这个函数中,你可以使用 hitbox
矩形的 colliderect
方法来检查它是否与另一个精灵的矩形发生碰撞.
Create a custom collision detection function which has to be passed as the collided
argument to pygame.sprite.spritecollide
or groupcollide
. In this function you can use the colliderect
method of the hitbox
rect to check if it collides with the rect of the other sprite.
def hitbox_collision(sprite1, sprite2):
"""Check if the hitbox of the first sprite collides with the
rect of the second sprite.
`spritecollide` will pass the player object as `sprite1`
and the sprites in the enemies group as `sprite2`.
"""
return sprite1.hitbox.colliderect(sprite2.rect)
然后这样调用spritecollide
:
collided_sprites = pg.sprite.spritecollide(
player, enemies, False, collided=hitbox_collision)
这是一个完整的例子(红色矩形是hitbox,绿色矩形是用作blit位置的self.rect
):
Here's a complete example (the red rect is the hitbox and the green rect the self.rect
which is used as the blit position):
import pygame as pg
class Player(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.image = pg.Surface((30, 50))
self.image.fill(pg.Color('dodgerblue1'))
self.rect = self.image.get_rect(center=pos)
# Give the sprite another rect for the collision detection.
# Scale it to the desired size.
self.hitbox = self.rect.inflate(100, 100)
def update(self):
# Update the position of the hitbox.
self.hitbox.center = self.rect.center
class Enemy(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.image = pg.Surface((30, 50))
self.image.fill(pg.Color('sienna1'))
self.rect = self.image.get_rect(center=pos)
def hitbox_collision(sprite1, sprite2):
"""Check if the hitbox of the first sprite collides with the
rect of the second sprite.
`spritecollide` will pass the player object as `sprite1`
and the sprites in the enemies group as `sprite2`.
"""
return sprite1.hitbox.colliderect(sprite2.rect)
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group()
enemies = pg.sprite.Group()
player = Player((100, 300), all_sprites)
enemy = Enemy((320, 240), all_sprites, enemies)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEMOTION:
player.rect.center = event.pos
all_sprites.update()
collided_sprites = pg.sprite.spritecollide(
player, enemies, False, collided=hitbox_collision)
for enemy_sprite in collided_sprites:
print(enemy_sprite)
screen.fill((30, 30, 30))
all_sprites.draw(screen)
pg.draw.rect(screen, (0, 255, 0), player.rect, 1)
pg.draw.rect(screen, (255, 0, 0), player.hitbox, 1)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
<小时>
如果你想要一个圆形的碰撞区域,你可以通过 pygame.sprite.collide_circle 函数作为 collided
参数.
给你的精灵一个 self.radius
属性,
Give your sprites a self.radius
attribute,
class Player(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.radius = 100
并在主循环中将collide_circle
传递给spritecollide
.
and in the main loop pass collide_circle
to spritecollide
.
collided_sprites = pg.sprite.spritecollide(
player, enemies, False, collided=pg.sprite.collide_circle)
这篇关于Python-pygame 如何在精灵之间进行光环碰撞?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!