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

如何在Pygame中生成八边形-六边形-正方形-梯形网格?

用Pygame生成八边形-六边形-正方形-梯形混合网格

核心逻辑

这类混合网格的关键是统一基础尺寸,按行列规律计算每个多边形的顶点坐标,先确定一个基础边长,再推导每种多边形的顶点位置,最后循环绘制整个网格。

步骤1:初始化Pygame基础环境

先搞定Pygame的基本设置,创建窗口、定义颜色、设置基础参数:

import pygame
import math

# 初始化Pygame
pygame.init()

# 窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("混合多边形网格")

# 颜色定义(可自行调整)
COLOR_OCTAGON = (100, 180, 220)
COLOR_HEXAGON = (220, 100, 180)
COLOR_SQUARE = (180, 220, 100)
COLOR_TRAPEZOID = (220, 180, 100)
OUTLINE_COLOR = (0, 0, 0)

# 基础参数:统一的多边形边长
BASE_SIDE = 30
# 计算八边形的水平宽度(矩形切角得到,确保边长为BASE_SIDE)
oct_width = BASE_SIDE * (1 + math.sqrt(2))
# 六边形的垂直高度
hex_height = BASE_SIDE * math.sqrt(3)

步骤2:定义各多边形的顶点生成函数

给每种多边形写一个函数,传入中心坐标,返回顶点列表:

def get_octagon_vertices(x, y):
    """生成中心在(x,y)的正八边形顶点"""
    half_side = BASE_SIDE / math.sqrt(2)
    # 按顺时针顺序定义顶点
    return [
        (x - oct_width/2, y - half_side),
        (x - half_side, y - oct_width/2),
        (x + half_side, y - oct_width/2),
        (x + oct_width/2, y - half_side),
        (x + oct_width/2, y + half_side),
        (x + half_side, y + oct_width/2),
        (x - half_side, y + oct_width/2),
        (x - oct_width/2, y + half_side)
    ]

def get_hexagon_vertices(x, y):
    """生成中心在(x,y)的正六边形顶点(水平方向为宽)"""
    half_side = BASE_SIDE / 2
    return [
        (x - BASE_SIDE, y),
        (x - half_side, y - hex_height/2),
        (x + half_side, y - hex_height/2),
        (x + BASE_SIDE, y),
        (x + half_side, y + hex_height/2),
        (x - half_side, y + hex_height/2)
    ]

def get_square_vertices(x, y):
    """生成中心在(x,y)的正方形顶点(边长匹配八边形的垂直段)"""
    half_size = oct_width/2 - BASE_SIDE/math.sqrt(2)
    return [
        (x - half_size, y - half_size),
        (x + half_size, y - half_size),
        (x + half_size, y + half_size),
        (x - half_size, y + half_size)
    ]

def get_trapezoid_vertices(x, y):
    """生成中心在(x,y)的直角梯形顶点(适配六边形和相邻多边形)"""
    top_width = BASE_SIDE
    bottom_width = oct_width - BASE_SIDE
    half_height = hex_height/2
    return [
        (x - bottom_width/2, y + half_height),
        (x + bottom_width/2, y + half_height),
        (x + top_width/2, y - half_height),
        (x - top_width/2, y - half_height)
    ]

函数说明

  • 八边形:用矩形切去四个等腰直角三角形,确保边长为BASE_SIDE,顶点按顺时针排列方便Pygame绘制
  • 六边形:正六边形的顶点坐标通过三角函数推导,保证水平方向对齐
  • 正方形:尺寸匹配八边形的垂直直边,确保和八边形无缝拼接
  • 梯形:调整上下底长度,让它能和六边形、正方形/八边形对齐

步骤3:按行列规律绘制网格

混合网格一般是周期性重复单元,比如奇数行绘制八边形+正方形,偶数行绘制六边形+梯形,同时处理行偏移:

# 主循环
running = True
while running:
    screen.fill((255, 255, 255))  # 白色背景
    
    # 遍历行
    for row in range(-1, int(HEIGHT / max(oct_width, hex_height)) + 1):
        # 计算当前行的Y坐标
        if row % 2 == 0:
            # 偶数行:八边形+正方形,Y坐标基于八边形高度
            y = row * oct_width + oct_width/2
        else:
            # 奇数行:六边形+梯形,Y坐标偏移,和上一行对齐
            y = row * hex_height + hex_height/2 + (oct_width - hex_height)/2
        
        # 遍历列
        for col in range(-1, int(WIDTH / (oct_width + BASE_SIDE)) + 1):
            # 计算当前列的X坐标
            if row % 2 == 0:
                # 偶数行:八边形和正方形交替
                if col % 2 == 0:
                    x = col * (oct_width + BASE_SIDE) + oct_width/2
                    vertices = get_octagon_vertices(x, y)
                    pygame.draw.polygon(screen, COLOR_OCTAGON, vertices)
                    pygame.draw.polygon(screen, OUTLINE_COLOR, vertices, 1)  # 绘制轮廓
                else:
                    x = col * (oct_width + BASE_SIDE) - BASE_SIDE/2 + oct_width
                    vertices = get_square_vertices(x, y)
                    pygame.draw.polygon(screen, COLOR_SQUARE, vertices)
                    pygame.draw.polygon(screen, OUTLINE_COLOR, vertices, 1)
            else:
                # 奇数行:六边形和梯形交替
                if col % 2 == 0:
                    x = col * (oct_width + BASE_SIDE) + oct_width/2
                    vertices = get_hexagon_vertices(x, y)
                    pygame.draw.polygon(screen, COLOR_HEXAGON, vertices)
                    pygame.draw.polygon(screen, OUTLINE_COLOR, vertices, 1)
                else:
                    x = col * (oct_width + BASE_SIDE) - BASE_SIDE/2 + oct_width
                    vertices = get_trapezoid_vertices(x, y)
                    pygame.draw.polygon(screen, COLOR_TRAPEZOID, vertices)
                    pygame.draw.polygon(screen, OUTLINE_COLOR, vertices, 1)
    
    # 处理事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    
    pygame.display.flip()  # 更新屏幕

pygame.quit()

新手注意事项

  • 调整BASE_SIDE可以放大/缩小整个网格,数值越大,多边形越大
  • 如果网格排列不对,检查行列的X/Y偏移计算,核心是让相邻多边形的边完全重合
  • Pygame的draw.polygon()函数要求顶点按顺时针或逆时针顺序排列,否则可能绘制出错
  • 可以修改颜色定义,让每种多边形更易区分

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:00:59