【问题标题】:Collision detection: Ball landing on Platform碰撞检测:球落地平台
【发布时间】:2020-01-23 01:46:28
【问题描述】:

我正在尝试制作一款游戏,并且平台会随机生成移动到屏幕顶部。球落在正在生成的平台上。

for i in range (12):
    platforms.append([random.randint(1,w), random.randint(1,h), random.randint(speed,-1)])

while True:  
    screen.fill(black)

    # Platforms
    for  i in range (len(platforms)):
        pygame.draw.rect (screen,white,(platforms[i][0],platforms[i][1],rectW,rectH))
        platforms[i][1] = platforms [i][1] + platforms [i][2]
        if (platforms [i][1] < 0):
            platforms [i][1] = h-death
            platforms [i][0] = random.randint(1,w)
    # Collision Detection
    print (x1,y1,platforms[i][1])
    for i in range (len(platforms)):
        if x1 >= platforms[i][0] and x1 <= platforms[i][0] + rectW:
            print ('hello')
            if y1 == platforms[i][0]:
                print ("HIT")

要使 y1 随平台向上移动或打印“HIT”,我需要更改什么

【问题讨论】:

  • 顺便说一句:pygame 有pygame.Rect() 来保持位置和大小,它有player_rect.colliderect(platform_rect)
  • 要检查与平台的冲突,您还必须比较y - 但使用&lt;= 而不是==,如果有冲突,则始终设置player.bottom = platform.top - 但你必须使用pygame.Rect() 可以访问 rect.bottomrect.top 。当平台向上移动时,player.bottom = platform.top 也会向上移动播放器。

标签: python-3.x pygame collision-detection collision


【解决方案1】:

编辑:很快:您应该使用&lt;= 而不是==[1] 而不是[0]

if y1 <= platforms[i][1]: 
   print ("HIT")
   y1 = platforms[i][1] # move up with platform

首先你应该使用pygame.Rect() 来保持位置和大小。它有属性xywidthheight,但也有用bottomtopcenter等。

它还有检查两个Rect()之间碰撞的方法

player_rect.colliderect(platform_rect)

当玩家和平台发生碰撞时,你必须使用平台的top 更改玩家的bottom

    if player_rect.colliderect(platform_rect):
        player_rect.bottom = platform_rect.top

它会随着平台移动玩家。


最少的工作代码:红色平台向上移动,玩家也自动向上移动。

import pygame

# --- constants --- (UPPER_CASE_NAMES)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

FPS = 25 # for more than 220 it has no time to update screen

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

# --- functions --- (lower_case_names)

# --- main ---

pygame.init()

screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT) )
screen_rect = screen.get_rect()

player_rect = pygame.Rect(0,0,50,50)
player_color = (0,255,0)
player_rect.centerx = screen_rect.centerx
player_rect.bottom = screen_rect.bottom-25

platform_rect = pygame.Rect(0,0,200,25)
platform_color = (255,0,0)
platform_rect.centerx = screen_rect.centerx
platform_rect.bottom = screen_rect.bottom

# --- mainloop ---

clock = pygame.time.Clock()

running = True
while running:

    # --- events ---
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_ESCAPE:
                running = False


    # --- changes/moves/updates ---

    platform_rect.y -= 1

    if player_rect.colliderect(platform_rect):
        player_rect.bottom = platform_rect.top

    # --- draws ---

    screen.fill(BLACK)

    pygame.draw.rect(screen, player_color, player_rect)    
    pygame.draw.rect(screen, platform_color, platform_rect)    

    pygame.display.flip()

    # --- FPS ---

    ms = clock.tick(FPS)

# --- end ---

pygame.quit()

编辑: 平台向下移动的示例。当平台向下移动时,它使用player_gravity 将玩家保持在平台上。

如果player_gravityplaftorm_speed 相同,则玩家停留在平台上 - 但player_gravity 小于plaftorm_speed,则玩家下落速度比平台慢(如降落伞)

import pygame

# --- constants --- (UPPER_CASE_NAMES)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

FPS = 25 # for more than 220 it has no time to update screen

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

# --- functions --- (lower_case_names)

# --- main ---

pygame.init()

screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT) )
screen_rect = screen.get_rect()

player_rect = pygame.Rect(0,0,50,50)
player_color = (0,255,0)
player_rect.centerx = screen_rect.centerx
player_rect.bottom = screen_rect.bottom-25
player_gravity = 3 # try 5

platform_rect = pygame.Rect(0,0,200,25)
platform_color = (255,0,0)
platform_rect.centerx = screen_rect.centerx
platform_rect.bottom = screen_rect.bottom
platform_direction = 'top'
platform_speed = 5

# --- mainloop ---

clock = pygame.time.Clock()

running = True
while running:

    # --- events ---
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_ESCAPE:
                running = False


    # --- changes/moves/updates ---

    if platform_direction == 'top':
        platform_rect.y -= platform_speed
        if platform_rect.top <= 100:
            platform_direction = 'bottom'
    else:
        platform_rect.y += platform_speed
        if platform_rect.bottom >= 600:
            platform_direction = 'top'

    player_rect.y += player_gravity 

    if player_rect.colliderect(platform_rect):
        player_rect.bottom = platform_rect.top

    # --- draws ---

    screen.fill(BLACK)

    pygame.draw.rect(screen, player_color, player_rect)    
    pygame.draw.rect(screen, platform_color, platform_rect)    

    pygame.display.flip()

    # --- FPS ---

    ms = clock.tick(FPS)

# --- end ---

pygame.quit()

【讨论】:

  • 这只有在我硬编码矩形时才有效,我将无法控制矩形并且我需要能够左右移动它们
  • 这只是minimal的例子,它展示了如何在平台移动时移动播放器。现在您必须将它与您的平台列表一起使用 - 即platforms[i][0]。我没有你的完整代码,所以不要指望你的代码有完整的解决方案。除了你不使用pygame.Rect()
  • 简短地说:你需要&lt;=[1] 而不是if y1 &lt;= platforms[i][1]: y1 = platforms[i][0] 中的[0]。我现在将其添加到答案中。
猜你喜欢
  • 1970-01-01
  • 2014-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-06
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
相关资源
最近更新 更多