示例#1
0
def _bounce_one(a1, a2):
    # Bounces a1
    dir_angle = vectors.angle(a2.pos, a1.pos)

    vel_angle = vectors.angle(a1.velocity)

    # If they are head on then we want to swivel them a little
    if vectors.bound_angle(dir_angle[0] + 180) == vel_angle[0]:
        dir_angle[0] = vectors.bound_angle(dir_angle[0] + 40)

    # Keep trying distances further and further apart until they're
    # not going to be overlapping any more
    overlapping = True
    dist = vectors.total_velocity(a1.velocity)

    a2_rect = (a2.pos[0], a2.pos[1], a2.size[0], a2.size[1])

    while overlapping:
        new_pos = vectors.add_vectors(a1.pos,
                                      vectors.move_to_vector(dir_angle, dist))

        new_rect = (new_pos[0], new_pos[1], a1.size[0], a1.size[1])

        if not geometry.rect_collision(new_rect, a2_rect, True):
            overlapping = False

        dist += 1

    # Add a bit to be safe
    new_pos = vectors.add_vectors(
        a1.pos,
        vectors.move_to_vector(dir_angle,
                               dist + vectors.total_velocity(a1.velocity)))

    a1.pos = new_pos
示例#2
0
def _bounce_one(a1, a2):
    # Bounces a1
    dir_angle = vectors.angle(a2.pos, a1.pos)
    
    vel_angle = vectors.angle(a1.velocity)
    
    # If they are head on then we want to swivel them a little
    if vectors.bound_angle(dir_angle[0]+180) == vel_angle[0]:
        dir_angle[0] = vectors.bound_angle(dir_angle[0] + 40)
    
    # Keep trying distances further and further apart until they're
    # not going to be overlapping any more
    overlapping = True
    dist = vectors.total_velocity(a1.velocity)
    
    a2_rect = (a2.pos[0], a2.pos[1], a2.size[0], a2.size[1])
    
    while overlapping:
        new_pos = vectors.add_vectors(a1.pos, vectors.move_to_vector(
            dir_angle, dist
        ))
        
        new_rect = (new_pos[0], new_pos[1], a1.size[0], a1.size[1])
        
        if not geometry.rect_collision(new_rect, a2_rect, True):
            overlapping = False
        
        dist += 1
    
    # Add a bit to be safe
    new_pos = vectors.add_vectors(a1.pos, vectors.move_to_vector(
        dir_angle, dist + vectors.total_velocity(a1.velocity)
    ))
    
    a1.pos = new_pos
示例#3
0
def test_possible_collision(actors, new_rect, convert=True):
    """
    Used to test if a potential actor will collide with anything else
    returns True if there will be a collision
    """
    
    for a in actors:
        if geometry.rect_collision(a.rect, new_rect, convert):
            return True
    
    return False
示例#4
0
def _will_collide(a1, a2, target=None):
    """Answers if a2 will collide with a1's movement target"""
    if not target:
        target = a1.current_action()[1]

    target_rect = pygame.Rect((0, 0, a1.rect.width, a1.rect.height))

    target_rect.left = target[0] - a1.rect.width / 2
    target_rect.top = target[1] - a1.rect.height / 2

    return geometry.rect_collision(target_rect, a2.rect, convert=True)
示例#5
0
def _will_collide(a1, a2, target=None):
    """Answers if a2 will collide with a1's movement target"""
    if not target:
        target = a1.current_action()[1]
    
    target_rect = pygame.Rect((0, 0, a1.rect.width, a1.rect.height))
    
    target_rect.left = target[0] - a1.rect.width/2
    target_rect.top = target[1] - a1.rect.height/2
    
    return geometry.rect_collision(target_rect, a2.rect, convert=True)
示例#6
0
def get_collisions(actors):
    collisions = []
    collided = set()
    for i, a in enumerate(actors):
        for j, b in enumerate(actors):
            if j in collided: continue
            if i == j: continue
            if geometry.rect_collision(a.rect, b.rect, True):
                collisions.append((a,b))
        
        collided.add(i)
    
    return collisions
示例#7
0
def _bounce_both(a1, a2):
    # These are the angles directly away from each other
    angle1 = vectors.angle(a2.pos, a1.pos)
    angle2 = vectors.angle(a1.pos, a2.pos)

    vel_angle1 = vectors.angle(a1.velocity)
    vel_angle2 = vectors.angle(a2.velocity)

    # If they are head on then we want to swivel them a little
    if vel_angle1[0] == angle2[0] and vel_angle2[0] == angle1[0]:
        angle1[0] = vectors.bound_angle(angle1[0] + 20)
        angle2[0] = vectors.bound_angle(angle2[0] + 20)

    # Keep trying distances further and further apart until they're
    # not going to be overlapping any more
    overlapping = True
    dist_multiplier = 0.1

    while overlapping:
        dist_multiplier += 0.1

        new_pos1 = vectors.add_vectors(
            a1.pos,
            vectors.move_to_vector(angle1,
                                   max(a1.size) * dist_multiplier))

        new_pos2 = vectors.add_vectors(
            a2.pos,
            vectors.move_to_vector(angle2,
                                   max(a2.size) * dist_multiplier))

        new_rect1 = (new_pos1[0], new_pos1[1], a1.size[0], a1.size[1])
        new_rect2 = (new_pos2[0], new_pos2[1], a2.size[0], a2.size[1])

        if not geometry.rect_collision(new_rect1, new_rect2):
            overlapping = False

    a1.pos = new_pos1
    a2.pos = new_pos2
示例#8
0
def _bounce_both(a1, a2):
    # These are the angles directly away from each other
    angle1 = vectors.angle(a2.pos, a1.pos)
    angle2 = vectors.angle(a1.pos, a2.pos)
    
    vel_angle1 = vectors.angle(a1.velocity)
    vel_angle2 = vectors.angle(a2.velocity)
    
    # If they are head on then we want to swivel them a little
    if vel_angle1[0] == angle2[0] and vel_angle2[0] == angle1[0]:
        angle1[0] = vectors.bound_angle(angle1[0] + 20)
        angle2[0] = vectors.bound_angle(angle2[0] + 20)
    
    # Keep trying distances further and further apart until they're
    # not going to be overlapping any more
    overlapping = True
    dist_multiplier = 0.1
    
    while overlapping:
        dist_multiplier += 0.1
        
        new_pos1 = vectors.add_vectors(a1.pos, vectors.move_to_vector(
            angle1, max(a1.size) * dist_multiplier
        ))
        
        new_pos2 = vectors.add_vectors(a2.pos, vectors.move_to_vector(
            angle2, max(a2.size) * dist_multiplier
        ))
        
        new_rect1 = (new_pos1[0], new_pos1[1], a1.size[0], a1.size[1])
        new_rect2 = (new_pos2[0], new_pos2[1], a2.size[0], a2.size[1])
        
        if not geometry.rect_collision(new_rect1, new_rect2):
            overlapping = False
    
    a1.pos = new_pos1
    a2.pos = new_pos2
示例#9
0
 def test_rectangle_collision(self):
     vals = (
         # R1 is up and to the left of R2
         ((5, 5, 15, 15), (10, 10, 20, 20), True),
         ((2, 2, 8, 8), (10, 10, 20, 20), False),
         
         # R1 is up of R2
         ((10, 5, 20, 15), (10, 10, 20, 20), True),
         ((10, 2, 20, 8), (10, 10, 20, 20), False),
         
         # R1 is up and to the right of R2
         ((15, 5, 25, 15), (10, 10, 20, 20), True),
         ((15, 2, 25, 8), (10, 10, 20, 20), False),
         
         # R1 is left of R2
         ((5, 10, 15, 20), (10, 10, 20, 20), True),
         ((2, 10, 8, 20), (10, 10, 20, 20), False),
         
         # R1 is right of R2
         ((15, 10, 25, 20), (10, 10, 20, 20), True),
         ((25, 10, 30, 20), (10, 10, 20, 20), False),
         
         # R1 is down and to the left of R2
         ((5, 15, 15, 25), (10, 10, 20, 20), True),
         ((2, 15, 8, 25), (10, 10, 20, 20), False),
         
         # R1 is down of R2
         ((10, 15, 20, 25), (10, 10, 20, 20), True),
         ((10, 22, 20, 28), (10, 10, 20, 20), False),
         
         # R1 is down and to the right of R2
         ((15, 15, 25, 25), (10, 10, 20, 20), True),
         ((22, 15, 28, 25), (10, 10, 20, 20), False),
         
         # Overlapping
         ((15, 15, 25, 25), (15, 15, 25, 25), True),# Exact same size
         ((279, 779, 279+41, 779+41), (279, 779, 279+41, 779+41), True),# Exact same size
         
         ((394, 79, 435, 435), (317, 79, 358, 120), False),
         
         ((10, 10, 30, 30), (15, 15, 25, 25), True),# R1 is bigger
         ((15, 15, 25, 25), (10, 10, 30, 30), True),# R2 is bigger
         
         # Different types
         ((5, 15, 15, 25), pygame.Rect(10, 10, 20, 20), True),
         ((2, 15, 8, 25), pygame.Rect(10, 10, 20, 20), False),
     )
     
     for r1, r2, expected in vals:
         # We want to make sure that it'll work for inputs regardless of order
         try:
             self.assertEqual(expected, geometry.rect_collision(r1, r2))
         except Exception as e:
             print("Failed on first pass of %s, %s" % (str(r1), str(r2)))
             raise
         
         try:
             self.assertEqual(expected, geometry.rect_collision(r2, r1))
         except Exception as e:
             print("Failed on second pass of %s, %s" % (str(r1), str(r2)))
             raise