找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 788|回复: 5

[经验] 实现鼠标点击效果

[复制链接]
发表于 2023-12-17 00:37:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
由于一些原因,我尝试写一个鼠标点击效果的功能,一开始没什么思路,逛了一圈国内外论坛也不太行。最后自己琢磨了个不是很完美的办法。

[RenPy] 纯文本查看 复制代码
# 序列帧动画
image fire:
    zoom 0.2

    "images/fire/gif_frame01.png"
    0.01
    "images/fire/gif_frame02.png"
    0.01
    "images/fire/gif_frame03.png"
    0.01
    "images/fire/gif_frame04.png"
    0.01
    "images/fire/gif_frame05.png"
    0.01
    "images/fire/gif_frame06.png"
    0.01
    "images/fire/gif_frame07.png"
    0.01
    "images/fire/gif_frame08.png"
    0.01
    "images/fire/gif_frame09.png"
    0.01
    "images/fire/gif_frame10.png"
    0.01
    "images/fire/gif_frame11.png"
    0.01
    "images/fire/gif_frame12.png"
    0.01
    "images/fire/gif_frame13.png"
    0.01
    "images/fire/gif_frame14.png"
    0.01
    "images/fire/gif_frame15.png"
    0.01
    "images/fire/gif_frame16.png"
    0.01
    "images/fire/gif_frame17.png"
    0.01
    "images/fire/gif_frame18.png"
    0.01
    "images/fire/gif_frame19.png"
    0.01


screen mouse_effect:
    default able = False
    $ x, y = renpy.get_mouse_pos()

    if able:
        add "fire" xpos x - 48 ypos y - 53

    key "mousedown_1" action SetScreenVariable("able", True) capture False
    key "mouseup_1" action SetScreenVariable("able", False) capture False



使用方法:复制代码后,在你每个需要有点击效果的界面末尾添加 use mouse_effect


如果有更好的解决方案请在帖子下面回复,谢谢!
发表于 2023-12-20 14:24:51 | 显示全部楼层
本帖最后由 被诅咒的章鱼 于 2023-12-20 14:27 编辑
ZYKsslm 发表于 2023-12-18 22:11
有个BUG不知道怎么修改,就是点击一下显示画面后,不移动鼠标再次点击就没有效果了 ...

这不算是个bug,而是Ren'Py的feature(嘴硬)!


我加了几行打印日志并调试过,任何鼠标点击都是可以进入到 add "fire" 那行的。但在鼠标坐标不变的情况下,Ren'Py此时认为 "fire" 已经在界面上了,并且所有transform的特性都完全一样,唯一性检查 Displayable._unique() 之后认为不需要再重新绘制一次,就什么也不做了。所以用楼主思路是没有办法解决的……
----------------------------------------------------------------------------------------------------------------

扯了些有的没的,解决方案是去掉 add "fire" ,直接捕获鼠标点击事件并显示一个可视组件。
[RenPy] 纯文本查看 复制代码
init python:
        
    def display_clickFX():
        x, y = renpy.get_mouse_pos()
        renpy.show("fire", at_list=[mouse_pos_trans(x, y)], layer='aboveall')

transform mouse_pos_trans(x, y):
    #这两个偏移量建议也改成参数
    xpos x-48
    ypos y-53

screen mouse_effect:
    key "mousedown_1" action Function(display_clickFX)


注意,renpy.show 中指定显示图层为“aboveall”,是为了保证该动画尽可能显示在其他图层上面,而不是被遮挡。(不使用“overlay”的原因是,mouse_effect 界面已经显示在overlay固定显示,renpy.show无法在同层的action中显示其他内容,很傻逼。)另外,需要在options.rpy中增加该图层:
[RenPy] 纯文本查看 复制代码
define config.layers = ['master', 'background', 'middle', 'forward', 'transient', 'screens', 'overlay', 'aboveall']


此外,之前的 config.overlay_screens 不能在菜单界面中生效,需要更强力的:
[RenPy] 纯文本查看 复制代码
define config.always_shown_screens = ['mouse_effect']



----------------------------------------------------------------------------------------------------------------

最后再扩展一下,简单说明一下满足楼主需求的通用设计方案:

楼主的核心需求是鼠标点击之后在画面上“显示”一个图像(序列帧)。图像(序列帧)是预先定义好的,唯一的变量只有鼠标坐标。我们可以在捕获鼠标点击事件时很容易地得到鼠标坐标。
接着就要设置一个始终显示的“图层”来“显示”之前定义的图像(序列帧)。该“图层”需要始终在其他所有图层上面,并且不影响其他图层的鼠标点击事件。这个“图层”具体的实现有多种方式,可以是layer、screen、component等等,不同的引擎有不同的方案。

此时有个关键问题在“显示”的定义和实现方法上。我们可以在图层上预先添加一个图像(序列帧),然后根据鼠标点击事件修改该图像(序列帧)的位置,也就是楼主的方案。可行,但不够好。另一种通用方案是,在捕获鼠标点击事件后,在对应坐标实时增加一个图像(序列帧)。也就是说,鼠标点了很多次之后,图层上会同时存在很多个图像(序列帧)。此时鼠标多次点击后可以在画面上看到多个动画,并且每一个都能完整播放。这会带来另一个问题,随着图像越来越多,占用内存越来越多,应用越来越卡……应对这个新问题时,我们可以在图像(序列帧)显示完毕后销毁(调用析构函数)。这种方法在大多数时候都够用,但在鼠标点击这种频发事件中新建对象和销毁对象都是会占用不少资源,可能会带来卡顿。更好的通用方案为“资源池”。“资源池”可以是任意容器,容器内的元素类型为图像(序列帧)对应的类。每次需要显示图像(序列帧)时都从“资源池”申请,如果资源池内有“空闲”的元素则从资源池弹出和“激活”该元素并移动到鼠标位置开始播放,如果资源池内没有“空闲”元素则重新生成一个对应类型元素并移动到鼠标位置开始播放。每个元素——图像(序列帧)需要在播放完毕后通过回调函数将自身重新加入到资源池。

由于我对Ren'Py不熟,所以不清楚怎样具体实现以上方案。楼主有空可以实现一下……
回复 支持 1 抱歉 0

使用道具 举报

发表于 2023-12-18 10:51:43 | 显示全部楼层
有两点改进建议:

1.序列帧"fire"最后会停止在“gif_frame19.png”。可以在资源层面上将这帧处理为完全透明的png图片,也可以在这帧后面再加一句 Null() 保证图片最终为空白。

2.直接把界面 mouse_effect 设置为最上层一直显示更方便一些。
[RenPy] 纯文本查看 复制代码
define config.overlay_screens = ['mouse_effect']

毕竟是鼠标点击就要出现,各个界面反复添加 use mouse_effect 比较麻烦,也可能会出现多次重复显示的问题。
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2023-12-18 22:06:01 | 显示全部楼层
被诅咒的章鱼 发表于 2023-12-18 10:51
有两点改进建议:

1.序列帧"fire"最后会停止在“gif_frame19.png”。可以在资源层面上将这帧处理为完全透 ...

感谢!
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2023-12-18 22:11:13 | 显示全部楼层
有个BUG不知道怎么修改,就是点击一下显示画面后,不移动鼠标再次点击就没有效果了
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2023-12-20 22:03:18 | 显示全部楼层
被诅咒的章鱼 发表于 2023-12-20 14:24
这不算是个bug,而是Ren'Py的feature(嘴硬)!
由于我对Ren'Py不熟

6。

感谢大佬
回复 支持 抱歉

使用道具 举报

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

本版积分规则

小黑屋|手机版|RenPy中文空间 ( 苏ICP备17067825号|苏公网安备 32092302000068号 )

GMT+8, 2024-12-22 19:52 , Processed in 0.126749 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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