游戏开发尝试, Pygame 中做「全程代码生成+渲染」并保持高性能
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。

分析原因,首先是运算量太大,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 操作

达到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渲染(大量对象的绘制)
复杂的图形效果
数值计算

使用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生成内容。作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~
