|
楼主 |
发表于 2024-8-18 14:39:36
|
显示全部楼层
本帖最后由 744865306 于 2024-8-18 14:42 编辑
图像进阶——仿射变换(实例演示)
事实上GF有预留一些宏定义之类的来帮助进行仿射变换,但我对图像研究不多,暂且不清楚这些,但我知道有这么几个宏定义控制sprite的仿射变换(sprite具体应该翻译成什么我并不清楚,但宝可梦图片是属于sprite)
这个宏定义控制缩放和旋转:
- #define AFFINEANIMCMD_FRAME(_xScale, _yScale, _rotation, _duration)
复制代码
_xScale和_yScale越大,缩放速度越快,这不是我们想要的缩放比例
接下来,我将缩短变量名方便称呼,x对应_xScale,y对应_yScale,d对应_duration,k是缩放比,我们有一个公式:
为了减少浮点数出现,我们接下来使用这样一个变形的公式:
在starter_choose.c中有如下程序控制开局选择宝可梦时,显示出的宝可梦图片大小:
- static const union AffineAnimCmd sAffineAnim_StarterPokemon[] =
- {
- AFFINEANIMCMD_FRAME(16, 16, 0, 0),
- AFFINEANIMCMD_FRAME(16, 16, 0, 15),
- AFFINEANIMCMD_END,
- };
复制代码
尝试将其修改为这样:
- static const union AffineAnimCmd gSpriteAffineAnim_StarterPokemon[] =
- {
- AFFINEANIMCMD_FRAME(8, 8, 0, 0),
- AFFINEANIMCMD_FRAME(8, 8, 0, 15),
- AFFINEANIMCMD_END,
- };
复制代码
此时我们得到了更小的图片,如图所示:
我们还可以进行旋转操作,1代表22.5度,所以我们可以写如下代码旋转90度:
- AFFINEANIMCMD_FRAME(16, 16, 0, 0),
- AFFINEANIMCMD_FRAME(16, 16, 0, 15),
- AFFINEANIMCMD_FRAME(16, 16, 0, 16),
- AFFINEANIMCMD_FRAME(-16, -16, -4, 16),
- AFFINEANIMCMD_END,
复制代码
值得一提的是,宏定义写仿射变换伴随着变换过程中的动画,因此你可以利用它们进行多次缩放来营造非常有趣的动画效果,rhh的pokeemerald-expansion中的极巨化动画就是这样的
以下是一些其他宏定义
控制仿射变换动画结束:
动画循环次数(我想rhh的极巨化应该就用了这个):
- AFFINEANIMCMD_LOOP(count)
复制代码
每行动画都存在一个AffineAnimCmd类型的数组中,你可以用这个语句跳转到第target+1行:
- AFFINEANIMCMD_JUMP(target)
复制代码
这个不清楚有啥效果,但它可以起到结束动画的效果:
- AFFINEANIMCMD_END_ALT(val)
复制代码
参考资料:
pokecommunity的Inmortal的帖子和Anon822的回复 |
|