2015-04-15 3 views
2

Я составил список пуль и список спрайтов, используя классы ниже. Как определить, сталкивается ли пуля со спрайтом, а затем удаляет спрайт и пулю?Как обнаружить столкновение в pygame?

#Define the sprite class 
class Sprite: 

    def __init__(self,x,y, name): 
     self.x=x 

     self.y=y 

     self.image = pygame.image.load(name) 

     self.rect = self.image.get_rect() 

    def render(self): 
     window.blit(self.image, (self.x,self.y)) 


# Define the bullet class to create bullets   
class Bullet: 

    def __init__(self,x,y): 
     self.x = x + 23 
     self.y = y 
     self.bullet = pygame.image.load("user_bullet.BMP") 
     self.rect = self.bullet.get_rect() 

    def render(self): 
     window.blit(self.bullet, (self.x, self.y)) 
+0

Я хотел бы отметить, что в pygame есть класс Sprite - я не уверен, что его определение в коде - хорошая идея. Кроме того, они действительно нацелены (не хотят лучшего слова), поскольку спрайт - это просто объект с графическим представлением на экране (и, следовательно, ваша Bullet тоже спрайт). –

ответ

4

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

def is_collided_with(self, sprite): 
    return self.rect.colliderect(sprite.rect) 

Тогда вы можете назвать это нравится:

sprite = Sprite(10, 10, 'my_sprite') 
bullet = Bullet(20, 10) 
if bullet.is_collided_with(sprite): 
    print 'collision!' 
    bullet.kill() 
    sprite.kill() 

Кроме того, ваши классы обычно должны распространяться object, так замените class Sprite: на class Sprite(object): и т. д.

+3

Обратите внимание, что если скорость пули относительно цели больше, чем ширина цели за галочку, пуля может просто «телепортироваться» на другую сторону цели без удара. Если это может быть так, вам может потребоваться проверить прямоугольник, который представляет траекторию пули из предыдущего кадра в текущий кадр, а не только сам пулю. – 9000

2

Существует очень простой метод для того, что вы пытаетесь сделать, используя встроенные методы.

вот пример.

import pygame 
import sys 

class Sprite(pygame.sprite.Sprite): 
    def __init__(self, pos): 
     pygame.sprite.Sprite.__init__(self) 
     self.image = pygame.Surface([20, 20]) 
     self.image.fill((255, 0, 0)) 
     self.rect = self.image.get_rect() 

     self.rect.center = pos 

def main(): 
    pygame.init() 
    clock = pygame.time.Clock() 
    fps = 50 
    bg = [255, 255, 255] 
    size =[200, 200] 


    screen = pygame.display.set_mode(size) 

    player = Sprite([40, 50]) 
    player.move = [pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN] 
    player.vx = 5 
    player.vy = 5 


    wall = Sprite([100, 60]) 

    wall_group = pygame.sprite.Group() 
    wall_group.add(wall) 

    player_group = pygame.sprite.Group() 
    player_group.add(player) 

    while True: 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       return False 

     key = pygame.key.get_pressed() 

     for i in range(2): 
      if key[player.move[i]]: 
       player.rect.x += player.vx * [-1, 1][i] 

     for i in range(2): 
      if key[player.move[2:4][i]]: 
       player.rect.y += player.vy * [-1, 1][i] 

     screen.fill(bg) 

     # first parameter takes a single sprite 
     # second parameter takes sprite groups 
     # third parameter is a do kill commad if true 
     # all group objects colliding with the first parameter object will be 
     # destroyed. The first parameter could be bullets and the second one 
     # targets although the bullet is not destroyed but can be done with 
     # simple trick bellow 
     hit = pygame.sprite.spritecollide(player, wall_group, True) 

     if hit: 
      # if collision is detected call a function in your case destroy 
      # bullet 
      player.image.fill((255, 255, 255)) 

     player_group.draw(screen) 
     wall_group.draw(screen) 

     pygame.display.update() 
     clock.tick(fps) 

    pygame.quit() 
    sys.exit 


if __name__ == '__main__': 
    main() 
Смежные вопросы