代码见 这里 。使用 python -m anp
可以打开一个 .reanim 动画播放器。在加载全部资源(耗时略长)后可以播放几乎所有动画。播放简单的动画不用加载资源。
解决性能问题
在之前的两篇文章中我们完成了一个能播放带有 attacher 层的动画的播放器,美中不足的就是性能不够,掉帧厉害。这里给出一个加速一倍的方法。
mypyc
把 Python 文件编译成 C,再把 C 编译成 .pyd 动态链接库,提供极大性能提升,使用 pip install mypy
安装。在这篇文章开头提到的代码中,mypyc anp/player.py
就可以编译了,什么都不用改。经我的眼睛观测发现大概能提升一倍性能。
我在实际使用中发现需要注意(大部分是因为 mypyc
用 mypy
这个强类型检查器引起的):
- 不能使用元类,所以继承
QGraphicsItem
等 Qt 类无法编译(它们都有一个连接器元类) - 对在特殊条件下不可能为
None
,但无法根据上下文自动推断出不可能为None
的变量使用assert ... is not None
。在这条语句之前添加if ... is None: return
也有同样的效果。 - 对于
@typing.overload
装饰的函数,记得在参数列表结尾添加/
,因为mypy
检查这样的函数,会检查是否所有符合声明的参数列表(包含关键字参数)都符合实现。比如def f(a: int, b: int) -> int
和def f(c: int, b: int) -> int
就不相符,因为(a=1, b=2)
满足第一种定义,但不满足第二种定义。而def f(a: int, b: int, /) -> int
和def f(c: int, b: int, /)
是符合的。
资源管理器
之前的文章中用到了 Resources
这个资源管理器,这里提供实现方式。
Resources
使用单例模式,用 Resources.instances()
获取实例。内部有 anim_cache
, img_cache
缓存动画和图片,都以名字为键。
_resources: 'Resources | None' = None
resources_root: Path = Path() # 填入植物大战僵尸可执行程序所在文件夹
REANIM_HEAD: Final = 'IMAGE_REANIM_'
class Resources:
def __init__(self):
self.img_chache: dict[str, QPixmap] = {
}
self.anim_cache: dict[str, Animation] = {
}
@staticmethod
def instance()