Как сделать, чтобы у спрайта, отображаемого дважды, было два отдельных поля столкновения в Pygame?

#python #pygame #collision-detection #collision #blit

#python #pygame #обнаружение столкновений #столкновение #blit

Вопрос:

Я не знаю, было ли мое название очень понятным, поэтому я попытаюсь объяснить это более четко здесь. Итак, у меня есть вызываемый спрайт в Pygame spikes . Я хочу, чтобы их было больше одного spikes , поэтому я blit добавляю второй. Проблема в том, что мой spike_collision блок работает только с первым, который я запускаю, а не со вторым. Помимо необходимости создания второго поля столкновения, как я могу сделать так, чтобы у второго spikes тоже было собственное поле столкновения?

Вот blit код:

         screen.blit(spikes, (spike_x, 500 - player_y   476))
        screen.blit(spikes, (spike_x   200, 500 - player_y   476))
 

Вот код поля столкновения:

 spike_collision = spikes.get_rect(topleft=(spike_x, 500 - player_y   476))
 

Спасибо.

Комментарии:

1. Почему бы просто не создать два спрайта?

2. да, я могу это сделать, но…. Я вроде как хочу сократить код. У меня уже довольно много кода, но он почти ничего не делает.

Ответ №1:

Я предполагаю, что когда вы пишете «sprite», вы имеете в виду bitmap-sprite, а не pygame.sprite.Sprite .

Вероятно, лучше всего поддерживать спрайт в виде растрового изображения и прямоугольника, затем всегда рисовать спрайт в его прямоугольнике, регулируя прямоугольник для изменения положения спрайта и используя его для любых столкновений.

Это можно легко сделать с помощью пар списков:

 spike_image = pygame.image.load('spikes.png').convert_alpha()
spike_rect  = spike_image.get_rect( )
spikes_a = [ spike_image, spike_rect( top_left=( 100, 100 ) )
spikes_b = [ spike_image, spike_rect( top_left=( 200, 200 ) )

# ...

screen.blit( spikes_a[0], spikes_a[1] )
screen.blit( spikes_b[0], spikes_b[1] )
# etc.

if ( spikes_a[1].colliderect( player_rect ) ):
    print( "ouch!" )
 

Однако вам следовало бы использовать «правильный» объект спрайта. Конечно, есть немного дополнительных настроек, но это многократно окупается простотой использования:

 class Spike( pygame.sprite.Sprite ):
    def __init__( self, position=( 0, 0 ) ):
        self.image = pygame.image.load('spikes.png').convert_alpha()
        self.rect  = self.image.get_rect( top_left = position )

    def moveTo( self, position ):
        self.rect  = self.image.get_rect( top_left = position )

    def moveBy( self, dx, dy ):
        self.rect.move_ip( dx, dy )


spike_a = Spike( ( 100, 100 ) )
spike_b = Spike( ( 200, 200 ) )

spike_a.draw( window )  # get this for free
 

Существует множество полезных функций группирования и столкновения, которые поставляются вместе с использованием объектов Sprite, это стоит прочитать: https://www.pygame.org/docs/ref/sprite.html