角色仅在碰撞的第二帧中被传送。为什么?

Character is being telported away only in the second frame of collision. Why?

对于大学编程课程的期末项目,我和我的团队正在构建一个平台。我负责制作碰撞系统。尽管我能够编写一个代码,但由于它的不完美,我对结果不满意。

问题是偶尔当角色到达平台后掉落时,玩家和方块会在一帧内相互重叠。当然,他们不会永远这样。我做到了,所以角色会传送回平台顶部。但是,该操作仅在第二帧中执行。对于玩这个游戏的人来说,这个角色似乎出现了故障。我相信问题出在碰撞检测的某个地方。可惜没找到。

如有任何帮助,我们将不胜感激。 我也希望这个问题不会被认为是我乞求别人完成我的作业。我只是在努力寻求建议:)

碰撞检测函数:

def Collision_Occurs(Block,Block_Length):
global Character, Max_Y_Speed
if(((Character.x <= Block.x + Block_Length and Character.x >= Block.x) or
  (Character.x + 100 <= Block.x + Block_Length and Character.x + 100 >= Block.x)) and
  (Character.y + 100 <= Block.y + Max_Y_Speed + 1 and Character.y + 100 >= Block.y)):
    return True
return False

整个游戏代码:

import pygame
from sys import exit

pygame.init()
screen = pygame.display.set_mode((1000,650))
pygame.display.set_caption("The Game")
Block1 = pygame.Rect(250,500,500,50)
Block2 = pygame.Rect(100,250,250,50)
Block3 = pygame.Rect(650,250,250,50)
clock = pygame.time.Clock()
Character = pygame.Rect(200,100,100,100)

Moving_X = False
X_Speed = 0
Max_X_Speed = 5
Y_Speed = 0
Max_Y_Speed = 15
Collisions_Off_Timer = 0
Jump_Count = 0
Time_Since_Last_Jump = 60

'''
-------------------------------------------------------------
Collision Detection
-------------------------------------------------------------
'''

def Collision_Occurs(Block,Block_Length):
    global Character, Max_Y_Speed
    if(((Character.x <= Block.x + Block_Length and Character.x >= Block.x) or
      (Character.x + 100 <= Block.x + Block_Length and Character.x + 100 >= Block.x)) and
      (Character.y + 100 <= Block.y + Max_Y_Speed + 1 and Character.y + 100 >= Block.y)):
        return True
    return False

'''
-------------------------------------------------------------
Teleportation back on the platform
-------------------------------------------------------------
'''

def Teleport_Back_Up(Block):
    global Character
    Character.bottom = Block.top

'''
-------------------------------------------------------------
Game loop
-------------------------------------------------------------
'''

while True:
    for event in pygame.event.get():
        if(event.type == pygame.QUIT):
            pygame.quit()
            exit()

    screen.fill((0,0,0))
    pygame.draw.rect(screen,'Red',Block1)
    pygame.draw.rect(screen,'Red',Block2)
    pygame.draw.rect(screen,'Red',Block3)
    pygame.draw.rect(screen,'Blue',Character)

    '''
    -------------------------------------------------------------
    Input
    -------------------------------------------------------------
    '''

    keys = pygame.key.get_pressed()

    if(keys[pygame.K_DOWN]):
        Collisions_Off_Timer = 5

    if(keys[pygame.K_UP] and Jump_Count < 2 and Time_Since_Last_Jump >= 30):
        Y_Speed = -20
        Collisions_Off_Timer = 20
        Jump_Count += 1
        Time_Since_Last_Jump = 0
    if(keys[pygame.K_RIGHT]):
        Moving_X = True
        if(X_Speed<Max_X_Speed):
            X_Speed+=1

    if(keys[pygame.K_LEFT]):
        Moving_X = True
        if(X_Speed>Max_X_Speed*(-1)):
            X_Speed-=1

    '''
    -------------------------------------------------------------
    Friction
    -------------------------------------------------------------
    '''

    if not(Moving_X):
        if X_Speed > 0:
            X_Speed -= 1
        if X_Speed < 0:
            X_Speed += 1

    Moving_X = False

    if not(Y_Speed>Max_Y_Speed):
        Y_Speed += 1

    '''
    -------------------------------------------------------------
    Checking for collisions
    -------------------------------------------------------------
    '''

    if(Y_Speed > 0 and Collisions_Off_Timer <=0):
        if Collision_Occurs(Block1,500):
            Teleport_Back_Up(Block1)
            Y_Speed = 0
            Jump_Count = 0
        if Collision_Occurs(Block2,250):
            Teleport_Back_Up(Block2)
            Y_Speed = 0
            Jump_Count = 0
        if Collision_Occurs(Block3,250):
            Teleport_Back_Up(Block3)
            Y_Speed = 0
            Jump_Count = 0

    '''
    -------------------------------------------------------------
    Teleport back to the middle when vertical bounds are crossed
    -------------------------------------------------------------
    '''

    if Character.y >=1500:
        Character.x = 450
        Character.y = 350
        Y_Speed = 0

    Collisions_Off_Timer -= 1
    Time_Since_Last_Jump +=1
    Character.x +=X_Speed
    Character.y +=Y_Speed

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

只需在碰撞检测之前进行移动即可。这会在播放器移动之后和显示更新之前更正播放器 (Teleport_Back_Up) 的 y 位置:

while True:
    # [...]

    Character.x +=X_Speed # <--- INSERT
    Character.y +=Y_Speed

    '''
    -------------------------------------------------------------
    Checking for collisions
    -------------------------------------------------------------
    '''

    if(Y_Speed > 0 and Collisions_Off_Timer <=0):
        if Collision_Occurs(Block1,500):
            Teleport_Back_Up(Block1)
            Y_Speed = 0
            Jump_Count = 0
        if Collision_Occurs(Block2,250):
            Teleport_Back_Up(Block2)
            Y_Speed = 0
            Jump_Count = 0
        if Collision_Occurs(Block3,250):
            Teleport_Back_Up(Block3)
            Y_Speed = 0
            Jump_Count = 0

    # [...]

    Collisions_Off_Timer -= 1
    Time_Since_Last_Jump +=1
    # Character.x +=X_Speed   <--- DELETE
    # Character.y +=Y_Speed