菜鸟学到的吐血教训:别写类似ds_list[| 0] = [ds_map1,"aaa",0]这样的代码……
因为在做一个带有卡牌要素的游戏,用ds_map和ds_list管理卡牌信息、牌序等等十分方便,于是当时就随手写出了类似ds_list[| 0] = [ds_map1,"aaa",0]这样的代码。现在想写存档系统了,结果一看教程,懵逼了。如果需要通过json_encode这种函数将ds数据转化为json,同时又是ds_map中含有ds_list或者ds_list中含有ds_map这种情况时,需要先使用ds_list_mark_as_map、ds_map_add_list等函数让ds_map和ds_list可以被正确写入和读取。而如果是前面这种ds_list含数组,数组里又含ds_map的形式,ds_list_mark_as_map、ds_map_add_list等函数貌似就不适用了,转成json来存档读档就会出错。于是乎不得不把ds连同相关的自定义function也改一遍……不幸中的万幸就是这部分代码本来就是刚学GMS的时候写的,也该优化了……
总之给同为新手的朋友一句话:如果想用json的格式来保存存档信息,就千万别因为一时方便就写成类似ds_list[| 0] = [ds_map1,"aaa",0]这样的代码,可以写成ds_list[| 0]=ds_map1; ds_map1[? "string"]="aaa"; ds_map[? "number"]=0;这样,把"aaa"、0这类写在ds_map里,才能正常用json函数创建/读取存档文件……
不过也可能有把ds_list[| 0] = [ds_map1,"aaa",0]这种函数正常转写成json的方法,只不过我太菜没注意到……
总之,供各位朋友参考了……含泪发布。
【GameMaker: Studio】instance_place和instance_position和一个小坑
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,我记住你了,以后走夜路给我小心点……
[求教]请问基于回合制的buff和debuff的实现,是否有比较便捷的方式?
如题,个人在尝试做一款基于回合制的游戏,因为会涉及到大量的buff和debuff,按照我目前粗略的想法,是在player和enemy的parent的create event中创建个名为buff的ds_map,并在step event中检测ds_map是否包含某项buff,如atk_up,def_up等,当然某些角色特有的buff会放在具体的obj的step里,然后具体呈现在角色上的特效,就在draw事件里判断并绘制了。虽然也能够实现,但感觉这个想法的开发效率和维护效率不太高……
不知道哪位大佬有比较高效或者便于维护的实现方式?感谢指教0.0
请教点GUI方面的问题,关于DRAW GUI耗费的性能是否比直接做成背景贴图要大很多?
如题,在设计GUI时因个人喜好原因,给画面上下加了很大的边框,于是问题来了:
1.直接将一个宽度为360,高度为100左右的图片素材作为GUI素材绘制(色彩比较少所以实际并不算大),是否比直接通过内置的绘图程序绘制大面积的色块区域,然后再导入边角装饰的线条之类,耗费的性能大得多?如果有差但差别不大的话我就打算直接用简单粗暴的方法搞算了……
2.如果直接将这部分直接贴到背景图层上,耗费的资源是否要比通过DRAW GUI绘制要小得多?(啊嘞?背景图层能不能放到实例图层上面来着?忘记了……)
以上,望知道的大佬解惑,手动比心