diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index add43d86..8957a93c 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -238,6 +238,7 @@ action | win_s | lose_s | if_s + | switch_s | while_s | break_s | continue_s @@ -1236,6 +1237,33 @@ var code = ['{"type": "if", "condition": "',expression_0,'",\n', return code; */; +switch_s + : '多重分歧 条件判定' ':' expression BGNL? Newline switchCase_s+ BEND Newline + + +/* switch_s +tooltip : switch: 多重条件分歧 +helpUrl : https://ckcz123.github.io/mota-js/#/event?id=choices%EF%BC%9A%E7%BB%99%E7%94%A8%E6%88%B7%E6%8F%90%E4%BE%9B%E9%80%89%E9%A1%B9 +default : ["判别值"] +colour : this.eventColor +var code = ['{"type": "switch", "condition": "',expression_0,'", "caseList": [\n', + switchCase_s_0, +'], },\n'].join(''); +return code; +*/; + +switchCase_s + : '如果是' expression '的场合' BGNL? Newline action+ + + +/* switchCase_s +tooltip : 选项的选择 +helpUrl : https://ckcz123.github.io/mota-js/#/event?id=choices%EF%BC%9A%E7%BB%99%E7%94%A8%E6%88%B7%E6%8F%90%E4%BE%9B%E9%80%89%E9%A1%B9 +colour : this.subColor +var code = '{"case": "'+expression_0+'", "action": [\n'+action_0+']},\n'; +return code; +*/; + choices_s : '选项' ':' EvalString? BGNL? '标题' EvalString? '图像' IdString? BGNL? Newline choicesContext+ BEND Newline @@ -1983,6 +2011,15 @@ ActionParser.prototype.parseAction = function() { this.insertActionList(data["false"]), this.next]); break; + case "switch": // 多重条件分歧 + var case_caseList = null; + for(var ii=data.caseList.length-1,caseNow;caseNow=data.caseList[ii];ii--) { + case_caseList=MotaActionBlocks['switchCase_s'].xmlText([ + this.isset(caseNow.case)?MotaActionBlocks['evalString_e'].xmlText([caseNow.case]):"值",this.insertActionList(caseNow.action),case_caseList]); + } + this.next = MotaActionBlocks['switch_s'].xmlText([ + MotaActionBlocks['evalString_e'].xmlText([data.condition]),case_caseList,this.next]); + break; case "choices": // 提供选项 var text_choices = null; for(var ii=data.choices.length-1,choice;choice=data.choices[ii];ii--) { diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 1c4b538b..582f98ff 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -108,6 +108,11 @@ editor_blockly = function () { ], '事件控制':[ MotaActionBlocks['if_s'].xmlText(), + MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别量", "caseList": [ + {"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]}, + {"action": []}, + {"case": "'default'", "action": [{"type": "comment", "text": "当没有符合的值的场合执行此事件"}]}, + ]}), MotaActionBlocks['while_s'].xmlText(), MotaActionBlocks['break_s'].xmlText(), MotaActionBlocks['continue_s'].xmlText(), diff --git a/libs/events.js b/libs/events.js index 220b6ba8..1f435edc 100644 --- a/libs/events.js +++ b/libs/events.js @@ -907,6 +907,18 @@ events.prototype.doAction = function() { core.events.insertAction(data["false"]) this.doAction(); break; + case "switch": // 条件选择 + var key = core.calValue(data.condition) + console.log(key); + for (var i = 0; i < data.caseList.length; i++) { + console.log(core.calValue(data.caseList[i].case)); + if (core.calValue(data.caseList[i].case) == key || core.calValue(data.caseList[i].case) == "default") { + core.events.insertAction(data.caseList[i].action); + this.doAction(); + break; + } + } + break; case "choices": // 提供选项 if (core.status.replay.replaying) { if (core.status.replay.toReplay.length==0) { // 回放完毕 diff --git a/project/floors/sample1.js b/project/floors/sample1.js index 87bbb9b2..a7ab22f8 100644 --- a/project/floors/sample1.js +++ b/project/floors/sample1.js @@ -1,340 +1,787 @@ -main.floors.sample1 = +main.floors.sample1= { - "floorId": "sample1", // 这里需要改楼层名,请和文件名及下面的floorId保持完全一致 - // 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头 - // 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等 - // 楼层唯一标识符,需要和名字完全一致 - "title": "样板 1 层", // 楼层中文名 - "name": "1", // 显示在状态栏中的层数 - "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) - "canUseQuickShop": true, // 该层是否允许使用快捷商店 - "defaultGround": "grass", // 默认地面的图块ID(terrains中) - "images": [[0,0,"bg.jpg",false]], // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。 - // "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 - "weather": ["snow",6], // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。 - // "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 - "item_ratio": 1, // 该层的宝石/血瓶倍率 - "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 - [ 7,131, 8,152, 9,130, 10,152,166,165,132,165,166], - [ 0, 0, 0, 0, 0, 0, 0,152,165,164, 0,162,165], - [152,152,152,152,121,152,152,152, 0, 0,229, 0, 0], - [ 43, 33, 44,151, 0, 0, 0,152,165,161, 0,163,165], - [ 21, 22, 21,151, 0, 0, 0,152,166,165, 0,165,166], - [151,245,151,151, 0, 87, 0,152,152,152, 85,153,153], - [ 0,246, 0,151, 0, 0, 0,152,152,221, 0,221,153], - [246, 0,246,151, 0, 0, 0,121, 85, 0, 0, 0,153], - [151,246,151,151, 0,153,153,153,153,153,153,153,153], - [ 0, 0, 0, 0, 0, 0, 0,164, 0, 0,163, 0, 0], - [ 1, 1, 1, 1, 0, 20, 0, 0, 0,162, 0,161, 0], - [ 1, 0,123, 1, 0, 20,124, 0,121, 0,122, 0,126], - [ 1, 0, 0, 1, 88, 20, 86, 0, 0, 0, 0, 0, 0] +"floorId": "sample1", +"title": "样板 1 层", +"name": "1", +"canFlyTo": true, +"canUseQuickShop": true, +"defaultGround": "grass", +"images": [ + [ + 0, + 0, + "bg.jpg", + false + ] +], +"weather": [ + "snow", + 6 +], +"item_ratio": 1, +"map": [ + [ 7,131, 8,152, 9,130, 10,152,166,165,132,165,166], + [ 0, 0, 0, 0, 0, 0, 0,152,165,164, 0,162,165], + [152,152,152,152,121,152,152,152, 0, 0,229, 0, 0], + [ 43, 33, 44,151, 0, 0, 0,152,165,161, 0,163,165], + [ 21, 22, 21,151, 0, 0, 0,152,166,165, 0,165,166], + [151,245,151,151, 0, 87, 0,152,152,152, 85,153,153], + [ 0,246, 0,151, 0, 0, 0,152,152,221, 0,221,153], + [246, 0,246,151, 0, 0, 0,121, 85, 0, 0, 0,153], + [151,246,151,151, 0,153,153,153,153,153,153,153,153], + [ 0, 0, 0, 0, 0, 0, 0,164, 0, 0,163, 0, 0], + [ 1, 1, 1, 1, 0, 20, 0, 0, 0,162, 0,161, 0], + [ 1, 0,123, 1, 0, 20,124, 0,121, 0,122, 0,126], + [ 1, 0, 0, 1, 88, 20, 86, 0, 0, 0, 0, 0,122] +], +"firstArrive": [], +"events": { + "4,10": [ + "\t[样板提示]本层楼将会对各类事件进行介绍。", + "左边是一个仿50层的陷阱做法,上方是商店、快捷商店的使用方法,右上是一个典型的杀怪开门的例子,右下是各类可能的NPC事件。", + "本样板目前支持的事件列表大致有:\ntext: 显示一段文字(比如你现在正在看到的)\ntip: 左上角显示提示\nshow: 使一个事件有效(可见、可被交互)\nhide: 使一个事件失效(不可见、不可被交互)\ntrigger: 触发另一个地点的事件\nanimate: 显示动画\nbattle: 强制和某怪物战斗\nopenDoor: 无需钥匙开门(例如机关门、暗墙)", + "openShop: 打开一个全局商店\ndisableShop: 禁用一个全局商店\nchangeFloor: 传送勇士到某层某位置\nchangePos: 传送勇士到当层某位置;转向\nshowImage: 显示图片\nsetFg: 更改画面色调\nsetWeather: 更改天气\nmove: 移动事件效果\nmoveHero: 移动勇士效果\nplayBgm: 播放某个背景音乐\npauseBgm: 暂停背景音乐\nresumeBgm: 恢复背景音乐的播放\nplaySound: 播放某个音频", + "if: 条件判断\nchoices: 提供选项\nsetValue: 设置勇士属性道具,或某个变量/flag\nupdate: 更新状态栏和地图显伤\nwin: 获得胜利(游戏通关)\nlose: 游戏失败\nsleep: 等待多少毫秒\nexit: 立刻结束当前事件\nrevisit: 立刻结束事件并重新触发\nfunction: 自定义JS脚本\n\n更多支持的事件还在编写中,欢迎您宝贵的意见。", + "有关各事件的样例,可参见本层一些NPC的写法。\n所有事件样例本层都有介绍。\n\n一个自定义事件处理完后,需要调用{\"type\": \"hide\"}该事件才不会再次出现。", + { + "type": "hide" + } ], - "firstArrive": [ // 第一次到该楼层触发的事件 - + "1,5": { + "enable": false, + "data": [] + }, + "1,6": { + "enable": false, + "data": [] + }, + "0,7": { + "enable": false, + "data": [] + }, + "2,7": { + "enable": false, + "data": [] + }, + "1,8": { + "enable": false, + "data": [] + }, + "1,7": [ + { + "type": "show", + "loc": [ + 1, + 5 + ], + "time": 1500 + }, + { + "type": "sleep", + "time": 500 + }, + "\t[redKing]欢迎来到魔塔,你是第一百位挑战者。\n若你能打败我所有的手下,我就与你一对一的决斗。\n现在你必须接受我的安排。", + { + "type": "show", + "loc": [ + [ + 1, + 6 + ], + [ + 0, + 7 + ], + [ + 1, + 8 + ], + [ + 2, + 7 + ] + ], + "time": 500 + }, + "\t[hero]什么?", + { + "type": "playSound", + "name": "attack.mp3" + }, + { + "type": "setValue", + "name": "status:atk", + "value": "status:atk/10" + }, + { + "type": "setValue", + "name": "status:def", + "value": "status:def/10" + }, + { + "type": "hide", + "loc": [ + [ + 1, + 6 + ], + [ + 0, + 7 + ], + [ + 2, + 7 + ], + [ + 1, + 8 + ] + ] + }, + { + "type": "hide", + "loc": [ + 1, + 5 + ], + "time": 500 + }, + { + "type": "hide" + }, + { + "type": "setFg", + "color": [ + 0, + 0, + 0 + ], + "time": 1250 + }, + { + "type": "sleep", + "time": 700 + }, + { + "type": "changeFloor", + "floorId": "sample1", + "loc": [ + 1, + 11 + ], + "direction": "right", + "time": 1000 + }, + { + "type": "trigger", + "loc": [ + 2, + 11 + ] + } ], - "events": { // 该楼的所有可能事件列表 - - "4,10": [ // 走到中间时的提示 - "\t[样板提示]本层楼将会对各类事件进行介绍。", - "左边是一个仿50层的陷阱做法,上方是商店、快捷商店的使用方法,右上是一个典型的杀怪开门的例子,右下是各类可能的NPC事件。", - "本样板目前支持的事件列表大致有:\ntext: 显示一段文字(比如你现在正在看到的)\ntip: 左上角显示提示\nshow: 使一个事件有效(可见、可被交互)\nhide: 使一个事件失效(不可见、不可被交互)\ntrigger: 触发另一个地点的事件\nanimate: 显示动画\nbattle: 强制和某怪物战斗\nopenDoor: 无需钥匙开门(例如机关门、暗墙)", - "openShop: 打开一个全局商店\ndisableShop: 禁用一个全局商店\nchangeFloor: 传送勇士到某层某位置\nchangePos: 传送勇士到当层某位置;转向\nshowImage: 显示图片\nsetFg: 更改画面色调\nsetWeather: 更改天气\nmove: 移动事件效果\nmoveHero: 移动勇士效果\nplayBgm: 播放某个背景音乐\npauseBgm: 暂停背景音乐\nresumeBgm: 恢复背景音乐的播放\nplaySound: 播放某个音频", - "if: 条件判断\nchoices: 提供选项\nsetValue: 设置勇士属性道具,或某个变量/flag\nupdate: 更新状态栏和地图显伤\nwin: 获得胜利(游戏通关)\nlose: 游戏失败\nsleep: 等待多少毫秒\nexit: 立刻结束当前事件\nrevisit: 立刻结束事件并重新触发\nfunction: 自定义JS脚本\n\n更多支持的事件还在编写中,欢迎您宝贵的意见。", - "有关各事件的样例,可参见本层一些NPC的写法。\n所有事件样例本层都有介绍。\n\n一个自定义事件处理完后,需要调用{\"type\": \"hide\"}该事件才不会再次出现。", - {"type": "hide"} - ], - - /****** 左边仿50F陷阱事件 ******/ - "1,5": {"enable": false}, // 这几个是白衣武士等怪物,起始时需要隐藏起来 - "1,6": {"enable": false}, - "0,7": {"enable": false}, - "2,7": {"enable": false}, - "1,8": {"enable": false}, - "1,7": [ // 走到白衣武士中间,触发陷阱事件 - {"type": "show", "loc": [1,5], "time": 1500}, // 显示红衣魔王,动画效果1500ms - {"type": "sleep", "time": 500}, // 等待500ms - "\t[redKing]欢迎来到魔塔,你是第一百位挑战者。\n若你能打败我所有的手下,我就与你一对一的决斗。\n现在你必须接受我的安排。", - {"type": "show", "loc": [[1,6],[0,7],[1,8],[2,7]], "time": 500}, // 显示四个白衣武士,每个动画效果500ms - "\t[hero]什么?", - {"type": "playSound", "name": "attack.mp3"}, // 播放战斗音频 - {"type": "setValue", "name": "status:atk", "value": "status:atk/10"}, // 勇士的攻防变成原来的十分之一 - {"type": "setValue", "name": "status:def", "value": "status:def/10"}, - {"type": "hide", "loc": [[1,6],[0,7],[2,7],[1,8]]}, // 直接隐藏四个白衣武士,没有动画效果 - {"type": "hide", "loc": [1,5], "time": 500}, // 隐藏红衣魔王,动画500ms - {"type": "hide"}, // 隐藏本事件 - {"type": "setFg", "color": [0,0,0], "time": 1250}, // 渐变为白色 - {"type": "sleep", "time": 700}, - {"type": "changeFloor", "floorId": "sample1", "loc": [1,11], "direction": "right", "time": 1000}, // 楼层切换。changeFloor必须指定floorId和loc。 - // 备注:这里也可以下面的这种写法: - // {"type": "changePos", "loc": [1,11]} - // 使用这种写法将不会有“楼层切换动画”,而是直接让勇士到达本层的loc位置。 - {"type": "trigger", "loc": [2,11]} // 立刻直接触发另一个事件(也就是下面的小偷事件);当前事件会被立刻结束 - ], - "2,11": [ // 小偷事件 - "\t[杰克,thief]喂!醒醒!快醒醒!", - {"type": "setFg", "time": 1500}, // 渐变回来 - "\t[hero]额,我这是在什么地方?", - "\t[杰克,thief]你被魔王抓了起来扔进了监狱,和我关在了一起,但是幸运的是我在昨天刚刚挖好一条越狱的暗道!", - {"type": "openDoor", "loc": [3,11]}, // 开门或墙必须指定门/墙的名称,否则不会执行 - {"type": "sleep", "time": 300}, // 等待300ms - "\t[杰克,thief]我先走了,祝你好运!", - {"type": "move", "time": 750, "steps": [ // 动画移动效果,time为每步事件(毫秒),steps是个数组指定了移动的方位 - {"direction": "right", "value": 2}, // 向右移动两步,再向下移动一步,并消失 - "down" // 如果该方向只移动一步,可以直接这样简写。 这种写法等价于: {"direction":"down","value":1} - ]}, - // 调用move事件后,hide事件也会被自动调用,因此无需再手动调用 {"type":"hide"} 来隐藏本事件了 - "上面是个move事件,可以对NPC等进行移动。\n详见样板中小偷事件的写法。", - "\t[hero]怎么跑的这么快..." - ], - - /****** 上方商店事件相关 ******/ - "4,2": [ // 商店门前的老人 - "\t[老人,man]本塔的商店有两类,全局商店和非全局商店。\n\n所谓非全局商店,就类似于右下角那个卖钥匙的老人一样,一定要碰到才能触发事件。\n\n而全局商店,则能在快捷商店中直接使用。", - "\t[老人,man]要注册一个全局商店,你需要在 data.js 中,找到 shops,并在内添加你的商店信息。", - "\t[老人,man]商店信息添加后,可以在需要的事件处调用{\"type\": \"openShop\"}来打开你添加的全局商店。", - "\t[老人,man]在上面的例子里,左边是一个仿50层的金币商店,右边是一个仿24层的经验商店。\n\n商店被访问后即可在快捷商店中进行使用。", - "\t[老人,man]如果你需要在某层暂时禁用快捷商店,可以在data.js中设置cannotUseQuickShop。\n如果需要永久禁用商店,请使用{\"type\":\"disableShop\"}", - {"type": "hide", "time": 500} - ], - "1,0": [ // 金币商店 - // 打开商店前,你也可以添加自己的剧情 - // 例如,通过if来事件来判断是不是第一次访问商店,是的则显示一段文字(类似宿命的华音那样) - {"type": "openShop", "id": "moneyShop1"} // 这里的id要和data.js中你定义的商店ID完全一致 - // 调用openShop事件后,所有当前事件都会被结束(同exit事件),然后打开一个全局商店 - ], - "5,0": [ // 经验商店 - {"type": "openShop", "id": "expShop1"} - ], - - - - /****** 右边陷阱、战斗相关 ******/ - "7,7": [ // 门口老人的提示 - "\t[老人,man]这是一个典型的杀怪开门、强制战斗事件。", - {"type": "hide"} // 不显示动画,直接消失 - ], - "8,7": {"enable": false}, // 门口的机关门,初始时是禁用状态 - "9,7": [ // 当你刚进去后,触发机关门 - {"type": "show", "loc": [8,7]}, // 显示机关门 - {"type": "hide"} // 该事件消失 - ], - // 注意:初级卫兵打死后的开门事件是在 afterBattle 中调用 - "10,4": [ // 开门后走进去的事件:强制战斗 - "\t[blackKing]你终于还是来了。", - "\t[hero]放开我们的公主!", - "\t[blackKing]如果我不愿意呢?", - "\t[hero]无需多说,拔剑吧!", - {"type": "battle", "id": "blackKing"}, // 强制战斗 - // 如果战斗失败直接死亡,不会继续触发接下来的剧情。 - {"type": "hide", "loc": [10,2]}, // 战斗后需要手动使怪物消失;战斗后不会引发afterBattle事件。 - {"type": "openDoor", "loc": [8,7]}, // 开门口的机关门 - "\t[blackKing]没想到你已经变得这么强大了... 算你厉害。\n公主就交给你了,请好好对她。", - {"type": "hide"} // 隐藏本事件 - ], - "10,0": [ // 公主事件 - "\t[hero]公主,我来救你了~", - "\t[公主,princess]快救我出去!我受够这里了!", - "\t[hero]公主别怕,我们走吧~", - {"type": "win", "reason": "救出公主"} // 获得胜利。此事件将显示获胜界面,并结束游戏。 - // 该事件将直接调用events.js中的win()函数;如需修改获胜界面内容可前往修改。 - // 下面这个是失败事件,同样会直接调用events.js中的lose()函数;如需修改失败界面内容可以前往修改。 - // {"type": "lose", "reason": "救了假公主"} - ], - - - - /****** 右下各种NPC事件相关 ******/ - "6,12": {"enable":false}, // 仙子下面的铁门,初始时是禁用的 - "6,11": [ // 仙子事件 - "\t[仙子,fairy]通过调用 {\"type\": \"show\"} 可以使隐藏的事件显示出来。\n比如我下面这个机关门。", - {"type": "show", "loc": [6,12]}, // 使隐藏的铁门显示出来 - "\t[仙子,fairy]通过调用 {\"type\": \"openDoor\"} 可以无需钥匙打开一扇门或暗墙。", - {"type": "openDoor", "loc": [6,12]}, // 开门 - "\t[仙子,fairy]同时,也可以对其它层进行操作,比如楼下的机关门,现在已经为你打开了。", - {"type": "openDoor", "loc": [11,10], "floorId": "sample0"}, // 打开其它层的门,需要指定floorId - "\t[仙子,fairy]如果 show 或 hide 指定了 time 参数,则以动画效果显示,指定的参数作为消失时间(毫秒)来计算。", - "\t[仙子,fairy]现在到楼下来找我吧~", - {"type": "show", "loc": [12,10], "floorId": "sample0"}, // 显示其它层的事件,需要指定其floorId - {"type": "hide", "time": 500} - ], - "8,11": [ // 老人事件,勇士状态的显示与变化 - {"type": "setValue", "name": "flag:man_times", "value": "flag:man_times+1"}, // 设置这个老人的访问次数 - "\t[老人,man]在文字中使用${' ${ '}和 } 可以计算并显示一个表达式的结果。\n", - "\t[老人,man]例如:\n你的当前攻击力是${status:atk},防御力是${status:def}。\n攻防和的十倍是${10*(status:atk+status:def)},攻防之积是${status:atk*status:def}。\n你有${item:yellowKey}把黄钥匙,${item:blueKey}把蓝钥匙,${item:redKey}把红钥匙。\n你有${item:pickaxe}个破,${item:bomb}个炸,${item:centerFly}个飞。\n这是你第${flag:man_times}次和我对话。", - "\t[老人,man]同时,你也可以通过{\"type\": \"setValue\"}来设置一个勇士的属性、道具,或某个Flag。", - "\t[老人,man]例如:\n现在我将让你的攻防提升50%,再将攻防和的十倍加到生命值上。", - {"type": "setValue", "name": "status:atk", "value": "status:atk*1.5"}, // 攻击提升50%;注意不要加${} - {"type": "setValue", "name": "status:def", "value": "status:def*1.5"}, // 防御提升50%;注意不要加${} - {"type": "setValue", "name": "status:hp", "value": "status:hp+10*(status:atk+status:def)"}, //生命提升攻防和的十倍 - "\t[老人,man]再送你500金币,1000经验,1破2炸3飞!", - {"type": "setValue", "name": "status:money", "value": "status:money+500"}, - {"type": "setValue", "name": "status:experience", "value": "status:experience+1000"}, - {"type": "setValue", "name": "item:pickaxe", "value": "item:pickaxe+1"}, // 1破 - {"type": "setValue", "name": "item:bomb", "value": "item:bomb+2"}, // 2炸 - {"type": "setValue", "name": "item:centerFly", "value": "item:centerFly+3"}, // 3飞 - "\t[老人,man]status:xxx 代表勇士的某个属性。\n其中xxx可取hp, atk, def, mdef, money,experience这几项。\n\nitem:xxx 代表勇士的某个道具的个数。\nxxx为道具ID,具体可参见items.js中的定义。\n\nflag:xxx 代表某个自定义Flag或变量。\nxxx为Flag/变量名,可以自行定义,由字母、数字和下划线组成。\n未定义过而直接取用的Flag默认值为false。", - // 如果老人不消失,则不要调用 {"type": "hide"} - "\t[老人,man]你现在可以重新和我进行对话,进一步看到属性值的改变。" - ], - "10,11": [ // 商人事件,if语句和choices语句的写法 - // 这部分逻辑相对比较长,细心看,很容易看懂的。 - {"type": "if", "condition": "flag:woman_times==0", // 条件判断:是否从未访问过此商人。 - "true": [ // 如果从未访问过该商人,显示一段文字 - "\t[老人,woman]这是个很复杂的例子,它将教会你如何使用if 语句进行条件判断,以及 choices 提供选项来供用户进行选择。", - "\t[老人,woman]第一次访问我将显示这段文字;从第二次开始将会向你出售钥匙。\n钥匙价格将随着访问次数递增。\n当合计出售了七把钥匙后,将送你一把大黄门钥匙,并消失不再出现。", - "\t[老人,woman]这部分的逻辑比较长,请细心看样板的写法,是很容易看懂并理解的。" - // 第一次访问结束 - ], - "false": [ // 如果已经访问过该商人 - {"type": "if", "condition": "flag:woman_times==8", // 条件判断:是否已经出售七把钥匙 - "true": [ // 如果已经出售过七把钥匙,则直接结束 - "\t[老人,woman]你购买的钥匙已经够多了,再继续卖给你的话我会有危险的。", - "\t[老人,woman]看在你贡献给我这么多钱的份上,送你一把大黄门钥匙吧,希望你能好好用它。", - {"type": "setValue", "name": "item:bigKey", "value": "item:bigKey+1"}, // 获得一把大黄门钥匙 - "\t[老人,woman]我先走了,拜拜~", - {"type":"hide", "time": 500}, // 消失 - {"type":"exit"} // 立刻结束当前事件。下面的 setValue 和 revisit 都不会再执行。 - ], - "false": [ // 否则,显示选择页面 - {"type": "choices", "text": "\t[老人,woman]少年,你需要钥匙吗?\n我这里有大把的!", // 显示一个选择页面 - "choices": [ // 提供四个选项:黄钥匙、蓝钥匙、红钥匙、离开。前三个选项显示需要的金额 - {"text": "黄钥匙(${9+flag:woman_times}金币)", "action": [ // 第一个选项,黄钥匙 - // 选择该选项的执行内容 - // 条件判断:钱够不够 - {"type": "if", "condition": "status:money>=9+flag:woman_times", + "2,11": [ + "\t[杰克,thief]喂!醒醒!快醒醒!", + { + "type": "setFg", + "time": 1500 + }, + "\t[hero]额,我这是在什么地方?", + "\t[杰克,thief]你被魔王抓了起来扔进了监狱,和我关在了一起,但是幸运的是我在昨天刚刚挖好一条越狱的暗道!", + { + "type": "openDoor", + "loc": [ + 3, + 11 + ] + }, + { + "type": "sleep", + "time": 300 + }, + "\t[杰克,thief]我先走了,祝你好运!", + { + "type": "move", + "time": 750, + "steps": [ + { + "direction": "right", + "value": 2 + }, + "down" + ] + }, + "上面是个move事件,可以对NPC等进行移动。\n详见样板中小偷事件的写法。", + "\t[hero]怎么跑的这么快..." + ], + "4,2": [ + "\t[老人,man]本塔的商店有两类,全局商店和非全局商店。\n\n所谓非全局商店,就类似于右下角那个卖钥匙的老人一样,一定要碰到才能触发事件。\n\n而全局商店,则能在快捷商店中直接使用。", + "\t[老人,man]要注册一个全局商店,你需要在 data.js 中,找到 shops,并在内添加你的商店信息。", + "\t[老人,man]商店信息添加后,可以在需要的事件处调用{\"type\": \"openShop\"}来打开你添加的全局商店。", + "\t[老人,man]在上面的例子里,左边是一个仿50层的金币商店,右边是一个仿24层的经验商店。\n\n商店被访问后即可在快捷商店中进行使用。", + "\t[老人,man]如果你需要在某层暂时禁用快捷商店,可以在data.js中设置cannotUseQuickShop。\n如果需要永久禁用商店,请使用{\"type\":\"disableShop\"}", + { + "type": "hide", + "time": 500 + } + ], + "1,0": [ + { + "type": "openShop", + "id": "moneyShop1" + } + ], + "5,0": [ + { + "type": "openShop", + "id": "expShop1" + } + ], + "7,7": [ + "\t[老人,man]这是一个典型的杀怪开门、强制战斗事件。", + { + "type": "hide" + } + ], + "8,7": { + "enable": false, + "data": [] + }, + "9,7": [ + { + "type": "show", + "loc": [ + 8, + 7 + ] + }, + { + "type": "hide" + } + ], + "10,4": [ + "\t[blackKing]你终于还是来了。", + "\t[hero]放开我们的公主!", + "\t[blackKing]如果我不愿意呢?", + "\t[hero]无需多说,拔剑吧!", + { + "type": "battle", + "id": "blackKing" + }, + { + "type": "hide", + "loc": [ + 10, + 2 + ] + }, + { + "type": "openDoor", + "loc": [ + 8, + 7 + ] + }, + "\t[blackKing]没想到你已经变得这么强大了... 算你厉害。\n公主就交给你了,请好好对她。", + { + "type": "hide" + } + ], + "10,0": [ + "\t[hero]公主,我来救你了~", + "\t[公主,princess]快救我出去!我受够这里了!", + "\t[hero]公主别怕,我们走吧~", + { + "type": "win", + "reason": "救出公主" + } + ], + "6,12": { + "enable": false, + "data": [] + }, + "6,11": [ + "\t[仙子,fairy]通过调用 {\"type\": \"show\"} 可以使隐藏的事件显示出来。\n比如我下面这个机关门。", + { + "type": "show", + "loc": [ + 6, + 12 + ] + }, + "\t[仙子,fairy]通过调用 {\"type\": \"openDoor\"} 可以无需钥匙打开一扇门或暗墙。", + { + "type": "openDoor", + "loc": [ + 6, + 12 + ] + }, + "\t[仙子,fairy]同时,也可以对其它层进行操作,比如楼下的机关门,现在已经为你打开了。", + { + "type": "openDoor", + "loc": [ + 11, + 10 + ], + "floorId": "sample0" + }, + "\t[仙子,fairy]如果 show 或 hide 指定了 time 参数,则以动画效果显示,指定的参数作为消失时间(毫秒)来计算。", + "\t[仙子,fairy]现在到楼下来找我吧~", + { + "type": "show", + "loc": [ + 12, + 10 + ], + "floorId": "sample0" + }, + { + "type": "hide", + "time": 500 + } + ], + "8,11": [ + { + "type": "setValue", + "name": "flag:man_times", + "value": "flag:man_times+1" + }, + "\t[老人,man]在文字中使用${' ${ '}和 } 可以计算并显示一个表达式的结果。\n", + "\t[老人,man]例如:\n你的当前攻击力是${status:atk},防御力是${status:def}。\n攻防和的十倍是${10*(status:atk+status:def)},攻防之积是${status:atk*status:def}。\n你有${item:yellowKey}把黄钥匙,${item:blueKey}把蓝钥匙,${item:redKey}把红钥匙。\n你有${item:pickaxe}个破,${item:bomb}个炸,${item:centerFly}个飞。\n这是你第${flag:man_times}次和我对话。", + "\t[老人,man]同时,你也可以通过{\"type\": \"setValue\"}来设置一个勇士的属性、道具,或某个Flag。", + "\t[老人,man]例如:\n现在我将让你的攻防提升50%,再将攻防和的十倍加到生命值上。", + { + "type": "setValue", + "name": "status:atk", + "value": "status:atk*1.5" + }, + { + "type": "setValue", + "name": "status:def", + "value": "status:def*1.5" + }, + { + "type": "setValue", + "name": "status:hp", + "value": "status:hp+10*(status:atk+status:def)" + }, + "\t[老人,man]再送你500金币,1000经验,1破2炸3飞!", + { + "type": "setValue", + "name": "status:money", + "value": "status:money+500" + }, + { + "type": "setValue", + "name": "status:experience", + "value": "status:experience+1000" + }, + { + "type": "setValue", + "name": "item:pickaxe", + "value": "item:pickaxe+1" + }, + { + "type": "setValue", + "name": "item:bomb", + "value": "item:bomb+2" + }, + { + "type": "setValue", + "name": "item:centerFly", + "value": "item:centerFly+3" + }, + "\t[老人,man]status:xxx 代表勇士的某个属性。\n其中xxx可取hp, atk, def, mdef, money,experience这几项。\n\nitem:xxx 代表勇士的某个道具的个数。\nxxx为道具ID,具体可参见items.js中的定义。\n\nflag:xxx 代表某个自定义Flag或变量。\nxxx为Flag/变量名,可以自行定义,由字母、数字和下划线组成。\n未定义过而直接取用的Flag默认值为false。", + "\t[老人,man]你现在可以重新和我进行对话,进一步看到属性值的改变。" + ], + "10,11": [ + { + "type": "if", + "condition": "flag:woman_times==0", + "true": [ + "\t[老人,woman]这是个很复杂的例子,它将教会你如何使用if 语句进行条件判断,以及 choices 提供选项来供用户进行选择。", + "\t[老人,woman]第一次访问我将显示这段文字;从第二次开始将会向你出售钥匙。\n钥匙价格将随着访问次数递增。\n当合计出售了七把钥匙后,将送你一把大黄门钥匙,并消失不再出现。", + "\t[老人,woman]这部分的逻辑比较长,请细心看样板的写法,是很容易看懂并理解的。" + ], + "false": [ + { + "type": "if", + "condition": "flag:woman_times==8", + "true": [ + "\t[老人,woman]你购买的钥匙已经够多了,再继续卖给你的话我会有危险的。", + "\t[老人,woman]看在你贡献给我这么多钱的份上,送你一把大黄门钥匙吧,希望你能好好用它。", + { + "type": "setValue", + "name": "item:bigKey", + "value": "item:bigKey+1" + }, + "\t[老人,woman]我先走了,拜拜~", + { + "type": "hide", + "time": 500 + }, + { + "type": "exit" + } + ], + "false": [ + { + "type": "choices", + "text": "\t[老人,woman]少年,你需要钥匙吗?\n我这里有大把的!", + "choices": [ + { + "text": "黄钥匙(${9+flag:woman_times}金币)", + "action": [ + { + "type": "if", + "condition": "status:money>=9+flag:woman_times", "true": [ - {"type": "setValue", "name": "status:money", "value": "status:money-(9+flag:woman_times)"}, // 扣减金钱 - {"type": "setValue", "name": "item:yellowKey", "value": "item:yellowKey+1"}, // 增加黄钥匙 - // 然后会继续执行下面的setValue来增加商人访问次数 + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(9+flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:yellowKey", + "value": "item:yellowKey+1" + } ], "false": [ "\t[老人,woman]你的金钱不足!", - {"type": "revisit"} // 直接重新访问;不执行下面的setValue来增加访问次数 + { + "type": "revisit" + } ] } - ]}, - {"text": "蓝钥匙(${18+2*flag:woman_times}金币)", "action": [ // 第二个选项:蓝钥匙 - // 逻辑和上面黄钥匙完全相同,不赘述 - {"type": "if", "condition": "status:money>=18+2*flag:woman_times", + ] + }, + { + "text": "蓝钥匙(${18+2*flag:woman_times}金币)", + "action": [ + { + "type": "if", + "condition": "status:money>=18+2*flag:woman_times", "true": [ - {"type": "setValue", "name": "status:money", "value": "status:money-(18+2*flag:woman_times)"}, - {"type": "setValue", "name": "item:blueKey", "value": "item:blueKey+1"}, + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(18+2*flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:blueKey", + "value": "item:blueKey+1" + } ], "false": [ "\t[老人,woman]你的金钱不足!", - {"type": "revisit"} + { + "type": "revisit" + } ] } - ]}, - {"text": "红钥匙(${36+4*flag:woman_times}金币)", "action": [ // 第三个选项:红钥匙 - // 逻辑和上面黄钥匙完全相同,不赘述 - {"type": "if", "condition": "status:money>=36+4*flag:woman_times", + ] + }, + { + "text": "红钥匙(${36+4*flag:woman_times}金币)", + "action": [ + { + "type": "if", + "condition": "status:money>=36+4*flag:woman_times", "true": [ - {"type": "setValue", "name": "status:money", "value": "status:money-(36+4*flag:woman_times)"}, - {"type": "setValue", "name": "item:redKey", "value": "item:redKey+1"}, + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(36+4*flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:redKey", + "value": "item:redKey+1" + } ], "false": [ "\t[老人,woman]你的金钱不足!", - {"type": "revisit"} + { + "type": "revisit" + } ] } - ]}, - {"text": "离开", "action": [ // 第四个选项:离开 - {"type": "exit"} // 立刻结束当前事件 - ]} - ] - } - ] - } - ] - }, - {"type": "setValue", "name": "flag:woman_times", "value": "flag:woman_times+1"}, // 增加该商人的访问次数。 - {"type": "revisit"} // 立即重新开始这个事件 - ], - "12,11": [ // 自定义事件的老人 - "\t[老人,womanMagician]使用 {\"type\":\"function\"} 可以写自定义的JS脚本。\n本塔支持的所有主要API会在doc文档内给出。", - "\t[老人,womanMagician]例如这个例子:即将弹出一个输入窗口,然后会将你的输入结果直接加到你的攻击力上。", - /* - {"type": "function", "function": function() { // 自己写JS脚本并执行 - - // 注意一下prompt对于录像是如何处理的 - var value; - if (core.status.replay.replaying) { - var action = core.status.replay.toReplay.shift(); - if (action.indexOf("input:")==0 ) { - value=parseInt(action.substring(6)); - } - else { - core.stopReplay(); - core.drawTip("录像文件出错"); - return; - } + ] + }, + { + "text": "离开", + "action": [ + { + "type": "exit" + } + ] + } + ] + } + ] } - else { - value = prompt("请输入你要加攻击力的数值:"); + ] + }, + { + "type": "setValue", + "name": "flag:woman_times", + "value": "flag:woman_times+1" + }, + { + "type": "revisit" + } + ], + "12,11": [ + "\t[老人,womanMagician]使用 {\"type\":\"function\"} 可以写自定义的JS脚本。\n本塔支持的所有主要API会在doc文档内给出。", + "\t[老人,womanMagician]例如这个例子:即将弹出一个输入窗口,然后会将你的输入结果直接加到你的攻击力上。", + { + "type": "input", + "text": "请输入你要加攻击力的数值:" + }, + { + "type": "if", + "condition": "flag:input>0", + "true": [ + { + "type": "setValue", + "name": "status:atk", + "value": "status:atk+flag:input" + }, + { + "type": "tip", + "text": "操作成功,攻击+${flag:input}" + }, + "操作成功,攻击+${flag:input}" + ], + "false": [] + }, + "\t[老人,womanMagician]具体可参见样板中本事件的写法。" + ], + "10,12": null, + "12,12": [ + { + "type": "switch", + "condition": "flag:woman_times", + "caseList": [ + { + "case": "0", + "action": [ + "\t[老人,woman]现在使用switch改写这个例子" + ] + }, + { + "case": "8", + "action": [ + "\t[老人,woman]你购买的钥匙已经够多了,再继续卖给你的话我会有危险的。", + "\t[老人,woman]看在你贡献给我这么多钱的份上,送你一把大黄门钥匙吧,希望你能好好用它。", + { + "type": "setValue", + "name": "item:bigKey", + "value": "item:bigKey+1" + }, + "\t[老人,woman]我先走了,拜拜~", + { + "type": "hide", + "time": 500 + }, + { + "type": "exit" + } + ] + }, + { + "case": "'default'", + "action": [ + { + "type": "comment", + "text": "当没有符合的值的场合执行此事件" + }, + { + "type": "choices", + "text": "\t[老人,woman]少年,你需要钥匙吗?\n我这里有大把的!", + "choices": [ + { + "text": "黄钥匙(${9+flag:woman_times}金币)", + "action": [ + { + "type": "if", + "condition": "status:money>=9+flag:woman_times", + "true": [ + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(9+flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:yellowKey", + "value": "item:yellowKey+1" + } + ], + "false": [ + "\t[老人,woman]你的金钱不足!", + { + "type": "revisit" + } + ] + } + ] + }, + { + "text": "蓝钥匙(${18+2*flag:woman_times}金币)", + "action": [ + { + "type": "if", + "condition": "status:money>=18+2*flag:woman_times", + "true": [ + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(18+2*flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:blueKey", + "value": "item:blueKey+1" + } + ], + "false": [ + "\t[老人,woman]你的金钱不足!", + { + "type": "revisit" + } + ] + } + ] + }, + { + "text": "红钥匙(${36+4*flag:woman_times}金币)", + "action": [ + { + "type": "if", + "condition": "status:money>=36+4*flag:woman_times", + "true": [ + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(36+4*flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:redKey", + "value": "item:redKey+1" + } + ], + "false": [ + "\t[老人,woman]你的金钱不足!", + { + "type": "revisit" + } + ] + } + ] + }, + { + "text": "离开", + "action": [ + { + "type": "exit" + } + ] + } + ] + } + ] } - value = parseInt(value)||0; - core.status.route.push("input:"+value); - - if (value>0) { // 检查 - core.setStatus("atk", core.getStatus("atk")+value); - // core.updateStatusBar(); // 和下面的 {"type": "update"} 等价,立即更新状态栏和地图显伤 - core.drawTip("操作成功,攻击+"+value); // 左上角气泡提示 - core.events.insertAction([ // 往当前事件列表前插入两条事件 - {"type": "update"}, // 更新状态栏和地图显伤 - "操作成功,攻击+"+value // 对话框提示 - ]); - } - }}, - */ - {"type": "input", "text": "请输入你要加攻击力的数值:"}, - {"type": "if", "condition": "flag:input>0", - "true": [ - {"type": "setValue", "name": "status:atk", "value": "status:atk+flag:input"}, - {"type": "tip", "text": "操作成功,攻击+${flag:input}"}, - "操作成功,攻击+${flag:input}" - ], - "false": [ - - ] - }, - "\t[老人,womanMagician]具体可参见样板中本事件的写法。" + ] + }, + { + "type": "setValue", + "name": "flag:woman_times", + "value": "flag:woman_times+1" + }, + { + "type": "revisit" + } + ] +}, +"changeFloor": { + "4,12": { + "floorId": "sample0", + "loc": [ + 6, + 0 ] }, - "changeFloor": { // 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖 - "4,12": {"floorId": "sample0", "loc": [6,0]}, // 由于楼下有多个上楼梯,所以需指定位置而不是简单地写"stair": "upFloor" - "5,5": {"floorId": "sample2", "stair": "downFloor", "direction": "up"} + "5,5": { + "floorId": "sample2", + "stair": "downFloor", + "direction": "up" }, - "afterBattle": { // 战斗后可能触发的事件列表 - "9,6": [ // 初级卫兵1 - {"type": "setValue", "name": "flag:door", "value": "flag:door+1"}, // 将"door"这个自定义flag加一 - {"type": "if", "condition": "flag:door==2", // 一个条件判断事件,条件是"door"这个flag值等于2 - "true": [ // 如果条件成立:打开机关门 - {"type": "openDoor", "loc": [10,5]} - ], - "false": [] // 如果条件不成立则无事件触发 - }, - ], - "11,6": [ // 初级卫兵2;注意由于打怪顺序问题,可能都得写一遍。 - {"type": "setValue", "name": "flag:door", "value": "flag:door+1"}, // 将"door"这个自定义flag加一 - {"type": "if", "condition": "flag:door==2", // 一个条件判断事件,条件是"door"这个flag值等于2 - "true": [ // 如果条件成立:打开机关门 - {"type": "openDoor", "loc": [10,5]} - ], - "false": [] // 如果条件不成立则无事件触发 - }, - ], - }, - "afterGetItem": { // 获得道具后可能触发的事件列表 + "10,12": null +}, +"afterBattle": { + "9,6": [ + { + "type": "setValue", + "name": "flag:door", + "value": "flag:door+1" + }, + { + "type": "if", + "condition": "flag:door==2", + "true": [ + { + "type": "openDoor", + "loc": [ + 10, + 5 + ] + } + ], + "false": [] + } + ], + "11,6": [ + { + "type": "setValue", + "name": "flag:door", + "value": "flag:door+1" + }, + { + "type": "if", + "condition": "flag:door==2", + "true": [ + { + "type": "openDoor", + "loc": [ + 10, + 5 + ] + } + ], + "false": [] + } + ], + "10,12": null +}, +"afterGetItem": { + "10,12": null +}, +"afterOpenDoor": { + "10,12": null +}, +"cannotMove": { + "10,12": null +}, +"bgmap": [ - }, - "afterOpenDoor": { // 开完门后可能触发的事件列表 - - }, - "cannotMove": { // 每个图块不可通行的方向 - // 可以在这里定义每个点不能前往哪个方向,例如悬崖边不能跳下去 - // "x,y": ["up", "left"], // (x,y)点不能往上和左走 - - }, -} +], +"fgmap": [ +], +} \ No newline at end of file