Pygame 我的游戏怎么设置碰撞,我不懂

Pygame how to set up collision in my game, I dont understand it

我知道这个问题已经被问过很多次了,但我只是无法理解碰撞的概念,现在我知道我问了很多,但我会非常感激!,我只需要有人补充碰撞我的游戏并解释每一步,这样我就可以尝试了解发生了什么,我尝试了 youtube 视频,但它们没有很好地解释,或者我只是不知所措,这就是我现在的感受,所以我只想让玩家撞到树就停下来,就这么简单!如果可能的话,我希望它从列表中获取碰撞,例如我会在列表中包含树木和其他图像。

import pygame
import sys
import math
from pygame.locals import *
import tiles_list

pygame.init()
display_w = 800
display_h = 600

window = pygame.display.set_mode((display_w, display_h), HWSURFACE | DOUBLEBUF | RESIZABLE)
pygame.display.set_icon(pygame.image.load("game_icon.png"))
pygame.display.set_caption("Work in progress")
clock = pygame.time.Clock()
background = pygame.image.load("background.png")


class Player(object):
    """The controllable player in game"""

    def __init__(self, x, y, width, height, speed):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.image = pygame.image.load("sprite_sheet.png")
        self.speed = speed
        self.timer = 0
        self.frames = 1
        self.direction = 2

    def animation(self):
        x_coord = 50 * self.frames
        y_coord = 50 * self.direction
        self.character = self.image.subsurface(x_coord, y_coord, self.width, self.height)

        self.timer += 0
        if self.timer >= 10:
            self.timer = 0
            self.frames += 1
            if self.frames >= 9:
                self.frames = 1

    def draw(self):
        window.blit(self.character, (self.x, self.y))
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)

    def movement(self):
        self.keys = pygame.key.get_pressed()
        if self.keys[pygame.K_LEFT] or self.keys[pygame.K_a]:
            self.x -= self.speed
            self.direction = 1
            self.timer += 2
        if self.keys[pygame.K_RIGHT] or self.keys[pygame.K_d]:
            self.x += self.speed
            self.direction = 3
            self.timer += 2
        if self.keys[pygame.K_UP] or self.keys[pygame.K_w]:
            self.y -= self.speed
            self.direction = 0
            self.timer += 2
        if self.keys[pygame.K_DOWN] or self.keys[pygame.K_s]:
            self.y += self.speed
            self.direction = 2
            self.timer += 2
        if self.x >= 780:
            self.x = 780
            self.frames = 0
        if self.y >= 555:
            self.y = 555
            self.frames = 0
        if self.x <= 0:
            self.x = 0
            self.frames = 0
        if self.y <= 0:
            self.y = 0
            self.frames = 0


player = Player(400, 300, 50, 50, 4.5)


class Tree:
    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.image = (
            pygame.transform.scale(tiles_list.tiles.subsurface(pygame.Rect(99, 147, self.width, self.height)),
                                   (62, 82)))

    def draw(self):
        window.blit(self.image, (self.x, self.y))


tree = Tree(348, 300, 42, 62)

running = True
while running:
    window.blit(background, (0, 0))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == VIDEORESIZE:
            screen = pygame.display.set_mode((event.w, event.h), RESIZABLE)
        elif event.type == pygame.KEYUP:
            if player.keys:
                player.frames = 0

    dist_x = math.hypot(tree.x - player.x)
    dist_y = math.hypot(tree.y - player.y)  # Does nothing except calculate the distence
    print("distx", dist_x, "disty", dist_y)

    tree.draw()
    player.movement()
    player.animation()
    player.draw()

    clock.tick(60)
    pygame.display.flip()

我愿意向你解释碰撞的过程。 在您的游戏中,您有两个对象——树和玩家。所以,你可以说如果玩家的 x 坐标和 y 坐标相同,就会发生碰撞。您可以使用此概念并创建用于检测碰撞的变量。 谢谢

首先,我建议您开始尝试实施碰撞测试,在您提问之前。如果你卡住了,你可以问一个关于让你卡住的代码的问题。
不管怎样,我会给你一些提示。

碰撞检测通常基于pygame.Rect. For instance create a rectangle from pygaem.Surface objects player.image and tree.image by get_rect(). Evaluate if the 2 objects are colliding by colliderect():

player_rect = player.image.get_rect(topleft = (player.x, player.y))
tree_rect = tree.image.get_rect(topleft = (tree.x, tree.y))
if player_rect.colliderect(tree_rect):
    print("hit")

如果您“只是想让玩家在撞到树时停下来”,请存储玩家的位置并移动玩家。之后评估玩家是否撞到树。如果玩家正在击中,则恢复位置:

while running:
    # [...]

    # store position of player
    player_pos = (player.x, player.y)
    
    # move player
    player.movement()

    player_rect = player.image.get_rect(topleft = (player.x, player.y))
    tree_rect = tree.image.get_rect(topleft = (tree.x, tree.y))
    
    # test collision of player and tree
    if player_rect.colliderect(tree_rect):

        # restore player position
        (player.x, player.y) = player_pos 

另见