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 scroll_left_rect(self): d = self.scroll_button_size r = Rect(0, 0, d, d) m = self.margin r.bottom = self.height - m r.left = m r.inflate_ip(-4, -4) return r
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 test_bottom( self ): """Changing the bottom attribute moves the rect and does not change the rect's height """ r = Rect( 1, 2, 3, 4 ) new_bottom = r.bottom + 20 expected_top = r.top + 20 old_height = r.height r.bottom = new_bottom self.assertEqual( new_bottom, r.bottom ) self.assertEqual( expected_top, r.top ) self.assertEqual( old_height, r.height )
def test_bottom(self): """Changing the bottom attribute moves the rect and does not change the rect's height """ r = Rect(1, 2, 3, 4) new_bottom = r.bottom + 20 expected_top = r.top + 20 old_height = r.height r.bottom = new_bottom self.assertEqual(new_bottom, r.bottom) self.assertEqual(expected_top, r.top) self.assertEqual(old_height, r.height)
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 draw_icon(self, map_element, x, y): px, py = self.trans_locate(0, 0) rect = Rect(px, py, self.block_size, self.block_size) # sprite的显示需要接通group name = str(map_element) ret = get_resource(name) px, py = self.trans_locate(x, y, "down") rect.centerx = px rect.bottom = py if type(ret) is tuple: # 属于精灵 (注意:此时不能直接导入精灵,因为先有map后有精灵) img = ret[0] img_rect = ret[1] # 以资源本体大小显示 用以支持超过32*32的图像 img_rect.topleft = rect.topleft sp = list(ret[2]) self.add_sprite(EventSprite(name, img, sp), fill_rect=img_rect) elif ret is not None: self.fill_surface(ret, fill_rect=rect)
def render_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) * 3 if seat == 0: rect.bottom = side_calculation + TILE_SIZE[1] + 20 if seat == 2: rect.top = -side_calculation tile_offset = 10 tiles_per_row = 12 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.width - full_width) / 2 beginning_of_across_line += full_width if seat == 2 else 0 across = beginning_of_across_line for tile in player.discard_pile: tile_pos = (across, -rect.y + (row * row_offset)) 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 == 0 else -(SMALL_TILE_SIZE[0] + tile_offset)) i += 1 if i >= tiles_per_row: i = 0 row += 1 if seat == 0 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 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 limit_paddles(self, paddle: pygame.Rect): if paddle.top < 0: paddle.top = 0 elif paddle.bottom > GAME_HEIGHT: paddle.bottom = GAME_HEIGHT return paddle
ai_speed -= player_a elif ai_speed < 0: ai_speed += player_a # update playerPaddle.move_ip(0, player_speed) aiPaddle.move_ip(0, ai_speed) ball.move_ip(ball_speed_x, ball_speed_y) # collisions if playerPaddle.y < 0: playerPaddle.y = 0 player_speed = 0 elif playerPaddle.bottom > height: playerPaddle.bottom = height player_speed = 0 if aiPaddle.y < 0: aiPaddle.y = 0 ai_speed = 0 elif aiPaddle.bottom > height: aiPaddle.bottom = height ai_speed = 0 if playerPaddle.colliderect(ball): playerSound.play() ball_speed_x = -ball_speed_x if player_speed == 0: ball_speed_y = ball_speed_y/abs(ball_speed_y)
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)
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: rect.bottom = field.h self.angle = angle self.center = rect.center def update_total_elapsed(self): current_ticks = time.get_ticks() self.total_elapsed += current_ticks - self.last_ticks self.last_ticks = current_ticks def draw_circle(self): center = tuple(map(int, self.center)) color = self.opaque_color draw.circle(self, color, center, self.get_radius(), self.thickness) def get_radius(self): radius_r = self.radius_range