diff --git a/_server/comment.js b/_server/comment.js index 92db9457..982153b9 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -22,7 +22,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "tools" ] }, - "_data": "只能取keys(钥匙) items(宝石、血瓶) constants(物品) tools(道具)" + "_data": "只能取keys(钥匙) items(宝石、血瓶) constants(永久物品) tools(消耗道具)" }, "name": { "_leaf": true, @@ -40,25 +40,25 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "textarea", "_lint": true, - "_data": "cls为items的即捡即用类物品的效果,执行时会对这里的字符串执行eval()" + "_data": "cls为items的即捡即用类物品的效果,如需设置可以先将其设置为空字符串\"\",然后双击进行编辑。" }, "itemEffectTip": { "_leaf": true, "_type": "textarea", "_lint": true, - "_data": "cls为items的即捡即用类物品,在获得时左上角额外显示的文字,执行时会对这里的字符串执行eval()得到字符串" + "_data": "cls为items的即捡即用类物品,在获得时左上角额外显示的文字,如需设置可以先将其设置为空字符串\"\",然后双击进行编辑。" }, "useItemEffect": { "_leaf": true, "_type": "textarea", "_lint": true, - "_data": "cls为tools或contants时的使用物品效果,执行时会对这里的字符串执行eval()" + "_data": "cls为tools或contants时的使用物品效果,如需设置可以先将其设置为空字符串\"\",然后双击进行编辑。" }, "canUseItemEffect": { "_leaf": true, "_type": "textarea", "_lint": true, - "_data": "cls为tools或contants时能否使用物品的判断,执行时会return这里的字符串执行eval()后的结果" + "_data": "cls为tools或contants时对当前能否使用该物品的判断,如需设置可以先将其设置为空字符串\"\",然后双击进行编辑。" } } }, @@ -231,7 +231,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "title": { "_leaf": true, "_type": "textarea", - "_data": "楼层中文名" + "_data": "楼层中文名,将在切换楼层和浏览地图时显示" }, "name": { "_leaf": true, @@ -274,7 +274,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_select": { "values": Object.keys(editor.core.icons.icons.terrains) }, - "_data": "默认地面的图块ID(terrains中)" + "_data": "默认地面的图块ID,此项修改后需要刷新才能看到效果。" }, "images": { "_leaf": true, @@ -284,17 +284,17 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "color": { "_leaf": true, "_type": "textarea", - "_data": "该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。" + "_data": "该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组如[255,0,0,0.3]" }, "weather": { "_leaf": true, "_type": "textarea", - "_data": "该层的默认天气。本项可忽略表示晴天,如果写则第一项为\"rain\"或\"snow\"代表雨雪,第二项为1-10之间的数代表强度。" + "_data": "该层的默认天气。本项可忽略表示晴天,如果写则第一项为\"rain\"或\"snow\"代表雨雪,第二项为1-10之间的数代表强度。\n如[\"rain\", 8]代表8级雨天。" }, "bgm": { "_leaf": true, "_type": "textarea", - "_data": "到达该层后默认播放的BGM。本项可忽略。" + "_data": "到达该层后默认播放的BGM。本项可忽略,或者为一个定义过的背景音乐如\"bgm.mp3\"。" }, "item_ratio": { "_leaf": true, @@ -306,7 +306,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "event", "_event": "firstArrive", - "_data": "第一次到该楼层触发的事件" + "_data": "第一次到该楼层触发的事件,可以双击进入事件编辑器。" } } }, @@ -318,7 +318,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "event", "_event": "event", - "_data": "该点的可能事件列表" + "_data": "该点的可能事件列表,可以双击进入事件编辑器。" }, "changeFloor": { "_leaf": true, @@ -330,24 +330,24 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "event", "_event": "afterBattle", - "_data": "该点战斗后可能触发的事件列表" + "_data": "该点战斗后可能触发的事件列表,可以双击进入事件编辑器。" }, "afterGetItem": { "_leaf": true, "_type": "event", "_event": "afterGetItem", - "_data": "该点获得道具后可能触发的事件列表" + "_data": "该点获得道具后可能触发的事件列表,可以双击进入事件编辑器。" }, "afterOpenDoor": { "_leaf": true, "_type": "event", "_event": "afterOpenDoor", - "_data": "该点开完门后可能触发的事件列表" + "_data": "该点开完门后可能触发的事件列表,可以双击进入事件编辑器。" }, "cannotMove": { "_leaf": true, "_type": "textarea", - "_data": "该点不可通行的方向 \n 可以在这里定义该点不能前往哪个方向,例如悬崖边不能跳下去 \n'x,y': ['up', 'left'], // (x,y)点不能往上和左走" + "_data": "该点不可通行的方向 \n 可以在这里定义该点不能前往哪个方向,可以达到悬崖之类的效果\n例如 [\"up\", \"left\"], // 代表该点不能往上和左走" } } } diff --git a/_server/data.comment.js b/_server/data.comment.js index 99f824e1..65db31e4 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -10,7 +10,7 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "floorIds": { "_leaf": true, "_type": "textarea", - "_data": "在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器的顺序和上楼器/下楼器的顺序" + "_data": "在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器、浏览地图和上/下楼器的顺序" }, "images": { "_leaf": true, @@ -35,12 +35,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "startBackground": { "_leaf": true, "_type": "textarea", - "_data": "标题界面的背景,建议使用jpg格式以压缩背景图空间" + "_data": "标题界面的背景,建议使用jpg格式以压缩背景图空间" }, "startLogoStyle": { "_leaf": true, "_type": "textarea", - "_data": "标题样式:可以改变颜色,也可以隐藏标题(如果背景图自带)" + "_data": "标题样式:可以改变颜色,也可以写\"display: none\"来隐藏标题" }, "levelChoose": { "_leaf": true, @@ -76,7 +76,8 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "name": { "_leaf": true, "_type": "textarea", - "_data": "游戏的唯一英文标识符。由英文、数字、下划线组成,不能超过20个字符。" + "_range": "/^[a-zA-Z0-9_]{1,30}$/.test(thiseval)", + "_data": "游戏的唯一英文标识符。由英文、数字、下划线组成,不能超过30个字符。\n此项必须修改,其将直接影响到存档的定位!" }, "version": { "_leaf": true, @@ -86,7 +87,7 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "floorId": { "_leaf": true, "_type": "textarea", - "_data": "初始楼层ID" + "_data": "初始楼层的ID" }, "hero": { "_leaf": false, @@ -95,7 +96,7 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "name": { "_leaf": true, "_type": "textarea", - "_data": "勇士初始数据 \n 勇士名;可以改成喜欢的" + "_data": "勇士名;可以改成喜欢的" }, "lv": { "_leaf": true, @@ -201,18 +202,18 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "event", "_event": "firstArrive", - "_data": "游戏开始前剧情。如果无剧情直接留一个空数组即可。" + "_data": "游戏开始前剧情。\n可以双击进入事件编辑器。\n如果无剧情直接留一个空数组即可。" }, "shops": { "_leaf": true, "_type": "event", "_event": "shop", - "_data": "全局商店,是一个数组 \n 每一项是一个Object代表一个全局商店 \n id 为商店的唯一标识符(ID),请确保任何两个商店的id都不相同 \n name 为商店的名称(打开商店后的标题) \n icon 为商店的图标,在icons.js的npcs中定义。如blueShop可代表蓝色商店。 \n textInList 为其在快捷商店栏中显示的名称,如\"3楼金币商店\"等 \n use 为消耗的类型,是金币(money)还是经验(experience)。 \n need 是一个表达式,计算商店所需要用到的数值,可以以times作为参数。 \n text 为商店所说的话。可以用${need}表示需要的数值。\n choices 为商店的各个选项,是一个list,每一项是一个选项,里面text为显示文字,effect为选项的效果,只能用+=,分号分开。" + "_data": "全局商店,是一个数组,可以双击进入事件编辑器。" }, "levelUp": { "_leaf": true, "_type": "textarea", - "_data": "经验升级所需要的数值,是一个数组 \n 第一项为初始等级,可以简单留空,也可以写name \n 每一个里面可以含有三个参数 need, name, effect \n need为所需要的经验数值,是一个正整数。请确保need所需的依次递增 \n name为该等级的名称,也可以省略代表使用系统默认值;本项将显示在状态栏中 \n effect为本次升级所执行的操作,可由若干项组成,由分号分开 \n 其中每一项写法和上面的商店完全相同,同样必须是X+=Y的形式,Y是一个表达式,同样可以使用status:xxx或item:xxx代表勇士的某项数值/道具个数" + "_data": "经验升级所需要的数值,是一个数组,可以双击进行编辑。 \n 第一项为初始等级,可以简单留空,也可以写name \n 每一个里面可以含有三个参数 need, name, effect \n need为所需要的经验数值,是一个正整数。请确保need所需的依次递增 \n name为该等级的名称,也可以省略代表使用系统默认值;本项将显示在状态栏中 \n effect为本次升级所执行的操作,可由若干项组成,由分号分开 \n 其中每一项写法和上面的商店完全相同,同样必须是X+=Y的形式,Y是一个表达式,同样可以使用status:xxx或item:xxx代表勇士的某项数值/道具个数" } } }, @@ -273,12 +274,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "sword0": { "_leaf": true, "_type": "textarea", - "_data": "默认装备折断的剑的攻击力" + "_data": "空剑的攻击力,此项请保持为0" }, "shield0": { "_leaf": true, "_type": "textarea", - "_data": "默认装备残破的盾的防御力" + "_data": "空盾的防御力,此项请保持为0" }, "sword1": { "_leaf": true, @@ -338,12 +339,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "breakArmor": { "_leaf": true, "_type": "textarea", - "_data": "破甲的比例(战斗前,怪物附加角色防御的x%作为伤害)" + "_data": "破甲的比例(战斗前,怪物附加角色防御的x倍作为伤害)" }, "counterAttack": { "_leaf": true, "_type": "textarea", - "_data": "反击的比例(战斗时,怪物每回合附加角色攻击的x%作为伤害,无视角色防御)" + "_data": "反击的比例(战斗时,怪物每回合附加角色攻击的x倍作为伤害,无视角色防御)" }, "purify": { "_leaf": true, @@ -364,7 +365,7 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "animateSpeed": { "_leaf": true, "_type": "textarea", - "_data": "动画时间" + "_data": "动画时间,一般300比较合适" } } }, @@ -544,7 +545,7 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "checkbox", "_bool": "bool", - "_data": "经过楼梯、传送门时是否能“穿透”。穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件" + "_data": "经过楼梯、传送门时是否能“穿透”。\n穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件" }, "enableMoveDirectly": { "_leaf": true, diff --git a/_server/editor_mode.js b/_server/editor_mode.js index 343b095c..e306464e 100644 --- a/_server/editor_mode.js +++ b/_server/editor_mode.js @@ -395,6 +395,10 @@ editor_mode = function (editor) { printe('不合法的idnum'); return; } + if (!/^[0-9a-zA-Z_]+$/.test(id)) { + printe('不合法的id,请使用字母、数字或下划线') + return; + } editor.file.changeIdAndIdnum(id, idnum, editor_mode.info, function (err) { if (err) { printe(err); @@ -452,6 +456,11 @@ editor_mode = function (editor) { printe("该楼层已存在!"); return; } + if (!/^[a-zA-Z_]*[a-zA-Z0-9_]*$/.test(newFileName)) { + printe("楼层名不合法!请使用字母、数字、下划线,且不能以数字开头!"); + return; + } + editor_mode.onmode(''); editor.file.saveNewFile(newFileName.value, function (err) { if (err) { diff --git a/docs/_start.md b/docs/_start.md new file mode 100644 index 00000000..568fc2ae --- /dev/null +++ b/docs/_start.md @@ -0,0 +1,222 @@ +# 快速上手 + +?> 目前版本**v2.2.1**,上次更新时间:* {docsify-updated} * + +在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔! + +## 前置需求 + +你需要有满足如下条件才能进行制作: + +- Windows 8以上操作系统;Windows 7需要安装.Net Framework 4.0。(能打开同目录下的“启动服务.exe”即可) +- Chrome浏览器。其他浏览器可能会导致本地服务器产生闪退等现象。 +- 一个很好的文本编辑器。推荐带有高亮染色、错误提示等效果。例如:WebStorm,VSCode,或者至少也要Sublime Text。 + - ([VSCode下载地址](https://code.visualstudio.com/),群里的群文件中也有,强烈推荐之。) + - **2.0版本可以不需要,但是仍然强烈推荐有一个,从而能对H5造塔有更深的了解。** + +只要满足了上述条件,你就可以开始做自己的塔啦! + +## V2.0的使用 + +目前版本已经更新到V2.0,在2.0版本中,我们可以进行全GUI造塔。 + +下面的文档主要是讲如何通过代码编辑的方式来造,仍然强烈建议进行阅读从而有着一定的了解。 + +如果想直接知道如何在V2.0造塔,可以直接参见[V2.0版本介绍](V2.0)的说明,或者看[B站视频教程](http://www.bilibili.com/video/av17608025/)。 + +## 启动HTTP服务 + +在根目录下有一个“启动服务.exe”,运行之。 + +![启动服务](img/server.png) + +* “启动游戏”按钮将打开一个网页,你能在里面看到现在游戏的效果。 +* “地图编辑器”允许你以可视化的方式进行编辑地图。 +* “便捷PS工具”能让你很方便的对自定义素材进行添加。参见[自定义素材](personalization#自定义素材)。 +* “地图生成器”能让你从已有的截图(如RMXP项目)中立刻生成可被本样板识别的地图数据。 +* “RM动画导出器”能让你从RMXP中导出动画而被H5魔塔使用。 +* “JS代码压缩工具”能对JS代码进行压缩,从而减少IO请求数和文件大小。 +* “伤害和临界值计算器”是一个很便捷的小工具,能对怪物的伤害和临界值进行计算。 + +!> **警告:** 非Chrome浏览器(如Edge/IE等)下本地服务器可能表现不正常,会出现闪退等现象。请务必下载安装Chrome浏览器。 + +## 新建剧本 + +类似于RMXP,本塔每层楼都是一个“剧本”,剧本内主要定义了本层的地图和各种事件。主函数将读取每个剧本,并生成实际的地图供游戏使用。 + +我们打开 `project/floors/` 目录,这个目录是所有剧本的目录。我们需要指定一个楼层名,例如MT1;然后,我们可以将`MT0.js`(模板)复制重命名为为`MT1.js`,并使用文本编辑器打开。 + +![新建剧本](./img/script.png) + +然后将楼层名改为MT1,floorId改名为MT1;title可以改成任意内容,将在切换楼层时进行显示(比如可以改成“1层小塔”)。 + +具体样板文件的每个要素如下: +- **`floorId`** 楼层唯一标识符;必须和文件名,以及 `main.floors.xxx` 完全一致 +- **`title`** 楼层中文名,将在切换楼层时进行显示 +- **`name`** 楼层再状态栏显示的名称 +- **`canFlyTo`** 当前楼层可否被楼传器飞到。如果该层不能飞到,则也在该层也不允许使用楼传器。 +- **`canUseQuickShop`** 当前楼层可否使用快捷商店。 +- **`defaultGround`** 该层的背景(地面)素材。 +- **`images`** 该层默认显示的前景/背景图片 +- **`color`** 该层的画面色调。 +- **`bgm`** 到达该层后默认播放的BGM。本项可忽略。 +- **`item_ratio`** 该层的宝石/血瓶倍率 +- **`map`** 本层地图,需要是13x13数组,建议使用地图生成器或者可视化地图编辑器制作。 +- **`firstArrive`** 第一次到该楼层触发的事件 +- **`events`** 该楼的所有可能事件列表 +- **`changeFloor`** 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖 +- **`afterBattle`** 战斗后可能触发的事件列表 +- **`afterGetItem`** 获得道具后可能触发的事件列表 +- **`afterOpenDoor`** 开完门后可能触发的事件列表 +- **`cannotMove`** 每个图块不可通行的方向,也就是悬崖效果 + +我们最终的任务其实是,将每个楼层的剧本(地图&事件)给写完即可。 + +换句话说,只需要简单的复制操作,我们就可以新建一个剧本了。 + +## 绘制地图 + +有两种绘制地图的方式:从头绘制地图;从RMXP中导入已有的地图。 + +### 从头绘制地图 + +我们直接打开“地图编辑器”,可以看到一个可视化的UI界面。 + +![地图编辑器](img/mapgui.png) + +然后可以在上面任意进行绘制地图。 + +!> **如果地图的数字和ID未被定义,则会进行提示:数字和ID未被定义!此时要对素材的ID和数字进行定义,请参见[自定义素材](personalization#自定义素材)。** + +绘制地图完毕后,点击"导出地图",即可在左边看到对应的JSON数组,并且已经复制到了剪切板。将其粘贴到剧本中的map位置即可。 + +![地图数组](./img/maparray.png) + +!> V2.0版本可以直接将当前地图进行保存或另存为,不需要这样手动打开进行编辑。 + +### 从RMXP导入已有的地图 + +如果我们想复刻一个现有的,已经被RMXP所制作的塔,也有很便捷的方式,那就是用到我们的“地图生成器”。 + +首先,我们打开RMXP和对应的项目,可以看到它的地图。 + +![绘制地图](./img/rmxp2.png) + +我们打开Windows自带的“截图工具”,并将整个地图有效区域截图下来,并将其复制到剪切板。 + +![绘制地图](./img/rmxp3.png) + +截图时请注意:**只截取有效游戏空间内数据,并且有效空间内的范围必须是13x13。(如果地图小于13*13,请用星空或墙壁填充到13x13)。** + +确认地图的图片文件已经复制到剪切板后,我们打开“地图生成器”,并点“加载图片”。大约1-2秒后,可以得到地图的数据。 + +![生成地图](./img/map1.png) + +然后点击“复制地图”,即可将地图数据复制到剪切板。 + +!> **如果有识别不一致的存在,即生成的地图和实际的地图不符,我们可以在地图编辑器中粘贴,再可视化进行编辑。** + +!> **地图生成器默认只支持经典素材。如果有自定义素材需求(例如原版的1层小塔那种素材),请参见[自定义素材](personalization#自定义素材)。** + +!> **请确保截图范围刚好为13x13,并且保证每个位置的像素都是32x32。** + + +## 录入数据 + +有了地图后,我们下一步需要做的就是录入数据。数据主要包括如下几种: + +- 勇士初始的属性 +- 全局变量(宝石效果、全局Flag等) +- 怪物数据(每个怪物的攻防血金币经验等等) + +下面依次进行说明。 + +我们打开`data.js`文件,这里面定义了各种全局属性和勇士初始值。 + +!> V2.0版本可以直接在地图编辑器的`全塔属性`中进行修改! + +我们可以将本塔标题改名为“1层小塔”, + +游戏的唯一标识符叫onefloor,然后可以直接修改勇士的各项初始数据. + +!> **注:name作为游戏的唯一标识符必须进行修改,否则可能会导致存档等出现问题。** + +![初始数据](./img/init.png) + +!> **请注意,勇士的初始位置一栏,x为横坐标,y为纵坐标;即,x为从左到右第几列,y为从上到下第几行,均从0开始计算。** + +修改完初始化信息后,接下来我们需要修改道具的信息(比如宝石加攻防的数值,血瓶加生命的数值等)。还是在这个`data.js`文件,往下拉,找到values一项,并进行相应的设置 + +![修改数据](./img/moddata.png) + +然后,再设置一些系统Flag,以进行游戏。继续将`data.js`往下拉,我们注意到本塔是存在魔防的,不存在经验,因此我们可以简单地将enableMDef改为true,enableExperience改成false,enableDebuff改成false。 + +同理,本塔的破墙镐只能破面前的墙壁,因此`pickaxeFourDirections`需要改成`false`。 + +![系统标志](./img/flag.png) + +其他的几项暂时不会被涉及到,因此不用考虑。 + +全局变量修改完毕后,我们需要告诉主函数加载该楼层。打开`data.js`,找到`floorIds`项,将其值改为楼层ID即MT1。 + +最后一步就是录入怪物数据。打开`enemys.js`文件,依次输入你在本塔内使用到的所有怪物的攻防血的数据。其中怪物的特殊属性(special项)与该文件下面的getSpecialText对应。 + +!> V2.0版本可以直接在“图块属性”一栏进行修改怪物属性! + +![怪物数据](./img/enemyarray.png) + +只需要修改自己用到的怪物属性即可,其他没有用到的怪物完全无所谓。 + +做完后保存所有文件,在本地服务器中“启动游戏”,就能立刻看到自己的塔并开始游戏啦!是不是很简单呢! + +![保存](./img/save.png) + +## 压缩与发布 + +当你将上述步骤完成后,你实际上已经做出来了一个魔塔,并且可以发布给大家进行游戏了。 +目前而言发布有如下几种方式: + +- 离线版本:直接将游戏文件夹打包,放到百度网盘等地方供用户下载;用户下载到本地后直接使用浏览器打开`index.html`进行游戏。 + - 手机端的部分浏览器如chrome也支持本地网页,可以下载到手机然后直接打开进行游戏。 +- 在线版本:将游戏放到某个服务器上,大家在线联网游戏。 + +**离线版本的好处是:先全部下载后再游戏,无需考虑流量的问题,也可以支持高清音乐的播放。坏处是:没办法在多平台之间迁移,无法及时获得游戏更新(需要重新下载),而浏览器打开本地文件有丢失存档的风险。 +在线版本的好处是:随时随地可以玩,可以多平台接档,还可以在后台看到一些统计信息,可以随时对游戏进行更新;坏处是需要一个服务器,且还要考虑到用户流量的问题。** + +在此我们只讨论在线版本。当你决定发布游戏时,强烈建议先将JS代码进行压缩以节省可能的IO请求以及网络流量。直接打开同目录下的“JS代码压缩工具”进行压缩即可。 + +压缩完毕后,你还需要将`main.js`中的useCompress从false改为true,这样方才只会加载压缩后的文件。 + +如果你需要发布到服务器上且你没有服务器,可以直接将本塔发给我(`艾之葵`),我会给负责你部署上去的。我的服务器至少能保证两年内有效。 + +然后就是发布帖子、链接二维码,能让任何人在任何时候任何平台上都能进行游戏啦!是不是很简单呢! + +## 注意事项和常见FAQ + +1. 截图请务必刚好截取13x13的图片,并需要保证每个位置必须为32x32像素。一般无放缩的RMXP符合条件。 +2. 游戏的唯一标识符name请务必修改。如果不修改可能会导致存档出现异常。 +3. 别忘了data.js中要修改floorIds指明所用到的所有楼层哦~ + +下面是几个常见的FAQ: + +**Q: 为什么截图识别不出来?** + +**A:** 请保证刚好为13x13,且每个位置必须32x32像素。如果不确定,可以保存你的截图,右键属性查看详细信息,看像素的宽高是不是在416左右。多少几十像素都是没关系的。 + +![图片大小](./img/imginfo.png) + +**Q: 打开游戏时卡死在了xxx.js加载完毕!无法进入游戏。** + +**A:** 最大的可能是因为少了逗号,或者反括号等等。一般而言VSCode都会有错误提示,你哪里少了东西。 + +如果没有,可以采用如下方式debug: + +Ctrl+Shift+I 打开Chrome的控制台,找到Console。 + +如果出现了语法错误,会有红色提示 **Unexpected xxx** ,找到后面文件名和行号,打开,使用VSCode检查该处是否存在问题,即可。 + +![检查错误](./img/chrome.png) + +========================================================================================== + +[继续阅读下一章:元件说明](element) \ No newline at end of file diff --git a/docs/img/drawmap.jpg b/docs/img/drawmap.jpg new file mode 100644 index 00000000..3f3f324c Binary files /dev/null and b/docs/img/drawmap.jpg differ diff --git a/docs/img/enemy.png b/docs/img/enemy.png new file mode 100644 index 00000000..cc64f9b8 Binary files /dev/null and b/docs/img/enemy.png differ diff --git a/docs/img/floor.png b/docs/img/floor.png new file mode 100644 index 00000000..7b606550 Binary files /dev/null and b/docs/img/floor.png differ diff --git a/docs/img/floorid.png b/docs/img/floorid.png new file mode 100644 index 00000000..63efa3d3 Binary files /dev/null and b/docs/img/floorid.png differ diff --git a/docs/img/point.png b/docs/img/point.png new file mode 100644 index 00000000..b218411f Binary files /dev/null and b/docs/img/point.png differ diff --git a/docs/img/register.png b/docs/img/register.png new file mode 100644 index 00000000..88ade048 Binary files /dev/null and b/docs/img/register.png differ diff --git a/docs/img/rmxp4.jpg b/docs/img/rmxp4.jpg new file mode 100644 index 00000000..081ab580 Binary files /dev/null and b/docs/img/rmxp4.jpg differ diff --git a/docs/start.md b/docs/start.md index 568fc2ae..195767ae 100644 --- a/docs/start.md +++ b/docs/start.md @@ -10,20 +10,12 @@ - Windows 8以上操作系统;Windows 7需要安装.Net Framework 4.0。(能打开同目录下的“启动服务.exe”即可) - Chrome浏览器。其他浏览器可能会导致本地服务器产生闪退等现象。 -- 一个很好的文本编辑器。推荐带有高亮染色、错误提示等效果。例如:WebStorm,VSCode,或者至少也要Sublime Text。 - - ([VSCode下载地址](https://code.visualstudio.com/),群里的群文件中也有,强烈推荐之。) - - **2.0版本可以不需要,但是仍然强烈推荐有一个,从而能对H5造塔有更深的了解。** +- 强烈推荐安装一个很好的文本编辑器:VSCode。在某些需要直接修改文件的场合,可能会非常重要。 + +上述软件均可以在群文件的常用软件中找到下载安装包。 只要满足了上述条件,你就可以开始做自己的塔啦! -## V2.0的使用 - -目前版本已经更新到V2.0,在2.0版本中,我们可以进行全GUI造塔。 - -下面的文档主要是讲如何通过代码编辑的方式来造,仍然强烈建议进行阅读从而有着一定的了解。 - -如果想直接知道如何在V2.0造塔,可以直接参见[V2.0版本介绍](V2.0)的说明,或者看[B站视频教程](http://www.bilibili.com/video/av17608025/)。 - ## 启动HTTP服务 在根目录下有一个“启动服务.exe”,运行之。 @@ -38,42 +30,6 @@ * “JS代码压缩工具”能对JS代码进行压缩,从而减少IO请求数和文件大小。 * “伤害和临界值计算器”是一个很便捷的小工具,能对怪物的伤害和临界值进行计算。 -!> **警告:** 非Chrome浏览器(如Edge/IE等)下本地服务器可能表现不正常,会出现闪退等现象。请务必下载安装Chrome浏览器。 - -## 新建剧本 - -类似于RMXP,本塔每层楼都是一个“剧本”,剧本内主要定义了本层的地图和各种事件。主函数将读取每个剧本,并生成实际的地图供游戏使用。 - -我们打开 `project/floors/` 目录,这个目录是所有剧本的目录。我们需要指定一个楼层名,例如MT1;然后,我们可以将`MT0.js`(模板)复制重命名为为`MT1.js`,并使用文本编辑器打开。 - -![新建剧本](./img/script.png) - -然后将楼层名改为MT1,floorId改名为MT1;title可以改成任意内容,将在切换楼层时进行显示(比如可以改成“1层小塔”)。 - -具体样板文件的每个要素如下: -- **`floorId`** 楼层唯一标识符;必须和文件名,以及 `main.floors.xxx` 完全一致 -- **`title`** 楼层中文名,将在切换楼层时进行显示 -- **`name`** 楼层再状态栏显示的名称 -- **`canFlyTo`** 当前楼层可否被楼传器飞到。如果该层不能飞到,则也在该层也不允许使用楼传器。 -- **`canUseQuickShop`** 当前楼层可否使用快捷商店。 -- **`defaultGround`** 该层的背景(地面)素材。 -- **`images`** 该层默认显示的前景/背景图片 -- **`color`** 该层的画面色调。 -- **`bgm`** 到达该层后默认播放的BGM。本项可忽略。 -- **`item_ratio`** 该层的宝石/血瓶倍率 -- **`map`** 本层地图,需要是13x13数组,建议使用地图生成器或者可视化地图编辑器制作。 -- **`firstArrive`** 第一次到该楼层触发的事件 -- **`events`** 该楼的所有可能事件列表 -- **`changeFloor`** 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖 -- **`afterBattle`** 战斗后可能触发的事件列表 -- **`afterGetItem`** 获得道具后可能触发的事件列表 -- **`afterOpenDoor`** 开完门后可能触发的事件列表 -- **`cannotMove`** 每个图块不可通行的方向,也就是悬崖效果 - -我们最终的任务其实是,将每个楼层的剧本(地图&事件)给写完即可。 - -换句话说,只需要简单的复制操作,我们就可以新建一个剧本了。 - ## 绘制地图 有两种绘制地图的方式:从头绘制地图;从RMXP中导入已有的地图。 @@ -82,17 +38,11 @@ 我们直接打开“地图编辑器”,可以看到一个可视化的UI界面。 -![地图编辑器](img/mapgui.png) +楼层切换到MT0层,然后可以开始任意绘制地图。 -然后可以在上面任意进行绘制地图。 +![绘制地图](./img/drawmap.jpg) -!> **如果地图的数字和ID未被定义,则会进行提示:数字和ID未被定义!此时要对素材的ID和数字进行定义,请参见[自定义素材](personalization#自定义素材)。** - -绘制地图完毕后,点击"导出地图",即可在左边看到对应的JSON数组,并且已经复制到了剪切板。将其粘贴到剧本中的map位置即可。 - -![地图数组](./img/maparray.png) - -!> V2.0版本可以直接将当前地图进行保存或另存为,不需要这样手动打开进行编辑。 +如果提示“该素材未被定义”或有红色问号框,请参见[素材注册](#素材注册)。 ### 从RMXP导入已有的地图 @@ -112,111 +62,144 @@ ![生成地图](./img/map1.png) -然后点击“复制地图”,即可将地图数据复制到剪切板。 +然后点击“复制地图”,即可将地图数据复制到剪切板,然后再地图编辑器中切换到“地图编辑”,并在左边的框进行粘贴。 -!> **如果有识别不一致的存在,即生成的地图和实际的地图不符,我们可以在地图编辑器中粘贴,再可视化进行编辑。** - -!> **地图生成器默认只支持经典素材。如果有自定义素材需求(例如原版的1层小塔那种素材),请参见[自定义素材](personalization#自定义素材)。** +!> **地图生成器默认只支持已被定义的素材。如果有自定义素材需求(例如原版的1层小塔那种素材),请先[导入并注册素材](#素材注册)后再进行操作。** !> **请确保截图范围刚好为13x13,并且保证每个位置的像素都是32x32。** +!> **地图生成器靠左上角来确定偏移量,如果左上角是全黑或者星空之类的素材可能导致识别不准,此时请在左上角放置一个岩浆后再进行截图识别。** -## 录入数据 +![岩浆](./img/rmxp4.jpg) -有了地图后,我们下一步需要做的就是录入数据。数据主要包括如下几种: +## 编辑属性 -- 勇士初始的属性 -- 全局变量(宝石效果、全局Flag等) -- 怪物数据(每个怪物的攻防血金币经验等等) +当地图绘制完毕后,我们可能需要进行属性的编辑。属性编辑有四类:楼层属性、怪物属性、道具属性、全塔属性。 -下面依次进行说明。 +### 楼层属性 -我们打开`data.js`文件,这里面定义了各种全局属性和勇士初始值。 +我们切换到楼层属性,并进行一项项的编辑。将鼠标放在中间有具体的每一项注释,这里不再细说。 -!> V2.0版本可以直接在地图编辑器的`全塔属性`中进行修改! +![楼层属性](./img/floor.png) -我们可以将本塔标题改名为“1层小塔”, +### 怪物属性 -游戏的唯一标识符叫onefloor,然后可以直接修改勇士的各项初始数据. +我们点击右边的怪物图块,可以在左边的框内设置该怪物的各项属性。将鼠标放在中间有具体的每一项注释,这里不再细说。 + +有关怪物的更详细信息可参见[元件说明:怪物](element#怪物)。 + +![怪物属性](./img/enemy.png) + +### 道具属性 + +同理,点击道具可以对道具属性进行编辑。 + +目前大多数道具都已有默认效果。更多信息可参见[元件说明:道具](element#道具)。 + +### 全塔属性 + +我们切换到全塔属性,并进行一项项的编辑。同样鼠标放在中间可以查看注释。 + +我们可以在这里定义一些全局的属性,比如开始剧情、宝石血瓶剑盾数值,破甲反击净化的比例,以及一些系统开关比如是否启用加点,是否允许负伤害等等。 !> **注:name作为游戏的唯一标识符必须进行修改,否则可能会导致存档等出现问题。** -![初始数据](./img/init.png) +  -!> **请注意,勇士的初始位置一栏,x为横坐标,y为纵坐标;即,x为从左到右第几列,y为从上到下第几行,均从0开始计算。** +上述属性全部修改完毕后,保存,然后点启动服务的“开始游戏”,就可以看到我们写的游戏效果啦! -修改完初始化信息后,接下来我们需要修改道具的信息(比如宝石加攻防的数值,血瓶加生命的数值等)。还是在这个`data.js`文件,往下拉,找到values一项,并进行相应的设置 +## 新建和删除楼层 -![修改数据](./img/moddata.png) +如果要新建楼层,请切换到“地图编辑”,输入新的楼层ID,并新建空白地图,然后刷新编辑器。 -然后,再设置一些系统Flag,以进行游戏。继续将`data.js`往下拉,我们注意到本塔是存在魔防的,不存在经验,因此我们可以简单地将enableMDef改为true,enableExperience改成false,enableDebuff改成false。 +请注意,楼层ID必须是由字母、数字和下划线组成且不能以数字开头,不能和任何已有的楼层ID重复。 -同理,本塔的破墙镐只能破面前的墙壁,因此`pickaxeFourDirections`需要改成`false`。 +你也可以删除当前楼层(比如几个样板层),只需要点击删除楼层再刷新就行。删除楼层并不会删除文件,只是不再被游戏所引入而已。 -![系统标志](./img/flag.png) +你可以在全塔属性 - floorIds中看到所有的楼层。其顺序将影响到楼传器的顺序、浏览地图的顺序和上下楼器等的顺序。 -其他的几项暂时不会被涉及到,因此不用考虑。 +## 事件编辑 -全局变量修改完毕后,我们需要告诉主函数加载该楼层。打开`data.js`,找到`floorIds`项,将其值改为楼层ID即MT1。 +我们点击任意一个图块,都可以进入事件编辑模式。 -最后一步就是录入怪物数据。打开`enemys.js`文件,依次输入你在本塔内使用到的所有怪物的攻防血的数据。其中怪物的特殊属性(special项)与该文件下面的getSpecialText对应。 +![地图选点](./img/point.png) -!> V2.0版本可以直接在“图块属性”一栏进行修改怪物属性! +从上至下有若干项,分别代表该点的一些事件。有关事件的详细信息请参见[事件](event)。 -![怪物数据](./img/enemyarray.png) +如果一个点存在事件,则在地图编辑器中该点的左下角会有一个小方框表示。 -只需要修改自己用到的怪物属性即可,其他没有用到的怪物完全无所谓。 +红色为自定义事件,绿色为楼层传送事件,黄色为战后事件,青色为道具获得后的事件,粉色为开门后的事件。 -做完后保存所有文件,在本地服务器中“启动游戏”,就能立刻看到自己的塔并开始游戏啦!是不是很简单呢! +## 自定义素材的添加与注册 -![保存](./img/save.png) +有关素材的更多详细信息,包括素材的机制等内容,请参见[自定义素材](personalization#自定义素材)。 -## 压缩与发布 +这里只对如何导入(新增)素材以及注册素材进行简要介绍。 -当你将上述步骤完成后,你实际上已经做出来了一个魔塔,并且可以发布给大家进行游戏了。 -目前而言发布有如下几种方式: +### 新素材的添加 -- 离线版本:直接将游戏文件夹打包,放到百度网盘等地方供用户下载;用户下载到本地后直接使用浏览器打开`index.html`进行游戏。 - - 手机端的部分浏览器如chrome也支持本地网页,可以下载到手机然后直接打开进行游戏。 -- 在线版本:将游戏放到某个服务器上,大家在线联网游戏。 +如果我们需要新增加一些素材,比如样板中没有的怪物等。 -**离线版本的好处是:先全部下载后再游戏,无需考虑流量的问题,也可以支持高清音乐的播放。坏处是:没办法在多平台之间迁移,无法及时获得游戏更新(需要重新下载),而浏览器打开本地文件有丢失存档的风险。 -在线版本的好处是:随时随地可以玩,可以多平台接档,还可以在后台看到一些统计信息,可以随时对游戏进行更新;坏处是需要一个服务器,且还要考虑到用户流量的问题。** +我们可以从启动服务打开编辑PS工具,然后选择对应的图片进行添加。 -在此我们只讨论在线版本。当你决定发布游戏时,强烈建议先将JS代码进行压缩以节省可能的IO请求以及网络流量。直接打开同目录下的“JS代码压缩工具”进行压缩即可。 +![便捷PS工具](img/ps.png) -压缩完毕后,你还需要将`main.js`中的useCompress从false改为true,这样方才只会加载压缩后的文件。 +在左边选择你要导入到的位置,比如怪物就是enemy.png,道具就是items.png等等,再在右边导入你的新素材图片。 -如果你需要发布到服务器上且你没有服务器,可以直接将本塔发给我(`艾之葵`),我会给负责你部署上去的。我的服务器至少能保证两年内有效。 +之后就可以简单的使用Ctrl+C和Ctrl+V来复制粘贴了。 -然后就是发布帖子、链接二维码,能让任何人在任何时候任何平台上都能进行游戏啦!是不是很简单呢! +保存后,刷新地图编辑器即可生效。 -## 注意事项和常见FAQ +### 素材注册 -1. 截图请务必刚好截取13x13的图片,并需要保证每个位置必须为32x32像素。一般无放缩的RMXP符合条件。 -2. 游戏的唯一标识符name请务必修改。如果不修改可能会导致存档出现异常。 -3. 别忘了data.js中要修改floorIds指明所用到的所有楼层哦~ +当我们使用新素材后,可能会出现素材不存在的情况,此时绘图时会存在红色问号方框。 -下面是几个常见的FAQ: +![素材注册](./img/register.png) -**Q: 为什么截图识别不出来?** +出现这种情况,是因为我们没有将该素材定义到游戏中,也无法进行使用。 -**A:** 请保证刚好为13x13,且每个位置必须32x32像素。如果不确定,可以保存你的截图,右键属性查看详细信息,看像素的宽高是不是在416左右。多少几十像素都是没关系的。 +要解决这个问题,只需要在左边的图块属性中定义新的图块ID和图块数字即可。ID必须由数字字母下划线组成,数字在1000以内,且均不能和已有的进行重复。 -![图片大小](./img/imginfo.png) +有关图块的ID和数字定义请参见[素材的机制](personalization#素材的机制)。 -**Q: 打开游戏时卡死在了xxx.js加载完毕!无法进入游戏。** +之后刷新编辑器即可。 -**A:** 最大的可能是因为少了逗号,或者反括号等等。一般而言VSCode都会有错误提示,你哪里少了东西。 +对于怪物和道具,我们也可以进行自动注册,只需要点击“自动注册”按钮,将对该栏下所有未注册的素材进行自动注册(自动分配ID和数字)。 -如果没有,可以采用如下方式debug: +素材注册完毕后,即可在游戏中正常使用,也可以被地图生成器所识别(需要重开地图生成器)。 -Ctrl+Shift+I 打开Chrome的控制台,找到Console。 +## 报错处理 -如果出现了语法错误,会有红色提示 **Unexpected xxx** ,找到后面文件名和行号,打开,使用VSCode检查该处是否存在问题,即可。 +有时候刷新后可能页面变成空白,即无法正确加载,游戏也无法正常进入。 + +出现这种问题的原因往往是如下几种: +- 手动直接打开并错误编辑了文件 +- 文件不存在(被误删等) +- 楼层floorId不合法(必须是字母数字下划线组成,且不能以数字开头) +- 楼层floorId定义存在重复(比如定义了两个MT0层) +- 初始楼层ID不存在(比如修改了全塔属性中的初始楼层ID,但是实际的该ID不存在,也会出错) +- ……(可能各种奇怪的报错问题) + +出现这种问题,(在Chrome浏览器中)请按Ctrl+Shift+I打开控制台,并找到Console查看报错。 + +一般都会具体到哪个楼层文件出错。 + +解决方式:哪个楼层文件出错,请使用VSCode等打开project目录下的data.js文件,并将出错的那个楼层定义删除。 + +例如下面这个问题: ![检查错误](./img/chrome.png) +那么使用VSCode打开data.js文件,并将 "floorIds": [..., "MT1"] 这里对它的楼层定义删除,再刷新即可。 + +![删除ID](./img/floorid.png) + +请注意,手动删除楼层时一定要确保“初始楼层ID”是一个有效且存在的floorId! + +  + +如有任何无法解决的问题,欢迎加群**539113091**寻求帮助。 + ========================================================================================== -[继续阅读下一章:元件说明](element) \ No newline at end of file +[继续阅读下一章:元件说明](element)