关键词:GAMA,几何运算,二次开发
有想过在YJK里面玩游戏吗?
在YJK-GAMA中拉了这些卡片以后,我做出了一个贪吃蛇。
有朋友会想,不管是GAMA还是YJK,好像都没办法用方向键控制,所以这个贪吃蛇其实是这么控制的↓
为什么选择制作贪吃蛇呢,因为
-
贪吃蛇的简单线条可以用到GAMA的一些几何运算卡片(最近点、交点等)。
-
GAMA未提供的现有功能,也可以借助二次开发自行实现。
接下来,我们看看这个项目ProjectSnake
是如何完成的。
控制器(输入)
实现形式:布尔按钮+即时编译卡片
GAMA能够捕获我的键盘输入的方向键,但是并没有现成的卡片能够接受键盘指令。我想到了一种折中的办法,用布尔按钮
+鼠标点击来模拟方向键,就像这样:
布尔按钮
布尔按钮在GAMA中很常用。简单来说,点击布尔按钮会向后传递一次true,其他时候均保持false。点击布尔按钮时,就和鼠标键的按下弹起两个动作一样,布尔按钮向后方传递的数据会经历false->true,true->false的过程。由于中间发生了数据变化,会触发相应的后续运算。
这个布尔按钮的样子是否让你想到了青葱岁月?
在布尔按钮后面,我还写了一个即时编译的自定义卡片
来处理方向键的信息,并继续向后传递方向向量数据,从而在后续卡片控制蛇的前进方向。
GAMA二次开发
GAMA目前支持C#二次开发,有两种形式:外部编译(官方教程)以及GAMA界面中的C#代码编译器卡片(即时编译,目前暂未支持自动补全,只能虚空编程),两者都可以引用到用于开发现有卡片的更底层的函数。
通常来说,如果只是写简单脚本、临时测试、熟悉C#或GAMA二次开发的API,使用C#代码编译器卡片。如果需要系统性编程和更好的IDE环境,追求更高的效率,使用外部编译进行二次开发。
本文统称自定义卡片。
输出
实现形式:无需实现
GAMA已定义卡片和自定义卡片都会自动将出口可识别类型的对象扔进渲染器,并在YJK的窗口中渲染。而蛇显然可以用一个多段直线来表达,这是GAMA中支持的数据类型,因此这一步不需要额外考虑。这也是比纯代码编程写游戏方便的地方。
时间和帧数
实现形式:二次开发 – 画布rebuild函数
相比于游戏中根据帧数需求每秒就要计算很多次,我们并不会让GAMA没事就重新计算建模数据,因此GAMA被设计为只在入口数据变化时触发重新运算。
帧
动画、游戏、电影相似的地方在于,可以理解为先创作/制作一帧帧图像,然后连起来呈现出了动态。制作游戏时需要考虑每帧的数据是怎么计算的。
在通常情况下,如果我在YJK-GAMA中用多段线绘出了一条蛇,如果不改变什么数据,它不会自己动起来。即使是点击方向键触发了蛇的数据计算,蛇只会在我点击方向键的时候动一下。
因此,这个会改变GAMA基本运行模式的功能只能通过二次开发
实现。
持续触发重新计算只需要一个函数(笔者也是问了负责开发的某螃蟹才知道),我将其写在了一个C#自定义卡片
中(下图的计时器),可以理解为持续往后传输一个自增的数据,这样就可以持续触发后续卡片的重新计算。
同时,控制自增间隔也就相当于控制了帧数。
全局变量
实现形式:二次开发 – 定义静态字段
正向数据流和循环
在考虑这个问题时就会意识到,GAMA和大部分低代码平台一样,主要提供正向数据流,并未直接提供卡片数据的循环、递归功能,因为它们大幅提高数据流的复杂度。
一个简单的例子 – 套娃
GAMA设计为禁止将下游卡片的输出连到上游卡片(循环),这可能会导致数据没有来源。
修改上游数据
但是只有正向数据流也带来一个问题。在GAMA中,我如果只想静默修改一个上游数据,而不触发后续运算,直接连卡片是做不到的。
一个简单的例子 – 蛇的长度变化
在正常的顺序流程中,需要通过蛇的长度来生成蛇的多段线,但在蛇与食物发生交互时,又会触发蛇长度增加,然后继续上述循环。
这个流程如果直接操作卡片连线就会触发循环调用错误。
因此,又需要使出万能的二次开发。
对于这个问题,我采用的解决方案是,在自定义卡片类中定义静态字段,这样可以通过接受this反射静态字段或者引用类(外部编译的卡片可以拿到类名)来直接修改类静态字段。
在后面的碰撞设计中,我采用的方式也是去修改一个上游自定义卡片类的静态的bool字段,然后触发相应碰撞事件。
元素交互与碰撞
实现形式:几何运算卡片 + 二次开发
游戏中一个必不可少的计算就是碰撞
。贪吃蛇中包含的元素和碰撞事件有:
-
元素:至少有[蛇]、[食物]、[墙]。
-
碰撞事件:至少有[game over]、[蛇变长]、[食物重新生成]。
而贪吃蛇的逻辑也很简单,他们之间发生碰撞,就会触发直观的结果:
-
[蛇]与[自己]碰撞 – [game over]
-
[蛇]与[墙]碰撞 – [game over]
-
[蛇]与[食物]碰撞 – [蛇变长]、[食物重新生成]
将这个问题进一步抽象,蛇是多段线SnakePolyline,墙也是多段线BoundPolyline,食物是一个点FoodPoint,因此他们的碰撞行为等同于:
-
蛇与自己碰撞 – SnakePolyline自交,GAMA中可以:
-
拆分SnakePolyline为一组直线(GAMA中暂未实现,通过自定义卡片实现)。
-
这组直线调用
打断一组线条
卡片,即获得交点集合。(GAMA中的实现包含了端点,不满足第3步的需求,因此这个卡片也重新实现了)。 -
交点集合的尺寸大于0,则发生了碰撞,触发事件 – game over。
-
蛇与墙碰撞 – SnakePolyline和BoundPolyline求交点,GAMA中可以:
-
拆分SnakePolyline为一组直线(同上)。
-
使用
曲线曲线相交
卡片计算这组直线和BoundPolyline的交点。 -
交点集合的尺寸大于0,则发生了碰撞,触发事件 – game over。
-
蛇与食物碰撞
-
使用
最近点
卡片计算SnakePolyline到食物的距离。 -
如果距离接近0,则发生了碰撞,触发事件 – 蛇变长、食物重新生成。
类设计
结合前面分析的需求设计以下类型,细节不赘述。有兴趣的朋友可以看看文末分享的一种实现。
蛇
-
长度
-
速度
-
方向
-
轨迹
-
移动()
-
生成蛇体多段线()
-
静默触发 – 长度增加()
-
静默触发 – 停止移动()
-
…
食物生成器
-
生成食物
-
静默触发 – 生成新的随机食物()
-
…
相关资源
下载链接 https://pan.baidu.com/s/1zJoIW9C3BU3Do8x5Z_wAdw 提取码: qjn8
其中crd文件需要放入已安装GAMA的电脑的以下文件夹内
C:Users<<您的电脑登录用户名称>>AppDataRoamingyjkSoftPenguin
资源中含ProjectSnake相关外部编译卡片的源代码,可直接编译,使用教程见官方教程。
11.11,YJK-GAMA公测开启
加入QQ群,您有机会成为我们
首批尊贵用户
转自:非解构-公众号
转自:非解构-公众号