🎮 Walimaker - 专为教学设计的Python游戏引擎
Walimaker 是一个专为教学场景设计的Python游戏引擎模块。它采用简洁直观的API设计,让学生能够快速上手游戏开发,同时掌握编程核心概念。模块基于Pygame和Pymunk构建,提供完整的2D游戏开发功能。
✨ 特性亮点
🎯 教学友好
- 简洁API:基于Python语法糖,类似Processing/turtle的直观接口
- 错误友好:详尽的错误提示和调试信息,帮助初学者快速定位问题
- 渐进学习:从简单绘图到复杂游戏逻辑的平滑过渡
🛠 功能完备
- 🎨 图形渲染:精灵动画、位图渲染、TileMap支持
- ⚙️ 物理系统:刚体动力学、碰撞检测、约束(Pymunk:
connect()刚性杆、Spring()弹簧) - 🎵 音频管理:背景音乐、音效播放、音量控制
- 📝 UI组件:文本框、对话框
- ⌨️ 输入系统:鼠标与键盘事件
- 📊 资源管理:智能 LRU 缓存,自动内存管理
🚀 开发效率
- 调试工具:调试绘制
debug()、自动刷新tracer()、移动限速speed()、性能基准脚本 - 类型友好:随包提供
py.typed,编辑器与 mypy 能直接提示参数类型 - 测试与门禁:8 个测试文件 +
scripts/check.py(一条命令跑 black / flake8 / mypy / 全部测试, 并支持--matrix自动跑 pymunk 6/7 双版本) - 模块化设计:对象模型、精灵动画、物理、渲染、资源各司其职,便于定制
🚀 快速开始
安装
通过pip安装
pip install Walimaker
第一个游戏:移动的角色
from Walimaker import *
# 初始化游戏窗口
setup(800, 600)
title("我的第一个Walimaker游戏")
# 创建角色
character = Character(["idle_1.png", "idle_2.png", "idle_3.png"])
character.scale(2, 2)
# 主游戏循环
while True:
# 事件处理:key_pressed 接收 pygame 的按键常量
# (K_UP / K_a / K_SPACE 等常量随 `from Walimaker import *` 一起提供)
if key_pressed(K_UP):
character.forward(5)
if key_pressed(K_LEFT):
character.left(5)
if key_pressed(K_RIGHT):
character.right(5)
if key_pressed(K_SPACE):
character.say("跳跃!")
# 动画播放
character.play_anim()
# 渲染更新
update()
🧭 中文报错提示(教学特性)
程序出错时,英文原始报错会完整保留(异常类型、消息、完整 traceback),中文解释追加在它的后面, 方便初学者对照着官方报错一起看:
Traceback (most recent call last):
File "main.py", line 12, in <module>
if key_pressed(K_SPACE):
NameError: name 'K_SPACE' is not defined
────────────────────────────────────────────────────────────────
【Walimaker 中文提示】按键/事件常量「K_SPACE」没有导入
原因:pygame 的按键、鼠标、事件常量(K_SPACE、KEYDOWN、QUIT、MOUSEBUTTONDOWN 等)需要先导入才能使用。
解决:① 确认 walimaker 版本 ≥ 2.1.0(pip install -U walimaker),这些常量会随 from Walimaker import *
一起提供;② 或者显式写 from pygame.locals import *。
参考:CHANGELOG 2.1.0「恢复 pygame 事件/按键常量的导出」
────────────────────────────────────────────────────────────────
覆盖的常见错误包括:缺少依赖、变量/函数未定义(按键常量有专项提示)、忘记调用 setup()、
图片/音乐路径找不到、没有声卡、pymunk 坐标类型错误、pymunk 版本兼容问题、key_pressed("w") 传了字符串、
图片类型不支持、setup() 参数不对、Tab 与空格混用、语法/缩进错误、除零、全局变量作用域、递归过深等;
如果报错发生在 Walimaker 自身代码里,会提示"可能是框架问题 + 如何反馈"。
关闭方式(默认开启):
WALIMAKER_ERROR_HELP=0 python main.py # 环境变量
set_error_help(False) # 或在代码里关闭
在 try/except 里主动取中文解释:
try:
character = Character("hero.png")
except Exception as e:
print(explain_exception(e)) # 返回中文解释文本
📁 项目结构
Walimaker/
├── 📄 pyproject.toml # 打包 / 依赖配置
├── 📄 README.md # 项目说明
├── 📄 LICENSE # MIT 许可证
├── 📄 OPTIMIZATION_PLAN.md # 性能 / 结构分析与优化计划
├── 📁 benchmarks/ # 性能基线脚本(不参与打包)
│ └── 🐍 perf_baseline.py
├── 📁 tests/ # 冒烟 / 回归测试(不参与打包)
│ └── 🐍 smoke_test.py
└── 📁 src/
└── 📁 Walimaker/ # 包源码(import Walimaker)
├── 📄 API.py # 主要API接口(Character、窗口管理等)
├── 📄 sprite.py # 精灵和动画系统
├── ⚙️ physics.py # 物理引擎封装(基于Pymunk)
├── 📷 camera.py # 相机系统(缩放、跟随)
├── 🗺️ tiledmap.py # TileMap地图系统
├── 📝 textbox.py # UI文本组件
├── 🎵 music.py # 音频管理系统
├── 📦 resource_manager.py # 资源管理(智能缓存)
├── 🔧 config.py # 全局配置和初始化
├── 🎮 test.py # 示例代码(walimaker-demo 入口)
└── 📁 static/ # 资源文件(只有体积很小的图片)
└── 🖼️ *.png # 图片资源
关于字体:从 2.3.0 起包内不再携带字体文件(原先的楷体/宋体合计 28.6 MB, 使 wheel 接近 16 MB,且属于微软版权字体不允许再分发)。中文显示改为运行时自动解析, 详见下文「🅰️ 中文字体」一节。
开发时可用 pip install -e .(或把 src/ 加入 PYTHONPATH)后 import Walimaker。
🧰 本地开发与测试(uv,推荐)
项目已按 uv 配好开发环境:一条命令建好隔离环境并装齐依赖
([dependency-groups] dev:black / flake8 / mypy / pytest / twine)。
uv sync # 创建 .venv(Python 版本由 .python-version 指定)并安装依赖
uv run python scripts/check.py # 静态检查 + 全部测试(等价于 CI)
uv run python scripts/check.py --matrix # 额外跑 pymunk 6.11.1 / 最新版 双版本矩阵
uv run python tests/smoke_test.py # 也可以只跑单个测试
uv run python benchmarks/perf_baseline.py
uv.lock随仓库提供(133 个包,按 Python 3.8.1+ 全范围解析),uv sync按锁文件精确安装; 升级依赖用uv lock --upgrade。--matrix用uv run --no-project --with pymunk==6.11.1现开临时环境,两个版本各跑一遍全部测试, 不需要手动准备两个 venv、也不会污染当前环境(整轮约 15 秒)。- 不想用 uv 也可以:
pip install -e ".[dev]"后python scripts/check.py,效果相同。
Python 支持矩阵(requires-python = ">=3.8.1"):
| 版本 | 说明 |
|---|---|
| 3.8.1 ~ 3.8.x | 可用,但会被解析到 pymunk 6.x(pymunk 7 要求 ≥ 3.9);3.8.0 不受支持(没有任何 flake8 版本可用) |
| 3.9 ~ 3.13 | 推荐区间:pymunk 7 + 官方 pygame wheel 齐备 |
| 3.14+ | 官方 pygame 尚无 wheel,需改用 pygame-ce |
📚 核心模块详解
🎨 sprite.py - 精灵与动画系统
- EasySpriteStrategy - 静态精灵策略
- ListSpriteStrategy - 帧动画策略
- AnimatorStrategy - 状态动画策略
- SpriteSheet - 精灵表支持
- 支持:旋转、缩放、翻转、颜色修改
📦 resource_manager.py - 资源管理
智能LRU缓存系统:
from Walimaker.resource_manager import ResourceManager
resource_manager = ResourceManager.get_instance()
# 自动缓存管理
image = resource_manager.load_image("image.png") # 首次加载
cached_image = resource_manager.load_image("image.png") # 从缓存读取
# 缓存统计
info = resource_manager.get_cache_info()
print(f"图片缓存: {info['images']['current_size']}/{info['images']['maxsize']}")
🎮 API.py - 主要接口
提供简洁的面向对象API:
from Walimaker import *
# 创建各种类型的角色
character = Character("image.png") # 静态角色
anim_character = Character(["frame1.png", "frame2.png"]) # 动画角色
state_character = Character({ # 状态机角色
"idle": ["idle_1.png", "idle_2.png"],
"walk": ["walk_1.png", "walk_2.png", "walk_3.png"]
})
🧭 API文档
📋 概述
Walimaker采用笛卡尔坐标系(像素单位),提供完整的游戏开发功能。坐标原点位于窗口左上角,角度系统:0°指向右侧,逆时针方向角度增加。
🖼️ 窗口设置模块
| 函数名 | 功能描述 | 参数说明 | 返回值 | 备注 |
|---|---|---|---|---|
setup(width, height) |
创建指定尺寸的窗口 | width: 宽度height: 高度 |
- | 窗口在屏幕中心生成 |
update() |
刷新画面显示 | - | - | 将修改内容更新到窗口 |
title(text) |
设置窗口标题 | text: 标题文本 |
- | - |
bgpic(image_path) |
设置背景(图片 / Surface / TiledMap),并把相机尺寸设为它的大小 |
image_path: 图片路径、Surface 或 TiledMap |
背景对象 | 图片小于窗口时显示黑色背景;传入 TiledMap 会真正渲染整张地图 |
bgmusic(music_path) |
播放背景音乐 | music_path: 音乐路径 |
- | 循环播放模式 |
set_volume(level) |
设置音量 | level: 0-1浮点数 |
- | 全局音量控制 |
tracer(enable) |
自动刷新控制 | enable: 布尔值 |
- | 防止主线程卡顿 |
save_screen(path) |
截图保存 | path: 保存路径 |
- | 保存当前窗口画面 |
set_mouse_visible(visible) |
鼠标显示控制 | visible: 布尔值 |
- | 显示/隐藏鼠标光标 |
Character 角色类
构造方法
| 方式 | 描述 | 参数 | 返回值 |
|---|---|---|---|
| 单图模式 | 创建静态角色 | image_path: 图片路径 |
Character对象 |
| 动画序列 | 创建帧动画角色 | image_list: 图片路径列表 |
Character对象 |
| 状态动画 | 创建多状态角色 | anim_dict: {状态名: 图片列表} |
Character对象 |
核心属性
| 属性 | 类型 | 描述 | 权限 |
|---|---|---|---|
x, y |
float |
角色坐标位置 | 读写 |
pos |
tuple |
坐标元组 (x, y) | 读写 |
rot |
float |
旋转角度 (0°=右侧,逆时针) | 读写 |
dir |
vec |
方向向量 | 读写 |
red, green, blue, alpha |
int |
颜色通道值 (0-255) | 读写 |
color |
tuple |
颜色元组 (r, g, b, a) | 读写 |
visible |
bool |
可见性状态 | 只读 |
width, height |
int |
图片尺寸 | 只读 |
frame |
int |
当前动画帧索引 | 读写 |
state |
str |
当前动画状态名 | 读写 |
dt |
float |
动画帧间隔时间 | 读写 |
layer |
int |
渲染层级 (0=底层) | 读写 |
动作方法
| 方法 | 功能 | 参数 | 返回值 |
|---|---|---|---|
forward(distance) |
向前移动 | distance: 像素距离 |
- |
backward(distance) |
向后移动 | distance: 像素距离 |
- |
left(angle) |
左转 | angle: 旋转角度 |
- |
right(angle) |
右转 | angle: 旋转角度 |
- |
goto(x, y) |
瞬移到坐标 | x, y: 目标坐标 |
- |
slide_to(pos, velocity) |
滑动移动 | pos: 目标位置velocity: 速度 |
- |
scale(width, height) |
缩放尺寸 | width, height: 缩放倍数 |
- |
flipx(enable) |
水平翻转 | enable: 布尔值 |
- |
flipy(enable) |
垂直翻转 | enable: 布尔值 |
- |
show() / hide() |
显示/隐藏角色 | - | - |
交互方法
| 方法 | 功能 | 参数 | 返回值 |
|---|---|---|---|
play_snd(sound_path, volume) |
播放音效 | sound_path: 音效路径volume: 音量(0-1) |
- |
collide(target) |
碰撞检测 | target: 角色或坐标 |
bool |
separate(target) |
分离检测 | target: 角色或坐标 |
bool |
distance(target) |
距离计算 | target: 角色或坐标 |
float |
say(text) |
显示对话气泡 | text: 对话内容 |
- |
动画控制
| 方法 | 功能 | 参数 | 返回值 |
|---|---|---|---|
play_anim() |
开始播放动画 | - | - |
stop_anim() |
停止播放动画 | - | - |
set_dt(state, interval) |
设置帧间隔 | state: 状态名interval: 间隔时间 |
- |
set_next_state(from_state, to_state) |
设置状态切换 | from_state: 当前状态to_state: 下一状态 |
- |
set_start_func(state, func) |
设置开始回调 | state: 状态名func: 回调函数 |
- |
set_end_func(state, func) |
设置结束回调 | state: 状态名func: 回调函数 |
- |
鼠标交互
| 方法 | 功能 | 参数 | 返回值 |
|---|---|---|---|
get_mouse_clicked() |
鼠标点击检测 | - | bool |
get_mouse_just_clicked() |
鼠标点击瞬间检测 | - | bool |
get_mouse_just_released() |
鼠标释放瞬间检测 | - | bool |
get_mouse_upon() |
鼠标悬停检测 | - | bool |
kill() |
销毁角色对象 | - | - |
TextBox 文本框类
构造函数
TextBox(font_size, font=None, bg_color=默认值, font_color=默认值)
font=None 表示自动选择字体(包内 static/ → 系统中文字体 → pygame 默认字体);
也可以直接给字体路径,例如 TextBox(25, font=r"C:\Windows\Fonts\simhei.ttf")。
属性
| 属性 | 类型 | 描述 | 权限 |
|---|---|---|---|
pos |
tuple |
文本框位置坐标 | 读写 |
color |
tuple |
文本颜色 (r, g, b) | 读写 |
方法
| 方法 | 功能 | 参数 | 返回值 |
|---|---|---|---|
write(content) |
设置文本内容 | content: 文本字符串 |
- |
print(content) |
write() 的兼容别名(旧代码可用,但会遮蔽内建 print) |
content: 文本字符串 |
- |
goto(x, y) |
移动文本框 | x, y: 目标坐标 |
- |
事件处理函数
鼠标事件
| 函数 | 功能 | 参数 | 返回值 |
|---|---|---|---|
get_mouse_pos() |
获取鼠标坐标 | - | tuple (x, y) |
get_mouse_rel() |
获取鼠标移动向量 | - | tuple (dx, dy) |
get_mouse_clicked() |
检测鼠标按下状态 | - | bool |
get_mouse_just_clicked() |
检测鼠标按下瞬间 | - | bool |
get_mouse_just_released() |
检测鼠标释放瞬间 | - | bool |
键盘事件
| 函数 | 功能 | 参数 | 返回值 |
|---|---|---|---|
key_pressed(key) |
检测按键按下状态 | key: 按键常量(可选) |
bool |
key_just_pressed(key) |
检测按键按下瞬间 | key: 按键常量(可选) |
bool |
key_just_released(key) |
检测按键释放瞬间 | key: 按键常量(可选) |
bool |
key_input() |
获取按键输入字符 | - | str |
🚦 高级用法
🌍 多世界(互不干扰的两套场景)
每个 World 拥有自己的窗口状态、相机、精灵组、物理空间与更新组。
所有接口的 world 参数都可以省略,省略即默认世界(global_var),所以旧代码完全不用改。
from Walimaker import *
from Walimaker.config import World
# 默认世界(老写法,等价于 world=None)
setup(800, 600)
hero = Character("hero.png", size=(32, 32))
# 第二个世界:自己的相机 / 空间 / 精灵组
w2 = World()
setup(800, 600, world=w2)
ghost = Character("ghost.png", size=(32, 32), world=w2)
text = TextBox(24, world=w2)
update() # 只推进默认世界
update(w2) # 只推进 w2;两个世界的物理与画面互不影响
ghost.velocity = vec(50, 0) # 只影响 w2 里的刚体
hero.kill() # 只移除默认世界里的对象
- 可用
world的接口:setup / update / done / save_screen、Screen、Camera、Character / Sensor / Wall / Mouse / NewGameObject、TextBox / DialogBox、Sprite、Body / TiledMapBodies、draw_line / set_gravity / debug / tracer / speed / random_pos / bgpic、 鼠标与键盘查询函数。 - 资源缓存(
ResourceManager)是进程内共享的:图片/字体只解码一次,两个世界共用。 - 相机不再全局唯一:
World().CAMERA属于各自的世界,Camera((宽, 高))会新建实例。
📷 相机手感(抖动 / 跟随死区 / 平滑缩放)
from Walimaker import *
hero = Character("hero.png", size=(32, 32))
camera = global_var.CAMERA
camera.follow(hero) # 跟随角色
camera.deadzone = (40, 30) # 在 80x60 的死区内移动时相机不动(默认 0 = 严格居中)
camera.zoom_to(2.0, speed=1.5) # 平滑缩放到 2 倍(每秒变化 1.5)
camera.smooth_zoom = True # 缩放时用 smoothscale(更平滑,但比 scale 慢)
camera.shake(amount=8, duration=0.3) # 被打中 / 爆炸时抖一下
这些都默认关闭(deadzone=(0,0)、smooth_zoom=False、不抖动),因此不影响既有项目。
🔗 把两个物体连起来(约束)
from Walimaker import *
a = Character("a.png", size=(32, 32))
b = Character("b.png", size=(32, 32))
a.goto(-50, 0)
b.goto(50, 0)
connect(a, b) # 刚性杆:保持当前距离(pymunk.PinJoint)
Spring(a, b, rest_length=100, stiffness=200) # 弹簧:把距离拉回 rest_length(DampedSpring)
两者都接受游戏对象或物理层的 Body,并自动把关节加到对象所属世界的空间;
距离/劲度/阻尼可以直接读改(spring.rest_length = 80)。
🗺️ TileMap:铺成背景 / 取出对象层
from Walimaker import *
tiled = TiledMap("map.tmx")
# 1) 把整张地图当背景铺上(相机尺寸自动设成地图大小),返回背景对象
bg = bgpic(tiled)
# 2) 把对象层里的对象变成可碰撞的游戏对象(每个对象一个 POLY 刚体)
# TMX 图块对象会自动带上贴图;也可以用 images={"对象名": 图片} 指定
objects = tiled.create_objects() # 全部
spawns = tiled.create_objects(name="spawn") # 按名字过滤
for obj in objects:
print(obj.name, obj.properties, tuple(obj.pos))
# 想自己建对象也行:直接看解析结果(几何 + 属性)
for obj in tiled.get_objects():
print(obj.name, obj.x, obj.y, obj.points)
状态机与动画控制
from Walimaker import *
character = Character({
"idle": ["idle_1.png", "idle_2.png"],
"walk": ["walk_1.png", "walk_2.png", "walk_3.png"],
"jump": ["jump_1.png", "jump_2.png"]
})
# 设置动画参数
character.set_dt("walk", 0.1) # 走路动画每帧0.1秒
character.set_next_state("walk", "idle") # 走路结束后回到空闲状态
# 状态切换回调
def on_jump_start():
print("开始跳跃!")
def on_jump_end():
print("跳跃结束!")
character.state = "idle"
character.set_start_func("jump", on_jump_start)
character.set_end_func("jump", on_jump_end)
# 切换状态
character.state = "walk" # 开始走路
character.state = "jump" # 开始跳跃(触发回调)
资源管理
from Walimaker import *
from Walimaker.config import global_var
# 预加载资源(顶层 API,避免第一次使用时卡顿)
preload({
"images": ["player.png", "enemy.png", "background.png"],
"fonts": [(None, 24), (None, 36)], # None = 自动选择中文字体
"sounds": ["jump.wav", "collect.wav"]
})
# 查看缓存状态
cache_info = global_var.RESOURCE_MANAGER.get_cache_info()
print(f"已缓存图片: {cache_info['images']['current_size']}张")
print(f"已缓存字体: {cache_info['fonts']['current_size']}种")
# 清理缓存
global_var.RESOURCE_MANAGER.clear_cache("image") # 仅清理图片缓存
图片/字体/音效用 LRU 缓存;碰撞 mask 用弱引用缓存——同一个 Surface 只构建一次, Surface 被回收后缓存条目自动消失,不会把临时 Surface 一直留在内存里。
🅰️ 中文字体
从 2.3.0 起包内不再携带字体文件(原先的 simkai.ttf + simsun.ttc 合计 28.6 MB,
使 wheel 接近 16 MB,且属于微软授权字体不允许再分发)。TextBox / DialogBox
的字体改为运行时按顺序解析:
| 顺序 | 来源 | 说明 |
|---|---|---|
| 1 | 显式传入路径 | TextBox(25, font=r"C:\Windows\Fonts\simhei.ttf") |
| 2 | 环境变量 WALIMAKER_FONT |
机房统一字体:set WALIMAKER_FONT=D:\fonts\SourceHanSansSC.otf |
| 3 | 包内 Walimaker/static/ |
把任意 ttf/ttc/otf 丢进去即可,无需改代码 |
| 4 | 操作系统中文字体 | Windows 微软雅黑/黑体/宋体;macOS 苹方/冬青黑体;Linux Noto CJK/文泉驿 |
| 5 | pygame 默认字体 | 任何平台都存在,但不含中文字形(中文显示成方框) |
-
找不到字体不会报错:只发出一次中文 + 英文的
RuntimeWarning,程序继续运行; 仅当“显式指定的字体文件确实存在但已损坏”时才抛出错误。 -
排查中文显示成方框:
from Walimaker.fonts import font_info print(font_info()) # {'path': '/System/Library/Fonts/Hiragino Sans GB.ttc', 'source': 'system', # 'source_label': '操作系统中文字体', 'has_cjk': True}
若
has_cjk为False,说明系统里没有中文字体(常见于精简 Linux / Docker 镜像), 安装fonts-noto-cjk(Debian/Ubuntu:apt install fonts-noto-cjk)或设置WALIMAKER_FONT指向一个中文字体文件即可。只跑逻辑、不显示画面 (SDL_VIDEODRIVER=dummy)的场景不受影响。
📊 性能优化建议
最佳实践
- 资源复用:尽量复用Character对象,避免频繁创建销毁
- 动画优化:使用精灵表和状态机,减少Draw Call
- 物理优化:将静态物体设为STATIC类型,减少物理计算
- 内存管理:使用resource_manager的预加载功能
- 批处理:相似的对象尽量使用相同的材质和大小
常见性能问题
-
问题: 游戏卡顿,FPS下降
-
检查: 使用
debug()模式查看物理调试绘制 -
解决: 减少同时活动的物理对象数量
-
问题: 内存占用过高
-
检查: 查看resource_manager缓存状态
-
解决: 调整缓存大小或手动清理缓存
🧪 测试示例
查看 Walimaker/test.py 获取更多完整的游戏示例:
- 平台跳跃游戏
- 弹球物理模拟
- TileMap使用示例
- UI交互演示
🤝 贡献指南
欢迎贡献代码!请遵循以下步骤:
- Fork项目
- 创建功能分支 (
git checkout -b feature/AmazingFeature) - 提交修改 (
git commit -m 'Add some AmazingFeature') - 推送分支 (
git push origin feature/AmazingFeature) - 开启Pull Request
代码规范
- 遵循 PEP 8 编码规范
- 使用 类型注解 (Python 3.7+)
- 注释:重要功能和复杂逻辑需要注释
- 测试:新增功能需包含测试用例
📄 许可证
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。
📞 支持与反馈
- 文档问题 / Bug 报告:附上重现步骤、错误日志与运行环境(Python、pygame、pymunk 版本)
- 功能建议:欢迎直接反馈
- 版本与更新日志:见 PyPI 项目页 与仓库根目录的
CHANGELOG.md
🙏 致谢
感谢以下开源项目:
🚀 下一步计划(Roadmap)
诚信说明:早期版本的介绍里曾把下面几项列为「已实现特性」,实际尚未落地。 现在统一移到 Roadmap,未做就是未做;欢迎反馈你最想要哪一个。
- 代码热重载(改代码即时生效,无需重启)
- 可视化编辑器
- 插件 / 组件系统
- 常用 UI 控件(按钮、输入框、列表…)
- 触控 / 移动端手势
- WebAssembly 支持(让 Walimaker 在浏览器中运行)
- 3D 渲染扩展(基于 OpenGL)
- 网络多人游戏支持
- 更多教学资源和示例
🧭 坐标系说明
- 坐标系统:笛卡尔坐标系,原点位于窗口左上角
- 角度系统:0°指向右侧,逆时针方向角度增加
- 颜色值范围:RGB通道 0-255,透明度 0-255
- 音量控制:0.0(静音)到 1.0(最大音量)
- 物理单位:像素为单位,重力默认 900 像素/秒²
教学提示:Walimaker的设计目标是让编程初学者能够在30分钟内制作出第一个可玩的游戏。从简单到复杂,循序渐进地学习游戏开发的核心概念。
Metadata
Release files for walimaker 3.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| walimaker-3.1.0.tar.gz | 230.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| walimaker-3.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 445.7 kB
Release files / walimaker-3.1.0.tar.gz
| Download URL | walimaker-3.1.0.tar.gz |
|---|---|
| Size | 230.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a192120d3ab90cba79b4a76b2e3dba078b4437e6241fe986cf51b2a542855482
|
|
BLAKE2b-256 checksum How to use checksums |
201391ef74b21900b30a0b99573c8e84dff9fc6109f7d93dfad46ba46958a12e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / walimaker-3.1.0-py3-none-any.whl
| Download URL | walimaker-3.1.0-py3-none-any.whl |
|---|---|
| Size | 215.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
11fa2f84ff7cde974335e0615725eb738ce234381f155a556dc54f894809ace9
|
|
BLAKE2b-256 checksum How to use checksums |
fd3493ce4c55ea892987f7bae7e342ed58ffca148be5963c9e39d3300c2e3f53
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|