【问题标题】:Wall collision in pygamepygame中的墙壁碰撞
【发布时间】:2017-12-13 23:11:24
【问题描述】:

我试图让碰撞起作用,但是当两个矩形碰撞时,它们会稍微相互碰撞,但我希望第二个矩形像一堵墙一样。有人知道我该如何解决这个问题吗?或者有没有更好的方法来为我的游戏添加碰撞?这就是我现在所拥有的。

import pygame

pygame.init()
screen = pygame.display.set_mode((1000, 800))
pygame.display.set_caption("Squarey")
done = False
is_red = True
x = 30
y = 30
x2 = 100
y2 = 30
clock = pygame.time.Clock()
WHITE = (255,255,255)
RED = (255,0,0)

charImg = pygame.image.load('character.png')



rect1 = pygame.Rect(30, 30, 60, 60)

rect2 = pygame.Rect(100, 100, 60, 60)

x_change = 0
y_change = 0

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True


#movement
      #left
    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_LEFT:
        x_change = -5
        y_change = 0

        #right
      elif event.key == pygame.K_RIGHT:
        x_change = 5
        y_change = 0
      #key release left and right
    if event.type == pygame.KEYUP:
      if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
        x_change = 0
        y_change = 0


      #up    
    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_UP:
        y_change = -5
        x_change = 0


        #down
      elif event.key == pygame.K_DOWN:
        y_change = 5
        x_change = 0


      #key release up and down
    if event.type == pygame.KEYUP:
      if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
        y_change = 0
        x_change = 0 
    rect1.x = rect1.x + x_change
    rect1.y = rect1.y + y_change

    screen.fill((0, 0, 0))

    pygame.draw.rect(screen, WHITE, rect1)
    pygame.draw.rect(screen, RED, rect2)

    if rect1.bottom > screen.get_rect().bottom:
      rect1.center = screen.get_rect().center

    #if rect1.colliderect(rect2):
    if rect1.colliderect(rect2):
      #print("Collision !!")

      rect1.x = rect1.x - x_change
      rect1.y = rect1.y - y_change

    pygame.display.flip()
    clock.tick(60)

pygame.quit()

【问题讨论】:

  • 您很可能在计算碰撞检测之前渲染每一帧。您需要颠倒这两个步骤。
  • screen.fill((0, 0, 0))之前进行所有计算
  • 顺便说一句:与两堵墙发生碰撞 - 即。在左侧和底部 - 最好先仅更改 rect.x,然后检查碰撞,然后仅更改 rect.y 并再次检查碰撞。这样做是因为colliderect 不会通知您是否仅在左侧或仅在底部或两者上发生碰撞。请参阅Lab 16: Pygame Platformer Examples 中的示例
  • 感谢您的快速帮助。它现在正在工作。

标签: python pygame collision


【解决方案1】:

您正在绘制矩形,然后在它们相互碰撞时将它们放回原处,以便它们相互移动片刻。确保在计算完成后进行所有绘图。

【讨论】:

    【解决方案2】:

    您的程序的唯一问题是您在检查碰撞之前绘制矩形。

    因为没有太多答案,所以我正在为其他人写一个。您需要两个变量 xy 来存储之前的位置,即碰撞前的位置。然后您需要使用Rect.colliderect 检查两个矩形是否发生碰撞。如果它们发生碰撞,则将当前位置重置为之前的位置,然后绘制墙。

    import pygame
    
    pygame.init()
    screen = pygame.display.set_mode((1000, 800))
    
    done = False
    
    clock = pygame.time.Clock()
    
    WHITE = (255,255,255)
    RED = (255,0,0)
    
    rect1 = pygame.Rect(30, 30, 60, 60)
    rect2 = pygame.Rect(100, 100, 60, 60)
    
    previous_x, previous_y = 0, 0
    x_change, y_change = 0, 0
    
    speed = 5
    
    while not done:
    
        screen.fill((0, 0, 0))
    
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
    
            if event.type == pygame.KEYDOWN:
    
                if event.key == pygame.K_LEFT:
                    x_change = -speed
                    y_change = 0
    
                if event.key == pygame.K_RIGHT:
                    x_change = speed
                    y_change = 0
    
                if event.key == pygame.K_UP:
                    y_change = -speed
                    x_change = 0
    
                if event.key == pygame.K_DOWN:
                    y_change = speed
                    x_change = 0
    
            if event.type == pygame.KEYUP:
                x_change = 0
                y_change = 0
    
        previous_x = rect1.x
        previous_y = rect1.y
    
        rect1.x = rect1.x + x_change
        rect1.y = rect1.y + y_change
    
        if rect1.colliderect(rect2):
            print("Collision")
            rect1.x = previous_x
            rect1.y = previous_y
    
        pygame.draw.rect(screen, WHITE, rect1)
        pygame.draw.rect(screen, RED, rect2)
    
        pygame.display.flip()
        clock.tick(60)
    
    pygame.quit()
    

    如果您有许多墙,请将它们的所有矩形存储在一个列表中。然后使用 pygame 的Rect.collidelist 来检查是否有碰撞。(注意:如果没有碰撞,collidelist 返回-1)。如果有则重置到之前的位置。

    【讨论】:

      猜你喜欢
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      • 1970-01-01
      • 1970-01-01
      • 2016-10-26
      • 2023-03-25
      • 1970-01-01
      相关资源
      最近更新 更多