Pygame tilemap碰撞(使其返回发生碰撞的那一侧)

问题描述 投票:0回答:1

我有一个由子画面构成的关卡(在子画面组中),这些子画面由2维数组放置,这是tilemap。

我有一个玩家精灵(在另一个精灵组中)

您如何以此来制作2D平台游戏?我只需要一段代码就能告诉玩家哪一边触摸瓷砖并返回,这样我就可以制定条件以阻止他从一侧移到另一侧或停止跳动。我已经尝试了许多不同的方法,但是由于tilemap的原因,我无法使其正常工作。

python pygame sprite tiles
1个回答
0
投票

我在这里为想学习如何编程的人回答问题。如果问题显然是“ gimme teh codez”,或者是“我从这里到那里复制了一些代码;现在为我修复它!”,那么我就不会花很多精力。因此,我希望您能理解为什么下面的答案在很大程度上是理论上的。

我假设您是在谈论具有“重力”的2D游戏,以使玩家以某种方式跳跃和摔倒。如果您要谈论的是2D rouge-like(俯视图,无重力),则下面的某些术语可能有点偏离,但逻辑相同。

基于图块的“地图”或“级别”可以认为是一组图层。我将可碰撞的精灵拆分为一个单独的精灵组,我们将其称为platforms。装饰瓷砖可以进入background组。背景是下层,除了必须绘制外,否则可以忽略。

因此,每当玩家尝试移动平台时,都需要对平台进行碰撞测试。 PyGame Sprite object中有一个方便的功能,称为pygame.sprite.spritecollideany()。这使您的代码可以非常轻松地检查单个sprite和while sprite组之间的冲突:

collided_with = player_sprite.spritecollideany( background_sprite_group )
if ( collided_with != None ):
    print( "Player collided with sprite: " + str( collided_with ) )

[另一个方便的功能是pygame.sprite.groupcollide(),这非常适合使一组精灵与另一组精灵碰撞-就像一束箭对抗一堆敌人。但是您也可以创建一个包含single item的sprite组,并将其也用于单个对象。

您实际上不需要知道玩家的哪一侧正在与平台碰撞。这是隐式信息,因为您已经知道玩家的移动方向。碰撞测试的基础是,意识到一次移动一个大于1个像素的精灵可以将播放器移动到现有精灵的顶部,而不会碰到侧面。假设玩家移动得非常快,那么下一个移动位置可能正好在另一个精灵的中间!那么,它击中了哪一边? (从其移动的那一侧)

例如,如果玩家想向左移动10个像素,但平台边缘距离5个像素,则玩家会“碰撞”但不触摸。发生碰撞后,代码需要确定可接受的运动幅度,并将运动幅度调整为该增量。由于PyGame精灵对象基于Rect object,因此这是一个相当简单的测试:

# Player has tried to move delta_x and delta_y pixels
collided_with = player_sprite.spritecollideany( background_sprite_group )
if ( collided_with != None ):
    print( "Player collided with sprite: " + str( collided_with ) )
    if ( delta_x > 0 ):    # moving right
        # collides on right side
        distance_to_sprite_x = player_sprite.rect.x - collided_with.rect.x
    elif ( delta_x < 0 ):  # moving left
        # collides on left side (take width of sprite into account)
        distance_to_sprite_x = player_sprite.rect.x - collided_with.rect.x + collided_with.rect.width
    else:                  # not moving horizontally
        distance_to_sprite_x = 0
    # Adjust the x-movement
    delta_x = distance_to_sprite_x

    # TODO: similarly for delta_y and collided_with.rect.height

显然,播放器移动得足够快(每帧许多像素),理论上它可以“跳跃”整个平台,而不会发生碰撞,直接通过。上面的代码有这个潜在的错误。但是大多数游戏都不需要担心这种情况。

因此,我希望上面介绍的逻辑足以让您开始处理各种冲突。只是尝试使一些代码正常工作,这是学习的最佳方法。编写,测试,犯错误,问问题。我们随时准备为您提供帮助。很容易陷入仅复制和粘贴他人代码(有时质量中等)的陷阱,以获得“快速解决方案”的陷阱。但这并不能真正帮助您学习基础知识。

© www.soinside.com 2019 - 2024. All rights reserved.