def test_calculate_tile_coverage(self): v = Rect(0,0,11,11) m = map.MapBase(50,50) e = map.MapEntity(1) m.place_character(e,(25,25)) c = m.map_tile_coverage #Normal centered e.move_to((25,25)) v.center = (25,25) m.calculate_tile_coverage(v) self.assertEqual(16,c.width) self.assertEqual(16,c.height) self.assertEqual((25,25),c.center) #Not enough map on up and left e.move_to((1,1)) v.center = (6,6) m.calculate_tile_coverage(v) self.assertEqual(0,c.left) self.assertEqual(0,c.top) #Not enough map on down and right e.move_to((48,48)) v.right = 50 v.bottom = 50 m.calculate_tile_coverage(v) self.assertEqual(50,c.right) self.assertEqual(50,c.bottom) #Refresh while walking north e.move_to((25,21)) v.center = (25,25) m.calculate_tile_coverage(v) self.assertEqual(v.bottom + 1,c.bottom) self.assertEqual(25,c.centerx) #Refresh while walking south e.move_to((25,29)) v.center = (25,25) m.calculate_tile_coverage(v) self.assertEqual(v.top - 1,c.top) self.assertEqual(25,c.centerx) #Refresh while walking east e.move_to((29,25)) v.center = (25,25) m.calculate_tile_coverage(v) self.assertEqual(v.left - 1,c.left) self.assertEqual(25,c.centery) #Refresh while walking west e.move_to((21,25)) v.center = (25,25) m.calculate_tile_coverage(v) self.assertEqual(v.right + 1,c.right) self.assertEqual(25,c.centery)
def scrollbar_rect(self): # Get the distance between the scroll buttons (d) sub = self.scroll_up_rect().bottom t = self.scroll_down_rect().top d = t - sub # Get the total row number (n). n = self.num_items() / getattr(getattr(self, 'parent', None), 'num_cols', lambda: 1)() # Get the displayed row number (v) v = self.num_rows() if n: s = float(d) / n else: s = 0 h = s * v if type(h) == float: if h - int(h) > 0: h += 1 top = max(sub, sub + (s * self.scroll) + self.scroll_rel) r = Rect(0, top, self.scroll_button_size, h) m = self.margin r.right = self.width - m r.bottom = min(r.bottom, t) r.inflate_ip(-4, -4) if r.h < 1: r.h = int(h) return r
def hscrollbar_rect(self): # Get the distance between the scroll buttons (d) slr, slt = self.scroll_left_rect().topright d = self.scroll_right_rect().left - slr # The predefined step value _s = self.cell_size[1] # Get the total step number n = float(self.virtual_width) / _s # Get the visible step number v = float(self.width) / _s s = float(d) / n w = s * v if isinstance(w, float): if w - int(w) > 0: w += 1 left = max( slr, slr + (d * (float(self.hscroll) / self.virtual_width)) + self.hscroll_rel) r = Rect(left, slt, w, self.scroll_button_size) r.right = min(r.right, d + slr) r.inflate_ip(-4, -4) if r.w < 1: r.w = int(w) return r
def bounce_in_box(bounce_obj_rect: Rect, bounce_object_speed, \ box_rect: Rect) -> bool: """ Bounce the object if it hits the border of the box. The speed and the position of the `bounce_obj` will be updated. @param bounce_obj_rect The Rect of the bouncing object @param bounce_obj_speed The 2D speed vector of the bouncing object. @return Whether the `bounce_obj` hits the box or not. """ hit = False if bounce_obj_rect.left <= box_rect.left: bounce_obj_rect.left = box_rect.left bounce_object_speed[0] *= -1 hit = True elif bounce_obj_rect.right >= box_rect.right: bounce_obj_rect.right = box_rect.right bounce_object_speed[0] *= -1 hit = True if bounce_obj_rect.top <= box_rect.top: bounce_obj_rect.top = box_rect.top bounce_object_speed[1] *= -1 hit = True elif bounce_obj_rect.bottom >= box_rect.bottom: bounce_obj_rect.bottom = box_rect.bottom bounce_object_speed[1] *= -1 hit = True return hit
def scroll_down_rect(self): d = self.scroll_button_size r = Rect(0, 0, d, d) m = self.margin r.bottom = self.height - m r.right = self.width - m r.inflate_ip(-4, -4) return r
def scroll_up_rect(self): d = self.scroll_button_size r = Rect(0, 0, d, d) m = self.margin r.top = m r.right = self.width - m r.inflate_ip(-4, -4) return r
def get_debug_zone(self, controller): w, h = self.size rect = Rect((0, PADDLE_MARGIN_Y), (PADDLE_MARGIN_X, h - 2 * PADDLE_MARGIN_Y)) if controller == self.cl: rect.right = PADDLE_MARGIN_X return rect else: rect.left = w - PADDLE_MARGIN_X return rect
def test_right(self): """Changing the right attribute moves the rect and does not change the rect's width """ r = Rect(1, 2, 3, 4) new_right = r.right + 20 expected_left = r.left + 20 old_width = r.width r.right = new_right self.assertEqual(new_right, r.right) self.assertEqual(expected_left, r.left) self.assertEqual(old_width, r.width)
def test_right( self ): """Changing the right attribute moves the rect and does not change the rect's width """ r = Rect( 1, 2, 3, 4 ) new_right = r.right + 20 expected_left = r.left + 20 old_width = r.width r.right = new_right self.assertEqual( new_right, r.right ) self.assertEqual( expected_left, r.left ) self.assertEqual( old_width, r.width )
def push_ip(larger_rect: Rect, smaller_rect: Rect): '''Larger rect pushes out smaller rect via the smallest possible vector.''' clip = larger_rect.clip(smaller_rect) if not clip: return if clip.height <= clip.width: if smaller_rect.centery <= clip.centery: smaller_rect.bottom = larger_rect.top else: smaller_rect.top = larger_rect.bottom else: if smaller_rect.centerx <= clip.centerx: smaller_rect.right = larger_rect.left else: smaller_rect.left = larger_rect.right
def render_vertical_discard_pile(board_render, player_id, seat): group = Group() match = board_render.match player = match.players[player_id] if player.discard_pile is None: return group rect = Rect(board_render.surface.get_rect()) rect.center = (0, 0) side_calculation = (SMALL_TILE_SIZE[1] + 10) * 4 if seat == 1: rect.right = side_calculation + 180 if seat == 3: rect.left = -side_calculation - 180 tile_offset = 10 tiles_per_row = 8 i = 0 row = 0 row_offset = SMALL_TILE_SIZE[1] + tile_offset full_width = tiles_per_row * (SMALL_TILE_SIZE[0] + tile_offset) - tile_offset beginning_of_across_line = rect.height - ((rect.height - full_width) / 2) beginning_of_across_line -= full_width if seat == 3 else 0 across = beginning_of_across_line for tile in player.discard_pile: tile_pos = (-rect.x + (row * row_offset), across) tile_sprite = TileRender( board_render.small_dictionary, tile, tile_pos, small_tile=True, rotation=seat, ) group.add(tile_sprite) across -= (SMALL_TILE_SIZE[0] + tile_offset if seat == 1 else -(SMALL_TILE_SIZE[0] + tile_offset)) i += 1 if i >= tiles_per_row: i = 0 row += 1 if seat == 1 else -1 across = beginning_of_across_line return group
def draw_text(text='sample text', color=(255, 255, 255), pos=(0, 0), surface=None, align_x='left', align_y='top'): if (surface == None): surface = api.screen text_rect = Rect(0, 0, *font.size(text)) if (align_x == 'left'): text_rect.left = pos[0] elif (align_x == 'center'): text_rect.centerx = pos[0] elif (align_x == 'right'): text_rect.right = pos[0] if (align_y == 'top'): text_rect.top = pos[1] elif (align_y == 'center'): text_rect.centery = pos[1] elif (align_y == 'bottom'): text_rect.bottom = pos[1] surface.blit(font.render(text, 1, color), text_rect)
def hscrollbar_rect(self): # Get the distance between the scroll buttons (d) slr, slt = self.scroll_left_rect().topright d = self.scroll_right_rect().left - slr # The predefined step value _s = self.cell_size[1] # Get the total step number n = float(self.virtual_width) / _s # Get the visible step number v = float(self.width) / _s s = float(d) / n w = s * v if type(w) == float: if w - int(w) > 0: w += 1 left = max(slr, slr + (d * (float(self.hscroll) / self.virtual_width)) + self.hscroll_rel) r = Rect(left, slt, w, self.scroll_button_size) r.right = min(r.right, d + slr) r.inflate_ip(-4, -4) return r
def bounce_in_box_ip(bounce_obj_rect: Rect, bounce_obj_speed, box_rect: Rect): """ Bounce the object if it hits the border of the box. The speed and the position of the `bounce_obj` will be updated. @param bounce_obj_rect The Rect of the bouncing object @param bounce_obj_speed The 2D speed vector of the bouncing object. """ if bounce_obj_rect.left <= box_rect.left: bounce_obj_rect.left = box_rect.left bounce_obj_speed[0] *= -1 elif bounce_obj_rect.right >= box_rect.right: bounce_obj_rect.right = box_rect.right bounce_obj_speed[0] *= -1 if bounce_obj_rect.top <= box_rect.top: bounce_obj_rect.top = box_rect.top bounce_obj_speed[1] *= -1 elif bounce_obj_rect.bottom >= box_rect.bottom: bounce_obj_rect.bottom = box_rect.bottom bounce_obj_speed[1] *= -1
def align_rect(outer: pygame.Rect, inner: pygame.Rect, coords, *, halign: Literal["left", "center", "right"] = "left", valign: Literal["top", "center", "bottom"] = "top", outer_halign: Literal["left", "center", "right"] = "left", outer_valign: Literal["top", "center", "bottom"] = "top"): """Calculate coordinates for an inner rectangle aligned to an outer rectangle""" x, y = coords if outer_halign == "left": pass elif outer_halign == "center": x = outer.centerx + x elif outer_halign == "right": x = outer.right + x if outer_valign == "top": pass elif outer_valign == "center": y = outer.centery + y elif outer_valign == "bottom": y = outer.bottom + y if halign == "left": inner.left = x elif halign == "center": inner.centerx = x elif halign == "right": inner.right = x if valign == "top": inner.top = y elif valign == "center": inner.centery = y elif valign == "bottom": inner.bottom = y return inner.topleft
def bounce_off_ip(bounce_obj_rect: Rect, bounce_obj_speed, \ hit_obj_rect: Rect, hit_obj_speed): """ Update the speed and position of the `bounce_obj` after it bounces off the `hit_obj`. This function is called only when two objects are colliding. @param bounce_obj_rect The Rect of the bouncing object @param bounce_obj_speed The 2D speed vector of the bouncing object. @param hit_obj_rect The Rect of the hit object @param hit_obj_speed The 2D speed vector of the hit object """ # Treat the hit object as an unmoveable object speed_diff_x = bounce_obj_speed[0] - hit_obj_speed[0] speed_diff_y = bounce_obj_speed[1] - hit_obj_speed[1] # The relative position between top and bottom, and left and right # of two objects at the last frame rect_diff_T_B = bounce_obj_rect.top - hit_obj_rect.bottom - speed_diff_y rect_diff_B_T = bounce_obj_rect.bottom - hit_obj_rect.top - speed_diff_y rect_diff_L_R = bounce_obj_rect.left - hit_obj_rect.right - speed_diff_x rect_diff_R_L = bounce_obj_rect.right - hit_obj_rect.left - speed_diff_x # Set the position and speed of the bouncing object # acccroding to the relative position of two objects if rect_diff_T_B > 0 and rect_diff_B_T > 0: bounce_obj_rect.top = hit_obj_rect.bottom bounce_obj_speed[1] *= -1 elif rect_diff_T_B < 0 and rect_diff_B_T < 0: bounce_obj_rect.bottom = hit_obj_rect.top bounce_obj_speed[1] *= -1 if rect_diff_L_R > 0 and rect_diff_R_L > 0: bounce_obj_rect.left = hit_obj_rect.right bounce_obj_speed[0] *= -1 elif rect_diff_L_R < 0 and rect_diff_R_L < 0: bounce_obj_rect.right = hit_obj_rect.left bounce_obj_speed[0] *= -1
def reverse_clamp_ip(larger_rect: Rect, smaller_rect: Rect): if not larger_rect.contains(smaller_rect): larger_rect.left = min(larger_rect.left, smaller_rect.left) larger_rect.right = max(larger_rect.right, smaller_rect.right) larger_rect.top = min(larger_rect.top, smaller_rect.top) larger_rect.bottom = max(larger_rect.bottom, smaller_rect.bottom)
return center def calculate_deltas(self): ang, distance = self.angle, self.speed return sin(ang) * distance, cos(ang) * distance def collide(self): angle = self.angle x, y = self.center radius = self.get_radius() rect = Rect(x - radius, y - radius, radius * 2, radius * 2) bandit = self.parent.bandit.rect if rect.colliderect(bandit): if bandit.left - rect.right > rect.top - bandit.bottom: angle = -angle rect.right = bandit.left else: angle = pi - angle rect.top = bandit.bottom field = self.parent.rect if rect.right > field.w or rect.left < 0: angle = -angle if rect.right > field.w: rect.right = field.w else: rect.left = 0 if rect.top < 0 or rect.bottom > field.h: angle = pi - angle if rect.top < 0: rect.top = 0 else:
else: ball_speed_y = player_speed ball.left = playerPaddle.right + 1 elif aiPaddle.colliderect(ball): playerSound.play() ball_speed_x = -ball_speed_x # prevent if ai_speed == 0: ball_speed_y = ball_speed_y/abs(ball_speed_y) else: ball_speed_y = ai_speed ball.right = aiPaddle.x - 1 if ball.y <= 0: sideSound.play() ball.y = 0 ball_speed_y = -ball_speed_y elif ball.y+10 >= height: sideSound.play() ball.y = height-10 ball_speed_y = -ball_speed_y if ball.x < 0 or ball.x > width: timePassed = 0.0 failSound.play() if ball.x < 0: