コード例 #1
0
    def check_not_friendly_fire(self, potential_target: object):
        """
        Проверка выстрела на friendly fair (циклом просматривает всех сокомандников и,
        если хотя бы один не проходит все проверки то возвращает False)

        :param potential_target: Цель, по которой дрону отдан приказ стрелять
        :type potential_target: Object
        :return: возвращает True, если выстрелить можно, и возвращает False, если стрелять нельзя
        :rtype: bool
        """

        vector_to_target = Vector.from_points(
            self.coord, potential_target.coord)  # ветор от дрона до цели
        for my_team_drone in self.my_brain_center.ret_drones_by_status(
                filter_alive=True, filter_our=True):
            if my_team_drone != self:  # в себя никак не попадешь, поэтому себя проверять на friendly fair не нужно
                if self.distance_to(potential_target) > self.distance_to(
                        my_team_drone
                ):  # если дистанция от дрона до цели больше, чем до сокомандника, то теоретически сокомандник может быть прямо между вами и целью - требуется дальнейшая проверка
                    if my_team_drone.near(
                            potential_target
                    ) is False:  # если цель и сокомандник находятся слишком близко друг к другу, то игра засчитает урон дрону или базе из другой команды
                        vector_to_teammate = Vector.from_points(
                            self.coord, my_team_drone.coord)
                        if vector_to_target.direction - self.ACCURACY_CANCEL_SHOT_FRIENDLY_FIRE <= \
                                vector_to_teammate.direction <= \
                                vector_to_target.direction + self.ACCURACY_CANCEL_SHOT_FRIENDLY_FIRE:  # проверка на зону поражения - если сокомандник находится в зоне поражения, то при выстреле с высокой вероятностью будет поражен
                            return False  # возвращаем False - нельзя стрелять
        return True  # возвращаем True, если все дроны прошли все проверки в цикле
コード例 #2
0
    def is_safe_way_to_target(self,
                              target):  # проверяет безопасно ли лететь до цели
        enemies = [
            drone for drone in self.scene.drones
            if self.team != drone.team and drone.is_alive
        ]

        vector_to_target = Vector.from_points(
            self.coord,
            target.coord if not isinstance(target, Point) else target)
        distance_to_target = vector_to_target.module if vector_to_target.module > 1 else 1
        _koef = 1 / distance_to_target
        normalize_vector = Vector(vector_to_target.x * _koef,
                                  vector_to_target.y * _koef)
        start_distance = 100 if self.is_near_base() else 1
        drones_on_way = []
        for i in range(start_distance, int(distance_to_target),
                       self.radius // 2):
            current_vector = normalize_vector * i
            check_point = Point(self.x + current_vector.x,
                                self.y + current_vector.y)
            for drone in enemies:
                if drone.distance_to(
                        check_point
                ) <= self.attack_range + 2 * self.radius:  # если по пути будем под обстрелом, то небезопасно
                    drones_on_way.append(drone.id)

        drones_on_way = set(drones_on_way)
        if len(
                drones_on_way
        ) <= 1:  # если во время перелёта по дрону будет стретять не больше 1 врага, то можно лететь
            return True
        else:
            return False
コード例 #3
0
    def shot(self, enemy):
        vector = Vector.from_points(self.coord, enemy.coord, module=1)
        self.vector = vector
        able_to_shot = True

        if any(self.point_in_circle(self.coord, teammate) for teammate in self.teammates) or \
                any(self.point_in_circle(self.coord, mother_ship.coord) for mother_ship in self.scene.motherships):
            point = self.make_a_step(
                self.coord,
                Point(scene.theme.FIELD_WIDTH / 2,
                      scene.theme.FIELD_HEIGHT / 2))
            self.move_at(point)
            return

        for teammate in self.teammates:
            vector = Vector.from_points(self.coord, teammate.coord, module=1)
            difference = abs(self.vector.direction - vector.direction)
            distance = self.distance_to(teammate)

            if difference < 15 and distance < self.gun.shot_distance:
                able_to_shot = False
                break

        if able_to_shot and self.distance_to(enemy) <= self.gun.shot_distance:
            if enemy.is_moving:
                self.gun.shot(
                    Point(enemy.coord.x + enemy.vector.x**enemy.vector.module,
                          enemy.coord.y + enemy.vector.y**enemy.vector.module))
            else:
                self.gun.shot(enemy)
コード例 #4
0
 def get_distance_from_points(cls, first_point, second_point):
     first_point, second_point = cls.check_on_points_errors(
         first_point, second_point)
     enemy_vector = Vector.from_points(first_point, second_point)
     enemy_distance_to_target = Vector.calc_module(enemy_vector.x,
                                                   enemy_vector.y)
     return enemy_distance_to_target
コード例 #5
0
ファイル: demo.py プロジェクト: kv2709/sandbox
    def game_step(self):
        if not self.have_gun:
            super(HunterDrone, self).game_step()
            return

        self.native_game_step()
        if self._hunting_strategy is None:
            return
        self._hunting_strategy.game_step(self)
        if self.victim is not None:
            vector = Vector.from_points(self.coord,
                                        self.victim.coord,
                                        module=self.gun.shot_distance)
            if int(self.distance_to(self.victim)) < 1 or (
                    self.distance_to(self.victim) < vector.module and abs(
                        nearest_angle_distance(vector.direction,
                                               self.direction)) < 7):
                self.gun.shot(self.victim)
        else:
            enemies = [
                enemy for enemy in self.scene.drones
                if enemy.team != self.team and enemy.is_alive
                and enemy.distance_to(self) < self.gun.shot_distance
            ]
            enemie = sorted(enemies, key=lambda x: -x.cargo.payload)
            for enemy in enemies:
                vector = Vector.from_points(self.coord, enemy.coord)
                if abs(nearest_angle_distance(vector.direction,
                                              self.direction)) < 7:
                    self.gun.shot(enemy)
                    break
        pass
コード例 #6
0
    def _get_places_near_mothership(self):
        """
            Выбор точки возле матери для защиты.
            :return: список доступных точек для защиты вокруг матери.
        """

        point_list = list()
        directions_list = list()
        start_vector = Vector(x=self.mothership.x, y=self.mothership.y)
        for direction in range(0, 361, 5):
            point_dir = start_vector.from_direction(direction=direction, module=int(MOTHERSHIP_HEALING_DISTANCE * 0.9))

            point_x = point_dir.x + start_vector.x
            point_y = point_dir.y + start_vector.y

            if (theme.FIELD_WIDTH - self.radius >= point_x >= self.radius) \
                    and (theme.FIELD_HEIGHT - self.radius >= point_y >= self.radius):
                directions_list.append(direction)

        start = 0
        stop = len(directions_list)
        step = len(directions_list) // (len(self.teammates) + 1)
        angle_list = list()

        for angle in range(start, stop, step):
            angle_list.append(directions_list[angle])
            new_point = start_vector.from_direction(direction=directions_list[angle],
                                                    module=int(MOTHERSHIP_HEALING_DISTANCE * 0.9))
            point_x = new_point.x + start_vector.x
            point_y = new_point.y + start_vector.y

            point_list.append(Point(point_x, point_y))

        return point_list
コード例 #7
0
 def get_place_near(point, target, angle):
     """
     Расчет места рядом с point с отклонением angle от цели target
     """
     vec = Vector(point.x - target.x, point.y - target.y)
     vec.rotate(angle)
     return Point(target.x + vec.x, target.y + vec.y)
コード例 #8
0
    def get_place_for_attack(self, soldier, target):
        """
        Выбор места для атаки цели, если цель не в радиусе атаки

        :param soldier: атакующий
        :param target: цель/объект атаки
        :return: Point  - место атаки или None - если не выбрано место атаки
        """
        if isinstance(target, GameObject):
            vec = Vector.from_points(target.coord, soldier.coord)
        elif isinstance(target, Point):
            vec = Vector.from_points(target, soldier.coord)
        else:
            raise Exception("target must be GameObject or Point!".format(
                target, ))

        dist = vec.module
        _koef = 1 / dist
        norm_vec = Vector(vec.x * _koef, vec.y * _koef)
        vec_gunshot = norm_vec * min(int(soldier.attack_range), int(dist))
        purpose = Point(target.coord.x + vec_gunshot.x,
                        target.coord.y + vec_gunshot.y)
        angles = [0, 60, -60, 30, -30]
        random.shuffle(angles)
        for ang in angles:
            place = self.get_place_near(purpose, target, ang)
            if place and soldier.validate_place(place):
                return place
        return None
コード例 #9
0
 def checking_the_line_of_fire(self, unit, target, point=None):
     """Проверить, что на линии огня нет союзников"""
     if point is None:
         point = unit.coord
     vec_target_self = Vector(target.coord.x - point.x,
                              target.coord.y - point.y)
     norm_vec_target_self = self.normalize_vector(vec_target_self)
     for friendly in self.data.my_units:
         if friendly is not unit:
             if friendly.distance_to(point) <= friendly.radius * 1.5:
                 return False
             vec_target_friendly = Vector(target.coord.x - friendly.coord.x,
                                          target.coord.y - friendly.coord.y)
             norm_vec_target_friendly = self.normalize_vector(
                 vec_target_friendly)
             scalar = self.scalar_vector_multiplication(
                 norm_vec_target_self, norm_vec_target_friendly)
             try:
                 angle = degrees(acos(scalar))
             except:
                 return False
             if angle < _MIN_ANGLE_ATTACK \
                     and (friendly.distance_to(target) < point.distance_to(target)):
                 return False
     else:
         return True
コード例 #10
0
def get_point_on_way_to(unit, target, at_distance=None):
    if at_distance is None:
        at_distance = theme.CARGO_TRANSITION_DISTANCE * 0.9
    va = Vector.from_points(unit.coord, target.coord)
    vb = Vector.from_direction(va.direction, at_distance)
    vb.rotate(180.0)
    return Point(unit.x + va.x + vb.x, unit.y + va.y + vb.y)
コード例 #11
0
 def _get_point_nearby_enemy(self, target):
     """
     Находит и возвращает валидную точку, которую можно занять для атаки цели
     :param target: цель атаки
     :return: оптимальную(нет) точку рядом с врагом
     """
     if isinstance(target, GameObject):
         vec = Vector.from_points(target.coord, self.drone.coord)
     elif isinstance(target, Point):
         vec = Vector.from_points(target, self.drone.coord)
     else:
         raise Exception("target must be GameObject or Point!".format(target, ))
     dist = vec.module
     _koef = 1 / dist
     norm_vec = Vector(vec.x * _koef, vec.y * _koef)
     vec_gunshot = norm_vec * min(int(self.drone.attack_range), int(dist))
     purpose = Point(target.coord.x + vec_gunshot.x, target.coord.y + vec_gunshot.y)
     angles = [0, 60, -60, 40, -40, 20, -20]
     shuffle(angles)
     if self.drone.drone_number == 1:
         place = self.get_place_near(purpose, target, angles[self.drone.drone_number])
         return place
     for ang in angles:
         place = self.get_place_near(purpose, target, ang)
         if place and self.valid_place(place):
             return place
     return Point(theme.FIELD_WIDTH // 2, theme.FIELD_HEIGHT // 2)
コード例 #12
0
    def _turn_to_purpose(self, drone, purpose):
        """
        Поворот к цели
        :param drone: экземпляр класса OkhotnikovFNDrone
        :param purpose: обект, колученный в методе next_purpose
        """
        if hasattr(purpose, 'is_moving') and purpose.is_moving:
            purpose_vec = Vector.from_direction(direction=purpose.direction,
                                                module=1)
            drone_purpose_vec = Vector.from_points(purpose.coord, drone.coord)

            length = drone_purpose_vec.module if drone_purpose_vec.module > 0 else 1
            _cos = ((purpose_vec.x * drone_purpose_vec.x +
                     purpose_vec.y * drone_purpose_vec.y) /
                    (length * purpose_vec.module))
            coef_b = (PROJECTILE_SPEED**2 - DRONE_SPEED**2)
            coef_d = (2 * DRONE_SPEED * length *
                      _cos)**2 + 4 * coef_b * (length**2)
            coef = round((-2 * DRONE_SPEED * length + coef_d**0.5) /
                         (2 * coef_b) * DRONE_SPEED)
            purpose_vec = purpose_vec * coef
            possible_purpose = Point(purpose.coord.x + purpose_vec.x,
                                     purpose.coord.y + purpose_vec.y)

            drone.actions.append(['turn', possible_purpose])
        else:
            drone.actions.append(['turn', purpose])
コード例 #13
0
    def devide_step_path(self, drone, target):

        if drone.distance_to(target) > 150:
            for angle_delta in range(12):
                vec = Vector.from_points(drone.coord, target.coord)
                vec = Vector.from_direction(
                    vec.direction + randint(angle_delta * 5, angle_delta * 5),
                    150)
                flag = True
                for d in drone.scene.drones:
                    if d.team != drone.team and drone.distance_to(
                            d) < drone.gun.shot_distance:
                        vec2 = Vector.from_points(d.coord, target.coord)
                        if ((abs(180 - abs(d.direction - vec.direction)) < 5 or
                             (abs(d.direction - vec.direction) < 5
                              and abs(vec2.direction - vec.direction) < 5))):
                            flag = False
                if flag:
                    break
            else:
                vec = Vector.from_points(drone.coord, target.coord)
                vec = Vector.from_direction(vec.direction, 150)
                new_coord = Point(x=drone.coord.x + vec.x,
                                  y=drone.coord.y + vec.y)
                drone.actions.append(['move_step', new_coord])
                return
            # передвигаемся не по прямой до цели, а по 150 точек, со случайным углом
            new_coord = Point(x=drone.coord.x + vec.x, y=drone.coord.y + vec.y)
            drone.actions.append(['move_step', new_coord])
        else:
            if drone.distance_to(target) > 1:
                drone.actions.append(['move', target])
コード例 #14
0
 def move_to(self, object):
     self.cost_forpost = 0
     self.target_move_to = object
     self.headquarters.save_static_move(self, object)
     vector_target = Vector.from_points(self.coord, object, module=1) if isinstance(object, Point) else \
         Vector.from_points(self.coord, object.coord, module=1)
     self.vector = vector_target
     super().move_at(object)
コード例 #15
0
    def get_angle(self, drone, partner, victim):
        def scalar(v1, v2):
            return v1.x * v2.x + v1.y * v2.y

        to_partner = Vector(partner.x - drone.x, partner.y - drone.y)
        to_victim = Vector(victim.x - drone.x, victim.y - drone.y)
        cos_partner_victim = scalar(to_partner, to_victim) / (to_partner.module * to_victim.module)
        return degrees(acos(cos_partner_victim))
コード例 #16
0
 def pursue(self, target_coord):
     """Двигаемся немного вперед к цели"""
     vec1 = Vector.from_points(self.coord, target_coord, module=1)
     self.vector = vec1
     vec2 = Vector.from_direction(round(self.direction), 30)
     new_coord = Point(round(int(self.x + vec2.x)),
                       y=round(int(self.y + vec2.y)))
     self.task = (self.move_to, new_coord)
     self.next_action()
コード例 #17
0
    def get_angle_Ox(self, drone, victim):
        def scalar(v1, v2):
            return v1.x * v2.x + v1.y * v2.y

        v1 = Vector(victim.x - drone.x, victim.y - drone.y)
        v2 = Vector(1200, 0)

        cos = scalar(v1, v2) / (v1.module * v2.module)
        return degrees(acos(cos))
コード例 #18
0
 def get_place_near_mothership(self, soldier):
     center_field = Point(theme.FIELD_WIDTH // 2, theme.FIELD_HEIGHT // 2)
     vec = Vector.from_points(soldier.my_mothership.coord, center_field)
     dist = vec.module
     _koef = 1 / dist
     norm_vec = Vector(vec.x * _koef, vec.y * _koef)
     vec_position = norm_vec * MOTHERSHIP_HEALING_DISTANCE * 0.9
     position = Point(soldier.my_mothership.coord.x + vec_position.x, soldier.my_mothership.coord.y + vec_position.y)
     return position
コード例 #19
0
 def get_angle(self, partner: GameObject, target: GameObject):
     """
     Получает угол между векторами self-target и partner-target
     """
     def scalar(vec1, vec2):
         return vec1.x * vec2.x + vec1.y * vec2.y
     v12 = Vector(self.drone.coord.x - target.coord.x, self.drone.coord.y - target.coord.y)
     v32 = Vector(partner.coord.x - target.coord.x, partner.coord.y - target.coord.y)
     _cos = scalar(v12, v32) / (v12.module * v32.module + 1.e-8)
     return math.degrees(math.acos(_cos))
コード例 #20
0
 def _get_position_from_points(first_point, second_point, koef, angle):
     vec = Vector.from_points(first_point, second_point)
     dist = vec.module
     first_koef = 1 / dist
     norm_vec = Vector(vec.x * first_koef * koef, vec.y * first_koef * koef)
     vec_position = norm_vec * MOTHERSHIP_HEALING_DISTANCE
     if angle:
         vec_position.rotate(angle)
     position = Point(first_point.x + vec_position.x, first_point.y + vec_position.y)
     return position
コード例 #21
0
 def get_place_near(self, point, target, angle):
     """
     Расчет места рядом с point с отклонением angle от цели target
     :param point:
     :param target:
     :param angle:
     :return: new place point
     """
     vec = Vector(point.x - target.x, point.y - target.y)
     vec.rotate(angle)
     return Point(target.x + vec.x, target.y + vec.y)
コード例 #22
0
 def get_place_near(point, target, angle):
     """
     Расчет места рядом с point с отклонением angle от цели target
     :param point: исходная точка
     :param target: предполагаемая цель
     :param angle: угол отклонения
     :return: точка недалеко от цели
     """
     vec = Vector(point.x - target.x, point.y - target.y)
     vec.rotate(angle)
     return Point(target.x + vec.x, target.y + vec.y)
コード例 #23
0
    def get_near_base(self, target):

        base = self.me.my_mothership
        new_vec = Vector.from_points(base.coord, target.coord)
        other_vec = new_vec.module
        _koef = 1 / other_vec
        norm_vec = Vector(new_vec.x * _koef, new_vec.y * _koef)
        vec_position = Vector(norm_vec.x * MOTHERSHIP_HEALING_DISTANCE * 0.9,
                              norm_vec.y * MOTHERSHIP_HEALING_DISTANCE * 0.9)
        new_position = Point(base.coord.x + vec_position.x, base.coord.y + vec_position.y)
        return new_position
コード例 #24
0
    def avoid_friendly_fire(self):
        """
        Метод меняет позицию дрона-истребителя на случайно генерируемую в пределах 150 от изначальной.
        Вызывается если в других методах valide_position() вернул False.

        :return: None

        """
        vec = Vector(self.drone.position.x, self.drone.position.y)
        point = vec.from_direction(direction=random.choice([90, 180, 270, 360]), module=random.choice([100, 150, 200]))
        self.change_position(
            position=Point(x=self.drone.coord.x + point.x, y=self.drone.coord.y + point.y))
コード例 #25
0
 def get_coords_for_attak(self, drones_in_my_team, mothership_name):
     mothership = self.scene.get_mothership(mothership_name)
     drones = list(d for d in self.scene.drones
                   if d.team == mothership.team)
     quantity = drones_in_my_team
     if mothership != self.mothership:
         distance = 400
     else:
         distance = 300
         angle = 85 / (quantity - 1)
         rotate = -5
         self.target_for_attack = None
     if mothership.x > self.scene.field[
             0] / 2 and mothership.y > self.scene.field[1] / 2:
         p = Point(mothership.x, mothership.y - distance)
         v = Vector.from_points(mothership.coord, p)
         angle = 40 / (quantity - 1)
         rotate = 0
     elif mothership.x > self.scene.field[
             0] / 2 and mothership.y < self.scene.field[1] / 2:
         p = Point(mothership.x - distance, mothership.y)
         v = Vector.from_points(mothership.coord, p)
         angle = 40 / (quantity - 1)
         rotate = -50
     elif mothership.x < self.scene.field[
             0] / 2 and mothership.y > self.scene.field[1] / 2:
         p = Point(mothership.x + distance, mothership.y)
         v = Vector.from_points(mothership.coord, p)
         angle = 40 / (quantity - 1)
         rotate = -50
     elif mothership.x < self.scene.field[
             0] / 2 and mothership.y < self.scene.field[1] / 2:
         p = Point(mothership.x, mothership.y + distance)
         v = Vector.from_points(mothership.coord, p)
         angle = 40 / (quantity - 1)
         rotate = 0
     len_alive = len(set(m for m in self.scene.motherships if m.is_alive))
     if len_alive == 2:
         angle = 90 / (quantity - 1)
         rotate = 0
     v.rotate(rotate)
     p = Point(mothership.x + v.x, mothership.y + v.y)
     points_to_stop = [p]
     difference = angle
     while len(points_to_stop) < quantity:
         next_v = Vector.from_direction(v.direction - angle, v.module)
         next_p = Point(mothership.x + next_v.x, mothership.y + next_v.y)
         points_to_stop.append(next_p)
         angle += difference
     for d in my_team:
         d.point_to_attack_mothership = points_to_stop.pop()
         d.move_at(self.point_to_attack_mothership)
         self.action = 'move_to_plase_for_attack'
コード例 #26
0
    def get_point_near_target(self):
        """
        Метод рассчитывает начальную точку атаки рядом с целью.

        :return: Point-class instance

        """
        vec = Vector.from_points(self.drone.coord, self.drone.aim.coord)
        dist = (self.drone.distance_to(self.drone.aim) - self.drone.gun.shot_distance) * 1.05
        direction = vec.direction
        vec_attack = Vector.from_direction(direction=direction + self.drone.hq.courses_k[self.drone.inner_team_id - 1],
                                           module=dist)
        point = Point(self.drone.coord.x + vec_attack.x, self.drone.coord.y + vec_attack.y)
        return point
コード例 #27
0
 def check_base_near(self, target):
     """
     Найти новую точку рядом с базой.
     """
     base = self.me.my_mothership
     new_vec = Vector.from_points(base.coord, target.coord)
     other_vec = new_vec.module
     _koef = 1 / other_vec
     norm_vec = Vector(new_vec.x * _koef, new_vec.y * _koef)
     vec_position = Vector(norm_vec.x * MOTHERSHIP_HEALING_DISTANCE * 0.9,
                           norm_vec.y * MOTHERSHIP_HEALING_DISTANCE * 0.9)
     new_position = Point(base.coord.x + vec_position.x,
                          base.coord.y + vec_position.y)
     return new_position
コード例 #28
0
 def _friendly_fire(self, enemy):
     enemy_vector = Vector.from_points(self.drone.coord, enemy.coord)
     for mate in self.drone.teammates:
         if self.drone.near(mate):
             return True
         mate_vector = Vector.from_points(self.drone.coord, mate.coord)
         scalar = int(enemy_vector.x * mate_vector.x +
                      enemy_vector.y * mate_vector.y)
         modules = int(enemy_vector.module * mate_vector.module)
         angle = math.degrees(math.acos(min(scalar / modules, 1)))
         if angle < 20 and self.drone.distance_to(enemy) > self.drone.distance_to(mate) \
                 and not isinstance(mate.state, StateMoving):
             return True
     return False
コード例 #29
0
 def verify_angle(self, partner: GameObject, target: Point):
     """
     :return: True, если partner перекрывает цель
     """
     v_from_self_to_target = Vector(target.x - self.coord.x,
                                    target.y - self.coord.y)
     v_from_self_to_partner = Vector(partner.coord.x - self.coord.x,
                                     partner.coord.y - self.coord.y)
     if v_from_self_to_target.module > v_from_self_to_partner.module and v_from_self_to_partner.module > 0:
         angle_partner = math.atan(
             70 / v_from_self_to_partner.module) * (180 / math.pi)
         return abs(v_from_self_to_target.direction -
                    v_from_self_to_partner.direction) < angle_partner
     else:
         return False
コード例 #30
0
    def get_turret_points(self):
        """
        Метод создает стартовые точки расстановки дронов

        :return: None

        """
        vec = Vector.from_points(self.my_mothership.coord, self.hq.center_field)
        dir = vec.direction
        angles_set = [dir - 70, dir + 40, dir + 10, dir - 10, dir - 40]

        for angle in angles_set:
            vec_turret = Vector.from_direction(direction=angle, module=MOTHERSHIP_HEALING_DISTANCE * 0.9)
            point_turret = Point(self.my_mothership.coord.x + vec_turret.x, self.my_mothership.coord.y + vec_turret.y)
            self.hq.TURRET_POINTS.append(Point(x=point_turret.x, y=point_turret.y))
コード例 #31
0
ファイル: objects.py プロジェクト: suguby/robogame_engine
 def __init__(self, coord=None, radius=None, direction=None):
     if self.__scene is None:
         raise RobogameException("You must create Scene instance at first!")
     if self.auto_team:
         self.__team = self.scene.get_team(cls=self.__class__)
     if radius is None:
         radius = self.__class__.radius
     self.coord = coord if coord else Point(0, 0)
     self.radius = radius
     self.__container.append(self)
     GameObject.__objects_count += 1
     self.id = GameObject.__objects_count
     if direction is None:
         direction = randint(0, 360)
     self.vector = Vector.from_direction(direction, module=1)
     self.target = None
     self.state = StateStopped(obj=self)
     self._heartbeat_tics = theme.HEARTBEAT_INTERVAL
     self._events = Queue()
     self._commands = Queue()
     self._selected = False
     self.add_event(EventBorned(self))
     self.debug('born {coord} {vector}')