Пример #1
0
    def tick(self):
        super(ChaseMixin, self).tick()

        if self.started:
            # Figure out how close we are to the player.
            player = get_engine().player

            distance_x = abs(player.rect.x - self.rect.x)
            distance_y = abs(player.rect.y - self.rect.y)

            if (self.following and
                (distance_x >= self.STOP_FOLLOWING_DISTANCE or
                 distance_y >= self.STOP_FOLLOWING_DISTANCE)):
                self.stop_following()
            if (self.following or
                (distance_x <= self.APPROACH_DISTANCE and
                 distance_y <= self.APPROACH_DISTANCE and
                 not self.following and
                 (not self.SHOW_EXCLAMATION or not self.exclamation))):

                if not self.following and not self.exclamation:
                    if self.SHOW_EXCLAMATION:
                        # They haven't noticed the player before, but they
                        # do now!
                        self.show_exclamation(on_done=self.start_following)
                        return
                    else:
                        self.start_following()

                x_dir = None
                y_dir = None

                if player.rect.x > self.rect.x:
                    x = 1
                    x_dir = Direction.EAST
                elif player.rect.x < self.rect.x:
                    x = -1
                    x_dir = Direction.WEST
                else:
                    x = 0

                if player.rect.y > self.rect.y:
                    y = 1
                    y_dir = Direction.SOUTH
                elif player.rect.y < self.rect.y:
                    y = -1
                    y_dir = Direction.NORTH
                else:
                    y = 0

                self.velocity = (x * self.CHASE_SPEED, y * self.CHASE_SPEED)

                if distance_x > distance_y:
                    self.direction = x_dir
                elif distance_y > distance_x:
                    self.direction = y_dir

                self.update_image()

        super(ChaseMixin, self).tick()
Пример #2
0
    def tick(self):
        if self.started:
            engine = get_engine()
            player = engine.player

            if (not self.attacking and
                self.can_attack and
                self._can_see_player()):
                self.stop_wandering()
                self.attacking = True
                self.autoset_velocity = False

                self.attack_start_pos = self.rect.topleft
                self.attack_dest_pos = player.rect.center

                self.velocity, self.max_attack_ticks = self._get_attack_data()

                # Let it go a bit longer than that
                self.max_attack_ticks += self.ATTACK_TICKS_PAD
                self.attack_ticks = 1

                self._update_attack_pos()
            elif self.attacking:
                self.attack_ticks += 1
                self._update_attack_pos()

                if self.attack_ticks >= self.max_attack_ticks:
                    self.stop_attacking()
            else:
                # Allow normal moving logic to happen.
                super(AttackLineMixin, self).tick()
Пример #3
0
    def on_dead(self):
        self.lives -= 1
        self.lives_changed.emit()
        self.stop_moving()

        engine = get_engine()

        if self.lives == 0:
            self.die(engine.game_over)
        else:
            self.health = self.MAX_HEALTH
            self.health_changed.emit()
            engine.dead()
Пример #4
0
    def __init__(self, ms, cb, one_shot=False, start_automatically=True):
        self.engine = get_engine()
        assert self.engine

        self.ms = ms
        self.cb = cb
        self.tick_count_count = 0
        self.started = False
        self.one_shot = one_shot
        self.tick_cnx = None
        self.start_automatically = True

        if ms > 0 and start_automatically:
            self.start()
Пример #5
0
    def _get_attack_data(self):
        player = get_engine().player
        delta_x = player.rect.center[0] - self.rect.topleft[0]
        delta_y = player.rect.center[1] - self.rect.topleft[1]
        dist = math.sqrt(delta_x * delta_x + delta_y * delta_y)

        if dist == 0:
            return (0, 0), 0

        velocity = ((delta_x * (1.0 / dist) * self.ATTACK_SPEED),
                    (delta_y * (1.0 / dist) * self.ATTACK_SPEED))

        if velocity[0] == 0:
            max_attack_ticks = int(delta_y / velocity[1])
        else:
            max_attack_ticks = int(delta_x / velocity[0])

        return velocity, max_attack_ticks
Пример #6
0
    def move_by(self, *args, **kwargs):
        super(Bullet, self).move_by(*args, **kwargs)

        camera_rect = get_engine().camera.rect

        if not self.layer:
            return

        screen_size = self.layer.parent.size

        if (self.started and
            (self.rect.x <= max(camera_rect.x - self.OFFSCREEN_DIST, 0) or
             self.rect.y <= max(camera_rect.y - self.OFFSCREEN_DIST, 0) or
             self.rect.right > min(camera_rect.right + self.OFFSCREEN_DIST,
                                   screen_size[0]) or
             self.rect.bottom > min(camera_rect.bottom + self.OFFSCREEN_DIST,
                                    screen_size[1]))):
            # We've hit the edge of the world, or far enough away from the
            # camera, so disappear.
            self.remove()
Пример #7
0
    def _can_see_player(self):
        player = get_engine().player

        distance_x = abs(player.rect.x - self.rect.x)
        distance_y = abs(player.rect.y - self.rect.y)

        if (distance_x <= self.ATTACK_DISTANCE and
            distance_y <= self.ATTACK_DISTANCE):
            # See if there's anything in the way. We'll simulate an attack.

            start_pos = self.rect.topleft
            velocity, max_attack_ticks = self._get_attack_data()

            for i in xrange(1, max_attack_ticks - 1):
                pos = self._get_attack_position(start_pos, velocity, i)
                rect = pygame.Rect(pos, self.rect.size)

                for sprite in self.layer.iterate_in_rect(rect):
                    if sprite != self and sprite != player:
                        return False

            return True

        return False
Пример #8
0
 def on_collision(self, dx, dy, obj, self_rect, obj_rect):
     if obj == get_engine().player and not self.showed_exclamation:
         get_engine().ui.close_monologues()
         self.show_exclamation('heart_exclamation',
                               self._transition_clean)
         self.showed_exclamation = True