2013-11-15 2 views
1

Я пытался написать платформер в Pygame, но за последние несколько недель я застрял в обнаружении столкновения между героем и платформой. Вот мои классы:Платформер Столкновение в Pygame

class Platform(object): 
    def __init__(self, colour, rect): 
     self.colour = colour 
     self.rect = rect 

    def draw(self, screen): 
     pygame.draw.rect(screen, self.colour, self.rect) 


class Character(Block): 
    def __init__(self, colour, rect, speed): 
     super().__init__(colour, rect) 
     (self.dx, self.dy) = speed 
     self.is_falling = True 

    def update(self, platforms): 
     self.is_falling = True 
     for platform in platforms: 
      if self.is_on(platform): 
       self.rect.bottom = platform.rect.top 
       self.dy = 0 
       self.is_falling = False 

     if self.is_falling: 
      self.gravity() 
     self.rect.x += self.dx 
     self.rect.y += self.dy 

    def is_on(self, platform): 
     return (pygame.Rect(self.rect.x, self.rect.y + self.dy, 
          self.rect.width, self.rect.height) 
       .colliderect(platform.rect) and self.dy > 0) 

    def left(self): 
     self.dx = -5 

    def right(self): 
     self.dx = 5 

    def stop_x(self): 
     self.dx = 0 

    def jump(self): 
     if self.dy == 0: 
      self.dy = -25 

    def gravity(self): 
     self.dy += 5 

и здесь мои функции:

def key_down(event, character): 
    if event.key == pygame.K_LEFT: 
     character.left() 
    elif event.key == pygame.K_RIGHT: 
     character.right() 
    elif event.key == pygame.K_UP: 
     character.jump() 

def key_up(event, character): 
    if event.key in (pygame.K_LEFT, pygame.K_RIGHT): 
     character.stop_x() 

def main(): 
    pygame.init() 
    screen = pygame.display.set_mode((640, 480)) 
    pygame.display.set_caption("PyPlatformer") 
    hero = Character((255, 255, 0), pygame.Rect(100, 0, 20, 20), (0, 0)) 
    platform1 = Block((0, 255, 255), pygame.Rect(100, 100, 100, 10)) 
    platform2 = Block((0, 255, 255), pygame.Rect(150, 150, 100, 10)) 
    platforms = (platform1, platform2) 
    clock = pygame.time.Clock() 
    while True: 
     clock.tick(60) 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       pygame.quit() 
       sys.exit() 
      elif event.type == pygame.KEYDOWN: 
       key_down(event, hero) 
      elif event.type == pygame.KEYUP: 
       key_up(event, hero) 

     screen.fill((0, 0, 0)) 
     hero.update(platforms) 
     [platform.draw(screen) for platform in platforms] 
     hero.draw(screen) 
     pygame.display.update() 

Однако, когда Character сидит на Block, обнаружение столкновения терпит неудачу, и персонаж падает через блок. Однако, когда он движется и внутри блока, обнаружение завершается успешно, и персонаж возвращается к сидящему на блоке. Затем этот цикл повторяется, и символ выглядит так, будто он отскакивает от блока.

Что вызывает эта ошибка? Как это исправить?

+0

добавить много 'print' с различными значениями, замедлить игру до 2 FPS и наблюдать напечатанную tex т. – furas

ответ

0

Эта версия работает для меня:

def is_on(self, platform): 
    return (pygame.Rect(self.rect.x, self.rect.y + self.dy+1, # +1 
         self.rect.width, self.rect.height) 
      .colliderect(platform.rect)) 

добавить +1 и удалить dy > 0


By The Way: Я нашел другую проблему.

Если вы поставите платформы слишком близко (см 128 в platform2)

platform1 = Block((0, 255, 255), pygame.Rect(100, 100, 100, 10)) 
platform2 = Block((0, 255, 255), pygame.Rect(150, 128, 100, 10)) # 128 

игрок, стоящий на platform2 может коснуться platform1, и он перемещается на platform1

Он может двигаться мне действительно высоко :)

platforms = [] 
platforms.append(Block((0, 255, 255), pygame.Rect(100, 400, 100, 10))) 
platforms.append(Block((0, 255, 255), pygame.Rect(150, 428, 100, 10))) 
platforms.append(Block((0, 255, 255), pygame.Rect(250, 28, 10, 400))) 
+0

Вместо удаления 'dy> 0' я добавил' dy> = 0' – LazySloth13

+0

Я сделал это как первый, но не помог - только '+ 1' в' self.rect.y + self.dy + 1' в работа обнаружения для меня. – furas

+0

Но я нашел другую проблему - я прыгнул с высокой стены, и я не остановился на полу - гравитация была большой, поэтому я слишком быстро передвигался, чтобы обнаружить пол :) – furas

Смежные вопросы