向下滚动传送我的玩家 pygame

时间:2021-02-01 04:05:33

标签: python pygame

每当我为我的播放器向上和向下滚动时,我都会遇到问题,并且我在高地然后与我的播放器一起跳下,它会干扰我的碰撞逻辑。我不确定它为什么要这样做。

例如她的视频:VIDEO

如您所见,我在高地,然后当我出于某种原因跳下时,到处都是小故障。

我的向上/向下滚动是这样的,当我的播放器 y 处于 50 时,它应该向上滚动我的播放器,当我的播放器处于 550 时,它应该随着我的播放器的下降速度向下滚动我的播放器,但是每当我在主循环中使用此代码时,它都会导致我的可碰撞矩形出现故障,即使我对所有侧面进行了碰撞以阻止播放器。

碰撞是玩家将要碰撞的矩形。

if playerman.y > 550:
    for obj in object_list:
        obj.y -= playerman.fall
    for shot in shots:
        shot.y -= playerman.fall
    
    for collid in collids:
        collid.y -= playerman.fall
    tall11.y -= playerman.fall



if playerman.y < 50:
    for obj in object_list:
        obj.y += playerman.speed

    for shot in shots:
        shot.y += playerman.speed
    
    for collid in collids:
        collid.y += playerman.speed

    tall11.y += playerman.speed

我的碰撞部分为玩家从左到右

    platform_rect_list = [p.rect for p in collids]
    player_rect = playerman.get_rect()
    player_rect.topleft = (px, py)


        
    playerman.y = py
    if player_rect.collidelist(platform_rect_list) < 0:
        playerman.x = px
        
    move_right = keys[pygame.K_d]
    move_left = keys[pygame.K_a]
    if move_right:
        for obj in object_list:
            obj.x -= playerman.speed
        for shot in shots:
            shot.x -= playerman.speed
        
        for collid in collids:
            collid.x -= playerman.speed

        tall11.x -= playerman.speed

        
    if move_left:
        for obj in object_list:
            obj.x += playerman.speed


        for shot in shots:
            shot.x += playerman.speed
        for collid in collids:
            collid.x += playerman.speed

        tall11.x += playerman.speed



    platform_rect_list = [p.get_rect() for p in collids] # get_rect()
    player_rect = playerman.get_rect()
    player_rect.topleft = (px, py)

    playerman.y = py
    cI = player_rect.collidelist(platform_rect_list)
    if cI >= 0:
        # undo movement of platforms dependent on the direction and intersection distance
        dx = 0
        if move_right: 
            dx = platform_rect_list[cI].left - player_rect.right
        if move_left:
            dx = platform_rect_list[cI].right - player_rect.left
        for collid in collids:
            collid.x -= dx
            collid.get_rect()
        base1.x -= dx
        base2.x -= dx
        base3.x -= dx
        base4.x -= dx
        base5.x -= dx
        base6.x -= dx
        crate1.x -= dx
        base44.x -= dx
        end1.x -= dx
        base45.x -= dx
        stopmove1.x -= dx
        text_show_collision.x -= dx
        text1.x -= dx
        rop1.x -= dx
        text22.x -= dx
        text_show_collision2.x -= dx
        portal1.x -= dx
        base46.x -= dx
        tall11.x -= dx

        for shot in shots:
            shot.x -= dx



    if not playerman.isJump:  
        playerman.y += playerman.fall
        playerman.fall += 0.5
        playerman.isJump = False


    # For player to get on top of platform
        collide = False
        for collid in collids:
            if playerman.get_rect().colliderect(collid.rect):
                collide = True
                playerman.isJump = False
                playerman.JumpCount = 10
                right = True
                left = True
                playerman.y = collid.rect.top - playerman.height
                if playerman.rect.right > collid.rect.left and playerman.rect.left < collid.rect.left - playerman.width:
                    playerman.x = collid.rect.left - playerman.width
                if playerman.rect.left < collid.rect.right and playerman.rect.right > collid.rect.right + playerman.width:
                    playerman.x = collid.rect.right

                if playerman.direction == "jump":
                    playerman.direction = "Idle"
                    
                if playerman.direction == "jump2":
                    playerman.direction = "leftid"

                        



        if collide:
            playerman.isJump = False
            playerman.fall = 1
            

        # Player jumping
        if collide:
            if keys[pygame.K_SPACE]:
                playerman.isJump = True
                right = False
                left = False
            playerman.fall = 0

    ##  playerman.isJump = False  <--  omit this line.  already False
        # What will happen when player jumps
    else:

        collideBottom = False
        for collid in collids:
            if (playerman.get_rect().colliderect(collid.rect) and 
                playerman.y + playerman.height > collid.rect.bottom):
                
                collideBottom = True
                playerman.y = collid.rect.bottom
                break

        if not collideBottom and playerman.JumpCount >= 0:    
            playerman.y -= (playerman.JumpCount*abs(playerman.JumpCount))*0.3
            playerman.JumpCount -= 1
            if playerman.direction == "right" or playerman.direction == "Idle":
                playerman.direction = "jump"

            if playerman.direction == "left" or playerman.direction == "leftid":
                playerman.direction = "jump2"




        else:
            playerman.isJump = False
            playerman.JumpCount = 10


    # redrawing the window
    redraw()

    # updating the game
    pygame.display.update()
# quiting the game
pygame.quit()

您可以使用 rects no images 运行并测试它,它的工作方式与跳到天空上的平台顶部然后跳下的方式相同,即使碰撞对双方都有效,由于某种原因您将开始出现故障.

Full script

1 个答案:

答案 0 :(得分:1)

既然你想滚动,你也需要滚动播放器。为避免浮点精度出现问题,请使用播放器矩形的积分 y 坐标来检查是否需要滚动:

if playerman.get_rect().y > 550:
    
    # scroll objects ...
    for obj in object_list:
        obj.y -= playerman.speed
    for shot in shots:
        shot.y -= playerman.speed
    for collid in collids:
        collid.y -= playerman.speed
    tall11.y -= playerman.speed
    
    # ... and scroll player
    playerman.y -= playerman.speed
    py -= playerman.speed

您可能希望使用 playerman.y - 550 而不是 playerman.speed 的量滚动:

if playerman.get_rect().y > 550:
    scroll_offset = playerman.y - 550

    # scroll objects ...
    for obj in object_list:
        obj.y -= scroll_offset
    for shot in shots:
        shot.y -= scroll_offset
    for collid in collids:
        collid.y -= scroll_offset
    tall11.y -= scroll_offset

    # ... and scroll player
    playerman.y -= scroll_offset
    py -= scroll_offset

如果您进行碰撞测试,那么您实际上使用了 rect 对象的 collide 属性:

<块引用>
platform_rect_list = [p.rect  for p in collids]

但是,您之前已经更改了 x 对象的 ycollide 属性。因此 rect 属性不反映对象的当前位置。您必须在碰撞测试之前更新 rect 属性:

幸运的是,您已经实现了 get_rect() 方法,该方法更新并返回了 rect 属性:

<块引用>
class collid:
   # [...]

   def get_rect(self):
       self.rect.topleft = (self.x,self.y)
       return self.rect

调用 get_rect() 而不是直接使用 rect 属性:

platform_rect_list = [p.rect for p in collids]

platform_rect_list = [p.get_rect()  for p in collids]

player_rect = playerman.get_rect()
player_rect.topleft = (px, py)

playerman.y = py
if player_rect.collidelist(platform_rect_list) < 0:
    playerman.x = px
相关问题