簡體   English   中英

2D平台游戲的碰撞檢測

[英]Collision detection for 2D platformer

我正在開發平台游戲,我想與平台進行基本的碰撞,遺憾的是仍然無法正確完成。 玩家移動計算如下:

velocity += acceleration
position += velocity + 0.5 * acceleration

所有變量都是具有xy值的向量。 這按預期工作,問題在於碰撞。 我的規則是:

  • 降落在平台上時停止墜落。
  • 從平台運行時開始下降。
  • 在跳躍過程中碰到平台時停止向上移動。
  • 撞牆時停止向一側移動,但可以向相反方向移動。

檢查底部是否與平台碰撞很簡單,但棘手的部分是檢測哪一側與平台碰撞並能夠為玩家設置適當的位置。

我試圖從每一側檢測角落和中間,但由於我的速度不是每幀 1px,有時玩家跌落到快速並被檢測為側面。

檢測哪一側發生碰撞的好方法是什么?

我在 javascript 中有幾個類似平台的游戲,這就是我實現碰撞的方式:

1.落地停止墜落:可以給你的精靈一個矩形作為邊界區域,然后使用Pygames內置的Rect類來檢測相交。 當您的精靈命中框(矩形)和平台矩形(另一個矩形)之間發生這種交集時,您可以將玩家的 Y 速度設置為 0。

2. 離台運行時開始墜落。 我通常有一個專門用於重力的變量,並且簡單地不斷將其應用於精靈以將其向下推。 這樣,當您不再與平台相交后,它會向下墜落。

3.跳躍時撞到平台停止向上移動:與之前的交叉點相同,在矩形碰撞后將Y速度設置為0,並讓玩家因為恆定的重力而墜落。

4. 撞牆時停止向一側移動,但可以向相反方向移動:同樣的,但這次將X速度設置為0。 (如果你被困在牆上,你總是可以將 X 設置為大於 0 來推動你回到游戲中)

還要注意的是,如果您只想在精靈碰到平台的某個邊緣時執行某些操作,您可以創建一個與精靈的邊對齊的矩形。 例如,如果我想查看某個東西是否與我的精靈左側相交,我可以使用 - height: same height - width: 1 - x: x + width - y: same y

矩形文檔: https : //www.pygame.org/docs/ref/rect.html

好吧,這里有代碼可以幫助檢測何時可以從平台跳轉:

self.rect.y += 2
platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
self.rect.y -= 2

# If it is ok to jump, set our speed upwards
if len(platform_hit_list) > 0:
    velocity += acceleration
    position += velocity + 0.5 * acceleration

然后用於檢測何時跌倒平台的代碼:

if self.rect.y >= constants.SCREEN_HEIGHT and self.change_y >= 0:
    self.change_y = 0
    self.rect.y = constants.SCREEN_HEIGHT

最后碰撞代碼:

block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:
    # If we are moving right,
    # set our right side to the left side of the item we hit
    if self.change_x > 0:
        self.rect.right = block.rect.left
    elif self.change_x < 0:
        # Otherwise if we are moving left, do the opposite.
        self.rect.left = block.rect.right

# Move up/down
velocity += acceleration
position += velocity + 0.5 * acceleration

# Check and see if we hit anything
block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:

    # Reset our position based on the top/bottom of the object.
    if self.change_y > 0:
        self.rect.bottom = block.rect.top
    elif self.change_y < 0:
        self.rect.top = block.rect.bottom

    # Stop our vertical movement
    self.change_y = 0

希望這一切都會以某種方式幫助您提供所需的答案。 請注意,這些塊是指平台,將檢查給定列表中的每個平台,我使用 rects,因為它是檢查沖突的最佳方法之一。 至於change_x 和change_y,它只是存儲玩家將移動多少的變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM