instance_place和instance_position,无论名字还是功能,都是非常接近的两个函数,其作用都是检测给定的坐标值上是否有指定的对象存在,如果有,就返回该对象的唯一ID。一眼看上去,差别相当细微。
不过,坑往往就在非常细微的差别之中。
昨天,我就踩进这个坑里去了。
事情是这样的,昨天晚上弄demo时,我惊讶地发现明明在房间a可以正常触发的事件,在房间b就怎么都触发不了了。
触发事件的代码思路很简单,检测鼠标是否在事件触发对象的碰撞遮罩(collision mask)上,如果是,用变量x记录该对象的唯一ID,变量x默认为noone,所以当x != noone时,按下鼠标左键,就能触发事件,会弹出一段文字。
为了查错,我把变量x的值画出来一看,结果发现在房间b中无论我如何把鼠标对准目标对象,得到的都是-4(即noone的值),而在房间a中就能十分顺利地获取ID。正因为在房间a事件是可以正常触发的,我没有第一时间怀疑问题出在触发事件的代码本身上,而是怀疑是否自己漏掉了什么条件,或者哪里的代码干扰了事件的正常触发。
然后就开始各种查错……
最后发现,原来之所以触发不了这个事件,是因为需要房间至少有两个该事件在,才能正确触发,而房间b里只有一个该事件存在,因此无法触发,添加一个之后也能正常工作了……
想了想,我是通过在该对象的step里,用instance_place(mouse_x,mouse_y,该对象ID)来检测的,然后悲剧就发生了……
为了查明原因,我仔细看了一遍instance_place的官方描述:
With this function you can check a position for a collision with another instance or all instances of an object using the collision mask of the instance that runs the code for the check. When you use this you are effectively asking GameMaker Studio 2 to move the instance to the new position, check for a collision, move back and tell you if a collision was found or not. This will work for precise collisions, but only if both the instance and the object being checked for have precise collision masks selected otherwise only bounding box collisions are applied...
也就是说,instance_place这个函数的工作原理,和碰瓷差不多,是把一个实例移到指定的坐标点,去碰另一个实例,如果碰到了,就返回被碰瓷实例的唯一ID。所以我在房间b的做法,无异于让触发事件的对象自己去碰自己,自然碰不到了。
然而,因为instance_place函数本身并不需要你填入用哪个实例来碰瓷,所以我一开始就没注意到这个工作原理。实现此类事件的正确做法,是用instance_position,这个函数就不是基于用实例碰瓷来判断的了(当然也享受不了实例的碰撞体积了),事件立刻可以正常触发了。
instance_place,我记住你了,以后走夜路给我小心点……
暂无关于此日志的评论。