# 挂机类RPG游戏制作 作者:丿我回来了 代表作 🚀提亚斯的冒险者们🚀 (opens new window) # 前言 本教程是一个相对较为复杂的制作流程,若对基础教程没有足够的了解建议前往上方了解基础教程,在本教程中对于基础教程内容将不做过多的讲述。 教程中所用数值、公式均只是教程类临时数值,都没有进行严格的推敲计算,可以不做参考。 # 需求描述 在游戏开始后,玩家通过探索地图生成随机数量的怪物(小于等于4个),之后玩家和怪物根据自身速度依次进行攻击,击杀完一波怪物后玩家会恢复10%的血量,并获得经验。
其他需求:
如果玩家死亡则等待60秒后复活 玩家经验满后会提升等级并加经验 每被击杀10波怪物关卡等级提升1级 玩家有50%概率触发暴击,额外造成200%伤害。 # 需求分析 游戏流程:
有一个开始游戏的按钮 作为玩家,需要生成一个玩家对象。(利用对象,方便拓展我方队伍人数,当前教程按照一个人去写) 如果不在战斗中则需要生成新怪物 玩家和怪物自动战斗,并且能正常判断战斗结果并获得战利品 关卡属性:
简述:关卡本身属性比较简单,可以不使用对象,而是使用普通属性即可。 属性:关卡等级、关卡进度 玩家对象:
战斗属性:当前血量、最大血量、攻击、攻击速度、暴击率、暴击伤害 常规属性:等级、当前经验、升级经验、 怪物对象:
战斗属性:当前血量、最大血量、攻击、攻击速度 常规属性:掉落经验 其他分析:
由于游戏本身需要自动运行,为了防止其流程混乱以及,所以需要以一个属性【状态值】对其进行核心控制。 游戏中只要一个普攻,那么我们可以把普攻理解成最简单类型的技能,在做其他项目技能的时候可以借此作为发挥。 利用对象制作玩家和怪物,可以节省属性,方便后续拓展,请务必学习对象的使用后,再阅读本教程。 最后效果如图所示:
# 开始界面制作 新建场景,命名为开始界面,勾选【隐藏标题】、【隐藏二级菜单标题】。 【界面样式】→【首页直接跳转类别】→选择【开始界面】。 新建控件,所属场景开始界面,命名为开始按钮。 新建控件,所属场景开始界面,命名为开始按钮控件容器,设置为控件容器。 # 开始按钮设置 【点击成功是否反馈】→ “否”
【点击失败是否反馈】→ “否”
【覆盖按钮文本】→ 写入文本:开始游戏
【按钮中显示提示】→ 关闭显示
【是否隐藏(无视需求)】→ “是”
【是否禁止显示详情】→ “是”
样式如下:
// [开始按钮]→【编辑最外层行样式】:设定整个控件的大小
{
"padding": "0px",
"margin": "0px",
"width": "60%",
"height": "100%"
}
// [开始按钮]→【编辑按钮样式】:设定控件按钮大小
{
"margin": "0px",
"width": "100%"
}
//[开始按钮]→【编辑文本域样式】:隐藏左侧文本区域显示
{
"display": "none"
}
# 开始按钮控件容器设置 控件容器添加控件 开始按钮
// [开始按钮控件容器]→【编辑最外层行样式】:设定区域大小
{
"border": "1px solid #ccc",
"padding": "0px",
"width": "98vw",
"height": "61.5vh"
}
# 战斗流程图
# 玩家对象制作 # 创建玩家属性 最大血量:别名设置为玩家,保留小数设置为0
当前血量:别名设置为玩家,保留小数设置为0,最大值设置为上方的【最大血量】
攻击力:别名设置为玩家,保留小数设置为0
攻击速度:别名设置为玩家,保留小数设置为0
暴击率:别名设置为玩家,保留小数设置为0(教程中暂时没用上)
暴击伤害:别名设置为玩家(教程中暂时没用上)
等级:别名设置为玩家,保留小数设置为0,最小值为1,默认值为1
当前经验:别名设置为玩家,保留小数设置为0
属性刷新开关:别名设置为玩家,其实可以每帧都刷新的,但是这里为了保证程序效率,采用触发式刷新
类型:别名设置为玩家,在当前项目中属于无用项目,未来扩展可以用来区分是玩家本体还是宠物等
攻击进度:别名设置为玩家,攻击进度条
# 创建组合属性 升级所需经验:50*等级,保留小数设置为0
# 创建玩家对象 把上方创建的属性关联至对象上,如下图所示:
(你也可以把暴击率和暴击伤害也加进去)
# 处理玩家升级事件 【玩家】对象事件中新建事件:玩家升级,设置如下图
提示
上图含义为,当类型为玩家(1为玩家)时,并且经验达到了升级所需的经验,那么就获得1等级,并且把属性刷新开关打开。另外清空当前经验。
【玩家】对象事件中新建事件:玩家升级后属性刷新,设置如下图
提示
利用开关,控制属性的刷新。实际上你可以通过其他方式实现。
当开发打开时,清空所有属性,然后加上对应的属性即可。比如当前攻击力为5点。你想把攻击力变为20。那么你可以先让攻击力变为0,即 -攻击力,然后再加上20点,即 +20。
【玩家】对象事件中新建事件:关闭属性刷新,设置如下图
三个事件得顺序从上至下排列分别是:玩家升级、升级后属性刷新、关闭属性刷新
注意
在每一帧中,事件的执行是有顺序的,一般不用特别考虑执行顺序,但是某些情况下,还是要注意一下。可以节省性能。
以上,咱们就做好了最基础的玩家对象,接下来制作怪物和关卡相关内容
# 怪物对象制作 # 创建关卡类属性 关卡等级:保留小数设置为0,最小值为1,默认值为1
关卡进度:保留小数设置为0
# 创建系统属性: 纯随机数值属性
# 创建怪物属性 最大血量:别名设置为怪物,别名设置为怪物,保留小数设置为0
当前血量:别名设置为怪物,保留小数设置为0,最大值设置为上方的【最大血量】
攻击力:别名设置为怪物,保留小数设置为0
攻击速度:别名设置为怪物,保留小数设置为0
怪物名称:别名设置为怪物
攻击进度:别名设置为怪物,攻击进度条
# 创建组合属性 关卡进度上限:10
攻击进度上限:1500
提示
直接填写组合属性的基值即可
# 创建怪物对象 把上方创建的怪物属性关联至对象上,如下图所示(公式只做参考):
# 战斗场景制作-基础 逻辑分析 若当前是寻找怪物状态,则生成怪物对象,并把游戏状态修改为战斗(接下来是战斗流程) 点击开始后,如果玩家没有被生成则生成玩家(一般针对第一次进游戏的玩家),并默认游戏状态为寻找怪物。 界面分析 我们需要显示玩家自己的生命值以及战斗状态 显示所有敌人的生命值以及战斗状态 处理开始游戏按钮的界面跳转 先创建一个场景,命名为战斗界面,勾选【隐藏标题】、【隐藏二级菜单标题】。 创建一个筛选器,命名为筛选所有玩家,对应的类玩家对象,条件需求添加类型 >= 1,条件需求添加类型 < 2,(意思为需求类型为1)然后点击【添加数量属性】得到筛选所有玩家的数量属性。 控件开始按钮,设置跳转场景→战斗界面,勾选底部的【是否与对象相关】,添加如下数据(实现玩家数据初始化): 获得对象 → 选择玩家对象,在添加出来的【获得玩家对象】中点击【编辑需求】。 在【编辑需求】中添加需求条件:筛选所有玩家的数量属性 < 1。(意思为还没创建玩家则创建玩家) 在【获得玩家对象】中点击【初始属性】在其中添加:【类型】属性赋值为1,【属性刷新开关】属性赋值为1,【等级】属性赋值为1。
# 战斗场景制作-框架 复制控件开始按钮控件容器,针对被复制后的控件进行如下修改:
修改命名为战斗总框架 修改所属场景战斗界面 清空【控件容器】中之前的关联 // -[战斗总框架]→【编辑最外层行样式】:
{
"border": "0px solid #ccc",
"height": "61.5vh",
"padding": "0px 0px 0px 0px",
"width": "97.5vw"
}
// [战斗总框架]→【控件容器/框/折叠面板样式】:
{
"display": "inline-block",
"height": "100%",
"width": "100%"
}
复制控件战斗总框架,针对被复制后的控件进行如下修改:
修改命名为玩家信息框架 勾选【是否隐藏(无视需求)】 // [玩家信息框架]→【编辑最外层行样式】:设定整个控件的水平方向大小,以及开启垂直方向滚动
{
"overflow-y": "auto",
"border": "1px solid #ccc",
"padding": "0px 0px 0px 0px",
"height": "30%",
"width": "100%"
}
// [玩家信息框架]→【控件容器/框/折叠面板样式】:
{
"height": "100%",
"width": "100%"
}
复制控件战斗总框架,针对被复制后的控件进行如下修改:
修改命名为怪物信息框架 【最外层行样式】修改:【"height": "30%"】 → 【"height": "70%"】 分别把玩家信息框架和怪物信息框架 依次 加入战斗总框架 # 战斗场景制作-玩家信息框 新建控件,所属场景战斗界面,别名添加为玩家血量条:
分别复制当前血量数量---玩家和最大血量数量---玩家的ID填入名称栏,然后再最后再将,攻击力--玩家、当前经验--玩家,加在后面。最终的控件名称为:<{xxxxxx}>/<{yyyyyy}> - 攻:<{aaaaaa}> 经验:<{bbbbbb}>。xxx\yyy\aaa\bbb为对应的属性ID。 【行布局】→ “进度条”,主属性设置为当前血量---玩家,上限属性设置为最大血量---玩家,颜色任意选择,一般选红色 【是否隐藏(无视需求)】→ “是” // [玩家血量条]→【最外层行样式】:
{
"padding": "0px 0px 0px 0px",
"border": "0px solid #ccc",
"outline": "0px solid red",
"box-shadow": "0px 0px 0px red",
"width": "100%",
"height": "20px",
"display": "block"
}
//[玩家血量条]→【进度条框样式】:
{
"border": "1px solid #ccc",
"padding": "0px 0px 0px 0px",
"margin": "0px 0px 0px 0px",
"height": "100%"
}
// [玩家血量条]→【进度条文本样式】:
{
"top": "-5px",
"font-size": "12px"
}
新建控件,所属场景战斗界面,命名为玩家进攻条:
【行布局】→ “进度条”,主属性设置为攻击进度---玩家,上限属性设置为攻击进度上限,颜色任意选择 【是否隐藏(无视需求)】→ “否” // [玩家进攻条]→【最外层行样式】:
{
"padding": "0px 0px 0px 0px",
"border": "0px solid #ccc",
"outline": "0px solid red",
"box-shadow": "0px 0px 0px red",
"width": "100%",
"height": "12px",
"display": "block"
}
// [玩家进攻条]→【进度条框样式】:
{
"border": "1px solid #ccc",
"padding": "0px 0px 0px 0px",
"margin": "0px 0px 0px 0px",
"height": "100%"
}
// [玩家进攻条]→【进度条文本样式】:
{
"display": "none"
}
新建控件,所属场景战斗界面,命名为单个玩家框架:
【是否隐藏(无视需求)】→ “否” 修改为【控件容器】,依次添加玩家进攻条和玩家血量条 // [玩家进攻条]→【最外层行样式】:
{
"width": "100%",
"margin": "0px 0px 0px 0px",
"padding": "0px 0px 0px 0px",
"height": "100%"
}
// [玩家进攻条]→【控件容器/框/折叠面板样式】:
{
"display": "block"
}
新建控件,所属场景战斗界面,命名为玩家对象:
【绑定类与对象】:开启,选择玩家对象 【是否隐藏(无视需求)】:开启 修改为【控件容器】,添加单个玩家框架 把玩家对象加入玩家信息框架的【控件容器】 // [玩家对象]→【最外层行样式】:
{
"display": "inline-block",
"width": "45%",
"margin": "3px 5px 3px 5px",
"padding": "0px 0px 0px 0px"
}
// [玩家对象]→【对象列表样式】:
{
"width": "100%",
"height": "95%",
"display": "inline-block",
"margin": "5px 5px 0px 5px",
"outline": "0px solid red",
"padding": "0px 0px 0px 0px"
}
至此玩家信息框内容已经制作完毕。
# 战斗场景制作-怪物信息框 复制控件玩家血量条,针对被复制后的控件进行如下修改:
别名修改为怪物血量条 分别复制当前血量数量---怪物和最大血量数量---怪物和攻击力---怪物的ID填入名称栏。最终的控件名称为:<{xxxxxx}>/<{yyyyyy}> - 攻:<{aaaaaa}>。xxx\yyy\aaa为对应的属性ID。 【行布局】→ “进度条”,主属性设置为当前血量---怪物,上限属性设置为最大血量---怪物,颜色任意选择,一般选红色 复制控件玩家进攻条,针对被复制后的控件进行如下修改:
命名修改为怪物进攻条 【行布局】→ “进度条”,主属性设置为攻击进度---怪物,上限属性设置为攻击进度上限,颜色任意选择 新建字符串,命名为怪物名称,添加以下内容:
怪物名1 怪物名2,条件设置:怪物名称---怪物 >= 1 怪物名3,条件设置:怪物名称---怪物 >= 2 新建控件,所属场景战斗界面,别名添加为怪物名:
复制怪物名称的动态ID填入名字框内 【是否隐藏(无视需求)】 → 开启 【点击成功是否反馈】 → 否 【点击失败是否反馈】 → 否 【是否禁止显示详情】 → 是 // [怪物名]→【最外层行样式】:
{
"text-align": "center",
"box-shadow": "0px 0px 0px red",
"border": "1px solid #ccc",
"padding": "0px 0px 0px 0px",
"margin": "0px 0px 0px 0px",
"width": "100%"
}
// [怪物名]→【按钮样式】:
{
"display": "none"
}
复制控件单个玩家框架,针对被复制后的控件进行如下修改:
修改名称为单个怪物框架 清空【控件容器】的内容,并依次绑定怪物进攻条、怪物血量条、怪物名 复制控件玩家对象,针对被复制后的控件进行如下修改:
名称修改为怪物对象 【绑定对象】修改为怪物对象 清空【控件容器】的内容,并绑定单个怪物框架 把怪物对象加入怪物信息框架的【控件容器】 至此怪物信息框内容已经制作完毕。
# 战斗逻辑制作 # 前置准备 创建属性,命名为玩家状态,这里可以备注下:0为暂停 1为寻找怪物 2为战斗中 3为死亡 创建一个筛选器,命名为筛选所有怪物,对应的类怪物对象,然后点击【添加数量属性】得到筛选所有怪物的数量属性。 创建一个筛选器,命名为筛选随机1个玩家,对应的类玩家对象,筛选对象数选择【最多某个数量】 → 1。 创建一个筛选器,命名为筛选随机1个怪物,对应的类怪物对象,筛选对象数选择【最多某个数量】 → 1。 创建组合,命名为万以内纯随机,公式为:纯随机数值属性%10000 控件开始按钮,在【点击后玩家获得属性】中添加如下数据: 玩家状态设置为1,需求条件设置为:玩家状态 < 1;如下图
# 刷怪 创建事件,命名为怪物刷新,添加如下数据:
【是否与对象相关】→ “是” 【事件触发需求属性】→ 玩家状态 >= 1 【事件触发需求属性】→ 玩家状态 < 2 【事件触发需求属性】→ 筛选所有怪物的数量属性 < 1 【触发后获得属性】→ 玩家状态 获得 1 【事件获得对象】 → 获得【怪物对象】 (备注:这是必然会刷出第一个怪) 【事件获得对象】 → 获得【怪物对象】,添加需求 万以内纯随机 < 5000 (备注:50%概率执行刷出这个2号怪物) 【事件获得对象】 → 获得【怪物对象】,添加需求 万以内纯随机 < 5000 (备注:50%概率执行刷出这个3号怪物) 【事件获得对象】 → 获得【怪物对象】,添加需求 万以内纯随机 < 5000 (备注:50%概率执行刷出这个4号怪物)
提示
以上就做到了,如果是寻找怪物状态且没有怪物在场上的时候,必然会出现1个怪物,87.5%出现2个怪,75%出现3个怪,50%出现4个怪。
# 玩家进攻 玩家对象,新增对象事件,命名为进攻条增加,添加如下数据:
【事件触发需求属性】 → 玩家状态 >= 2 【事件触发需求属性】 → 玩家状态 <= 3 【触发后获得属性】 → 攻击进度---玩家 获得 攻击速度---玩家 玩家对象,新增对象事件,命名为进攻,添加如下数据:
【是否与对象相关】→ “是” 【事件触发需求属性】 → 攻击进度---玩家 >= 攻击进度上限 【事件触发需求属性】 → 玩家状态 >= 2 【事件触发需求属性】 → 玩家状态 <= 3 【触发后获得属性】 → 攻击进度---玩家 获得 -1 * 攻击进度---玩家 【对象获得属性】 → 筛选器筛选随机1个怪物,添加【获得属性】→ 当前血量---怪物 获得 -1*攻击力---玩家 【对象获得属性】 → 筛选器筛选随机1个怪物,添加【获得属性】→ 当前血量---怪物 获得 -1*攻击力---玩家,添加需求条件 万以内存随机 < 5000 (50%概率额外造成100%伤害,模拟暴击。聪明的同学可以思考下如何利用玩家的暴击率和暴击伤害属性实现更加好的暴击效果。)
其中获得属性填写如下:
提示
意思就是对筛选出来的对象,做属性变换操作,此处为减少玩家攻击力点怪物生命值
# 玩家死亡 玩家对象,新增对象事件,命名为死亡,添加如下数据(这里只有玩家本体死亡才会判断战斗失败): 【事件触发需求属性】 → 当前血量---玩家 < 1 【事件触发需求属性】 → 玩家状态 >= 2 【事件触发需求属性】 → 玩家状态 <= 3 【事件触发需求属性】 → 类型 >= 1 【事件触发需求属性】 → 类型 <= 2 【触发后获得属性】 → 玩家状态 获得 1
提示
即当玩家血量小于1时,玩家状态从2变为3
# 玩家复活 玩家对象,新增对象事件,命名为复活,添加如下数据:
【事件触发需求属性】 → 玩家状态 >= 3 【事件触发需求属性】 → 玩家状态 <= 4 【触发后获得属性】 → 当前血量 获得 最大血量/25【向上取整】,添加条件 当前血量---玩家 < 最大血量---玩家 【触发后获得属性】 → 玩家状态 获得 -1*玩家状态 + 2,添加条件 当前血量---玩家 >= 最大血量---玩家
提示
当血量不满时,缓慢恢复血量。当血量满时,玩家状态从3置为2
玩家对象所有事件如下排序
# 怪物进攻 怪物对象,新增对象事件,命名为进攻条增加,添加如下数据:
【事件触发需求属性】 → 玩家状态 >= 2 【事件触发需求属性】 → 玩家状态 <= 3 【触发后获得属性】 → 攻击进度---怪物 获得 攻击速度---怪物 怪物对象,新增对象事件,命名为进攻,添加如下数据:
【是否与对象相关】→ “是” 【事件触发需求属性】 → 攻击进度---怪物 >= 攻击进度上限 【事件触发需求属性】 → 玩家状态 >= 2 【事件触发需求属性】 → 玩家状态 <= 3 【触发后获得属性】 → 攻击进度---怪物 获得 -1 * 攻击进度---怪物 【对象获得属性】 → 筛选器筛选随机1个玩家,添加【获得属性】→ 当前血量---玩家 获得 -1*攻击力---怪物 # 怪物死亡 怪物对象,新增【摧毁对象条件】:
当前血量---怪物 < 1 怪物对象,新增【销毁时触发的事件】,命名为死亡掉落,添加如下数据:
【每帧概率】 → 100 【是否与对象相关】→ “是” 【对象获得属性】 → 筛选器筛选所有玩家,添加【获得属性】→ 当前经验---玩家 获得 5*关卡等级 怪物事件排序和玩家相同
# 状态转换 创建公共事件,命名为怪物全部死亡,添加如下数据:
【事件触发需求属性】 → 筛选所有怪物的数量属性 < 1 【事件触发需求属性】 → 玩家状态 >= 2 【事件触发需求属性】 → 玩家状态 <= 3 【触发后获得属性】 → 玩家状态 获得 -1 【触发后获得属性】 → 关卡进度 获得 1,新增条件:关卡进度 < 关卡进度上限 【触发后获得属性】 → 关卡等级 获得 1,新增条件:关卡进度 >= 关卡进度上限 【触发后获得属性】 → 关卡进度 获得 -1*关卡进度,新增条件:关卡进度 >= 关卡进度上限
提示
玩家状态从2变为1、并且更新关卡进度或关卡等级。
至此,我们的作品就基本做完啦!最后我们再把一些常见属性添加到属性栏中,方便我们观察。
点击顶部界面设置,添加属性打属性栏中。
如有疑问~随时加QQ群923454388交流哦~