0

基本上我试图使用以下内容向下面的精灵添加碰撞检测:

self.rect = bounds_rect


                collide = pygame.sprite.spritecollide(self, wall_list, False)

                if collide:
            # yes

                     print("collide")

然而,似乎当碰撞被触发时,它会一遍又一遍地连续打印“碰撞”,而我希望他们根本无法穿过物体,有什么帮助吗?

def update(self, time_passed):
        """ Update the creep.

            time_passed:
                The time passed (in ms) since the previous update.
        """
        if self.state == Creep.ALIVE:
            # Maybe it's time to change the direction ?
            #
            self._change_direction(time_passed)

            # Make the creep point in the correct direction.
            # Since our direction vector is in screen coordinates 
            # (i.e. right bottom is 1, 1), and rotate() rotates 
            # counter-clockwise, the angle must be inverted to 
            # work correctly.
            #
            self.image = pygame.transform.rotate(
                self.base_image, -self.direction.angle)

            # Compute and apply the displacement to the position 
            # vector. The displacement is a vector, having the angle
            # of self.direction (which is normalized to not affect
            # the magnitude of the displacement)
            #
            displacement = vec2d(    
                self.direction.x * self.speed * time_passed,
                self.direction.y * self.speed * time_passed)

            self.pos += displacement

            # When the image is rotated, its size is changed.
            # We must take the size into account for detecting 
            # collisions with the walls.
            #
            self.image_w, self.image_h = self.image.get_size()
            global bounds_rect
            bounds_rect = self.field.inflate(
                            -self.image_w, -self.image_h)

            if self.pos.x < bounds_rect.left:
                self.pos.x = bounds_rect.left
                self.direction.x *= -1
            elif self.pos.x > bounds_rect.right:
                self.pos.x = bounds_rect.right
                self.direction.x *= -1
            elif self.pos.y < bounds_rect.top:
                self.pos.y = bounds_rect.top
                self.direction.y *= -1
            elif self.pos.y > bounds_rect.bottom:
                self.pos.y = bounds_rect.bottom
                self.direction.y *= -1

            self.rect = bounds_rect


            collide = pygame.sprite.spritecollide(self, wall_list, False)

            if collide:
        # yes

                 print("collide")




        elif self.state == Creep.EXPLODING:
            if self.explode_animation.active:
                self.explode_animation.update(time_passed)
            else:
                self.state = Creep.DEAD
                self.kill()

        elif self.state == Creep.DEAD:
            pass

        #------------------ PRIVATE PARTS ------------------#

    # States the creep can be in.
    #
    # ALIVE: The creep is roaming around the screen
    # EXPLODING: 
    #   The creep is now exploding, just a moment before dying.
    # DEAD: The creep is dead and inactive
    #
    (ALIVE, EXPLODING, DEAD) = range(3)

    _counter = 0

    def _change_direction(self, time_passed):
        """ Turn by 45 degrees in a random direction once per
            0.4 to 0.5 seconds.
        """
        self._counter += time_passed
        if self._counter > randint(400, 500):
            self.direction.rotate(45 * randint(-1, 1))
            self._counter = 0

    def _point_is_inside(self, point):
        """ Is the point (given as a vec2d) inside our creep's
            body?
        """
        img_point = point - vec2d(  
            int(self.pos.x - self.image_w / 2),
            int(self.pos.y - self.image_h / 2))

        try:
            pix = self.image.get_at(img_point)
            return pix[3] > 0
        except IndexError:
            return False

    def _decrease_health(self, n):
        """ Decrease my health by n (or to 0, if it's currently
            less than n)
        """
        self.health = max(0, self.health - n)
        if self.health == 0:
            self._explode()

    def _explode(self):
        """ Starts the explosion animation that ends the Creep's
            life.
        """
        self.state = Creep.EXPLODING
        pos = ( self.pos.x - self.explosion_images[0].get_width() / 2,
                self.pos.y - self.explosion_images[0].get_height() / 2)
        self.explode_animation = SimpleAnimation(
            self.screen, pos, self.explosion_images,
            100, 300)
        global remainingCreeps

        remainingCreeps-=1

        if remainingCreeps == 0:
                print("all dead")
4

1 回答 1

2

碰撞检查只是检查两个矩形精灵是否具有公共区域。没有在碰撞期间无法让玩家输入的内置碰撞。你必须自己写。

您可能希望在发生碰撞时更改玩家坐标。一个例子:

假设我们玩马里奥。当 mario 的状态为 JUMPING 时,检查碰撞。我们将在某个地方存储 mario 的速度在 y 轴上。当碰撞返回 True 时,对于任何块,我们现在将速度设置为 0,将 y 设置为块的顶部/底部。如果它是底部,我们仍然保持跳跃,所以它可以落回地面。

我对爬行者的建议是有一些 oldx 和 oldy 值,以便在碰撞发生时返回。这样爬行者就永远不会进入墙壁。另一种方法是在发生碰撞时简单地改变方向,但这可能并不总是有效。

于 2012-12-02T17:15:04.637 回答