游戏开发尝试, Pygame 中做「全程代码生成+渲染」并保持高性能

2025-07-10 18:25:28 4点赞 3收藏 0评论

Pygame作为一个python的游戏开发库,本身性能在python环境下是不错的,但是纯CPU运算导致高负载下FPS非常低。

1.首先尝试在cpu端进行优化


  • pygame.draw.* / pygame.gfxdraw.* 本质上 在 CPU 端逐像素填充

  • 每一次绘制调用都会产生 Python→C→SDL 的跨语言开销。

  • 如果你每帧都重新生成同样的图形,相当于“在主线程白忙活”。

解决思路:能画一次的不画两次;能批量画的不拆开;能让 GPU 干的别让 CPU 干。


总体流程

启动 主循环 ├─生成 & 缓存形状 ─▶ 更新坐标/状态 │ └─生成噪声/地图 ─▶ 批量 blit │ └─ 脏区刷新 ▼

只在“启动阶段”用 draw 函数;主循环里尽量只做 blit+transform。

成千上万个实例共用同一张 Surface;显存只占一份。

LayeredDirty.draw() 会把需要刷新的 rect 汇总为一个列表 → pygame.display.update(dirty) 只更新小区域。

避免 per-pixel 特效,或用 NumPy 向量化

需要火焰、波纹、体积光等像素 shader,先计算到 numpy.ndarray,pygame.surfarray.make_surface(arr) 转 Surface(或 blit_array 覆盖到已有 Surface)。只在帧率允许的情况下每几帧更新一次,而不是每帧

结果仍不够快,尝试渲染10000个星星,只有1-2FPS。

游戏开发尝试, Pygame 中做「全程代码生成+渲染」并保持高性能

分析原因,首先是运算量太大,10 000 次 Python→C 调用 / 帧 即使每次 blit 只有几个 μs,也会把一帧拖到数百 ms。

其次默认的 Surface 属于“软件表面” 只有最后一次 flip/update 把像素整体上传 GPU;中间 10 000 次都在 CPU 端逐字节拷贝。

代码:

import pygame, random pygame.init() W, H = 1280, 720 screen = pygame.display.set_mode((W, H), pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.SCALED, vsync=1) clock = pygame.time.Clock() star_frames = [] for r in (1, 2, 3): s = pygame.Surface((r*2, r*2), pygame.SRCALPHA) pygame.draw.circle(s, (255,255,255), (r,r), r) star_frames.append(s.convert_alpha()) class Star(pygame.sprite.DirtySprite): def __init__(self): super().__init__() self.image = random.choice(star_frames) self.rect = self.image.get_rect( center=(random.randrange(W), random.randrange(H))) self.speed = random.uniform(20, 80) self.dirty = 1 def update(self, dt): self.rect.y += self.speed * dt if self.rect.top > H: self.rect.bottom = 0 self.dirty = 1 stars = pygame.sprite.LayeredDirty() stars._use_update = True for _ in range(10_000): # 一万颗 stars.add(Star()) running = True while running: dt = clock.tick(120)/1000 for e in pygame.event.get(): if e.type == pygame.QUIT: running = False stars.update(dt) screen.fill((5,10,20)) # 背景一次覆盖 dirty = stars.draw(screen) pygame.display.update(dirty + [(0,0,W,H)]) pygame.display.set_caption(f'FPS {clock.get_fps():.0f}') pygame.quit()

2.切到 SDL2-Renderer

Pygame 自带 pygame._sdl2.video,它直接暴露 SDL_Renderer。使用GPU 硬件加速渲染,相比传统的 CPU 渲染性能大幅提升。

基本思路是

  • 创建一个带透明度的 Surface

  • 绘制白色圆形作为星星

  • 转换为 GPU 纹理对象,这是性能优化的关键,纹理缓存在显存,不需要频繁 Surface 操作

游戏开发尝试, Pygame 中做「全程代码生成+渲染」并保持高性能

达到160FPS左右的帧率,效果比较好了。

代码:

import random, pygame from pygame._sdl2 import Window, Renderer, Texture pygame.init() W, H = 1280, 720 # ---------- 窗口 + GPU 渲染器 ---------- window = Window("GPU Starfield", (W, H)) renderer = Renderer(window, accelerated=True, vsync=False) # ---------- 生成星形 Surface 并转纹理 ---------- def make_star(radius=3, color=(255,255,255)): surf = pygame.Surface((radius*2, radius*2), pygame.SRCALPHA) pygame.draw.circle(surf, color, (radius, radius), radius) return surf star_surf = make_star(3) STAR_W, STAR_H = star_surf.get_size() star_tex = Texture.from_surface(renderer, star_surf) # ↑ star_tex 绑定到了上面的 renderer,所以 draw() 时会自动用它 # ---------- 随机星数据 ---------- N_STARS = 10_000 stars = [pygame.Vector2(random.randrange(W), random.randrange(H)) for _ in range(N_STARS)] speed = [random.uniform(20, 80) for _ in range(N_STARS)] clock = pygame.time.Clock() running = True while running: dt = clock.tick(360) / 1000 for e in pygame.event.get(): if e.type == pygame.QUIT: running = False # 逻辑更新 ------------------------------------------------- for i, p in enumerate(stars): p.y += speed[i] * dt if p.y >= H: p.y -= H # GPU 批量绘制 -------------------------------------------- renderer.draw_color = (5, 10, 20, 255) # 背景色 renderer.clear() for p in stars: # Texture.draw 支持多种调用形式;这里传 dstrect star_tex.draw(dstrect=(int(p.x), int(p.y), STAR_W, STAR_H)) renderer.present() window.title = f"FPS {clock.get_fps():.0f}" pygame.quit()


3. Taichi + GPU 方案

以上方案的问题是在游戏开发中还是会有大量的物理模拟,粒子系统使用了CPU。还是有可能导致性能瓶颈。因此可以引入Taichi来进行运算。

  • 高性能计算(粒子系统、物理模拟)

  • GPU渲染(大量对象的绘制)

  • 复杂的图形效果

  • 数值计算

游戏开发尝试, Pygame 中做「全程代码生成+渲染」并保持高性能

使用ai完成了程序,已经可以处理10万粒子数了,应该可以作为游戏引擎使用了。

代码:

""" Pygame + Taichi 混合引擎 (坐标系统修复版) 修复图像旋转90度的问题 """ import pygame import taichi as ti import numpy as np import time import math import os import sys # 初始化 pygame.init() ti.init(arch=ti.gpu) # Taichi使用GPU # ============ 字体管理 ============ def get_chinese_font(size): """获取支持中文的字体""" # Windows系统字体路径 font_paths = [ "C:/Windows/Fonts/msyh.ttc", # 微软雅黑 "C:/Windows/Fonts/simhei.ttf", # 黑体 "C:/Windows/Fonts/simsun.ttc", # 宋体 "C:/Windows/Fonts/simkai.ttf", # 楷体 ] # 尝试加载中文字体 for font_path in font_paths: if os.path.exists(font_path): try: return pygame.font.Font(font_path, size) except: continue # 如果没有找到字体文件,尝试系统字体 try: return pygame.font.SysFont("microsoftyahei,simhei,simsun", size) except: # 最后使用默认字体(不支持中文,但至少不会崩溃) print("⚠️ 警告: 无法加载中文字体,将使用英文显示") return pygame.font.Font(None, size) # ============ 混合引擎核心 ============ @ti.data_oriented class HybridEngine: def __init__(self, width=1280, height=720, title="Hybrid Engine"): self.width = width self.height = height # Pygame窗口和表面 self.screen = pygame.display.set_mode((width, height)) pygame.display.set_caption(title) self.clock = pygame.time.Clock() # 🔧 修复:正确的Taichi渲染缓冲区定义 # 注意:这里使用 (height, width) 来匹配pygame的坐标系统 self.pixels = ti.Vector.field(3, dtype=ti.f32, shape=(height, width)) # 性能监控 self.fps_counter = 0 self.fps_timer = 0 self.frame_times = [] def clear_taichi_buffer(self, color=(0.0, 0.0, 0.1)): """清空Taichi渲染缓冲区""" self._clear_kernel(color) @ti.kernel def _clear_kernel(self, color: ti.template()): for i, j in self.pixels: self.pixels[i, j] = color def taichi_to_pygame(self): """将Taichi渲染结果转换为Pygame Surface - 🔧 坐标修复版""" # 将Taichi field转为numpy数组 np_array = self.pixels.to_numpy() # 确保数值范围正确 np_array = np.clip(np_array, 0.0, 1.0) # 转换颜色范围 [0,1] -> [0,255] np_array = (np_array * 255).astype(np.uint8) # 🔧 修复:现在数组形状是 (height, width, 3) # pygame.surfarray.make_surface 期望 (width, height) 或 (width, height, 3) # 所以我们需要转置前两个维度 np_array = np.transpose(np_array, (1, 0, 2)) # (height, width, 3) -> (width, height, 3) # 创建pygame surface try: surface = pygame.surfarray.make_surface(np_array) return surface except Exception as e: print(f"Surface创建错误: {e}") print(f"数组形状: {np_array.shape}") # 备用方案:创建空白surface surface = pygame.Surface((self.width, self.height)) surface.fill((10, 20, 50)) return surface def update_fps(self, dt): """更新FPS统计""" if dt > 0: fps = 1.0 / dt self.frame_times.append(dt) self.fps_counter += 1 self.fps_timer += dt if self.fps_timer >= 1.0: avg_fps = self.fps_counter / self.fps_timer avg_frame_time = np.mean(self.frame_times[-60:]) * 1000 title = f"Hybrid Engine | {avg_fps:.0f} FPS | {avg_frame_time:.2f}ms | CUDA" pygame.display.set_caption(title) self.fps_counter = 0 self.fps_timer = 0 # ============ Taichi高性能粒子系统 ============ @ti.data_oriented class TaichiParticles: def __init__(self, n_particles=100000): self.n = n_particles # GPU内存中的粒子数据 self.pos = ti.Vector.field(2, dtype=ti.f32, shape=n_particles) self.vel = ti.Vector.field(2, dtype=ti.f32, shape=n_particles) self.color = ti.Vector.field(3, dtype=ti.f32, shape=n_particles) self.life = ti.field(dtype=ti.f32, shape=n_particles) self.size = ti.field(dtype=ti.f32, shape=n_particles) # 物理参数 self.gravity = ti.Vector([0.0, -150.0]) self.drag = 0.99 self.init_particles() @ti.kernel def init_particles(self): for i in range(self.n): # 从屏幕底部发射 self.pos[i] = [ti.random() * 1280, 100.0 + ti.random() * 50.0] # 向上发射,带随机角度 angle = ti.random() * 1.0 + 1.0 # 大致向上 speed = ti.random() * 300.0 + 150.0 self.vel[i] = [ti.cos(angle) * speed, ti.sin(angle) * speed] # 火焰颜色渐变 temp = ti.random() if temp < 0.4: self.color[i] = [1.0, 0.3 + ti.random() * 0.4, 0.0] # 红橙色 elif temp < 0.7: self.color[i] = [1.0, 0.7 + ti.random() * 0.3, 0.0] # 黄色 else: self.color[i] = [1.0, 1.0, ti.random() * 0.3] # 白黄色 self.life[i] = ti.random() * 4.0 + 2.0 self.size[i] = ti.random() * 4.0 + 2.0 @ti.kernel def update(self, dt: float): for i in range(self.n): if self.life[i] > 0.0: # 物理更新 self.vel[i] += self.gravity * dt self.vel[i] *= self.drag self.pos[i] += self.vel[i] * dt # 生命周期 self.life[i] -= dt # 颜色随生命值变化(火焰效果) life_ratio = self.life[i] / 6.0 if life_ratio > 0.7: # 明亮的火焰 self.color[i] = [1.0, 0.8, 0.2] elif life_ratio > 0.3: # 橙色火焰 self.color[i] = [1.0, 0.5, 0.0] else: # 暗红余烬 self.color[i] = [0.8, 0.2, 0.0] # 边界检查 if self.pos[i].y < -50 or self.pos[i].x < -100 or self.pos[i].x > 1380: self.life[i] = 0.0 else: # 重生粒子 self.pos[i] = [ti.random() * 1280, 100.0 + ti.random() * 50.0] angle = ti.random() * 1.0 + 1.0 speed = ti.random() * 300.0 + 150.0 self.vel[i] = [ti.cos(angle) * speed, ti.sin(angle) * speed] self.life[i] = ti.random() * 4.0 + 2.0 self.size[i] = ti.random() * 4.0 + 2.0 @ti.kernel def render(self, pixels: ti.template(), width: int, height: int): for i in range(self.n): if self.life[i] > 0.0: x = int(self.pos[i].x) y = int(height - self.pos[i].y) # 翻转Y轴 if 0 <= x < width and 0 <= y < height: # 生命值影响透明度和大小 life_ratio = self.life[i] / 6.0 alpha = ti.min(life_ratio, 1.0) color = self.color[i] * alpha size = int(self.size[i] * life_ratio) + 1 # 绘制火焰粒子(带光晕效果) for dx in range(-size, size + 1): for dy in range(-size, size + 1): px, py = x + dx, y + dy if 0 <= px < width and 0 <= py < height: dist = ti.sqrt(dx*dx + dy*dy) if dist <= size: # 中心更亮,边缘渐暗 falloff = ti.max(0.0, 1.0 - dist / (size + 1)) contribution = color * falloff * 0.3 # 🔧 修复:现在使用 [y, x] 索引来匹配新的坐标系统 pixels[py, px] = ti.min(pixels[py, px] + contribution, 1.0) # ============ Taichi星空背景 ============ @ti.data_oriented class TaichiStarfield: def __init__(self, n_stars=20000): self.n = n_stars self.pos = ti.Vector.field(2, dtype=ti.f32, shape=n_stars) self.brightness = ti.field(dtype=ti.f32, shape=n_stars) self.twinkle_phase = ti.field(dtype=ti.f32, shape=n_stars) self.speed = ti.field(dtype=ti.f32, shape=n_stars) self.color_type = ti.field(dtype=ti.i32, shape=n_stars) self.init_stars() @ti.kernel def init_stars(self): for i in range(self.n): self.pos[i] = [ti.random() * 1280, ti.random() * 720] self.brightness[i] = ti.random() * 0.5 + 0.2 self.twinkle_phase[i] = ti.random() * 6.28 self.speed[i] = ti.random() * 20.0 + 5.0 self.color_type[i] = int(ti.random() * 3) @ti.kernel def update(self, dt: float, time: float): for i in range(self.n): # 星星向下移动 self.pos[i].y += self.speed[i] * dt # 循环回到顶部 if self.pos[i].y > 750: self.pos[i].y = -30 self.pos[i].x = ti.random() * 1280 # 更新闪烁相位 self.twinkle_phase[i] += dt * 2.0 @ti.kernel def render(self, pixels: ti.template(), width: int, height: int, time: float): for i in range(self.n): x = int(self.pos[i].x) y = int(self.pos[i].y) if 0 <= x < width and 0 <= y < height: # 闪烁效果 twinkle = ti.sin(self.twinkle_phase[i]) * 0.3 + 0.7 brightness = self.brightness[i] * twinkle # 确保color变量总是被定义 color = ti.Vector([brightness, brightness, brightness]) # 默认白色 # 不同颜色的星星 color_type = self.color_type[i] if color_type == 1: # 蓝色星星 color = ti.Vector([brightness * 0.6, brightness * 0.8, brightness]) elif color_type == 2: # 黄色星星 color = ti.Vector([brightness, brightness * 0.9, brightness * 0.5]) # 🔧 修复:现在使用 [y, x] 索引 pixels[y, x] = ti.min(pixels[y, x] + color * 0.2, 1.0) # ============ Pygame UI系统 (中文支持) ============ class PygameUI: def __init__(self, screen): self.screen = screen # 🔧 修复:使用支持中文的字体 self.font = get_chinese_font(28) self.small_font = get_chinese_font(18) self.tiny_font = get_chinese_font(14) # UI状态 self.show_debug = True self.particle_count = 100000 self.mouse_pos = (0, 0) self.mouse_pressed = False # 测试中文是否正常显示 test_surface = self.font.render("测试", True, (255, 255, 255)) if test_surface.get_width() < 10: # 如果中文渲染失败,宽度会很小 print("⚠️ 中文字体加载失败,使用英文界面") self.use_chinese = False else: print("✅ 中文字体加载成功") self.use_chinese = True def get_text(self, key): """获取本地化文本""" texts = { "title": "🚀 混合引擎状态" if self.use_chinese else "🚀 Hybrid Engine Status", "fps": "帧率" if self.use_chinese else "FPS", "particles": "粒子数" if self.use_chinese else "Particles", "runtime": "运行时间" if self.use_chinese else "Runtime", "backend": "GPU后端" if self.use_chinese else "GPU Backend", "mouse": "鼠标位置" if self.use_chinese else "Mouse Pos", "memory": "内存使用" if self.use_chinese else "Memory", "controls": "🎮 控制" if self.use_chinese else "🎮 Controls", "f1": "F1: 切换调试信息" if self.use_chinese else "F1: Toggle Debug", "arrows": "↑↓: 调整粒子数量" if self.use_chinese else "↑↓: Adjust Particles", "space": "空格: 重置粒子" if self.use_chinese else "Space: Reset Particles", "r": "R: 重置星空" if self.use_chinese else "R: Reset Stars", "esc": "ESC: 退出程序" if self.use_chinese else "ESC: Exit" } return texts.get(key, key) def handle_events(self): """处理Pygame事件""" for event in pygame.event.get(): if event.type == pygame.QUIT: return False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: return False elif event.key == pygame.K_F1: self.show_debug = not self.show_debug status = "开启" if self.show_debug else "关闭" print(f"🔧 调试信息: {status}") elif event.key == pygame.K_UP: old_count = self.particle_count self.particle_count = min(500000, self.particle_count + 25000) print(f"⬆️ 粒子数量: {old_count:,} -> {self.particle_count:,}") elif event.key == pygame.K_DOWN: old_count = self.particle_count self.particle_count = max(10000, self.particle_count - 25000) print(f"⬇️ 粒子数量: {old_count:,} -> {self.particle_count:,}") elif event.key == pygame.K_SPACE: print("🎆 重新初始化粒子系统") elif event.key == pygame.K_r: print("🌟 重新初始化星空系统") elif event.type == pygame.MOUSEMOTION: self.mouse_pos = event.pos elif event.type == pygame.MOUSEBUTTONDOWN: self.mouse_pressed = True elif event.type == pygame.MOUSEBUTTONUP: self.mouse_pressed = False return True def draw_ui(self, fps, particle_system, engine_time): """绘制UI元素""" if not self.show_debug: return # 半透明背景 ui_surface = pygame.Surface((400, 300)) ui_surface.set_alpha(180) ui_surface.fill((5, 10, 20)) self.screen.blit(ui_surface, (10, 10)) # 边框 pygame.draw.rect(self.screen, (50, 100, 150), (10, 10, 400, 300), 2) # 性能信息 y_offset = 25 # 标题 title = self.font.render(self.get_text("title"), True, (255, 255, 100)) self.screen.blit(title, (20, y_offset)) y_offset += 40 # 性能数据 perf_data = [ (self.get_text("fps"), f"{fps:.1f}"), (self.get_text("particles"), f"{particle_system.n:,}"), (self.get_text("runtime"), f"{engine_time:.1f}s"), (self.get_text("backend"), str(ti.cfg.arch)), (self.get_text("mouse"), f"{self.mouse_pos}"), (self.get_text("memory"), "GPU优化" if self.use_chinese else "GPU Optimized") ] for label, value in perf_data: # 标签 label_surface = self.small_font.render(f"{label}:", True, (200, 200, 255)) self.screen.blit(label_surface, (25, y_offset)) # 数值 color = (150, 255, 150) if "FPS" in label and fps > 60 else (255, 255, 255) value_surface = self.small_font.render(value, True, color) self.screen.blit(value_surface, (200, y_offset)) y_offset += 25 # 分隔线 pygame.draw.line(self.screen, (100, 100, 100), (25, y_offset), (390, y_offset)) y_offset += 20 # 控制说明 control_title = self.small_font.render(self.get_text("controls"), True, (255, 200, 100)) self.screen.blit(control_title, (25, y_offset)) y_offset += 30 controls = [ self.get_text("f1"), self.get_text("arrows"), self.get_text("space"), self.get_text("r"), self.get_text("esc") ] for control in controls: rendered = self.tiny_font.render(control, True, (180, 180, 180)) self.screen.blit(rendered, (30, y_offset)) y_offset += 20 def draw_mouse_effects(self): """在鼠标位置绘制特效""" if self.mouse_pressed: # 鼠标按下时的特效 pygame.draw.circle(self.screen, (255, 100, 100), self.mouse_pos, 25, 3) pygame.draw.circle(self.screen, (255, 200, 100), self.mouse_pos, 15, 2) pygame.draw.circle(self.screen, (255, 255, 255), self.mouse_pos, 8, 1) else: # 普通鼠标指示器 pygame.draw.circle(self.screen, (100, 150, 255), self.mouse_pos, 12, 2) pygame.draw.circle(self.screen, (200, 200, 255), self.mouse_pos, 6, 1) # ============ 主程序 ============ def main(): print("🚀 Pygame + Taichi 混合引擎启动!") print(f"📊 Taichi后端: {ti.cfg.arch}") print(f"🎮 Pygame版本: {pygame.version.ver}") # 创建引擎组件 engine = HybridEngine(1280, 720, "混合引擎启动中...") ui = PygameUI(engine.screen) # 创建Taichi系统 print("🔄 初始化粒子系统...") particles = TaichiParticles(100000) print("🔄 初始化星空系统...") starfield = TaichiStarfield(20000) print("✅ 系统初始化完成!") print("🎆 粒子系统: 10万火焰粒子") print("⭐ 星空系统: 2万闪烁星星") print("🎮 控制: F1=调试 ↑↓=粒子数 空格=重置 R=重置星空") print("🔧 坐标系统已修复,应该不会再旋转90度了") # 游戏循环 running = True last_time = time.time() start_time = time.time() frame_count = 0 while running: current_time = time.time() dt = current_time - last_time last_time = current_time engine_time = current_time - start_time frame_count += 1 # Pygame事件处理 running = ui.handle_events() if not running: break # 动态调整粒子数量 if ui.particle_count != particles.n: print(f"🔄 重新创建粒子系统: {particles.n:,} -> {ui.particle_count:,}") particles = TaichiParticles(ui.particle_count) # Taichi系统更新 starfield.update(dt, engine_time) particles.update(dt) # Taichi渲染 engine.clear_taichi_buffer((0.01, 0.02, 0.05)) # 深蓝夜空 starfield.render(engine.pixels, engine.width, engine.height, engine_time) particles.render(engine.pixels, engine.width, engine.height) # 转换Taichi结果到Pygame taichi_surface = engine.taichi_to_pygame() engine.screen.blit(taichi_surface, (0, 0)) # Pygame UI绘制 ui.draw_mouse_effects() ui.draw_ui(1.0 / dt if dt > 0 else 0, particles, engine_time) # 显示和FPS控制 pygame.display.flip() engine.clock.tick(120) # 限制120FPS engine.update_fps(dt) # 每1000帧打印一次状态 if frame_count % 1000 == 0: print(f"📊 运行状态: {frame_count} 帧, {engine_time:.1f}s, {1.0 / dt:.1f} FPS") print("🎯 引擎正常关闭") print(f"⏱️ 总运行时间: {time.time() - start_time:.1f}秒") print(f"📊 总帧数: {frame_count}") pygame.quit() # ============ 性能测试函数 ============ def performance_test(): """性能基准测试""" print("🧪 开始性能基准测试...") # 测试不同粒子数量的性能 test_counts = [10000, 50000, 100000, 200000] for count in test_counts: print(f"n📊 测试 {count:,} 粒子:") # 创建测试系统 particles = TaichiParticles(count) # 运行100帧测试 start_time = time.time() for _ in range(100): particles.update(0.016) # 60FPS end_time = time.time() avg_time = (end_time - start_time) / 100 fps = 1.0 / avg_time if avg_time > 0 else 0 print(f" 平均帧时间: {avg_time * 1000:.2f}ms") print(f" 理论FPS: {fps:.1f}") print(f" 粒子/秒: {count * fps:.0f}") # ============ 调试工具 ============ def debug_coordinates(): """调试坐标系统""" print("🔧 坐标系统调试工具") # 创建小型测试环境 ti.init(arch=ti.gpu) width, height = 100, 100 pixels = ti.Vector.field(3, dtype=ti.f32, shape=(height, width)) @ti.kernel def test_render(): # 在四个角落放置不同颜色的点 pixels[10, 10] = [1.0, 0.0, 0.0] # 红色 - 左上 pixels[10, 90] = [0.0, 1.0, 0.0] # 绿色 - 右上 pixels[90, 10] = [0.0, 0.0, 1.0] # 蓝色 - 左下 pixels[90, 90] = [1.0, 1.0, 0.0] # 黄色 - 右下 # 画一条对角线 for i in range(100): pixels[i, i] = [1.0, 1.0, 1.0] # 白色对角线 test_render() # 转换为numpy并保存 np_array = pixels.to_numpy() np_array = (np_array * 255).astype(np.uint8) np_array = np.transpose(np_array, (1, 0, 2)) print(f"数组形状: {np_array.shape}") print("如果坐标正确,应该看到:") print("- 左上角红色,右上角绿色") print("- 左下角蓝色,右下角黄色") print("- 白色对角线从左上到右下") # ============ 主入口 ============ if __name__ == "__main__": try: import sys # 检查命令行参数 if len(sys.argv) > 1: if sys.argv[1] == "--test": performance_test() elif sys.argv[1] == "--debug": debug_coordinates() elif sys.argv[1] == "--help": print("🚀 Pygame + Taichi 混合引擎") print("用法:") print(" python main.py # 正常运行") print(" python main.py --test # 性能测试") print(" python main.py --debug # 坐标调试") print(" python main.py --help # 显示帮助") else: print(f"未知参数: {sys.argv[1]}") print("使用 --help 查看帮助") else: # 正常运行主程序 main() except KeyboardInterrupt: print("n🛑 用户中断程序") except Exception as e: print(f"❌ 运行错误: {e}") import traceback traceback.print_exc() # 等待用户按键再退出 try: input("按回车键退出...") except: pass


作者提示含AI生成内容。作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

展开 收起
0评论

当前文章无评论,是时候发表评论了
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章
最新文章 热门文章
3
扫一下,分享更方便,购买更轻松