pygameP
Pygame Plus — 一个面向 Pygame 的高级扩展框架,提供 GLSL 着色器特效、性能优化工具、JSON 场景管理、简单物理引擎和扩展输入设备支持。
安装
pip install pygameP
依赖项会自动安装:
pygame >= 2.0.0PyOpenGL >= 3.1.0(用于着色器支持)
核心特性
| 模块 | 功能 |
|---|---|
| shaders | GLSL 着色器系统 + 内置特效(灰度/模糊/反转/亮度/脉冲/波浪) |
| performance | 对象池、空间哈希、帧率监控、批处理渲染 |
| scene | .pgstage JSON 场景文件,支持多场景切换 |
| physics | 简单刚体物理(重力、碰撞、射线检测) |
| input | 键盘、鼠标、手柄、多点触摸统一输入管理 |
快速开始
1. GLSL 着色器特效
支持从 .glsl 文件加载或从代码字符串创建着色器。可作用于整个屏幕或单个精灵。
from pygameP import Shader, ShaderEffect, BuiltInEffects
# 使用内置特效
grayscale = BuiltInEffects.grayscale()
blur = BuiltInEffects.blur(radius=3.0)
invert = BuiltInEffects.invert()
pulse = BuiltInEffects.pulse(speed=2.0)
wave = BuiltInEffects.wave(amplitude=0.05, frequency=10.0)
# 应用到整个屏幕
grayscale.apply(screen)
# 应用到单个精灵
pulse.apply(my_sprite)
# 自定义 GLSL 代码
my_shader = Shader(fragment_source="""
#version 330 core
in vec2 v_texcoord;
out vec4 frag_color;
uniform sampler2D u_texture;
uniform float u_time;
void main() {
vec4 c = texture(u_texture, v_texcoord);
frag_color = vec4(c.r, c.g * abs(sin(u_time)), c.b, c.a);
}
""")
# 从文件加载
custom = Shader(
vertex_file="assets/shaders/default.vert",
fragment_file="assets/shaders/plasma.frag"
)
2. 性能优化
from pygameP import ObjectPool, SpatialHash, FPSMonitor, BatchRenderer
# 对象池 - 减少子弹/粒子的创建开销
bullet_pool = ObjectPool(lambda: Bullet(), initial_size=200)
bullet = bullet_pool.acquire() # 从池中获取
# ... 使用后 ...
bullet_pool.release(bullet) # 归还
# 空间哈希 - 快速碰撞检测
spatial = SpatialHash(cell_size=64)
spatial.insert(enemy, enemy.rect)
nearby = spatial.query(player.rect) # 只检测附近对象
# FPS 监控 + 自适应质量
fps_monitor = FPSMonitor(target_fps=60)
while running:
dt = fps_monitor.tick()
if fps_monitor.should_reduce_quality():
reduce_particle_count()
# 批处理渲染 - 合并绘制调用
batch = BatchRenderer(screen)
for sprite in sprites:
batch.blit(sprite.image, sprite.rect.topleft)
batch.render() # 一次性执行
3. 场景管理(.pgstage)
.pgstage 是 pygameP 的自定义场景文件格式,基于 JSON。
场景编辑器下载:
.pgstage文件由 Objector Coder 可视化编辑器创建和管理,pygameP 库只负责加载和运行场景。 下载地址:https://tomlct2015.github.io/Objector-Coder/#download
{
"name": "ExampleLevel",
"width": 1600,
"height": 1200,
"background_color": [20, 25, 40],
"camera_x": 0,
"camera_y": 0,
"properties": {
"music": "assets/music/level1.ogg",
"difficulty": "normal"
},
"entities": [
{
"type": "Player",
"x": 100,
"y": 800,
"layer": 5,
"hp": 100,
"tag": "player"
},
{
"type": "Enemy",
"x": 500,
"y": 800,
"layer": 4,
"hp": 50,
"ai": "patrol"
}
]
}
Python 中使用:
from pygameP import Scene, SceneManager, SceneEntity
# 创建场景
scene = Scene("Level1", width=1600, height=1200)
scene.background_color = (20, 25, 40)
scene.add_entity(SceneEntity(100, 800, hp=100, tag="player"))
# 保存为 .pgstage 文件
scene.save("levels/level1.pgstage")
# 加载场景
loaded = Scene.load("levels/level1.pgstage")
# 多场景管理(带过渡效果)
manager = SceneManager()
manager.add_scene("menu", Scene("Menu"))
manager.add_scene("game", Scene.load("levels/level1.pgstage"))
manager.switch_to("game", transition_duration=0.5)
# 游戏主循环
while running:
dt = clock.tick(60) / 1000.0
manager.update(dt)
manager.draw(screen)
4. 简单物理引擎
from pygameP import RigidBody, PhysicsWorld, BoxCollider, CircleCollider
# 创建物理世界
world = PhysicsWorld(gravity=980.0)
# 动态刚体(受重力影响)
player = RigidBody(x=100, y=0, mass=1.0, collider=BoxCollider(32, 64))
player.restitution = 0.3 # 弹性
player.friction = 0.2 # 摩擦
world.add_body(player)
# 静态刚体(地面、平台)
ground = RigidBody(x=0, y=600, mass=0, collider=BoxCollider(800, 40))
world.add_body(ground)
# 施加力或冲量
player.apply_force(500, 0) # 持续力
player.apply_impulse(0, -300) # 跳跃(瞬间)
# 每帧更新
world.update(dt)
# 碰撞回调
def on_hit(body1, body2):
print("碰撞!")
world.on_collision = on_hit
# 射线检测
hit = world.raycast((100, 300), (1, 0), max_distance=500)
if hit:
body, distance, point = hit
print(f"命中 {body},距离 {distance}")
5. 扩展输入设备
from pygameP import InputManager
input_mgr = InputManager()
# 映射动作到多种输入
input_mgr.map_action("jump", "keyboard", pygame.K_SPACE)
input_mgr.map_action("jump", "gamepad", (0, 0)) # 手柄 0 的按钮 0
input_mgr.map_action("shoot", "mouse", 1) # 鼠标左键
input_mgr.map_action("move_right", "gamepad", (0, "axis_0"))
# 游戏主循环
while running:
events = pygame.event.get()
input_mgr.update(events)
if input_mgr.is_action_just_pressed("jump"):
player.jump()
if input_mgr.is_action_pressed("move_right"):
player.move_right()
# 模拟输入(手柄摇杆)
move_x = input_mgr.get_action_value("move_right")
# 直接访问手柄
pad = input_mgr.get_gamepad(0)
if pad:
left_stick = pad.get_left_stick()
pad.rumble(0.5, 0.5, 100) # 震动
# 触摸输入
if input_mgr.touch.is_touching():
pos = input_mgr.touch.get_touch_position()
支持的输入设备:
- 键盘 — 按键按下/释放/刚刚按下
- 鼠标 — 位置、相对运动、滚轮、按钮状态
- 手柄 — 按钮、摇杆轴、方向帽、震动(rumble)
- 触摸 — 多点触控、触摸开始/结束/移动
API 参考
Shader
Shader(vertex_source, fragment_source, vertex_file, fragment_file)— 创建着色器shader.use()/shader.stop()— 启用/停用shader.set_uniform(name, value)— 设置 uniform(支持 float/int/vec2/vec3/vec4)shader.apply_to_surface(surface)— 应用于整个屏幕shader.apply_to_sprite(sprite)— 应用于单个精灵
BuiltInEffects(内置特效)
grayscale()— 灰度blur(radius)— 模糊invert()— 颜色反转brightness(amount)— 亮度pulse(speed)— 脉冲发光wave(amplitude, frequency)— 波浪扭曲
ObjectPool
acquire()— 获取对象release(obj)— 归还对象release_all()— 归还所有resize(n)— 调整池大小
SpatialHash
insert(obj, rect)— 插入对象query(rect)— 查询区域内对象query_nearby(obj, rect)— 查询附近(排除自己)remove(obj)/clear()
Scene / SceneManager
scene.save(path)— 保存为.pgstageScene.load(path)— 加载.pgstagemanager.switch_to(name, transition_duration)— 切换场景
PhysicsWorld
add_body(body)/remove_body(body)update(dt)— 更新物理(自动处理重力和碰撞)raycast(start, direction, max_distance)— 射线检测
InputManager
update(events)— 更新所有输入设备is_action_pressed(action)— 动作是否被按住is_action_just_pressed(action)— 动作是否刚刚按下get_action_value(action)— 获取模拟值(-1 到 1)map_action(action, device, binding)— 映射动作
完整示例
import pygame
from pygameP import (
SceneManager, Scene, SceneEntity,
PhysicsWorld, RigidBody, BoxCollider,
InputManager, FPSMonitor, BuiltInEffects
)
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
# 场景
manager = SceneManager()
game = Scene("Game", 800, 600)
game.background_color = (30, 40, 60)
manager.add_scene("game", game)
manager.switch_to("game")
# 物理
world = PhysicsWorld(gravity=980.0)
player = RigidBody(400, 100, mass=1.0, collider=BoxCollider(32, 32))
world.add_body(player)
ground = RigidBody(0, 550, mass=0, collider=BoxCollider(800, 50))
world.add_body(ground)
# 输入
input_mgr = InputManager()
input_mgr.map_action("jump", "keyboard", pygame.K_SPACE)
input_mgr.map_action("left", "keyboard", pygame.K_LEFT)
input_mgr.map_action("right", "keyboard", pygame.K_RIGHT)
# 性能监控
fps = FPSMonitor(target_fps=60)
# 着色器
effect = BuiltInEffects.pulse(speed=2.0)
running = True
while running:
dt = clock.tick(60) / 1000.0
fps.tick()
events = pygame.event.get()
input_mgr.update(events)
for event in events:
if event.type == pygame.QUIT:
running = False
# 输入
if input_mgr.is_action_just_pressed("jump") and player.grounded:
player.apply_impulse(0, -500)
if input_mgr.is_action_pressed("left"):
player.apply_force(-300, 0)
if input_mgr.is_action_pressed("right"):
player.apply_force(300, 0)
# 更新
world.update(dt)
manager.update(dt)
# 绘制
manager.draw(screen)
pygame.draw.rect(screen, (255, 200, 100),
(player.x, player.y, 32, 32))
pygame.draw.rect(screen, (100, 100, 100),
(ground.x, ground.y, 800, 50))
pygame.display.flip()
pygame.quit()
许可证
MIT License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
pygamep-0.0.1.tar.gz
(30.9 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
pygamep-0.0.1-py3-none-any.whl
(24.7 kB
view details)
File details
Details for the file pygamep-0.0.1.tar.gz.
File metadata
- Download URL: pygamep-0.0.1.tar.gz
- Upload date:
- Size: 30.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fda5991a7a6716a04f89cc8948efc24a5e2c6decb9e5c75b35033f83d53c77a6
|
|
| MD5 |
32892288eaf4bc0896f2becc795cdefe
|
|
| BLAKE2b-256 |
b9bea88daffbed10b7d4091be179f513ff518406789842bafb1d14c200ead64c
|
File details
Details for the file pygamep-0.0.1-py3-none-any.whl.
File metadata
- Download URL: pygamep-0.0.1-py3-none-any.whl
- Upload date:
- Size: 24.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e7aca1056ac51cf4f0baa5bd4870086244333200308a89da7653b197e7fd89b
|
|
| MD5 |
b92770a48d3fd85532b017943a02d53b
|
|
| BLAKE2b-256 |
0a2151ac07a023f7d6c7a0dd715d64086346cecb3deeb606fa09ce1d4101dc3f
|