如何在pygame中制作碰撞系统?

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

如何在 pygame 中以最简单的方式制作碰撞系统,而不使用类。 我已经尝试了很长一段时间,但没有一种方法有效,在我上次尝试中,代码是这样的:(如果写错了,抱歉,我是这一切的初学者)

import pygame
from pygame.locals import *
from sys import exit

pygame.init()

G = 9.807 # GRAVITY

screen = pygame.display.set_mode((400, 400))
time = pygame.time.Clock()

y_speed = 0
playersize = [20, 20]
playerpos = [0, 0]

def move(dx):
    playerpos[0] += dx

    if player.colliderect(block):
        if dx > 0:
            playerpos[0] -= player.right - block.left
        if dx < 0:
            playerpos[0] -= player.left - block.right
               
while 1:
    time.tick(30)
    screen.fill((255,255,255))
    player = pygame.draw.rect(screen, (255,0,0), (playerpos[0], playerpos[1], playersize[0], playersize[1]))
    block = pygame.draw.rect(screen, (0,0,0), (100, 380, 20, 20))

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            exit()
        if event.type == KEYDOWN:
            if event.key == K_SPACE or event.key == K_UP or event.key == K_w:
                if playerpos[1] == 380:
                    y_speed = -5
                    time = pygame.time.Clock()
                else:
                    pass
    
    T = time.get_time() / 1000
    F = G * T
    y_speed += F
    playerpos[1] += y_speed
    
    if playerpos[1] >= 380:
        playerpos[1] = 380
        y_speed = 0
        time = pygame.time.Clock()
    else:
        pass
    
    keys = pygame.key.get_pressed()
    if keys[K_a] or keys[K_LEFT]:
        move(-5)
    if keys[K_d] or keys[K_RIGHT]:
        move(5)
        
    pygame.display.update()
python pygame collision-detection pygame-surface
1个回答
1
投票

在碰撞测试之前,您必须使用玩家当前位置创建一个

pygame.Rect
对象。如果玩家从左侧击中方块,则玩家的右侧必须设置在方块的左侧。如果玩家从右侧击中方块,则玩家的右侧必须设置在方块的左侧:

def move(dx):
    playerpos[0] += dx

    player = pygame.Rect((playerpos[0], playerpos[1], playersize[0], playersize[1]))
    if player.colliderect(block):
        if dx > 0:
            player.right = block.left
            playerpos[0] = player.left
        if dx < 0:
            player.left = block.right
            playerpos[0] = player.left

您可以以类似的方式添加 y 方向的碰撞。但是,必须先进行 y 方向的碰撞检测,然后才能进行 x 方向的碰撞检测:

def move(dx, dy):

    playerpos[1] += dy
    player = pygame.Rect((playerpos[0], playerpos[1], playersize[0], playersize[1]))
    if player.colliderect(block):
        if dy > 0:
            player.bottom = block.top
            playerpos[1] = player.top

    playerpos[0] += dx
    player = pygame.Rect((playerpos[0], playerpos[1], playersize[0], playersize[1]))
    if player.colliderect(block):
        if dx > 0:
            player.right = block.left
            playerpos[0] = player.left
        if dx < 0:
            player.left = block.right
            playerpos[0] = player.left

完整且有效的示例:

import pygame
from pygame.locals import *
from sys import exit

pygame.init()

G = 9.807 # GRAVITY

screen = pygame.display.set_mode((400, 400))
time = pygame.time.Clock()

y_speed = 0
playersize = [20, 20]
playerpos = [0, 0]

def move(dx, dy):

    playerpos[1] += dy
    player = pygame.Rect((playerpos[0], playerpos[1], playersize[0], playersize[1]))
    if player.colliderect(block):
        if dy > 0:
            player.bottom = block.top
            playerpos[1] = player.top

    playerpos[0] += dx
    player = pygame.Rect((playerpos[0], playerpos[1], playersize[0], playersize[1]))
    if player.colliderect(block):
        if dx > 0:
            player.right = block.left
            playerpos[0] = player.left
        if dx < 0:
            player.left = block.right
            playerpos[0] = player.left

block = pygame.Rect(150, 330, 20, 20)
ground_y = 350

run = True            
while run:
    time.tick(30)
    for event in pygame.event.get():
        if event.type == QUIT:
            run = False
        if event.type == KEYDOWN:#
            if event.key == K_SPACE or event.key == K_UP or event.key == K_w:
                if playerpos[1] == ground_y - playersize[1]:
                    y_speed = -5

    keys = pygame.key.get_pressed()
    move_left = keys[K_a] or keys[K_LEFT]
    move_right = keys[K_d] or keys[K_RIGHT]
    x_speed = (move_right - move_left) * 5
    
    T = time.get_time() / 1000
    F = G * T
    y_speed += F
    move(x_speed, y_speed)
    if playerpos[1] >= ground_y - playersize[1]:
        playerpos[1] = ground_y - playersize[1]
        y_speed = 0
        
    screen.fill((255,255,255))
    pygame.draw.rect(screen, "gray", (0, ground_y, 400, 400-ground_y))
    pygame.draw.rect(screen, (255,0,0), (playerpos[0], playerpos[1], playersize[0], playersize[1]))
    pygame.draw.rect(screen, (0,0,0), block)
    pygame.display.update()

pygame.quit()
exit()
© www.soinside.com 2019 - 2024. All rights reserved.