我的战舰-制作游戏入门(三)坚持30秒

2021/1/13160 浏览游戏开发攻略
我的战舰-制作游戏入门(三)坚持30秒
这个教程我们来创建一个新的工程,名字叫“坚持30秒”,导入一个空机械命名为“主角”并随意拼装一个造型
TapTap
导入一个空地图,添加好主角对应的机械产生器
TapTap
在蓝色的“逻辑方块”中的“玩家加入房间事件”中添加生成玩家机械的逻辑
TapTap
这个游戏中我们不使用物理,所以拖动“零件变量/机械/M/开关物理”方法来关闭物理功能
TapTap
为了手动控制摄像机角度,在“主角”机械产生器的启动事件中,拖动“功能调用/系统/摄像机/设置摄像机目标和角度”方法并设置好参数
TapTap
进入测试后,镜头不再随着拖动转动了。
接下来我们让主角机械跟随鼠标移动。点击“主角”机械的“每帧循环”事件,添加一个新的方法,方法名字改为“手指触摸平面”
TapTap
拖动“功能调用/系统/输入/触摸位置”,得到鼠标或者手机触摸屏的位置,0,0代表左下角的位置,1,1代表右上角的位置
TapTap
拖动“功能调用/系统/屏幕/转换为分辨率”,作用是把刚才0~1的屏幕位置转换为分辨率,比如如果你的屏幕分辨率是1080*720,那么0.5,0.5的触摸位置就会换算为540,360
TapTap
拖动“功能调用/系统/屏幕/屏幕坐标到世界坐标”,作用时把屏幕空间上的坐标根据摄像机的位置和朝向变换到世界空间。
TapTap
拖动“功能调用/系统/摄像机/摄像机坐标”,并与之前的坐标相减,得到鼠标指向的方向
TapTap
调用“功能调用/系统/检测/射线与平面交点”功能得到鼠标指向的方向和水平面的交点
TapTap
最后拖动“当前零件/强制移动”让机械移动到这个位置即可,进入测试可以发现机械可以跟随鼠标移动了。
TapTap
接下来我们来增加敌人,回到工程目录,导入一个空的机械,简单编辑下造型,并选择核心,将喷漆改为红色
TapTap
TapTap
回到地图编辑器,同样的增加一个别名叫"AI"的机械产生器,机械选择“敌人”这个机械
TapTap
我们现在要随机生成敌人,因为我们在第一个教程里面就做过敌人的循环生成逻辑,我们可以打开第一个教程的工程,打开蓝色“逻辑方块”的启动事件,并找到那段代码
TapTap
你也可以直接复制下面这段代码
begincodeV1;
name:生成敌人;
1:Float i=fun create.float(Float 0);
2:while fun float.lt(var i:Float 10);
3: Mech ai=fun createAIMech(String AI:Float 0:Vector3 5,5,0:Vector3 0,0,1:Enum 0);
4: Float i=fun float.add(var i:Float 1);
endcode
别忘了回到我们的新工程,之前的这段代码里面敌人的坐标是固定的,我们来改成圆形上的随机位置,拖动“功能调用/创建变量/向量”
TapTap
拖动“功能调用/小数计算/随机数”
TapTap
拖动“功能调用/向量计算/绕轴旋转”
TapTap
这几行的功能是:
3:生成一个指向水平向右5米的坐标V
4:生成一个0~360之间的随机数
5:让坐标V沿着竖直方向旋转随机角度
这样循环中每次运行到第5行都能得到一个以地图0,0,0点为圆心,半径为5的一个圆上的坐标,将第6行坐标改为V,因为我们的主角默认阵营是0,这里将AI的阵营参数改为1,最后关闭AI机械的物理,
TapTap
进入测试可以看到生成了一圈的AI机械
TapTap
现在我们来给AI增加智能,点击敌人的机械产生器的“每帧循环”事件,拖动“地图/阵营/得到阵营机械列表”
TapTap
拖动“变量功能/玩家机械列表/读取机械”
TapTap
然后得到玩家机械的坐标和自己的坐标,并用向量减法得到距离
TapTap
这个方向就是我们要追踪玩家的移动方向,为了距离不同的时候移动速度不同,我们统一设置好方向的长度,然后用AI当前的位置加上这个方向计算出AI的新位置并移动AI
TapTap
6:拖动“变量功能/方向/设置长度”
7:拖动“功能调用/向量计算/加”
8:拖动“当前零件/强制移动”
这时进入测试可以看到AI会自动跟踪玩家了,但是可以发现这种AI有规律很容易躲避,所以需要增加一些随机性来提高难度。我们先来规划一下AI的思路,当AI离玩家较远时应该靠近玩家,当AI离玩家较近时,为了让玩家难以躲避,应该随机运动,所以我们先判断距离,在第5行计算出方向后判断长度,拖动“变量功能/方向/长度”
TapTap
拖动“如果/小数计算/小于”
TapTap
进入测试,可以发现敌人追踪到一定距离就不动了,这里为了让敌人随机运动,可以利用之前添加过的随机产生敌人的逻辑,我们可以打开蓝色的“逻辑方块”的“事件”中的方法
TapTap
点击右侧的菜单按钮,选择复制多行,复制3-5行,并回到刚才的敌人AI的代码中
TapTap
TapTap
点击右侧的菜单按钮,选择“黏贴代码到后面”,并增加如果距离小于等于10的代码
TapTap
这里得到的V是个0~360度随机朝向的方向,因为计算位置和强制移动的代码是两种条件下都要使用的,所以我们将第9-10行拖动到最外面,将12行的返回值改为“方向”并设置好第10行的长度使速度合理
TapTap
进入测试可以发现敌人靠近玩家后,会剧烈的抖动,这是因为每帧敌人都在改变方向,这并不是我们想要的,需要改成每间隔一段时间才改变一次,这里我们使用时间功能来实现。
拖动“功能调用/系统/当前时间”
TapTap
拖动“功能调用/创建变量/小数”到13行
TapTap
判断只有当前时间比上次变向时间间隔了0.5秒才进行一次变向
TapTap
再次进入测试,可以发现AI的难度已经很高了。由于是关闭了物理的方式移动,这里是无法使用机械的被撞击事件来处理伤害的,我们可以简单的使用距离来做判定,当距离较近时,判定删除玩家机械。
TapTap
测试后发现玩家死亡时会有一个报错
TapTap
这是因为玩家的机械死亡了,所以我们要在这里加个判定,使用“功能调用/系统/跳过”方法在找不到玩家机械时跳过后面的所有代码(跳过方法如果用在循环里面则只会跳出循环部分)
TapTap
我们再来增加一个得分道具:导入一个新的机械,命名为“奖励”,拖动下方“功能类/机械探测器”到核心上,大小缩放到0.5左右
TapTap
将“同一机械是否只触发一次”开关关闭
TapTap
再增加一些装饰物
TapTap
点击“机械产生器”的“机械触碰”事件
TapTap
机械产生器是一个没有实体的物体,当其他零件进入或离开其区域时“机械触碰”和“机械离开”事件会被调用。可以看到“机械触碰”事件的方法有一个描述为“触发者”的参数
TapTap
拖动“变量功能/$trigger/是否存在方法”,参数填写为“吃奖励”,拖动“变量功能/$trigger/调用方法”,参数填写为“吃奖励”,游戏会去触发者零件上查找名为“吃奖励”的自定义方法,如果存在就会调用它。并在最后删除自己的机械
TapTap
现在回到地图编辑器,打开“主角”的机械产生器的逻辑面板,添加这个自定义方法
TapTap
为了简单的测试出这个方法是否被调用了,我们这里先添加一个调试用代码,拖动“功能调用/系统/调试/调试输出”
TapTap
并在地图中添加奖励道具对应的机械产生器,产生器别名为“奖励”
TapTap
打开蓝色的“逻辑方块”的启动事件中的“生成敌人方法”,点击左上角的复制按钮复制整个代码
TapTap
然后在启动事件中再添加一个新方法并点击左上方的黏贴按钮
TapTap
将新方法名改为“生成奖励”,并将随机生成位置逻辑改为在-30,0,-30到30,0,30的矩形区域内随机
TapTap
进入测试可以看到随机生成的奖励道具
TapTap
在主角吃掉道具时会显示调试信息
TapTap
接下来我们要增加一个计分板来统计玩家的得分,虽然在第二章我们学习了基本的按钮UI的使用,但因为是使用代码直接生成,UI的编辑不够直观。这里我们来学习UI布局功能:
在“主角”机械产生器的“机械启动”事件中拖动“功能调用/创建变量/UI布局”
TapTap
点击这个布局的图标可以打开UI布局编辑器
TapTap
点击上方的“方框”
TapTap
可以看到产生了一个方框,左侧可以看到这个按钮相关的属性
TapTap
首先将“名称”输入框的内容改为“计分板”
TapTap
左下角可以看到有个绿色的准星
TapTap
这个代表这个按钮相对于父空间的参考位置,你可以点击“父空间”按钮切换
TapTap
比如,这里点击“左”,绿色的准星就移动到界面左侧中间了,代表这个按钮的坐标是相对这个准星的
另外方框上有个黄色的图标表示按钮的对齐方式,默认是“左下”
TapTap
也可以点击“坐标对齐”按钮进行切换,这里也选择“左”
TapTap
将属性中的“X坐标”和“Y坐标”都设置为0,这样按钮的位置就是相对屏幕左侧中间靠边。
TapTap
将“厚度”设为-1,颜色设为半透明的白色,宽度设为200,高度设为100
TapTap
点击选中这个方框再添加一个“文本框”,并将它的位置设置为“父空间:右”,“坐标对齐:右”,坐标0,0
TapTap
TapTap
将它的名称设置为“分数”
然后将两个按钮的文字分别设置为“左”,“右”
TapTap
由于不同手机、电脑屏幕的分辨率不同,UI的坐标如果都是按照统一的左下角位置计算会导致在你当前的屏幕上刚好紧贴屏幕右侧的按钮在别的显示器上位置错误,所以设置好正确的UI对齐方式很重要。
下面点击空白处,在左侧的属性面板中,将“布局名称”这个输入框中填入“界面”,我们稍后会用到这个名字来引用这个布局。
TapTap
点击左上方的“结构树”按钮,可以看到布局中现在有两个UI,其中“计分板”是“分数”的父级,这里选中"分数"这个UI,
TapTap
点击左上角的“属性面板”,下拉面板可以找到“访问路径”,点击它会自动复制到剪贴板
TapTap
回到代码编辑器后,拖动“变量功能/界面/读取文本框”,路径参数直接黏贴即可
TapTap
回到逻辑面板,将“分数文本框”设置为全局变量
TapTap
点击“吃奖励”这个自定义方法
TapTap
TapTap
这里我们删除之前的调试输出代码,添加显示计分的代码
TapTap
进入测试后可以发现,每次吃掉一个奖励左侧的UI都会显示分数了。为了让没吃掉一个奖励都自动补充一个,我们需要在蓝色的“逻辑方块里”添加一个叫做“补充奖励”的自定义方法(你可以复制启动里面的生成奖励方法,然后修改一下实现)
TapTap
然后为了调用这个方法,要给蓝色的逻辑方块设置一个别名叫做“逻辑”
TapTap
然后就可以在主角的“吃奖励”代码中调用它了
TapTap
到这里为止你已经实现了一个躲避敌人吃道具得分的小游戏的基础功能。
扩展一:
保存最好成绩到存档
拖动“地图/存档/得到玩家存档”方法
TapTap
拖动“变量功能/存档/读取小数”方法
TapTap
这个功能是从这个字典中得到一个名为“最高分”的小数,如果找不到就则返回0
然后判断当前的分数是否大于存档中旧的最高分,如果是就替换
TapTap
拖动“地图/存档/上传玩家存档”
TapTap
文本框的内容也要改为"当前分数/最高分"的样式,拖动"功能调用/文字/拼接"方法
TapTap
点击代码后面的加号可以增加参数
TapTap
最后当分数超过旧分数时,更新旧分数的数值,并将文本框的文本替换为拼接内容
TapTap
这里得到的存档数据类型是个“字典”,字典和列表一样都是可以存储多个变量,不同点在于字典里面的元素没有顺序,并且是使用“名称”进行插入和查找,当插入的“名称”重复时会自动覆盖数据
更换背景:
因为我们这次要做的是一个在空中的躲避AI攻击的飞行游戏,回到机械编辑器,点击上方的地图设置按钮
TapTap
其中“地面类型”选择“无”,“天空”选择“天空4”,可以看到现在地图中的地面消失了,
TapTap
TapTap
3
1