あなたはスプライトクラスに追加offset
属性(Vector2)を得た後、forループでスプライトを反復して、画像を、ブリットしているとき.rect.topleft
位置にこのoffset
を追加することができます。完全を期すために
import pygame as pg
from pygame.math import Vector2
class Player(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.image = pg.Surface((220, 120))
self.image.fill(pg.Color('steelblue2'))
self.rect = self.image.get_rect(center=pos)
self.rect.inflate_ip(-42, -72) # Make the rect smaller.
self.vel = Vector2(0, 0)
self.pos = Vector2(pos)
# Offset is half of the inflation size,
# so that the rect will be centered.
self.offset = Vector2(-21, -36)
def update(self):
self.pos += self.vel
self.rect.center = self.pos
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group()
player = Player((300, 200), all_sprites)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_d:
player.vel.x = 5
elif event.type == pg.KEYUP:
if event.key == pg.K_d:
player.vel.x = 0
all_sprites.update()
screen.fill((30, 30, 30))
# Assign `blit` to a local variable to improve the performance.
screen_blit = screen.blit
for sprite in all_sprites:
# Now blit the sprites at topleft + offset.
screen_blit(sprite.image, sprite.rect.topleft+sprite.offset)
pg.draw.rect(screen, (250, 30, 0), sprite.rect, 2)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
、ここでは第二と解決策だ、「ヒットボックス」RECTとあなたはpygame.sprite.spritecollide
のような衝突検出機能の一つに渡すことができるカスタムcollided
コールバック関数をスケールされました。
import pygame as pg
from pygame.math import Vector2
class Player(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.image = pg.Surface((70, 40))
self.image.fill(pg.Color('steelblue4'))
self.rect = self.image.get_rect(center=pos)
# A inflated rect as the hitbox.
self.hitbox = self.rect.copy()
self.hitbox.inflate_ip(-42, -22)
self.vel = Vector2(0, 0)
self.pos = Vector2(pos)
def update(self):
self.pos += self.vel
self.rect.center = self.pos
self.hitbox.center = self.pos # Also update the hitbox coords.
def collided(sprite, other):
"""Check if the hitboxes of the two sprites collide."""
return sprite.hitbox.colliderect(other.hitbox)
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group()
player = Player((300, 200), all_sprites)
enemies = pg.sprite.Group(
Player((100, 250), all_sprites),
Player((400, 300), all_sprites),
)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEMOTION:
player.pos = event.pos
all_sprites.update()
# Pass the custom collided callback function to spritecollide.
collided_sprites = pg.sprite.spritecollide(
player, enemies, False, collided)
for sp in collided_sprites:
print('Collision', sp)
screen.fill((30, 30, 30))
all_sprites.draw(screen)
for sprite in all_sprites:
# Draw rects and hitboxes.
pg.draw.rect(screen, (0, 230, 0), sprite.rect, 2)
pg.draw.rect(screen, (250, 30, 0), sprite.hitbox, 2)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
私は.image'は 'topleft'を値を使用することはありません'を知っている - それだけの幅と高さを返すために、 'Rect'を使用しています。 '.image'をblitするには、位置を保持する' .rect'( 'topleft')を使用する必要があります。 – furas