Обнаружение столкновений с использованием спрайтов в Pygame - PullRequest
1 голос
/ 13 января 2011

Я пытаюсь использовать обнаружение столкновений, чтобы определить, когда моя мышь попадает в импортированное мной изображение.Я получаю сообщение об ошибке «У кортежа нет атрибута rect»

 def main():


    #Call the SDL arg to center the window when it's inited, and then init pygame
    os.environ["SDL_VIDEO_CENTERED"] = "1"
    pygame.init()

    #Set up the pygame window
    screen = pygame.display.set_mode((600,600))


    image_one = pygame.image.load("onefinger.jpg").convert()

    screen.fill((255, 255, 255))
    screen.blit(image_one, (225,400))
    pygame.display.flip()

    while 1:
        mousecoords = pygame.mouse.get_pos() 
        left = (mousecoords[0], mousecoords[1], 10, 10)
        right = image_one.get_bounding_rect()
        if pygame.sprite.collide_rect((left[0]+255, left[1]+400, left[2], left[3]), right):
            print('Hi')

Ответы [ 3 ]

1 голос
/ 14 января 2011

Проблема в том, что pygame.sprite.collide_rect () принимает два объекта Sprite. Вы передаете ему два кортежа - ни курсор, ни изображение не являются спрайтами и поэтому не имеют атрибута rect.

Вы можете создать Sprite, используя image_one, но будет сложнее преобразовать курсор в Sprite. Я думаю, что было бы проще вручную проверить, находится ли курсор внутри изображения.

#Set up the pygame window
screen = pygame.display.set_mode((200,200))
screen.fill((255, 255, 255))

#Set up image properties (would be better to make an object)
image_one = pygame.image.load("image_one.png").convert()
image_x = 225
image_y = 400
image_width = image_one.get_width()
image_height = image_one.get_height()

# Mouse properties
mouse_width = 10
mouse_height = 10

screen.blit(image_one, (image_x, image_y))
pygame.display.flip()

while 1:
    for event in pygame.event.get():
        if event.type == pygame.MOUSEMOTION:
            mouse_x, mouse_y = pygame.mouse.get_pos()

            # Test for 'collision'
            if image_x - mouse_width < mouse_x < image_x + image_width and image_y - mouse_height < mouse_y < image_y + image_height:
                print 'Hi!'

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

0 голосов
/ 26 августа 2014

Питер предложил, и вы также поняли, что легче работать с Rects вместо позиций при работе с обнаружением столкновений.

Я бы сделал еще один шаг: всегда работаю с Спрайтами !

С помощью Sprites вы получаете доступ ко всем этим удобным функциям обнаружения столкновений в pygame.sprite. И если вы когда-нибудь решите переместить это изображение, гораздо проще обновить положение и анимировать. Он также содержит поверхность изображения, все в одном объекте. Не говоря уже о спрайте Группы !

Спрайты также имеют атрибут .rect, поэтому вы всегда можете выполнять низкоуровневые прямоугольные манипуляции, если хотите, с помощью mysprite.rect

Тем не менее, вот как вы можете получить Sprite из вашего изображения:

image_one = pygame.sprite.Sprite()
image_one.image = pygame.image.load("image_one.png").convert()
image_one.rect = pygame.Rect((image_x, image_y), image_one.image.get_size())

Создайте больше спрайтов для image_two, _three и т. Д. Или создайте функцию (или, что еще лучше, подкласс Sprite), получая в качестве аргументов позицию и имя файла, чтобы вы могли создавать спрайты в одиночная строка как:

image_two = MySprite(filename, x, y)

Теперь вы можете при желании группировать их:

my_images = pygame.sprite.Group(image_one, image_two, image_three)

Рисование так же просто, как:

my_images.draw(screen)

Это приведет к блику всех изображений одновременно , каждое на своих позициях! Круто, да?

Давайте создадим «поддельный» спрайт для курсора мыши:

mouse = pygame.sprite.Sprite()
mouse.rect = pygame.Rect(pygame.mouse.get_pos(), (1, 1))

Я сделал его спрайтом 1х1, чтобы он сталкивался только с горячей точкой мыши. Обратите внимание, что у него нет атрибута .image (отсюда и «поддельный» спрайт), но pygame это не волнует, так как мы не собираемся его рисовать.

А теперь лучшая часть:

imagehit = pygame.sprite.spritecollideany(mouse, my_images)
print imagehit

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

Использование спрайтов действительно окупается;)

0 голосов
/ 13 января 2011

Это не относится к pygame или python, но может помочь.

У Lazy Foo есть много отличных руководств по SDL, но они есть в C ++.Они чрезвычайно хорошо прокомментированы, хотя.Ссылка на них здесь: http://www.lazyfoo.net/SDL_tutorials/index.php

...