查看: 84|回复: 0

[转载发布] 【脚本库+】Aprite感知精灵库

[复制链接]
  • TA的每日心情
    开心
    5 天前
  • 签到天数: 33 天

    连续签到: 1 天

    [LV.5]常住居民I

    2022

    主题

    32

    回帖

    7144

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    0
    卡币
    5074
    OK点
    16
    积分
    7144
    发表于 同元一千年八月八日(秋) | 显示全部楼层 |阅读模式
    0x001 前言:什么是Aprite?它能做什么?
            Aprite是一个基于Sprite升级的精灵库,它的出现其目的是为了简化脚本工作者(后面简称 程序狗)的工作量,使得开发效率适当的提升。Aprite创建的初衷是使得在创建简易动画特效,简单事件触发上更加容易。目前Aprite还处在一个弱demo时期,正在一步步升级强大起来,它现在的主要构成是由 感知精灵管理器 和 感知精灵库 一同构成,管理器是为了更加方便和集中化的管理我们使用Aprite创建出来的精灵。那么,说这么多也是口水话,不如让我们来尝试学习一下Aprite的使用吧!

    0x002 让我们从显示开始
            尝试输入如下代码:
            player = Aprite.new
            loop do
              $Aprite_manager.update
              Graphics.update
              Input.update
            end
            此时保存并且运行游戏,就会发现在屏幕上有一个 100*100 的红色矩形。

           我们可以看出,在创建默认Aprite的时候,它自动为你初始化了一个 100*100 红色矩形 Bitmap对象,如果你不满意这个红色方块,你可以通过它的bitmap属性替换,在上述代码中,你可以再起一行写上: player.bitmap = Bitmap.new(xxxx),这样你就可以为Aprite对象更换材质了。我们发现,和传统意义上不同了,这里我们没有再单独的为Aprite对象进行更新了,我们直接使用$Aprite_manager.update来做精灵的更新,这样,无论你有多少个Aprite,它都会帮你集群化的更新,是不是很方便?其实,Aprite是继承于Sprite的,所以Sprite存在的方法属性,在Aprite上同样适用。


    0x003 从一句单行动画命令开始
            Aprite的主要特性是简易动画,那我们看看它---到底可以有多简单?我们在上述代码的基础上写下了如下代码:
                player.run( "width 0 100 50" )
            我们来测试一下运行效果,可以看出,启动后那个小红块的宽度正在慢慢变长... ...

            没错,只要这么简单就能实现一个简易的线性动画,run方法一次性只能执行一句  动画指令,对于动画指令来说,其实很容易理解,就上述动画指令解释( width 0 100 50 ),可以直观的翻译成:让宽度从0到100,用时30帧。是不是很容易理解?同理,现在我随便写一句动画指令,都可以被这么直观的翻译出来,比如  moveX 0 20 10,这一句就是指x方向移动从0到20,用时10帧... ...很简单的就实现了我们要的线性动画效果,那么,目前都有哪些动画指令呢?请看下表:
    sx 在前面带有s是指精灵的位图传送矩阵,sx就是该传送矩阵的x(传送矩阵是相对bitmap位图进行变换的,用它可以实现人物行走动画)
    sy 传送矩阵的x
    sheight 传送矩阵的高
    swidth 传送矩阵的宽
    fade 淡入淡出效果(也指透明度),变换的值最小为0,最大255
    width 宽度(这个的变换是会拉升图像)
    height 高度(这个的变换是会拉升图像)
    moveX x坐标
    moveY y坐标
    rotate 旋转角度(这个比较影响性能)
    wait 只接受一个参数,就是等待的帧数
    autowait 无参数,自动判断等待时间
    do 设置一个标记点
    loop 跳转到最近的一个do标记点,如果没有,则跳转到第一条指令

    0x004 利用scan来写动画脚本
            上述的动画利用run来实现的,但是前面也说了,run一次只执行一行指令,那么一些复杂点的线性动画都是很多简单线性动画合成的,一行是肯定不行,所以这里我们使用多行扫描指令scan,现在我们写下下列代码:
                animate = "width 0 100 50\n"
                animate = animate + "autowait\n"
                animate = animate + "do\n"
                animate = animate + "fade 255 160 20\n"
                animate = animate + "autowait\n"
                animate = animate + "fade 160 255 20\n"
                animate = animate + "autowait\n"
                animate = animate + "loop"
                player.scan( animate )
            
            看,通过多行命令,就成功的实现了一个多组合的动画效果,而且后面的闪烁效果会一直循环下去。讲到这里,我们必须要尝试了解一下Aprite代码的机制问题,这样能让你更加清楚它的运行流程,从而减少错误或者bug的产生。刚刚写的多行语句,被scan扫描后变成了单行语句存放在任务列表里,精灵每次刷新都会执行任务列表里的值,本让列表指针加一,如果任务列表指针下一次指向空,就不会再运行了,注意,此时动画虽然不再运行,但是任务列表里的任务还存在,这时候只要将指针更改到有效值,它依然会运行,这就是do-loop循环的机制,同时这也意味着一件事,如果我想更换动画效果怎么办?这里给开发者提供了一个方法就是  clear_task,并且将指针指向起点。

    0x005 人物行走帧动画的实现
            我们来尝试实现一下人物行走的帧动画,这里我们用的character里的4*4行走图,意味着每行有四个动作,四个动作完成一次行走,我们首先要将bitmap给Aprite,然后我们现在要限制显示区域了,不然它一次性显示全部就没有意义了。限制区域用src_rect来限制,这个是sprite对象的原生方法。对与动画,我们每一帧只需要让 sx 移动到下一个状态的雪碧图位置,即一次4帧行走可以看作sx从 width*0 ---> width*1 ---> width*2 ---> width*3 的这么一个过程,具体代码实现可以看下图:
            
            
            说实话,作为作者的我来说,我觉得这样实现确实有一点点麻烦,所以下一改版我会尝试变得让它更容易实现。

    0x006 它,是一个事件触发性的精灵
            没有听错,它带有基本的事件感知,由于是demo版,目前仅提供四种基本事件    聚焦 / 失焦 / 碰撞 / 控制器,每一个事件都有相应的事件触发方法,这一章将一一为大家讲解。
            ⚪focused与on_focus / on_blur事件
                    所有刚创建出来的精灵,都没有被聚焦即 focused = false,当focused从false --> true的时候,将会触发on_focus,并且会将管理器里其他所有精灵全部失焦(因为我们每次聚焦只能对一个精灵,不然就会歧义),我们来看看它能做什么吧。
                     
                   
            ⚪on_collision碰撞事件和点对点判断collisionInxy(x, y)函数
                    这里的碰撞事件与Unity3D不太相同,这里没有所谓的刚体,这里的碰撞也是矩形碰撞(考虑到RM性能问题),所有不支持多边形碰撞,当然由于demo版本,目前不止持精灵的绑定,后期可以通过精灵绑定实现多边形碰撞。什么情况下会触发on_collision事件呢?只要collisionInxy(x, y)方法了,它检测到碰撞物体了,就会触发,所有这里的碰撞是一种  可预知的碰撞, 这种碰撞机制是为了让开发者更容易的实现PID算法下的矫正。
            ⚪player玩家与control控制器
                    要想使控制器生效,你需要做两件事情,第一件事情,将它的player属性设置为true,第二件事情,它的状态应该被聚焦。这种情况下,刷新的时候,每一帧都会触发控制器,即control事件,如果你不想写control事件,没关系,每个Aprite都内置一个control默认事件,下面是内核代码,可以看一下内置的control事件长什么样。
                   

                    可以看出,默认控制器已经帮我们实现了方向的控制和碰撞的检测,这意味我们只需要写很少一部分代码就能实现控制了,快来看看如何做吧!
                   
                   
                    可以看见,就这么简单实现了控制,如果我们觉得它动的太慢,可以将speed属性写高一点就好了。

    0x007 一些细节
            1)关于Aprite是否影响性能?答案是肯定的,但是你把它当sprite使用,它的性能和sprite相当,用它做丰富的动画,随之而来的也是性能问题,这个问题就RM渲染机制暂时没办法解决,你可以尝试用论坛大佬的 RGD引擎 ,目前暂时没做对RGD引擎的兼容,也没做测试。
            2)每次转换场景时,我们应该销毁我们创建的精灵,因为有管理器的存在,可以直接使用$Aprite_manager.dispose。
            3)管理器的存在是为了更加好的集群化管理,我们应该善用管理器。

    0x008 关于未来版本的展望
            其实我最讨厌立flag,我希望能有更多的开发者协同开发和维护Aprite,毕竟它是开源的。有兴趣可以去我的 github 给个小星星。
            未来可能会加入:
                1)键盘和鼠标触发事件
                2)样式表和对应的样式语法
                3)component组件化
                4)内置更多便于开发的小方法
                5)基于bitmap上的图像处理
                6)精灵绑定和继承
                7)精灵计算,+ - * /

    0x009 代码Code




    GitHub晚一些再上传。























                 本帖来自P1论坛作者antilmid,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=477782  若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    天天去同能,天天有童年!
    回复 论坛版权

    使用道具 举报

    ahome_bigavatar:guest
    ahome_bigavatar:welcomelogin
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2024-5-3 09:17 , Processed in 0.050181 second(s), 44 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表