You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PyGame中创建可扩展的条形Sprite?

用PyGame实现UI元素的九宫格缩放(边框不变,中间拉伸)

可以的,PyGame完全能实现这种UI适配效果,核心是用九宫格切片绘制法——这是行业内保留边框样式、适配任意尺寸的标准方案,能精准保留你素材的像素化边框和角落。

核心逻辑

把原始素材切割成9个区域:4个固定尺寸的角落、4条可拉伸的边、1个可自由缩放的中间区域。绘制时,角落和边保持原始像素大小,仅拉伸中间区域填充空白,以此适配目标尺寸。

具体实现代码

假设你的原始素材名为bar_asset.png,先根据素材实际像素确定边框宽度(示例中设为4像素,你可自行调整):

1. 加载素材并切割区域

import pygame

pygame.init()

# 加载带透明通道的原始素材
original_bar = pygame.image.load("bar_asset.png").convert_alpha()
orig_width, orig_height = original_bar.get_size()

# 定义边框宽度(根据你的素材实际值修改)
border_size = 4

# 切割9个区域
# 四个角落(固定尺寸)
top_left = original_bar.subsurface((0, 0), (border_size, border_size))
top_right = original_bar.subsurface((orig_width - border_size, 0), (border_size, border_size))
bottom_left = original_bar.subsurface((0, orig_height - border_size), (border_size, border_size))
bottom_right = original_bar.subsurface((orig_width - border_size, orig_height - border_size), (border_size, border_size))

# 四条边(仅单一维度拉伸)
top_edge = original_bar.subsurface((border_size, 0), (orig_width - 2*border_size, border_size))
bottom_edge = original_bar.subsurface((border_size, orig_height - border_size), (orig_width - 2*border_size, border_size))
left_edge = original_bar.subsurface((0, border_size), (border_size, orig_height - 2*border_size))
right_edge = original_bar.subsurface((orig_width - border_size, border_size), (border_size, orig_height - 2*border_size))

# 中间区域(可双向拉伸)
middle_area = original_bar.subsurface((border_size, border_size), (orig_width - 2*border_size, orig_height - 2*border_size))

2. 封装绘制函数

def draw_scaled_bar(target_surface, pos_x, pos_y, target_width, target_height):
    # 创建适配目标尺寸的透明表面
    scaled_bar = pygame.Surface((target_width, target_height), pygame.SRCALPHA)
    
    # 绘制固定角落
    scaled_bar.blit(top_left, (0, 0))
    scaled_bar.blit(top_right, (target_width - border_size, 0))
    scaled_bar.blit(bottom_left, (0, target_height - border_size))
    scaled_bar.blit(bottom_right, (target_width - border_size, target_height - border_size))
    
    # 拉伸并绘制上下边
    scaled_top = pygame.transform.scale(top_edge, (target_width - 2*border_size, border_size))
    scaled_bottom = pygame.transform.scale(bottom_edge, (target_width - 2*border_size, border_size))
    scaled_bar.blit(scaled_top, (border_size, 0))
    scaled_bar.blit(scaled_bottom, (border_size, target_height - border_size))
    
    # 拉伸并绘制左右边
    scaled_left = pygame.transform.scale(left_edge, (border_size, target_height - 2*border_size))
    scaled_right = pygame.transform.scale(right_edge, (border_size, target_height - 2*border_size))
    scaled_bar.blit(scaled_left, (0, border_size))
    scaled_bar.blit(scaled_right, (target_width - border_size, border_size))
    
    # 拉伸并绘制中间填充区域
    scaled_middle = pygame.transform.scale(middle_area, (target_width - 2*border_size, target_height - 2*border_size))
    scaled_bar.blit(scaled_middle, (border_size, border_size))
    
    # 将最终绘制好的bar放到目标表面上
    target_surface.blit(scaled_bar, (pos_x, pos_y))

3. 主循环调用示例

screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()

running = True
while running:
    screen.fill((30, 30, 30))
    
    # 绘制一个宽300、高50的适配bar
    draw_scaled_bar(screen, 250, 275, 300, 50)
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

关键提示

  • 如果你要保留像素风格,务必用pygame.transform.scale(最近邻插值),别用smoothscale,避免边框模糊。
  • 边框尺寸一定要精确对应素材的实际像素,否则切割区域会错位。

内容的提问来源于stack exchange,提问作者kokoko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:05:12