Godot4桌宠教程补充:对于拖拽的优化

大家好,我是致力于让所有画画人都学会编程的灰(微博@天外灰仙儿,CSDN@overpara灰)很多同学反映桌宠的拖拽过于卡顿,在这里我做一些补充!

对于不同的Godot版本和不同的操作系统下,确实有很大概率出现卡顿的情况,在这里我完全抄袭了B站up主@Shary的布丁 写的方法,再稍加了一丢丢改进,下面大家来跟我一起写。

大家之前用来拖拽的代码应该是在character脚本里的这一段:

我们来复习一下,这里就是用我们之前划好的Area_2d区域来监测输入事件,当事件是鼠标事件并且是右键点击的时候,就不停地把窗口的位置加上鼠标每一帧改变的位移。

这个方法在以前是有效的,但是这会导致系统频繁监测鼠标右键按下这个条件,就会让窗口跟随鼠标的速度会很慢,而且在每台电脑上都不一样。

我们先把这段代码屏蔽掉,用pass来占位。选中要屏蔽的行,然后按ctrl+k就可以屏蔽掉。加pass是因为Godot不允许出现空的代码块

在这里Shary的布丁老师用了一种很巧妙的方法,来规避掉之前那种每帧检测鼠标右键是否按下的方法。也就是当鼠标右键第一次按下的时候,我们记录一下此刻的鼠标位置并且允许拖拽。后续鼠标不管怎么动,桌宠都会跟随,虽然这个时候鼠标右键还不能松开,但其实系统已经不会检测右键按下这个事件了。然后当我们拖拽到想要的位置后,就可以松开右键,系统检测到右键松开就会禁止掉拖拽。

也就是说相比之前系统主动地每一帧监测鼠标右键是否按下,换成了被动的监听鼠标按下松开这两次而已。可以说真的是天才的想法! 

那我们这里就需要新建两个变量,用来储存允许拖拽的标志位can_drag,以及鼠标按下右键时的位置mouse_position。至于这里为什么我们要记录下当前的鼠标位置,我们先按下不表。

注意标志位是bool类型的,位置是Vector2i类型的,也就是二维整数向量,代表坐标

然后我们来判断一下event,也就是_input方法检测到的事件,是不是鼠标按键事件(InputEventMouseButton)。如果是的话判断一下是否是按下了鼠标右键(MOUSE_BUTTON_RIGHT)。

如果以上都满足,判断一下,是不是右键刚刚被按下(pressed)。

- 如果是的话,记录一下当前鼠标的位置(注意这里记录的是相对于游戏窗口的位置,不是相对于电脑屏幕的位置!),同时把can_flag置为true。

- 如果不是的话,一个按键要么是被按下,要么是松开嘛,所以这里else判断的是右键松开的话,就把can_drag置回false。

我们再来检测一下鼠标移动事件,如果can_drag为true并且鼠标移动(InputEventMouseMotion),就去执行窗口移动的操作。这里之所以把can_drag放在前面,是因为在代码里,如果and左边的事件不满足的话就不会去判断右边的事件,而右边这个鼠标移动会经常触发,把鼠标移动的判断放在左边会比较烧内存。

在这里为什么我们不用之前那个不停加鼠标相对位移的方法呢?因为以前那种计算方式也不稳定,在引擎里运行的时候好好的,导出exe后就卡的不行,所以这里采用了新的计算方式。

这里DisplayServer.window_set_position就是将当前窗口的位置设置为括号里的值。DisplayServer.mouse_get_position()就是获取屏幕上鼠标的位置,大家要注意和前面的get_global_mouse_position()区分一下。如果实在难以理解,大家可以在_physics_process方法里print一下两种坐标,就能理解了。

只要让窗口的位置等于“屏幕上的鼠标位置减去我们之前记录的鼠标相对于窗口的位置”,就可以造成一种窗口始终跟着我们鼠标走的假象啦!(再次感叹这位up主的天才想法!)

说的再明白点,就是不管是屏幕还是游戏窗口,坐标的原点(0,0)都是在左上角,假如你现在按下了右键,鼠标位置相对窗口位置(10,10),这个位置我们先记下来。然后只要你右键没松开,我们就会一直记录鼠标相对屏幕的位置,假如说此刻你鼠标就是在(0,0),也就是屏幕的左上角。那窗口在哪个位置才对呢?

如果窗口位置直接等于你鼠标位置了,那窗口的左上角和屏幕的左上角就对齐了吧,都是(0,0)。但是我们拖拽的时候,希望鼠标相对于窗口的位置是不变的,也就是窗口的位置要继续移动一个距离,这个距离等于我们之前记录的鼠标位置相对于窗口位置(10,10)。这里之所以用减的,因为对于屏幕和窗口来说,右和下是正值,左和上是负值!那我们之前记录的位置是(10,10),算是处于游戏窗口位置右下角10x10的地方,那么窗口自身的位置减去(10,10)的话相当于往左上角窜了10x10的位置,这样窗口(10,10)的位置不就自动喂到我们鼠标上了嘛

~如果还没有理解的话,不妨自己画个图试试,同时用一下我上面说的print大法~

这里也给大家留个小作业,感兴趣的也可以做一下。如果我想在拖拽的时候也加一个角色被拖拽的动画,并且不希望被对话和提醒打断,该怎么做呢?(这是微博博主@春雨假熊猫 已经做出来的想法哦!)

这里也给大家一个提示,如果大家只做了第一期的桌宠的话,可以好好利用一下can_drag这个标志位~如果大家第二期也做了的话,可以考虑在状态机里加一个“拖拽”这个状态!

好啦,这期教程到此为止,下课!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值