当墙是一组,而我的精灵在另一组中时,如何实现墙碰撞

时间:2019-04-20 16:50:24

标签: python pygame

我正在做一个游戏,其中一名玩家穿过一个关卡,目标随机穿过一个关卡,并且有守卫(尚不是游戏的一部分)。我难以实现壁碰撞,因为我的精灵是圆形的,我的墙壁是矩形的,所以我也不知道该怎么做,因为墙壁和精灵位于不同的类和组中。

我已经考虑过将精灵用于蒙版,但是我对如何做到这一点不自信。我也不知道该如何设计墙面碰撞的方法,因为当前的墙面碰撞会将我的玩家(我也没有为目标击中它)发送到任何墙面的底部。

class characters(pygame.sprite.Sprite):
    def __init__(self, colour, width, height):
        super().__init__()
        self.colour = colour
        self.width = width
        self.height = height
        self.image = pygame.Surface([self.width, self.height])
        self.image.fill(white)
        self.image.set_colorkey(white)
        self.rect = self.image.get_rect() 
        pygame.draw.circle(self.image, self.colour, [int(self.width/2), int(self.height/2)], int(self.width/2))

    def moveRight(self, pixels):
        self.rect.x += pixels

    def moveLeft(self, pixels):
        self.rect.x -= pixels

    def moveUp(self, pixels):
        self.rect.y -= pixels

    def moveDown(self, pixels):
        self.rect.y += pixels

    def moveRandom(self, pixels, clockrate, count, xdirection, ydirection):
        self.rect.x += pixels * xdirection
        self.rect.y += pixels * ydirection
        #print(self.rect.x,self.rect.y)

    def wallCollide(self):
        x = self.rect.x
        for xpos in [-5,5]:
            self.rect.x += xpos
            if pygame.sprite.spritecollide(self, wallSet, False, pygame.sprite.collide_rect):
                self.rect.x -= xpos
            else:
                self.rect.x = x
        y = self.rect.y
        for ypos in [-5,5]:
            self.rect.y += ypos
            if pygame.sprite.spritecollide(self, wallSet, False, pygame.sprite.collide_rect):
                self.rect.y -= ypos
            else:
                self.rect.y = y

我在下面的Wall类中尝试了一个面具,认为它不起作用。

class walls(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height):
        super().__init__()
        self.width  = width
        self.height = height
        self.x      = x
        self.y      = y

        self.image = pygame.Surface([width,height])
        self.image.fill(black)
        #self.image.set_colorkey(black) Using this will make the walls invisible as I have textured walls drawn over
        self.rect = self.image.get_rect(topleft=(self.x, self.y))
        pygame.mask.from_surface(self.image)

我只给了一堵墙并降低了分辨率,因为在编写代码时要容易得多。分辨率应为1920 x1080。使用600 x 650查看两堵墙。

characterSet = pygame.sprite.Group()
player = characters(black, 30, 30)
target = characters(green, 30, 30)
characterSet.add(player, target)

wallSet = pygame.sprite.Group()
Wall1 = walls(288,176, 200,142)
Wall2 = walls(286,427, 201,140)
wallSet.add(Wall1,Wall2)

主游戏循环

while not end:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            end = True

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        player.moveLeft(5)
    if keys[pygame.K_RIGHT]:
        player.moveRight(5)
    if keys[pygame.K_UP]:
        player.moveUp(5)
    if keys[pygame.K_DOWN]:
        player.moveDown(5)

    if count%clockrate == 0:
        xdirection = random.choice(direction)
        ydirection = random.choice(direction)
    target.moveRandom(2, clockrate, count, xdirection, ydirection)
    count += 1

    if pygame.sprite.spritecollide(player, wallSet, False, pygame.sprite.collide_rect):
        player.wallCollide()
    gameDisplay.blit(level1,[0,0])
    wallSet.draw(gameDisplay)
    gameDisplay.blit(innerWalls,[0,0])
    characterSet.draw(gameDisplay)

1 个答案:

答案 0 :(得分:1)

如果我正确理解,您有一个墙对象列表和一个角色对象列表,并且您想检查所有这些对象之间的碰撞。可以通过遍历两个列表来快速完成此操作:

for wall in WallSet:
    for character in CharacterSet:
        character.checkCollision(wall)

checkCollision()方法非常简单,检查对象周围的矩形是否重叠仅是一些if语句。如果您想让此checkCollisions()方法对舍入字符有效,则需要写一些奇妙的东西。我建议:

  1. 编写一个函数,该函数将在最接近另一个点的矩形内给出该点(最困难的部分!尽管我确定有在线教程)

  2. 将该点置于墙的矩形内,并检查该点是否离角色的中间位置足够远,以免发生碰撞。

希望这会有所帮助!对于以后的问题,我建议您尝试非常清楚地提出1个问题,并减少您要进一步发布的代码。对于您所提出的问题,您发布的代码太多,可能在过去的两天内拒绝了潜在的答复者。