Exemple #1
0
 def get_blocking_position(self, world):
     # Calculate blocking position
     possession = world.robot_in_possession
     if not possession:
         error(
             "Attempting to find blocking position while no robot in possession"
         )
         return Vector(0, 0, 0, 0)
     assert (not possession.is_our_team)
     target = None
     if world.in_our_half(possession):
         info("Blocking our goal which is at ({0}, {1})".format(
             world.our_goal.x, world.our_goal.y))
         target = world.our_goal
     else:
         # Use their other robot as target
         info("Blocking opponent pass")
         target = ([r for r in world.their_robots if r != possession])[0]
     if (possession.x - target.x) == 0:
         error("Robot in possession in line on x!")
         return Vector(0, 0, 0, 0)
     # m =  (possession.y - target.y) / (possession.x - target.x)
     # return Vector(self.x, possession.y + m * (self.x - possession.x), 0, 0)
     return Vector((target.x + possession.x) / 2,
                   (target.y + possession.y) / 2, 0, 0)
     """dx = target.x - possession.x
Exemple #2
0
def defender_get_rotation_to_catch_point(robot_vec, ball_vec, catch_distance):
    '''
    Finds a relative angle by which the defending robot needs to rotate to face the catching point.
    Catching point is the location where the robot is facing the ball and so can grab
    the ball easily.
    There are usually two grabbing point from each side of the ball, so the 'is_ball_between_angles'
    method is used to find the one that is suitable for taking the ball.
    Also, it tries to approach the ball from the left side and the righ side from the kicker and
    return the rotation that is shorter.
    positive angle - clockwise rotation
    negative angle - counter-clockwise rotation
    '''

    # Two vectors from the left and the right side of movement
    robot_vec_left = Vector(robot_vec.x, robot_vec.y, robot_vec.angle - math.pi / 2, 0)
    robot_vec_right = Vector(robot_vec.x, robot_vec.y, robot_vec.angle + math.pi / 2, 0)

    # calculates catching point angles for each side of movement
    first_front_angle, first_theta, first_alpha = defender_get_rotation_to_catch_point_helper(robot_vec_left, ball_vec, catch_distance, "left")
    second_front_angle, second_theta, second_alpha = defender_get_rotation_to_catch_point_helper(robot_vec_right, ball_vec, catch_distance, "right")

    # gets the best rotation angle for each side if movement
    first_relative_angle = is_ball_between_angles(first_front_angle, robot_vec.angle, first_theta, first_alpha)
    second_relative_angle = is_ball_between_angles(second_front_angle, robot_vec.angle, second_theta, second_alpha)

    # returns the rotation angle that is shorter
    if abs(first_relative_angle) < abs(second_relative_angle):
        logging.debug("Returning first:" + str(first_relative_angle) + " in degrees " + str(math.degrees(first_relative_angle)))
        # logging.info(">>>>>>>>> LEFT")
        return (first_relative_angle, "left")
    else:
        logging.debug("Returning second:" + str(second_relative_angle) + " in degrees " + str(math.degrees(second_relative_angle)))
        # logging.info(">>>>>>>>> RIGHT")
        return (second_relative_angle, "right")
Exemple #3
0
    def perform(self, comms):
        # get robot
        robots = filter(lambda r: not r.is_missing(), self.world.their_robots)
        robots.sort(key=lambda r: math.hypot(r.x - self.robot.x, r.y - self.robot.y))
        if len(robots) == 0:
            logging.error("There is no enemy here. Gimme someone to destroy!")
            return 1
        robot = robots[0]

        # Find our goal
        goal = Vector(0, 225, 0, 0)
        if self.robot.x > 300:
            goal = Vector(600, 225, 0, 0)

        # get the point
        robots = self.world.their_robots
        y_diff = goal.y - robot.y
        x_diff = goal.x - robot.x
        ratio = (self.world.our_defender.x - robot.x) / x_diff

        y_mean = robot.y + (y_diff * ratio)

        distance = utils.defender_distance_on_y(self.world.our_defender.vector, y_mean)

        print("DISTANCE: " + str(distance))
        logging.info("Wants to move by: " + str(distance))
        comms.move(distance)

        return utils.defender_move_delay(distance)
Exemple #4
0
class GoToStaticBall(Action):
    '''
    Move defender to the ball when static
    '''
    preconditions = [(lambda w, r: abs(
        utils.defender_get_rotation_to_catch_point(
            Vector(r.x, r.y, r.angle, 0), Vector(w.ball.x, w.ball.y, 0, 0), r.
            catch_distance)[0]) < ROTATION_THRESHOLD,
                      "Defender is facing ball"),
                     (lambda w, r: r.catcher == 'OPEN', "Grabbers are open."),
                     (lambda w, r: utils.ball_is_static(w), "Ball is static.")]

    def perform(self, comms):
        # reset dynamic threshold
        # TODO: has to be restarted everywhere!
        global ROTATION_THRESHOLD
        ROTATION_THRESHOLD = 0.1

        dx = self.world.ball.x - self.robot.x
        dy = self.world.ball.y - self.robot.y
        displacement = math.hypot(dx, dy)

        if displacement == 0:
            alpha = 0
        else:
            # TODO: has to handle this edge case better
            try:
                alpha = math.degrees(
                    math.asin(self.robot.catch_distance / float(displacement)))
            except ValueError as er:
                print(er)
                x = self.world.ball.x
                y = self.world.ball.y
                angle = utils.get_rotation_to_point(self.robot.vector,
                                                    Vector(x, y, 0, 0))
                logging.info("Wants to close-rotate by: " + str(angle))
                comms.turn(angle)
                return 1  # TODO: NO FIXED DELAY
        beta = 90 - alpha

        if math.sin(math.radians(alpha)) == 0:
            distance_to_move = 15  # something is obviously wrong so we have to move a bit
        else:
            distance_to_move = math.sin(
                math.radians(beta)) * self.robot.catch_distance / math.sin(
                    math.radians(alpha))

        # Find the movement side
        angle, side = utils.defender_get_rotation_to_catch_point(
            Vector(self.robot.x, self.robot.y, self.robot.angle, 0),
            Vector(self.world.ball.x, self.world.ball.y, 0, 0),
            self.robot.catch_distance)
        if side == "left":
            distance_to_move = -distance_to_move

        logging.info("Wants to move by: " + str(distance_to_move))
        comms.move(distance_to_move)

        return utils.defender_move_delay(distance_to_move)
Exemple #5
0
    def test3(self):
        initial_state = {
            'task': 'move-grab',
            'max_steps': 2,
            'our_defender': Vector(250, 220, math.radians(200), 0),
            'our_attacker': None,
            'ball': Vector(200, 170, 0, 0),
        }

        self.run(initial_state, "Test 3")
Exemple #6
0
    def testm3_1(self):
        initial_state = {
            'task': 'm31',
            'max_steps': 2,
            'our_defender': Vector(400, 300, math.radians(90), 0),
            'our_attacker': Vector(50, 200, math.radians(45), 0),
            'ball': Vector(100, 200, 0, 0),
        }

        self.run(initial_state, "Test M3 - Receiving a pass")
Exemple #7
0
def defender_rotation_to_defend_point(robot_vec, ball_vec, center, center_radius, side):

    def defender_get_defend_point(robot_vec, ball_vec, center, center_radius, side):
        dx = ball_vec.x - center.x
        dy = ball_vec.y - center.y
        alpha = math.atan2(dx, dy) % (math.pi * 2)

        # lovely for ifs to make your life easier reader
        offset = math.radians(20)
        if side == "left":
            if alpha < offset:
                alpha = offset
            elif alpha > math.radians(180) - offset:
                alpha = math.radians(180) - offset
        else:
            if alpha < math.radians(180) + offset:
                alpha = math.radians(180) + offset
            elif alpha > math.radians(360) - offset:
                alpha = math.radians(360) - offset

        x = center.x + center_radius * math.sin(alpha)
        y = center.y + center_radius * math.cos(alpha)

        return Vector(x, y, 0, 0)

    defend_point = defender_get_defend_point(robot_vec, ball_vec, center, center_radius, side)

    global DEFEND_POINT
    DEFEND_POINT = Vector(defend_point.x, 470 - defend_point.y, 0, 0)

    angle, side = defender_get_rotation_to_catch_point(robot_vec, defend_point, 1)

    return (angle, side, defend_point)
Exemple #8
0
    def perform(self, comms):
        global ROTATION_THRESHOLD
        logging.info('---- ' + str(ROTATION_THRESHOLD))
        x = self.world.ball.x
        y = self.world.ball.y
        angle = utils.defender_get_rotation_to_catch_point(
            Vector(self.robot.x, self.robot.y, self.robot.angle, 0),
            Vector(x, y, 0, 0), self.robot.catch_distance)[0]
        logging.info("Wants to rotate by: " + str(angle))

        comms.turn(angle)

        if ROTATION_THRESHOLD < 0.30:
            ROTATION_THRESHOLD += 0.07

        return utils.defender_turn_delay(angle)
Exemple #9
0
def get_defence_point(world):
    if world.our_side == 'left':
        x = 100
    else:
        x = world.pitch.width - 100
    y = world.pitch.height / 2
    return Vector(x, y, 0, 0)
Exemple #10
0
    def check_object(vec3):
        dx = vec2.x - vec1.x
        if dx == 0:
            dx = SMALL_VALUE
        m_straight = float(vec2.y - vec1.y) / dx
        if m_straight == 0:
            m_straight = SMALL_VALUE
        c_straight = vec1.y - vec1.x * m_straight
        m_perp = float(-1) / m_straight
        c_perp = vec3.y - vec3.x * m_perp

        dm = m_straight - m_perp
        if dm == 0:
            dm = SMALL_VALUE
        ix = -(c_straight - c_perp) / dm
        iy = m_straight * ix + c_straight
        intercept = Vector(ix, iy, 0, 0)
        if dist(vec1, intercept) > dist(vec1, vec2):
            return None

        distance_from_line = dist(intercept, vec3)
        if distance_from_line < AVOID_DISTANCE:
            return dist(vec1, intercept)
        else:
            return None
Exemple #11
0
 def perform(self, comms):
     rot_angle = utils.defender_get_rotation_to_catch_point(
         Vector(self.robot.x, self.robot.y, self.robot.angle, 0),
         utils.get_defence_point(self.world), 0)[0]
     logging.info("Facing direction to move to defence area. Rotating %f degrees.", math.degrees(rot_angle))
     comms.turn(rot_angle)
     return utils.defender_turn_delay(rot_angle)
Exemple #12
0
    def perform(self, comms):
        # reset dynamic threshold
        # TODO: has to be restarted everywhere!
        global ROTATION_THRESHOLD
        ROTATION_THRESHOLD = 0.1

        dx = self.world.ball.x - self.robot.x
        dy = self.world.ball.y - self.robot.y
        displacement = math.hypot(dx, dy)

        if displacement == 0:
            alpha = 0
        else:
            # TODO: has to handle this edge case better
            try:
                alpha = math.degrees(
                    math.asin(self.robot.catch_distance / float(displacement)))
            except ValueError as er:
                print(er)
                x = self.world.ball.x
                y = self.world.ball.y
                angle = utils.get_rotation_to_point(self.robot.vector,
                                                    Vector(x, y, 0, 0))
                logging.info("Wants to close-rotate by: " + str(angle))
                comms.turn(angle)
                return 1  # TODO: NO FIXED DELAY
        beta = 90 - alpha

        if math.sin(math.radians(alpha)) == 0:
            distance_to_move = 15  # something is obviously wrong so we have to move a bit
        else:
            distance_to_move = math.sin(
                math.radians(beta)) * self.robot.catch_distance / math.sin(
                    math.radians(alpha))

        # Find the movement side
        angle, side = utils.defender_get_rotation_to_catch_point(
            Vector(self.robot.x, self.robot.y, self.robot.angle, 0),
            Vector(self.world.ball.x, self.world.ball.y, 0, 0),
            self.robot.catch_distance)
        if side == "left":
            distance_to_move = -distance_to_move

        logging.info("Wants to move by: " + str(distance_to_move))
        comms.move(distance_to_move)

        return utils.defender_move_delay(distance_to_move)
Exemple #13
0
 def translate_position(self, obj, v):
     deltax = v.x - (self._pitch.width / 2)
     deltay = v.y - (self._pitch.height / 2)
     factor = (self._camera_height - obj.height) / self._camera_height
     deltax *= factor
     deltay *= factor
     return Vector(deltax + self._pitch.width / 2,
                   deltay + self._pitch.height / 2, v.angle, v.velocity)
Exemple #14
0
    def perform(self, comms):
        x = self.world.ball.x
        y = self.world.ball.y
        angle = utils.get_rotation_to_point(self.robot.vector, Vector(x, y, 0, 0))
        logging.info("Wants to rotate by: " + str(angle))
        comms.turn(angle)

        return utils.defender_turn_delay(angle)
Exemple #15
0
def attacker_can_score_from_position(world, position):
    assert(position.angle == 0)
    goal_points = [Vector(world.their_goal.x, world.their_goal.y + (world.their_goal.width / 4) * i, 0, 0) for i in [1, 2, 3]]
    for point in goal_points:
        obstacle = find_obstacle(world, position, point, exclude=[world.our_attacker])
        if not obstacle:
            return True
    return False
Exemple #16
0
def defender_distance_on_y(robot_vec, y_value):
    '''
    Calculates the moving distance on y axis.
    '''
    distance = abs(y_value - robot_vec.y)

    target_point = Vector(robot_vec.x, y_value, 0, 0)
    direction = get_movement_direction_from_vector(robot_vec, target_point)

    return (distance + 2) * direction
Exemple #17
0
class KickToScoreZone(Action):
    '''
    Pass ball to our attacker's score zone
    '''
    preconditions = [(lambda w, r: abs(r=utils.defender_get_rotation_to_catch_point(Vector(r.x, r.y, r.angle, 0)[0], Vector(w.score_zone.x, w.score_zone.y, 0, 0), r.catch_distance)) < FACING_ROTATION_THRESHOLD,
                      "Defender is facing attacker's score zone"),
                     (lambda w, r: r.has_ball(w.ball), "Defender has ball")]

    def perform(self, comms):
        raise NotImplementedError
Exemple #18
0
 def vector(self, new_vector):
     if new_vector is None:  # or not isinstance(new_vector, Vector):
         raise ValueError(
             'The new vector can not be None and must be an instance of a Vector'
         )
     else:
         self._vector = Vector(new_vector.x, new_vector.y,
                               new_vector.angle - self._angle_offset,
                               new_vector.velocity)
         self._is_missing = False
Exemple #19
0
class MoveToDefenceArea(Action):

    preconditions = [(lambda w, r: abs(utils.defender_get_rotation_to_catch_point(Vector(r.x, r.y, r.angle, 0), utils.get_defence_point(w), 0)[0]) < ROTATION_THRESHOLD, "Aligned to move to defence point.")]

    def perform(self, comms):
        dist = utils.dist(self.robot, utils.get_defence_point(self.world))
        dist *= utils.get_movement_direction_from_vector(self.robot, utils.get_defence_point(self.world))
        logging.info("Moving to defence area. Moving %f right.", dist)
        comms.move(dist)
        return utils.defender_move_delay(abs(dist))
Exemple #20
0
def defender_follow_ball_distance(robot_vec, ball_vec):
    robot_vec_left = Vector(robot_vec.x, robot_vec.y, robot_vec.angle - math.pi / 2, 0)
    alpha_left = get_rotation_to_point(robot_vec_left, ball_vec)

    robot_vec_right = Vector(robot_vec.x, robot_vec.y, robot_vec.angle + math.pi / 2, 0)
    alpha_right = get_rotation_to_point(robot_vec_right, ball_vec)

    # Find the closes angle (side to move)
    side = -1
    alpha = alpha_left
    if alpha_left > alpha_right:
        side = 1
        alpha = alpha_right

    dx = ball_vec.x - robot_vec.x
    dy = ball_vec.y - robot_vec.y
    hypotenus = math.hypot(dx, dy)

    distance_to_move = math.cos(alpha) * hypotenus * side

    return distance_to_move
Exemple #21
0
def defender_angle_to_pass_upfield(world, defender_robot, enemy_zone_radius=40):
    """
    Calculates the angle for defender to rotate by to pass to attacker or, if not possible,
    angle to kick upfield which is not contested by enemy robots.

    :param world: World object
    :param defender_robot: The robot who is trying to kick
    :param enemy_zone_radius: The radius of the circle around enemy robots in which the ball should not pass
    :return: The calculated angle
    """

    def can_pass_to_attacker(defender_vec, attacker_vec, their_robots_vecs):
        can_pass = True
        defender_attacker_line = ((defender_vec.x, defender_vec.y), (attacker_vec.x, attacker_vec.y))
        for t in their_robots_vecs:
            if line_intersects_circle(defender_attacker_line, ((t.x, t.y), enemy_zone_radius)):
                can_pass = False
                break
        return can_pass

    aim_vector = world.our_attacker.vector
    if world.our_attacker.is_missing():
        aim_vector = world.their_goal.vector

    their_vecs = [t.vector for t in world.their_robots if not t.is_missing()]

    if can_pass_to_attacker(defender_robot.vector, aim_vector, their_vecs):
        return get_rotation_to_point(defender_robot.vector, aim_vector)
    else:
        # TODO possibly improve this to be less brute force
        x = aim_vector.x
        num_of_iterations = 100
        step = world.pitch.height / num_of_iterations
        # Upper range
        for y in range(world.pitch.height / 2, world.pitch.height, step):
            new_vec = Vector(x, y, 0, 0)
            # Could skip by enemy_zone_radius but can't work out a way to update loop variable in python
            if can_pass_to_attacker(defender_robot.vector, new_vec, their_vecs):
                return get_rotation_to_point(defender_robot.vector, new_vec)
        # Lower range

        for y in range(world.pitch.height / 2, 0, -step):
            new_vec = Vector(x, y, 0, 0)
            # Could skip by enemy_zone_radius but can't work out a way to update loop variable in python
            if can_pass_to_attacker(defender_robot.vector, new_vec, their_vecs):
                return get_rotation_to_point(defender_robot.vector, new_vec)

        # Could not find an angle, choose a random one within the cone between the defender and their corners
        top_corner = Vector(0, 0, 0, 0)
        bottom_corner = Vector(0, world.pitch.height, 0, 0)
        if world.our_side == 'left':
            top_corner = Vector(world.pitch.width, 0, 0, 0)
            bottom_corner = Vector(world.pitch.width, world.pitch.height, 0, 0)

        top_angle = get_rotation_to_point(defender_robot.vector, top_corner)
        bottom_angle = get_rotation_to_point(defender_robot.vector, bottom_corner)

        return random.uniform(min(top_angle, bottom_angle), max(top_angle, bottom_angle))
Exemple #22
0
def get_avoiding_angle_to_point(world, vec1, vec2):
    straight_angle = get_rotation_to_point(vec1, vec2)
    # straight_distance = dist(vec1, vec2)
    # straight_vector = Vector(vec1.x, vec1.y, vec1.angle, 0)
    obstacle = find_obstacle(world, vec1, vec2)
    if not obstacle:
        return straight_angle

    logging.info("Obstacle on path")

    m_straight = float(vec2.y - vec1.y) / ((vec2.x - vec1.x) + 1)
    c_straight = vec1.y - vec1.x * m_straight
    m_perp = float(-1) / m_straight
    c_perp = obstacle.y - obstacle.x * m_perp

    ix = -(c_straight - c_perp) / ((m_straight - m_perp) + 1)
    iy = m_straight * ix + c_straight
    intercept = Vector(ix, iy, 0, 0)

    obstacle_from_line = dist(intercept, obstacle) + 1
    delta_length = AVOID_DISTANCE / 2
    dx = (obstacle.x - ix) / obstacle_from_line * delta_length
    dy = (obstacle.y - iy) / obstacle_from_line * delta_length

    closest = None
    for j in range(-10, 10):
        v = Vector(ix + dx * j, iy + dy * j, 0, 0)
        if not find_obstacle(world, vec1, v) and world.is_possible_position(world.our_attacker, v.x, v.y):
            angle = get_rotation_to_point(vec1, v)
            if not closest or abs(angle - straight_angle) < abs(closest - straight_angle):
                closest = angle
    if not closest:
        logging.info("Didn't find any suitable angle!!!")
    else:
        logging.info("Found suitable angle {0}".format(closest))
    return closest
Exemple #23
0
def get_movement_direction_from_vector(robot_vec, point_vec):
    '''
    Returns either
        1 - move right; or
        -1 - move left
    '''
    robot_vec_left = Vector(robot_vec.x, robot_vec.y, robot_vec.angle - math.pi / 2, 0)
    # point_vec = Vector(point[0], point[1], 0, 0)

    rotation_for_left = get_rotation_to_point(robot_vec_left, point_vec)
    # rotation_for_right = get_rotation_to_point(robot_vec_right, direction_vec)

    if abs(math.degrees(rotation_for_left)) < 90:
        return -1
    else:
        return 1
Exemple #24
0
 def __init__(self,
              x,
              y,
              angle,
              velocity,
              width,
              length,
              height,
              angle_offset=0):
     if width < 0 or length < 0:
         raise ValueError('Object dimensions must be positive')
     else:
         self._width = width
         self._length = length
         self._height = height
         self._angle_offset = angle_offset
         self._vector = Vector(x, y, angle, velocity)
         self._is_missing = True
Exemple #25
0
 def get_new_score_zone(self):
     halfway = self.pitch.centre_line_x
     x = halfway + (self.pitch.goal_box_x['right'] - halfway) / 2 if self._our_side == 'left'\
         else halfway - (halfway - self.pitch.goal_box_x['left']) / 2
     y_step = (self.pitch.top - self.pitch.bottom) / 5
     centroids = [Vector(x, y_step * i, 0, 0) for i in range(1, 5)]
     filtered_centroids = filter(
         lambda v: utils.defender_can_pass_to_position(self, v) and utils.
         attacker_can_score_from_position(self, v) and self.
         is_possible_position(self.our_attacker, v.x, v.y), centroids)
     sorted_centroids = sorted(filtered_centroids,
                               key=lambda v: (v.x)**2 + (v.y)**2,
                               reverse=True)
     if not sorted_centroids:
         self._score_zone = None
     else:
         self._score_zone = sorted_centroids[0]
     info("Found score zone at {0}".format(self.score_zone))
     return self.score_zone
Exemple #26
0
def defender_scan_angle_to_pass_absolute(world, defender_vec, enemy_zone_radius=40):
    '''
    Calculates the angle for defender to rotate by to pass to attacker or, if not possible,
    angle to kick upfield which is not contested by enemy robots.
    '''

    target_vec = world.our_attacker.vector
    if world.our_attacker.is_missing():
        target_vec = world.their_goal.vector

    possible_angles = defender_scan_area_to_pass(world, defender_vec, enemy_zone_radius)

    # offset
    offset = 0
    if world.our_side == 'right':
        offset = 180

    # find degree of our attacker
    zero_vec = Vector(defender_vec.x, defender_vec.y, 0 + offset, 0)
    friend_degree = int(math.degrees(get_rotation_to_point(zero_vec, target_vec)))

    # find the closest degree possible
    low = 0
    for n in xrange(friend_degree, -1, -1):
        if possible_angles[n]:
            low = n
            break

    hi = 180
    for n in xrange(friend_degree, 180):
        if possible_angles[n]:
            hi = n
            break

    print("low: " + str(low))
    print("hi: " + str(hi))
    if abs(friend_degree - low) < abs(friend_degree - hi):
        print("Return by: " + str(math.radians(low + offset - math.degrees(defender_vec.angle))))
        return math.radians(low + offset - math.degrees(defender_vec.angle))
    else:
        print("Return by: " + str(math.radians(low + offset - math.degrees(defender_vec.angle))))
        return math.radians(hi + offset - math.degrees(defender_vec.angle))
Exemple #27
0
    def defender_get_defend_point(robot_vec, ball_vec, center, center_radius, side):
        dx = ball_vec.x - center.x
        dy = ball_vec.y - center.y
        alpha = math.atan2(dx, dy) % (math.pi * 2)

        # lovely for ifs to make your life easier reader
        offset = math.radians(20)
        if side == "left":
            if alpha < offset:
                alpha = offset
            elif alpha > math.radians(180) - offset:
                alpha = math.radians(180) - offset
        else:
            if alpha < math.radians(180) + offset:
                alpha = math.radians(180) + offset
            elif alpha > math.radians(360) - offset:
                alpha = math.radians(360) - offset

        x = center.x + center_radius * math.sin(alpha)
        y = center.y + center_radius * math.cos(alpha)

        return Vector(x, y, 0, 0)
Exemple #28
0
 def rotation_precondition(self, w, r):
     possessing = w.robot_in_posession
     rotation = utils.defender_get_rotation_to_catch_point(Vector(r.x, r.y, r.angle, 0), Vector(possessing.x, possessing.y, 0, 0), r.catch_distance)[0]
     return abs(rotation) < FACING_ROTATION_THRESHOLD
Exemple #29
0
def defender_move_vec(vec):
    return Vector(vec.x, vec.y, vec.angle + pi / 2, vec.velocity)
Exemple #30
0
 def __init__(self, x, y, angle=0):
     self.vector = Vector(x, y, angle, 0)