为矩形正确实现碰撞

implementing collision correctly for rectangles

我正在尝试 pygame 并正在创建一个简单的原型游戏。

我需要一些关于玩家矩形和“食物”矩形碰撞的帮助。 我正在尝试制作一个简单的游戏,其中包含一个玩家和一个食物对象。食物对象的位置在游戏开始时是随机的

class Food(Player):
    def __init__(self):
        super().__init__()
        self.rand_x = random.randint(0, width)
        self.rand_y = random.randint(0, height)
        self.food = pg.Rect(self.rand_x,
                            self.rand_y,
                            15, 15)
    ...

这个食物class包含一个处理玩家与食物碰撞的函数,如果玩家与食物发生碰撞,食物的位置会再次改变

    def playerCollision(self):
        if self.sprite.colliderect(self.food) or self.food.colliderect(self.sprite):
            self.food.x = self.rand_x
            self.food.y = self.rand_y

这是我的播放器class

class Player:
    def __init__(self):
        self.sprite = pg.Rect(x, y, 50, 50)

    def handle_keys(self):
        keys = pg.key.get_pressed()
        if keys[pg.K_w]:
            self.sprite.move_ip(0, -velocity)
        elif keys[pg.K_a]:
            self.sprite.move_ip(-velocity, 0)
        elif keys[pg.K_s]:
            self.sprite.move_ip(0, velocity)
        elif keys[pg.K_d]:
            self.sprite.move_ip(velocity, 0)

    def draw(self, surface):
        pg.draw.rect(surface, spriteColors[0], self.sprite)

这是完整的食物class

class Food(Player):
    def __init__(self):
        super().__init__()
        self.rand_x = random.randint(0, width)
        self.rand_y = random.randint(0, height)
        self.food = pg.Rect(self.rand_x,
                            self.rand_y,
                            15, 15)

    def randomize_pos(self):  # debugger function to test randomized food locations
        self.food.x = random.randint(0, width)
        self.food.y = random.randint(0, height)
        self.drawFood(screen)

    def playerCollision(self):
        if self.sprite.colliderect(self.food) or self.food.colliderect(self.sprite):
            self.food.x = self.rand_x
            self.food.y = self.rand_y

    def drawFood(self, surface):
        pg.draw.rect(surface, spriteColors[1], self.food)

我到处寻找解决方案并将解决方案实施到我的代码中,但 none 工作。

如果你们都需要的话,这里是完整的代码

import pygame as pg
from pygame.locals import *
import sys, random

pg.init()

# Setup and screen properties
pg.display.set_caption("prototype \u2014 game")
width, height = (800, 600)
screen = pg.display.set_mode([width, height])
spriteColors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]  # Red, Green, Blue

x = 25
y = 25
velocity = 5

class Player:
    def __init__(self):
        self.sprite = pg.Rect(x, y, 50, 50)

    def handle_keys(self):
        keys = pg.key.get_pressed()
        if keys[pg.K_w]:
            self.sprite.move_ip(0, -velocity)
        elif keys[pg.K_a]:
            self.sprite.move_ip(-velocity, 0)
        elif keys[pg.K_s]:
            self.sprite.move_ip(0, velocity)
        elif keys[pg.K_d]:
            self.sprite.move_ip(velocity, 0)

    def draw(self, surface):
        pg.draw.rect(surface, spriteColors[0], self.sprite)

class Food(Player):
    def __init__(self):
        super().__init__()
        self.rand_x = random.randint(0, width)
        self.rand_y = random.randint(0, height)
        self.food = pg.Rect(self.rand_x,
                            self.rand_y,
                            15, 15)

    def randomize_pos(self):  # debugger function to test randomized food locations
        self.food.x = random.randint(0, width)
        self.food.y = random.randint(0, height)
        self.drawFood(screen)

    def playerCollision(self):
        if self.sprite.colliderect(self.food) or self.food.colliderect(self.sprite):
            self.food.x = self.rand_x
            self.food.y = self.rand_y

    def drawFood(self, surface):
        pg.draw.rect(surface, spriteColors[1], self.food)


# Initialize Player and Food Object
player = Player()
food = Food()
clock = pg.time.Clock()

# Game Loop
while True:
    for event in pg.event.get():
        if event.type == QUIT:
            pg.quit()
            sys.exit()

        elif event.type == pg.KEYDOWN:
            if event.key == pg.K_ESCAPE:
                pg.quit()
                sys.exit()

    screen.fill((0, 0, 0))

    player.handle_keys()
    player.draw(screen)
    food.drawFood(screen)
    food.playerCollision()
    pg.display.update()

    clock.tick(60)

我推荐阅读How do I detect collision in pygame?。 在您的特定代码中, playerfood 是不同的对象。 player.spritefood.sprite 不同。 Food中对Player的继承没有用,去掉。您必须将 player 对象传递给 food 对象的 playerCollision 方法:

class Food():
    def __init__(self):
        self.food = pg.Rect(0, 0, 15, 15)
        self.randomize_pos()

    def randomize_pos(self):
        self.food.x = random.randint(0, width)
        self.food.y = random.randint(0, height)

    def playerCollision(self, player):
        if player.sprite.colliderect(self.food):
            self.randomize_pos()

    def drawFood(self, surface):
        pg.draw.rect(surface, spriteColors[1], self.food)
# Initialize Player and Food Object
player = Player()
food = Food()
clock = pg.time.Clock()

# Game Loop
while True:
    for event in pg.event.get():
        if event.type == QUIT:
            pg.quit()
            sys.exit()

        elif event.type == pg.KEYDOWN:
            if event.key == pg.K_ESCAPE:
                pg.quit()
                sys.exit()

    screen.fill((0, 0, 0))

    player.handle_keys()
    player.draw(screen)
    food.drawFood(screen)
    food.playerCollision(player)     # <-- detect collision between food and player 
    pg.display.update()

    clock.tick(60)