import pygame import math import os from pygame.locals import * from OpenGL.GL import * from OpenGL.GLU import * # 初始化 Pygame pygame.init() # 设置窗口大小 width, height = 800, 600 display = pygame.display.set_mode((width, height), DOUBLEBUF | OPENGL) pygame.display.set_caption('3D Sphere') # 初始化剪贴板系统 pygame.scrap.init() # 启用深度测试 glEnable(GL_DEPTH_TEST) # 设置光照 glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) # 设置光源位置 light_position = [1.0, 1.0, 1.0, 0.0] # directional light glLightfv(GL_LIGHT0, GL_POSITION, light_position) # 设置材质属性 material_ambient = [0.3, 0.7, 0.3, 1.0] material_diffuse = [0.0, 1.0, 0.0, 1.0] material_specular = [0.3, 0.7, 0.3, 1.0] material_shininess = [50.0] glMaterialfv(GL_FRONT, GL_AMBIENT, material_ambient) glMaterialfv(GL_FRONT, GL_DIFFUSE, material_diffuse) glMaterialfv(GL_FRONT, GL_SPECULAR, material_specular) glMaterialfv(GL_FRONT, GL_SHININESS, material_shininess) # 设置视角 gluPerspective(45, (width/height), 0.1, 50.0) # 移动相机 glTranslatef(0.0, 0.0, -5) # 文件夹结构 folder_structure = [] show_structure = False # 检查剪贴板内容 def check_clipboard(): clipboard = pygame.scrap.get('text/plain') if clipboard: path = clipboard.decode('utf-8').strip() if os.path.exists(path) and os.path.isdir(path): return path return None # 扫描文件夹函数(递归) def scan_folder(path, parent_distance=2, parent_angle=0, depth=0, max_depth=3): structure = [] if depth >= max_depth: return structure if os.path.exists(path) and os.path.isdir(path): items = os.listdir(path) for i, item in enumerate(items): item_path = os.path.join(path, item) is_dir = os.path.isdir(item_path) # 计算位置 angle = parent_angle + (i / len(items)) * 360 distance = parent_distance + 1 radius = 0.2 if is_dir else 0.1 # 添加当前项目 structure.append({ 'name': item, 'path': item_path, 'is_dir': is_dir, 'angle': angle, 'distance': distance, 'radius': radius, 'parent_distance': parent_distance, 'parent_angle': parent_angle }) # 递归扫描子文件夹 if is_dir: structure.extend(scan_folder(item_path, distance, angle, depth + 1, max_depth)) return structure # 使用默认路径 E:\myaliyun\IamHere default_path = "E:\\myaliyun\\IamHere" if os.path.exists(default_path) and os.path.isdir(default_path): folder_structure = scan_folder(default_path) show_structure = True else: # 启动时检查剪贴板 clipboard_path = check_clipboard() if clipboard_path: folder_structure = scan_folder(clipboard_path) show_structure = True # 主循环 running = True while running: # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 清除屏幕 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # 旋转大球 glRotatef(1, 3, 1, 1) # 绘制大球 quad = gluNewQuadric() gluQuadricNormals(quad, GLU_SMOOTH) gluSphere(quad, 1, 32, 32) gluDeleteQuadric(quad) print(folder_structure) # 绘制文件夹结构 if show_structure: for item in folder_structure: # 计算当前项目位置 angle_rad = math.radians(item['angle']) x = item['distance'] * math.cos(angle_rad) y = item['distance'] * math.sin(angle_rad) z = 0 # 计算父项目位置 parent_angle_rad = math.radians(item['parent_angle']) parent_x = item['parent_distance'] * math.cos(parent_angle_rad) parent_y = item['parent_distance'] * math.sin(parent_angle_rad) parent_z = 0 # 绘制连线(连接到父项目) glBegin(GL_LINES) glVertex3f(parent_x, parent_y, parent_z) # 父项目位置 glVertex3f(x, y, z) # 当前项目位置 glEnd() # 保存当前矩阵 glPushMatrix() # 移动到当前项目位置 glTranslatef(x, y, z) # 设置材质颜色(文件夹为绿色,文件为蓝色) if item['is_dir']: glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.0, 1.0, 0.0, 1.0]) else: glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.0, 0.0, 1.0, 1.0]) # 绘制小球 quad = gluNewQuadric() gluQuadricNormals(quad, GLU_SMOOTH) gluSphere(quad, item['radius'], 16, 16) gluDeleteQuadric(quad) # 恢复材质颜色 glMaterialfv(GL_FRONT, GL_DIFFUSE, material_diffuse) # 恢复矩阵 glPopMatrix() # 更新角度 item['angle'] = (item['angle'] + 1) % 360 # 交换缓冲区 pygame.display.flip() # 控制帧率 pygame.time.wait(10) # 退出 Pygame pygame.quit()