首页 > 解决方案 > 碰撞检测在 pygame 中不起作用

问题描述

我正在尝试制作一个自上而下的游戏,我需要功能性的墙才能让它工作,我已经尝试过多次,但是当我一次击中两个方向时,玩家会穿过墙。我现在拥有的系统应该通过将玩家的速度减去/添加到当前( xy )坐标来抵消玩家的任何速度,但它不起作用,我也尝试过这样做,所以应该没有反应当您按下按钮时,但这也会破坏代码。

import pygame
import random
#sets up the screen
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("collision test")

#defines the size and coords for the player
wall_height, wall_width = 200, 20
wall_x, wall_y = 400, 300

last_key = 0
x = 400
y = 300
width = 40
height = 60
vel = 5

#where the main code is run
run = True
while run:
    pygame.time.delay(50)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    #movement code
    keys = pygame.key.get_pressed()


    
    if keys[pygame.K_LEFT] and x > vel:
        last_key = "left"
        x -= vel
    if keys[pygame.K_RIGHT] and x < 800 - width:
        last_key = "right"
        x += vel
    if keys[pygame.K_UP] and y > vel:
        last_key = "up"
        y -= vel
    if keys[pygame.K_DOWN] and y < 600 - height - vel:
        last_key = "down"
        y += vel
    
    #draws the player
    screen.fill((0,0,0))
    wall = pygame.draw.rect(screen, (244, 247, 30), (wall_x, wall_y, wall_width, wall_height))
    player = pygame.draw.rect(screen, (255, 255, 255), (x, y, width, height))

    #collision code
    if player.colliderect(wall) and last_key == "left":
        x += vel
    elif player.colliderect(wall) and last_key == "right":
        x -= vel
    elif player.colliderect(wall) and last_key == "up":
        y += vel
    elif player.colliderect(wall) and last_key == "down":
        y -= vel
        
        
    pygame.display.update()

pygame.quit()

标签: pythonpygame

解决方案


我会给您一个完整的答案,只需对您的代码进行最少的更改。

改变顺序。在绘图之前进行碰撞检测。创建pygame.Rect对象:

wall = pygame.Rect(wall_x, wall_y, wall_width, wall_height)
player = pygame.Rect(x, y, width, height)

将玩家的位置限制在墙的边界内:

if player.colliderect(wall) and last_key == "left":
    x += vel
    x = wall.right
elif player.colliderect(wall) and last_key == "right":
    x -= vel
    x = wall.left - width
elif player.colliderect(wall) and last_key == "up":
    y += vel
    y = wall.bottom
elif player.colliderect(wall) and last_key == "down":
    y -= vel
    y = wall.top - height

完整示例:

import pygame

#sets up the screen
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("collision test")

#defines the size and coords for the player
wall_height, wall_width = 200, 20
wall_x, wall_y = 400, 300

last_key = 0
x = 400
y = 240
width = 40
height = 60
vel = 5

#where the main code is run
run = True
while run:
    pygame.time.delay(50)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    #movement code
    keys = pygame.key.get_pressed() 
    if keys[pygame.K_LEFT] and x > vel:
        last_key = "left"
        x -= vel
    if keys[pygame.K_RIGHT] and x < 800 - width:
        last_key = "right"
        x += vel
    if keys[pygame.K_UP] and y > vel:
        last_key = "up"
        y -= vel
    if keys[pygame.K_DOWN] and y < 600 - height - vel:
        last_key = "down"
        y += vel

    wall = pygame.Rect(wall_x, wall_y, wall_width, wall_height)
    player = pygame.Rect(x, y, width, height)

    #collision code
    if player.colliderect(wall) and last_key == "left":
        x += vel
        x = wall.right
    elif player.colliderect(wall) and last_key == "right":
        x -= vel
        x = wall.left - width
    elif player.colliderect(wall) and last_key == "up":
        y += vel
        y = wall.bottom
    elif player.colliderect(wall) and last_key == "down":
        y -= vel
        y = wall.top - height

    #draws the player
    screen.fill((0,0,0))
    pygame.draw.rect(screen, (244, 247, 30), (wall_x, wall_y, wall_width, wall_height))
    pygame.draw.rect(screen, (255, 255, 255), (x, y, width, height))    
    pygame.display.update()

pygame.quit()

推荐阅读