diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index 2483aaef..4fc0c32f 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -839,7 +839,7 @@ playSound_s /* playSound_s tooltip : playSound: 播放音效 helpUrl : https://ckcz123.github.io/mota-js/#/event?id=playsound%EF%BC%9A%E6%92%AD%E6%94%BE%E9%9F%B3%E6%95%88 -default : ["item.ogg"] +default : ["item.mp3"] colour : this.soundColor var code = '{"type": "playSound", "name": "'+EvalString_0+'"},\n'; return code; @@ -1000,7 +1000,7 @@ function_s /* function_s -tooltip : function: 自定义JS脚本 +tooltip : function: 自定义JS脚本\n可以双击进行多行编辑,常见可能会被用到的系统API请参见文档的附录 helpUrl : https://ckcz123.github.io/mota-js/#/event?id=function%EF%BC%9A%E8%87%AA%E5%AE%9A%E4%B9%89js%E8%84%9A%E6%9C%AC default : ["alert(core.getStatus(\"atk\"));"] colour : this.dataColor diff --git a/_server/editor.js b/_server/editor.js index 7f9d1fca..d2a6b517 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -542,6 +542,29 @@ editor.prototype.listen = function () { currDrawData = JSON.parse(JSON.stringify(reDo)); reDo = null; } + // PGUP和PGDOWN切换楼层 + if (e.keyCode==33) { + e.preventDefault(); + var index=editor.core.floorIds.indexOf(editor.currentFloorId); + if (index>0) { + var toId = editor.core.floorIds[index-1]; + editor_mode.onmode('nextChange'); + editor_mode.onmode('floor'); + document.getElementById('selectFloor').value = toId; + editor.changeFloor(toId); + } + } + if (e.keyCode==34) { + e.preventDefault(); + var index=editor.core.floorIds.indexOf(editor.currentFloorId); + if (index', + MotaActionFunctions.actionParser.parse([ + {"type": "setValue", "name": "flag:y", "value": "core.status.event.data.y-2"}, + {"type": "setValue", "name": "flag:x", "value": "core.status.event.data.x-1"}, + {"type": "hide", "loc": ["flag:x", "flag:y"]}, + {"type": "setValue", "name": "flag:x", "value": "core.status.event.data.x"}, + {"type": "hide", "loc": ["flag:x", "flag:y"]}, + {"type": "setValue", "name": "flag:x", "value": "core.status.event.data.x+1"}, + {"type": "hide", "loc": ["flag:x", "flag:y"]}, + {"type": "setValue", "name": "flag:y", "value": "core.status.event.data.y-1"}, + {"type": "hide", "loc": ["flag:x", "flag:y"]}, + {"type": "setValue", "name": "flag:x", "value": "core.status.event.data.x"}, + {"type": "hide", "loc": ["flag:x", "flag:y"]}, + {"type": "setValue", "name": "flag:x", "value": "core.status.event.data.x-1"}, + {"type": "hide", "loc": ["flag:x", "flag:y"]}, + {"type": "setValue", "name": "flag:y", "value": "core.status.event.data.y"}, + {"type": "hide", "loc": ["flag:x", "flag:y"]}, + {"type": "setValue", "name": "flag:x", "value": "core.status.event.data.x+1"}, + {"type": "hide", "loc": ["flag:x", "flag:y"]}, + ],'afterBattle'), '', MotaActionFunctions.actionParser.parse({ "trigger": "action", diff --git a/_server/editor_file.js b/_server/editor_file.js index ae7dac9e..711a1bb1 100644 --- a/_server/editor_file.js +++ b/_server/editor_file.js @@ -161,11 +161,17 @@ editor_file = function (editor, callback) { var image = info.images; - if (image!='items' && image.indexOf('enemy')!=0) { - callback('只有怪物和道具才能自动注册!'); + if (image=='autotile') { + callback('不能对自动元件进行自动注册!'); return; } - var c=image=='items'?'I':'M'; + var c=image.toUpperCase().charAt(0); + + // terrains id + var terrainsId = []; + Object.keys(core.material.icons.terrains).forEach(function (id) { + terrainsId[core.material.icons.terrains[id]]=id; + }) var allIds = []; editor.ids.forEach(function (v) { @@ -180,17 +186,25 @@ editor_file = function (editor, callback) { for (var y=0; y0) + saveSetting('icons', iconActions, tempcallback); + else tempcallback(null); + saveSetting('maps', mapActions, tempcallback); + if (image=='items') saveSetting('items', templateActions, tempcallback); - else + else if (image.indexOf('enemy')==0) saveSetting('enemys', templateActions, tempcallback); + else tempcallback(null); } editor_file.changeIdAndIdnum = function (id, idnum, info, callback) { diff --git a/_server/fs.js b/_server/fs.js index 31b24811..59bd1441 100644 --- a/_server/fs.js +++ b/_server/fs.js @@ -1,8 +1,47 @@ (function () { fs = {}; + + + var _http = function (type, url, formData, success, error, mimeType, responseType) { + var xhr = new XMLHttpRequest(); + xhr.open(type, url, true); + if (core.isset(mimeType)) + xhr.overrideMimeType(mimeType); + if (core.isset(responseType)) + xhr.responseType = responseType; + xhr.onload = function(e) { + if (xhr.status==200) { + if (core.isset(success)) { + success(xhr.response); + } + } + else { + if (core.isset(error)) + error("HTTP "+xhr.status); + } + }; + xhr.onabort = function () { + if (core.isset(error)) + error("Abort"); + } + xhr.ontimeout = function() { + if (core.isset(error)) + error("Timeout"); + } + xhr.onerror = function() { + if (core.isset(error)) + error("Error on Connection"); + } + if (core.isset(formData)) + xhr.send(formData); + else xhr.send(); + } + + var postsomething = function (data, _ip, callback) { if (typeof(data) == typeof([][0]) || data == null) data = JSON.stringify({1: 2}); - core.http("POST", _ip, data, function (data) { + + _http("POST", _ip, data, function (data) { if (data.slice(0, 6) == 'error:') { callback(data, null); } diff --git a/docs/api.md b/docs/api.md index 37580c0d..fbd09055 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,4 +1,4 @@ -# 附录:API列表 +# 附录: API列表 ?> 目前版本**v2.2.1**,上次更新时间:* {docsify-updated} * @@ -8,6 +8,8 @@ 可以在chrome浏览器的控制台中(`ctrl+shift+I`,找到Console)中直接进行调用,以查看效果。 +**以下所有异步API都会加上[异步]的说明,存在此说明的请勿在事件处理的自定义脚本中使用。** + !> 最常用的新手向命令,强烈建议每个人了解 ``` text @@ -25,7 +27,7 @@ core.status.thisMap core.floors -获得所有楼层的信息,常常用来获取事件坐标。 +获得所有楼层的信息。例如core.floors[core.status.floorId].events可获得本楼层的所有自定义事件。 core.status.hero @@ -94,13 +96,14 @@ core.hasFlag('xyz') 返回是否存在某个变量且不为0。等价于 core.getFlag('xyz', 0)!=0 。 -core.insertAction(list) +core.insertAction(list, x, y, callback) 插入并执行一段自定义事件。在这里你可以写任意的自定义事件列表,有关详细写法请参见文档-事件。 +x和y如果设置则覆盖"当前事件点"的坐标,callback如果设置则覆盖事件执行完毕后的回调函数。 例如: core.insertAction(["楼层切换", {"type":"changeFloor", "floorId": "MT3"}]) 将依次显示剧情文本,并执行一个楼层切换的自定义事件。 -core.changeFloor(floorId, stair, heroLoc, time, callback) +core.changeFloor(floorId, stair, heroLoc, time, callback) [异步] 立刻切换到指定楼层。 floorId为目标楼层ID,stair为到达的目标楼梯,heroLoc为到达的指定点,time为动画时间,callback为切换完毕后的回调。 例如: @@ -140,13 +143,13 @@ core.nextX() core.nextY() 获得勇士面向的下一个位置的y坐标 -core.openDoor(id, x, y, needKey, callback) +core.openDoor(id, x, y, needKey, callback) [异步] 尝试开门操作。id为目标点的ID,x和y为坐标,needKey表示是否需要使用钥匙,callback为开门完毕后的回调函数。 例如:core.openDoor('yellowDoor', 10, 3, false, function() {console.log("1")}) -core.battle(id, x, y, force, callback) -执行战斗事件。id为怪物的id,x和y为坐标,force为bool值表示打不过是否强制战斗,callback为战斗完毕后的回调函数。 +core.battle(id, x, y, force, callback) [异步] +执行战斗事件。id为怪物的id,x和y为坐标,force为bool值表示是否是强制战斗,callback为战斗完毕后的回调函数。 例如:core.battle('greenSlime', null, null, true) @@ -155,7 +158,8 @@ core.trigger(x, y) core.clearMap(mapName) -清空某个画布。mapName可为'bg', 'event', 'fg', 'event2', 'hero', 'animate', 'weather', 'ui', 'data', 'all'之一。 +清空某个画布图层。 +mapName可为'bg', 'event', 'fg', 'event2', 'hero', 'animate', 'weather', 'ui', 'data', 'all'之一。 如果mapName为'all',则为清空所有画布;否则只清空对应的画布。 @@ -164,7 +168,7 @@ core.drawBlock(block) core.drawMap(floorId, callback) -重绘某一层的地图数据。floorId为要绘制那一层的floorId,callback为绘制完毕后的回调函数。 +重绘某一层的地图。floorId为要绘制楼层的floorId,callback为绘制完毕后的回调函数。 core.terrainExists(x, y, id, floorId) @@ -187,7 +191,7 @@ needEnable表示该点是否启用时才返回,其值不设置则默认为true core.getBlockId(x, y, floorId, needEnable) -获得某个点的图块ID +获得某个点的图块ID。 x和y为坐标;floorId为楼层ID,可忽略或null表示当前楼层。 needEnable表示是否需要该点处于启用状态才返回,其值不设置则默认为true。 如果该点不存在图块,则返回null,否则返回该点的图块ID。 @@ -219,8 +223,9 @@ core.drawTip(text, itemIcon) 在左上角绘制一段提示信息,2秒后消失。itemIcon为道具图标的索引。 -core.drawText(contents, callback) +core.drawText(contents, callback) [异步] 绘制一段文字。 +不推荐使用此函数,尽量使用core.insertAction(contents)来显示剧情文本。 core.closePanel() @@ -260,7 +265,7 @@ num如果设置大于0,则生成一个[0, num-1]之间的数;否则生成一 但是,此函数会将生成的随机数值存入录像,因此如果调用次数太多则会导致录像文件过大。 -core.restart() +core.restart() [异步] 返回标题界面。 @@ -345,15 +350,16 @@ core.events.gameOver(ending, fromReplay) 该函数将提问是否上传和是否下载录像,并返回标题界面。 -core.events.doEvents(list, x, y, callback) +core.events.doEvents(list, x, y, callback) [异步] 开始执行某个事件。 +请不要执行此函数,尽量使用 core.insertAction(list, x, y, callback) 来开始执行一段事件。 core.events.doAction() 执行下一个事件。此函数中将对所有自定义事件类型分别处理。 -core.events.openShop(shopId, needVisited) +core.events.openShop(shopId, needVisited) [异步] 打开一个全局商店。needVisited表示是否需要该商店已被打开过。 @@ -394,7 +400,7 @@ core.maps.removeBlockByIds(floorId, ids) 根据索引删除或禁用若干块。 -========== core.ui.XXX 和地图处理相关的函数 ========== +========== core.ui.XXX 和对话框绘制相关的函数 ========== ui.js主要用来进行UI窗口的绘制,比如对话框、怪物手册、楼传器、存读档界面等等。 @@ -404,7 +410,7 @@ floorId为目标楼层ID,canvas为要绘制到的图层,blocks为要绘制 x,y为该图层开始绘制的起始点坐标,size为每一格的像素,heroLoc为勇士坐标,heroIcon为勇士图标。 -========== core.utils.XXX 和地图处理相关的函数 ========== +========== core.utils.XXX 工具类的辅助函数 ========== utils.js主要用来进行一些辅助函数的计算。 @@ -437,12 +443,12 @@ core.utils.decodeRoute(route) 解压缩(解密)路线。 -core.utils.readFile(success, error, readType) +core.utils.readFile(success, error, readType) [异步] 尝试请求读取一个本地文件内容。 success和error为成功/失败后的回调,readType不设置则以文本读取,否则以DataUrl形式读取。 -core.utils.readFileContent(content) +core.utils.readFileContent(content) [异步] 文件读取完毕后的内容处理。 @@ -454,9 +460,9 @@ core.utils.copy(data) 尝试复制一段文本到剪切板。 -core.http(type, url, formData, success, error, mimeType) +core.utils.http(type, url, formData, success, error) [异步] 发送一个异步HTTP请求。 type为'GET'或者'POST';url为目标地址;formData如果是POST请求则为表单数据。 -success为成功后的回调,error会失败后的回调,mimeType如果设置则覆盖。 +success为成功后的回调,error为失败后的回调。 ``` diff --git a/docs/element.md b/docs/element.md index 3e915cdb..11816adf 100644 --- a/docs/element.md +++ b/docs/element.md @@ -199,7 +199,7 @@ floorId指定的是目标楼层的唯一标识符(ID)。 ]; "sounds": [ // 在此存放所有的SE,和文件名一致 // 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 - 'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg', 'zone.ogg' + 'floor.mp3', 'attack.mp3', 'door.mp3', 'item.mp3', 'zone.mp3' ] ``` diff --git a/docs/event.md b/docs/event.md index d8d50530..7fe90b60 100644 --- a/docs/event.md +++ b/docs/event.md @@ -857,7 +857,7 @@ move完毕后移动的NPC/怪物一定会消失,只不过可以通过immediate 使用playSound可以立刻播放一个音效。 -使用方法:`{"type": "playSound", "name": "item.ogg"}` +使用方法:`{"type": "playSound", "name": "item.mp3"}` 值得注意的是,如果是额外添加进文件的音效,则需在main.js中this.sounds里加载它。 @@ -1169,7 +1169,24 @@ choices为一个数组,其中每一项都是一个选项列表。 `{"type":"function"}`需要有一个`"function"`参数,它是一个JS函数,里面可以写任何自定义的JS脚本;系统将会执行它。 -系统所有支持的API都在[附录](api)中给出,请进行参照。 +系统常见可能会被造塔所用到的的API都在[附录:API列表](api)中给出,请进行参照。 + +**警告:自定义脚本中只能执行同步代码,不可执行任何异步代码,比如直接调用core.changeFloor(...)之类都是不行的。** + +[附录:API列表](api)中的所有异步API都进行了标记;如果你不确定一个函数是同步的还是异步的,请向小艾咨询。 + +如果需要异步的代码都需要用事件(insertAction)来执行,这样事件处理过程和录像回放才不会出错。 + +举个例子,如果我们想随机切换到某个楼层的某个点,我们可以这么写自定义脚本: + +``` js +var toFloor = core.floorIds[core.rand(core.floorIds.length)]; // 随机一个楼层ID +var toX = core.rand(13), toY = core.rand(13); // 随机一个点 +core.insertAction([ + {"type": "changeFloor", "floorId": toFloor, "loc": [toX, toY]} // 插入一个changeFloor事件,并在该脚本结束后执行。 +]) +// 请勿直接调用 core.changeFloor(toFloor, ...),这个代码是异步的,会导致事件处理和录像出问题! +``` ## 同一个点的多事件处理 diff --git a/docs/personalization.md b/docs/personalization.md index 36191624..f7a59f18 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -309,6 +309,52 @@ control.prototype.checkBlock = function () { ``` 4. 如果有更高的需求,例如想让吸血效果变成一半,则还是在上面这些地方进行对应的修改即可。 +## 新增门和对应的钥匙 + +如果要新增一个门和对应的钥匙,需要进行如下几步: + +1. 在terrains.png中添加新的门的素材,并在地图编辑器中注册门的ID。该ID必须是以`Door`结尾,例如`abcDoor`。 +2. 在animates.png中添加开门的四格动画,然后直接打开icons.js文件,在animates下直接添加ID和索引信息,例如`'abcDoor': 34`。 +3. 在items.png中添加钥匙的素材,并在地图编辑器中注册钥匙的ID。该ID必须是和门对应且以`Key`结尾,例如`abcKey`。 +4. 该道具的cls应为`tools`,可以自行写道具描述,最下面几项均留`null`即可。 + +!> **请勿在animates中对门的动画素材进行注册!而是请直接打开icons.js文件并添加ID和索引信息!!!** + +!> terrains和animates的门ID必须完全一致,且以`Door`结尾;所对应的钥匙ID应当是把`Door`换成`Key`,这样才能对应的上! + +## 覆盖楼传事件 + +对于特殊的塔,我们可以考虑修改楼传事件来完成一些特殊的要求,比如镜子可以按楼传来切换表里。 + +要修改楼传事件,需要进行如下几步: + +1. 截获楼传的点击事件。在control.js中找到useFly函数,并将其替换成如下内容: +``` js +////// 点击楼层传送器时的打开操作 ////// +control.prototype.useFly = function (need) { + if (!core.status.heroStop) { + core.drawTip("请先停止勇士行动"); + return; + } + if (core.canUseItem('fly')) core.useItem('fly'); + else core.drawTip("当前无法使用"+core.material.items.fly.name); +} +``` +2. 让录像记下楼传的使用。在items.js的useItem函数中找到记录路线的那几行,修改为: +``` js + // 记录路线 + if (itemId!='book') { // 把 `&& itemId!='fly'` 给删除 + core.status.route.push("item:"+itemId); + } +``` +3. 修改楼传的使用事件。和其他永久道具一样,在地图编辑器的图块属性中修改楼传的useItemEffect和canUseItemEffect两个内容。例如: +``` js +"useItemEffect": "core.insertAction([...])" // 执行某段自定义事件,或者其他脚本 +"canUseItemEffect": "true" // 任何时候可用 +``` +修改时,请先把`null`改成空字符串`""`,然后再双击进行编辑。 + + ## 自定义装备 由于HTML5魔塔并不像RM那样存在一个装备界面可供我们对装备进行调整,但是我们也可以使用一个替代的方式实现这个目标。 @@ -334,7 +380,7 @@ control.prototype.checkBlock = function () { "shield1": {"atk": 0, "def": 10, "mdef": 10}, // 铁盾加10防和10魔防 ``` -通过这种方式,当穿上装备时,将会给你的三围分别加上对应项的数值。 +通过这种方式,当穿上装备时,将会给你的三围分别加上对应项的数值(支持负数,比如装剑减防御)。 ### 新增剑盾 @@ -396,6 +442,37 @@ this.useEquipment = function (itemId) { // 使用装备 `getCritical`, `getCriticalDamage`和`getDefDamage`三个函数依次计算的是该怪物的临界值、临界减伤和1防减伤。也可以适当进行修改。 +## 自定义快捷键 + +如果需要绑定某个快捷键为处理一段事件,也是可行的。 + +要修改按键,我们可以在`actions.js`的`keyUp`进行处理: + +比如,我们设置一个快捷键进行绑定,比如`W`,其keycode是87。(有关每个键的keycode搜一下就能得到) + +然后在`actions.js`的`keyUp`函数的`switch`中进行处理。 + +``` js +case 87: // W + if (core.status.heroStop) { + // ... 在这里写你要执行脚本 + // 请使用同步脚本,请勿执行任何异步代码,否则可能导致游戏过程或录像出现问题。 + core.insertAction([...]) // 例如,插入一段自定义事件并执行。 + + core.status.route.push("key:"+keyCode); // 录像的支持!这句话必须要加,不然录像回放会出错! + } + break; +``` + + +在勇士处于停止的条件下,按下W键时,将执行你写的脚本代码。请只使用同步脚本而不要使用异步代码,不然可能导致游戏出现问题。 + +`core.status.route.push("key:"+keyCode);` 这句话是对录像的支持,一定要加(这样录像播放时也会模拟该按键)。 + +!> H5不支持组合快捷键,所以不存在`W+1`这种组合快捷键的说法! + +!> 手机端可以通过长按任何位置调出虚拟键盘,再进行按键,和键盘按键是等价的效果! + ## 公共事件 在RM中,存在公共事件的说法;也就是通过某个指令来调用一系列事件的触发。 @@ -520,26 +597,20 @@ core.statusBar.skill.innerHTML = core.getFlag('skillName', '无'); // 使用flag ### 技能的触发 -我们可以按键触发技能。 +我们可以按键触发技能。有关绑定按键请参见[自定义快捷键](#自定义快捷键)。 -要修改按键,我们可以在`actions.js`的`keyUp`进行处理: - -我们设置一个快捷键进行绑定,比如`W`,其keycode是87。(有关每个键的keycode搜一下就能得到) - -!> H5不支持组合快捷键,所以不存在`W+1`这种组合快捷键的说法! - -然后在`actions.js`的`keyUp`函数的`switch`中进行处理。 +下面是一个很简单的例子,当勇士按下W后,如果魔力不小于5点则允许开启技能"二倍斩",再次按W则关闭技能。 ``` js case 87: // W if (core.status.heroStop) { // 当前停止状态;这个if需要加,不能在行走过程中触发不然容易出错。 if (core.getFlag('skill', 0)==0) { // 判断当前是否已经开了技能 - if (能开技能) { // 这里要写当前能否开技能的条件判断 + if (core.getStatus('mana')>=5) { // 这里要写当前能否开技能的条件判断,比如魔力值至少要多少 core.setFlag('skill', 1); // 开技能1 core.setFlag('skillName', '二倍斩'); // 设置技能名 } else { - core.drawTip("当前不能开技能!"); + core.drawTip("魔力不足,无法开技能"); } } else { // 关闭技能 @@ -599,6 +670,69 @@ if (core.getFlag('skill', 0)==1) { // 开启了技能1 通过上述这几种方式,我们就能成功的让H5支持技能啦! +## 多角色的支持 + +其实,我们的样板还能支持多角色的制作。比如《黑·白·间》之类的塔也是完全可以刻的。 + +你只需要如下几步来达到多角色的效果。 + +1. 每个勇士弄一张行走图。相关信息参见[自定义事件:setHeroIcon](event#setHeroIcon:更改角色行走图) +2. [覆盖楼传事件](#覆盖楼传事件),这样可以通过点工具栏的楼层传送按钮来切换角色。 +当然你也完全可以自己写一个道具来实现,或[自定义快捷键](#自定义快捷键)来进行绑定。 +3. 在脚本编辑的setInitData中初始化新角色的属性值。 +``` js +// 所有需要保存的内容;这些保存的内容不会多角色共用,在切换时会进行恢复。 +// 你也可以自行新增或删除,比如不共用金币则可以加上"money"的初始化,不共用道具则可以加上"items"的初始化, +// 多勇士共用hp的话则删除hp,等等。 +var initData = { + "floorId": "MT0", // 该角色楼层ID + "icon": "hero2.png", // 角色的行走图名称 + "name": "2号角色", + "lv": 1, + "hp": 1000, + "atk": 10, + "def": 10, + "mdef": 0, + "loc": {"x": 0, "y": 0, "direction": "up"}, + // 不共用的数据都可以在这里加上定义 +} +core.setFlag("hero1", initData); // 将属性值存到变量中 +``` + +3. 道具(或快捷键)的脚本如下: +``` js +// 这个saveList和上面的初始化定义中的的key,除了不要icon(行走图名称)其他应完全相同。 +var saveList = ["floorId", "name", "lv", "hp", "atk", "def", "mdef", "loc"]; + +// 保存当前内容 +var toSave = {}; +saveList.forEach(function(name) { + if (name=='floorId') toSave[name] = core.status.floorId; // 楼层单独设置 + else toSave[name] = core.clone(core.status.hero[name]); // 使用core.clone()来创建新对象 +}) + +var currHeroId = core.getFlag("heroId", 0); // 获得当前角色ID +var toHeroId = (currHeroId+1)%2; // 获得要切换到的角色ID,比如 0->1,1->0 + +core.setFlag("hero"+currHeroId, toSave); // 将当前勇士信息进行保存 + +var data = core.getFlag("hero"+toHeroId); // 获得要切换的勇士保存内容 + +// 将勇士属性值设置回来 +saveList.forEach(function(name) { + if (core.isset(core.status.hero[name]) && core.isset(loadData[name])) + core.status.hero[name] = core.clone(loadData[name]); +}) + +// 插入事件:改变勇士行走图并进行楼层切换 +core.insertAction([ + {"type": "setHeroIcon", "name": loadData.icon||"hero.png"}, // 改变行走图 + {"type": "changeFloor", "floorId": loadData.floorId, "loc": [loadData.loc.x, loadData.loc.y], + "direction": loadData.loc.direction, "time": 0} +]) +core.setFlag("heroId", toHeroId); // 保存切换到的勇士ID +``` + ## 根据难度分歧来自定义地图 遗憾的是,所有地图数据必须在剧本的map中指定,换句话说,我们无法在游戏进行中动态修改地图,比如为简单难度增加一个血瓶。 diff --git a/libs/control.js b/libs/control.js index c4e956f3..7c15fb88 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1010,7 +1010,7 @@ control.prototype.checkBlock = function () { } if (damage>0) { - core.playSound('zone.ogg'); + core.playSound('zone.mp3'); core.drawAnimate("zone", x, y); } @@ -1810,6 +1810,8 @@ control.prototype.openSettings = function (need) { ////// 自动存档 ////// control.prototype.autosave = function (removeLast) { + if (core.status.event.id!=null) + return; var x=null; if (removeLast) x=core.status.route.pop(); diff --git a/libs/core.js b/libs/core.js index 78d0a7fa..888725f0 100644 --- a/libs/core.js +++ b/libs/core.js @@ -889,8 +889,8 @@ core.prototype.debug = function() { } ////// 重置当前地图 ////// -core.prototype.resetMap = function() { - core.maps.resetMap(); +core.prototype.resetMap = function(floorId) { + core.maps.resetMap(floorId); } ////// 开始播放 ////// diff --git a/libs/events.js b/libs/events.js index 8cf62d64..a0018f7b 100644 --- a/libs/events.js +++ b/libs/events.js @@ -407,8 +407,6 @@ events.prototype.doAction = function() { } if (floorId==core.status.floorId) { core.drawMap(floorId); - core.drawHero(); - core.updateStatusBar(); } } this.doAction(); @@ -838,7 +836,7 @@ events.prototype.getNextItem = function() { ////// 获得某个物品 ////// events.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) { // core.getItemAnimate(itemId, itemNum, itemX, itemY); - core.playSound('item.ogg'); + core.playSound('item.mp3'); var itemCls = core.material.items[itemId].cls; core.items.getItemEffect(itemId, itemNum); core.removeBlock(itemX, itemY); @@ -888,7 +886,7 @@ events.prototype.openDoor = function (id, x, y, needKey, callback) { } // open - core.playSound("door.ogg"); + core.playSound("door.mp3"); var state = 0; var doorId = id; if (!(doorId.substring(doorId.length-4)=="Door")) { @@ -942,11 +940,11 @@ events.prototype.battle = function (id, x, y, force, callback) { else { if (core.flags.equipment && core.getFlag('sword', 'sword0')!='sword0') { - core.playSound('zone.ogg'); + core.playSound('zone.mp3'); core.drawAnimate('sword', x, y); } else { - core.playSound('attack.ogg'); + core.playSound('attack.mp3'); core.drawAnimate('hand', x, y); } @@ -1033,10 +1031,10 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback } } if (core.status.maps[floorId].canFlyTo && core.status.hero.flyRange.indexOf(floorId)<0) { - if (core.floorIds.indexOf(floorId)>core.floorIds.indexOf(core.status.floorId)) - core.status.hero.flyRange.push(floorId); - else - core.status.hero.flyRange.unshift(floorId); + core.status.hero.flyRange.push(floorId); + core.status.hero.flyRange.sort(function (a, b) { + return core.floorIds.indexOf(a) - core.floorIds.indexOf(b); + }) } window.setTimeout(function () { @@ -1094,29 +1092,27 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback }) } core.drawMap(floorId, function () { - setTimeout(function() { - if (core.isset(heroLoc.direction)) - core.setHeroLoc('direction', heroLoc.direction); - core.setHeroLoc('x', heroLoc.x); - core.setHeroLoc('y', heroLoc.y); - core.drawHero(); - core.updateStatusBar(); + if (core.isset(heroLoc.direction)) + core.setHeroLoc('direction', heroLoc.direction); + core.setHeroLoc('x', heroLoc.x); + core.setHeroLoc('y', heroLoc.y); + core.clearMap('hero', 0, 0, 416, 416); + core.drawHero(); - var changed = function () { - core.unLockControl(); - core.status.replay.animate=false; - core.events.afterChangeFloor(floorId); - if (core.isset(callback)) callback(); - } - if (displayAnimate) { - core.hide(core.dom.floorMsgGroup, time/4, function () { - changed(); - }); - } - else { + var changed = function () { + core.unLockControl(); + core.status.replay.animate=false; + core.events.afterChangeFloor(floorId); + if (core.isset(callback)) callback(); + } + if (displayAnimate) { + core.hide(core.dom.floorMsgGroup, time/4, function () { changed(); - } - }, 25) + }); + } + else { + changed(); + } }); } core.playSound('floor.mp3'); diff --git a/libs/maps.js b/libs/maps.js index 39a0e306..d631cf43 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -389,8 +389,10 @@ maps.prototype.drawMap = function (mapName, callback) { } } else { drawEvent(); + core.setGlobalAnimate(core.values.animateSpeed); + core.drawHero(); + core.updateStatusBar(); } - core.setGlobalAnimate(core.values.animateSpeed); if (core.isset(callback)) callback(); } @@ -398,7 +400,7 @@ maps.prototype.drawMap = function (mapName, callback) { ////// 绘制Autotile ////// maps.prototype.drawAutotile = function(ctx, mapArr, block, size, left, top){ var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块 - // +----+----+----+----+----+----+ + // +----+----+----+----+----+----+ [10, 9, 4, 3 ], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 | [10, 9, 4, 13], //1 bin:0001 +----+----+----+----+----+----+ [10, 9, 18, 3 ], //2 bin:0010 | 7 | 8 | 9 | 10 | 11 | 12 | @@ -896,11 +898,15 @@ maps.prototype.drawAnimate = function (name, x, y, callback) { }, 50); } -maps.prototype.resetMap = function() { - var floorId = core.status.floorId; +maps.prototype.resetMap = function(floorId) { + var floorId = floorId||core.status.floorId; core.status.maps[floorId] = this.loadFloor(floorId); - this.drawMap(floorId, function() { - core.drawHero(); - core.updateStatusBar(); - }) + if (floorId==core.status.floorId) { + this.drawMap(floorId, function () { + core.drawTip("地图重置成功"); + }) + } + else { + core.drawTip(floorId+"地图重置成功"); + } } \ No newline at end of file diff --git a/libs/ui.js b/libs/ui.js index b539d278..ef9adc03 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -981,7 +981,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { core.fillText("ui", "S", right_start-8, 208+15, "#FFFFFF", "italic bold 40px Verdana"); var battleInterval = setInterval(function() { - core.playSound("attack.ogg"); + core.playSound("attack.mp3"); if (turn==0) { // 勇士攻击 @@ -1513,8 +1513,19 @@ ui.prototype.drawToolbox = function(index) { if (core.isset(selectId)) { var item=core.material.items[selectId]; core.fillText('ui', item.name, 10, 32, '#FFD700', "bold 20px Verdana") - core.fillText('ui', item.text||"该道具暂无描述。", 10, 62, '#FFFFFF', '17px Verdana'); - core.fillText('ui', '<继续点击该道具即可进行使用>', 10, 89, '#CCCCCC', '14px Verdana'); + + var text = item.text||"该道具暂无描述。"; + var lines = core.splitLines('ui', text, 406, '17px Verdana'); + + core.fillText('ui', lines[0], 10, 62, '#FFFFFF', '17px Verdana'); + + if (lines.length==1) { + core.fillText('ui', '<继续点击该道具即可进行使用>', 10, 89, '#CCCCCC', '14px Verdana'); + } + else { + var leftText = text.substring(lines[0].length); + core.fillText('ui', leftText, 10, 89, '#FFFFFF', '17px Verdana'); + } } core.canvas.ui.textAlign = 'right'; diff --git a/project/data.js b/project/data.js index 257d7b4f..63a4c455 100644 --- a/project/data.js +++ b/project/data.js @@ -14,7 +14,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = 'bgm.mp3' ], "sounds" : [ - 'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg', 'zone.ogg' + 'floor.mp3', 'attack.mp3', 'door.mp3', 'item.mp3', 'zone.mp3' ], "startBackground" : "bg.jpg", "startLogoStyle" : "color: black", diff --git a/project/floors/sample1.js b/project/floors/sample1.js index 54098420..87bbb9b2 100644 --- a/project/floors/sample1.js +++ b/project/floors/sample1.js @@ -56,7 +56,7 @@ main.floors.sample1 = "\t[redKing]欢迎来到魔塔,你是第一百位挑战者。\n若你能打败我所有的手下,我就与你一对一的决斗。\n现在你必须接受我的安排。", {"type": "show", "loc": [[1,6],[0,7],[1,8],[2,7]], "time": 500}, // 显示四个白衣武士,每个动画效果500ms "\t[hero]什么?", - {"type": "playSound", "name": "attack.ogg"}, // 播放战斗音频 + {"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]]}, // 直接隐藏四个白衣武士,没有动画效果 diff --git a/project/floors/sample2.js b/project/floors/sample2.js index 666e5f64..5db5310c 100644 --- a/project/floors/sample2.js +++ b/project/floors/sample2.js @@ -36,22 +36,22 @@ main.floors.sample2 = "6,11": {"enable": false}, // 下楼梯口的机关门,初始处于关闭状态 "6,10": [ // 进入陷阱后关门 - {"type": "playSound", "name": "door.ogg"}, + {"type": "playSound", "name": "door.mp3"}, {"type": "show", "loc": [6,11]}, // 显示机关门 {"type": "hide"}, // 隐藏该事件 {"type": "trigger", "loc": [6,7]}, // 直接引发"6,7"处的事件,即下面的杰克 // 请再次注意"trigger"会立刻结束当前事件,因此"type":"hide"需要在trigger前调用 ], "6,7": [ // 杰克事件 - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]杰克,你究竟是什么人?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[杰克,thief]……", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]我们……是朋友对吧?\n是朋友就应该相互信任对吧?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[杰克,thief]……事到如今也没有什么好隐瞒的了。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[杰克,thief]没错,我就是这一切的背后主谋。", {"type": "move", "steps": [ // 移动到黑暗大法师的位置;使用move会自动调用hide进行隐藏,无需再手动调用 {"direction": "up", "value": 3} @@ -59,105 +59,105 @@ main.floors.sample2 = {"type": "show", "loc": [6,4], "time": 1000}, // 显示黑暗大法师 {"type": "sleep", "time": 500}, // 等待500毫秒 // 下面是黑暗大法师的事件 - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]我的真名为——黑暗大法师,第四区域的头目。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]呵呵,不知道为什么,我竟然对事情走到现在这一步毫不感觉意外。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]以杰克的名义利用了你这么久,真是抱歉啊。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]真正的杰克现在在哪里?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]盗贼杰克这个人类从未存在过,他只是我用来接近你的一副皮囊而已。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]……这样啊,呵呵。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]为什么你看上去丝毫不生气?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]多亏了鬼帝,我现在的脾气好得连我自己都害怕。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]说起来我还得好好感谢你呢,如果没有杰克……你的帮助,我早就死在第一区域了。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]不论你的目的如何,你的所作所为都是对我有利的。不是吗?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]能够如此淡定的面对背叛,看来跟五年前相比,你确实成长了很多啊。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]五年前?……黑暗大法师,在这之前,我们好像素未谋面吧?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]五年前那场屠城你应该这一生都不会忘记吧。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]很不巧,那场屠城的主谋,也是我。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]……", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]这么说,击中我双亲的那道紫色闪电,也就是你释放的吧……", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]你的双亲?这种事情我怎么可能会记得?\n你难道在踩死蚂蚁的时候还会一只只记下他们的样子吗?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]老 子 要 你 的 命", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]你应该对我心怀感激才对,如果不是那时的我看出了你隐藏的稀有勇者体质,你绝对不可能活到今天。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]在暗中动手脚让你通过勇者选拔的人也是我,我一直一直在暗中引导你走到今天这一步。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]是我救赎了一无是处的你。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]为什么只有我一个人活了下来!!!!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]为什么偏偏是我!!!!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]我刚才不是说过了吗?因为我看出了你有稀有勇者体质啊。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]你刚刚跟鬼帝交过手,应该已经很清楚这稀有勇者体质意味着什么了吧?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]……就因为我有这种体质,就不得不背负如此残酷的宿命吗?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]愚蠢!这意味着只要我对你加以引导跟培养,你就能成为这世间实力最强的存在!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]……所以,你究竟想利用我干什么?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]我利用你干的事情,你不是已经完成了吗?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]……你说什么?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]不知不觉间,你已经在我的指引下跟鬼帝正面交手并且杀掉了他啊。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]就连我跟鬼帝的对决……也是被你安排好了的?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]你们两个一个是人类勇者,一个是魔物勇者,迟早会有交手的一天。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]我只不过是操纵了一系列的连锁事件让这一天提早了数十年到来而已。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]……你这样做对谁有好处?他可是你们魔物世界的救世主啊。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]一个惧怕征战,爱好和平的懦夫,也配叫救世主?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]获得了力量,却只会被动挨打而不主动向人类世界出击,龟缩在第二区域惶惶度日,他根本就不配拥有稀有勇者体质。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]为了不让这种人霸占着积累多年的庞大灵魂能量无作为,我设计让你杀掉了他。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]你没有辜负我的期待,成功战胜了那个废物,现在你体内累积的灵魂能量……也就是魔力,已经达到了能跟魔王匹敌的地步。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]……是吗?现在的我能与魔王匹敌?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]不止如此,你现在的力量之强就算是统治世界也是绰绰有余!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]怎么样?要不要加入我的麾下,跟随我去征战人类世界?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]能与魔王匹敌的话,也就是说。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]我 现 在 对 付 你 这 种 杂 碎 也 绰 绰 有 余 吧 ?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]……什么?!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]等一下!别冲动!你先等我把这利害关系理一理——", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]你给老子闭嘴。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]老子什么都不想听。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]老子现在想做的事情只有一件——", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]剁掉你的头,把它放回我双亲的墓前。", {"type": "update"} // 本事件剧情结束,更新地图显伤 ], @@ -175,7 +175,7 @@ main.floors.sample2 = "data": [ "\t[blackMagician]听不进去人话的蠢货,就要用疼痛来管教!", {"type": "changePos", "direction": "up"}, - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]出来吧!禁忌——紫电凶杀阵!", {"type": "show", "loc": [[4,3],[4,6],[8,6],[8,3]], "time": 500}, // 依次显示四个角的法师 {"type": "sleep", "time": 500}, @@ -195,13 +195,13 @@ main.floors.sample2 = {"type": "animate", "name": "yongchang", "loc": [8,6]}, {"type": "animate", "name": "yongchang", "loc": [8,3]}, {"type": "sleep", "time": 200}, - {"type": "playSound", "name": "attack.ogg"}, // 播放攻击音效 + {"type": "playSound", "name": "attack.mp3"}, // 播放攻击音效 {"type": "animate", "name": "thunder", "loc": "hero"}, {"type": "sleep", "time": 200}, "\t[hero]唔……!!(吐血)", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]我的魔力可是充足的很啊!我会一直折磨到你屈服于我为止!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]人类!好好感受吧!当初你们施加于我的痛苦!如今我要百倍奉还!", {"type": "show", "loc": [6,6], "time": 1000}, // 显示妖精 {"type": "sleep", "time": 700}, @@ -232,45 +232,45 @@ main.floors.sample2 = "6,6": { // 妖精 "enable":false, // 初始时禁用状态 "data": [ // 妖精事件 - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]…妖精…小姐……是你吗?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]不要绝望,也不要悲伤。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]你从来都不是独自一人在前进。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]咱一直,一直都在注视着你。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]耍小聪明的你、笨笨的你呆呆的你、胆小的你、勇敢的你帅气的你……全部全部都是你。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]所以放心吧,无论发生什么,咱都会陪伴在你身边的。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]因为你要是离开我的话,立刻就会死掉吧?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]…妖精…小姐……其实一直以来,我都非常感激你……", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]笨蛋!都这种时候了就不要作出像是临终遗言的发言了啊!!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]喂!那边穿衣品味差到极点的黑暗大法师,别左顾右盼说的就是你!你应该知道咱的身份吧?\n还不速速退下!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]可恶…多管闲事的妖精族…明明只要再让他承受一点疼痛来瓦解他的意志力,我的计划就成功了!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]哼哼哼~抱歉哦,这个笨蛋的意志力可不像你想象的那么薄弱哦!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]不甘心!我不甘心!妖精公主又如何!\n只要是阻挡我的,不管是谁我都要铲除!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]终于露出狐狸尾巴了,其实咱早就看出你有谋反的念头。你的计划就是拉拢这家伙入伙然后推翻魔王对魔塔的统治对吧?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]呵呵呵……那个昏庸的魔王,掌握着那么庞大的魔物军队却只知道固守魔塔,而不主动侵略人类世界扩张领土!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]我实在是看不过眼,所以我才决定把这个具备稀有勇者体质的家伙培养成新一任魔王!\n来让这个世界的势力重新洗牌!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]你觉得一个满脑子想着回家种田的废柴勇者会成为改变世界的魔王?你晃晃脑袋试试,是不是能听到大海的声音?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]恼人至极的妖精族!呵呵呵……我干脆一不做二不休,连你也一块收拾了吧!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]别小瞧咱!咱好歹也是妖精族里实力数一数二的存在!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]只会耍嘴皮子的恼人苍蝇!我倒要看看一块焦炭会不会说话!\n——招雷弹!!", /* {"type": "hide", "loc": [4,3], "time": 150}, // 由于没有动画效果,暂时使用“闪一下”表示 @@ -286,7 +286,7 @@ main.floors.sample2 = {"type": "animate", "name": "yongchang", "loc": [4,6]}, {"type": "animate", "name": "yongchang", "loc": [8,6]}, {"type": "animate", "name": "yongchang", "loc": [8,3]}, - {"type": "playSound", "name": "attack.ogg"}, // 播放攻击音效 + {"type": "playSound", "name": "attack.mp3"}, // 播放攻击音效 /* {"type": "hide", "loc": [6,6], "time": 150}, // 妖精也闪一下表示收到了伤害 {"type": "show", "loc": [6,6], "time": 150}, // 妖精也闪一下表示收到了伤害 @@ -294,38 +294,38 @@ main.floors.sample2 = {"type": "animate", "name": "thunder", "loc": [6,6]}, {"type": "sleep", "time": 500}, // 等待500毫秒 "\t[小妖精,fairy]切,这点伤痛跟他刚才经历的身心地狱相比根本就不算什么。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]哼!翅膀都被烧焦了还要嘴硬?你难不成真以为我不会对你动真格?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]……你这混蛋!给我离她远点!!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]!…你现在受了很严重的致命伤,乱动什么?\n乖。别怕,这里有咱顶着!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]对了,咱再问你一遍,你是很珍惜自己性命的对吧?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]!…等等…妖精小姐,你不会是……?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]喂,黑暗大法师,你作为魔塔里最博学多识的蠢货,应该对咱妖精族的特殊能力再清楚不过吧?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]什么?!难不成你是想!!不可能……\n就为了一个渺小的人类,不可理喻!!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]哼哼哼!你害怕的表情可真美味!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]不过比起这个,咱更期待你吃到“妖精自灭冲击”之后的死状哦!~", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[blackMagician]不!!不应该是这样的!我完美的计划竟然会被一只小小的妖精破坏!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]不要!……千万不要!……为了我这种人……唔!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]笨蛋,动都动不了了就不要强撑着站起来了啊。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]真是的,都到最后一刻了,你这家伙好歹也让咱省点心吧。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[小妖精,fairy]那么,再见了……我的勇者大人。", {"type": "move", "time": 700, "steps": [ // 向上移动三个,撞上黑暗大大法师;本事件的hide会自动被调用 {"direction": "up", "value": 3} ]}, - {"type": "playSound", "name": "attack.ogg"}, // 播放攻击音效 + {"type": "playSound", "name": "attack.mp3"}, // 播放攻击音效 {"type": "sleep", "time": 200}, "\t[blackMagician]不可能!!!!!", {"type": "hide", "loc": [6,3]}, // 法师消失 @@ -336,24 +336,24 @@ main.floors.sample2 = {"type": "changeFloor", "floorId": "sample2", "loc": [6,6], "direction": "up", "time": 1000}, // 更换勇士地点,合计1秒 {"type": "show", "loc": [6,5]}, // 显示黄宝石 {"type": "sleep", "time": 200}, // 等待200毫秒 - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, {"type": "sleep", "time": 200}, // 等待200毫秒 "\t[hero]…妖精…小姐……", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]……妖精小姐!", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]是梦吗?……不对,为什么我在流泪?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]这颗漂亮的宝石是……?", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]我全都想起来了……妖精小姐为了我……\n牺牲了自己的性命。", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]在这颗宝石上,我能感受到你的温度……\n熟悉而又令人安心,这就是你最后留给我的东西吗……", - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]好温暖……", {"type": "setValue", "name": "item:yellowJewel", "value": "1"}, // 获得1个黄宝石 {"type": "hide", "loc": [6,5]}, // 隐藏黄宝石 - {"type": "playSound", "name": "item.ogg"}, + {"type": "playSound", "name": "item.mp3"}, "\t[hero]……", {"type": "openDoor", "loc": [6,2]}, // 开门 {"type": "openDoor", "loc": [6,11]} diff --git a/project/functions.js b/project/functions.js index 975d9aab..0c7862d1 100644 --- a/project/functions.js +++ b/project/functions.js @@ -346,7 +346,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = console.log("插件函数执行测试"); } - var _useEquipment = function (itemId, name, type) { + var _useEquipment = function (itemId, name, type) { // 具体的装备使用效果 if (itemId.indexOf(name)==0) { var now=core.getFlag(name, name+"0"); @@ -356,7 +356,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = else { core.status.hero.atk -= core.values[now].atk || 0; core.status.hero.def -= core.values[now].def || 0; - core.status.hero.mdef -= core.values[now].mdef || 0; + core.status.hero.mdef -= core.values[now].mdef || 0; } if (typeof core.values[itemId] == 'number') { diff --git a/project/icons.js b/project/icons.js index 1b6208fe..b7461654 100644 --- a/project/icons.js +++ b/project/icons.js @@ -27,8 +27,8 @@ icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = 'white': 17, 'ground6': 18, 'soil': 19, - 'star': 20, - 'lava': 21, + 'ground7': 20, + 'ground8': 21, 'ice': 22, 'downFloor': 23, 'upFloor': 24, @@ -70,9 +70,9 @@ icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = 'lavaDoor': 13, 'starDoor': 14, 'starPortal': 15, - //'exclamation': 16, + 'fire': 16, 'portal': 17, - //'switch': 18, + 'switch': 18, 'lavaNet': 19, 'poisonNet': 20, 'weakNet': 21, diff --git a/project/images/animates.png b/project/images/animates.png index 0bfad0df..f6245285 100644 Binary files a/project/images/animates.png and b/project/images/animates.png differ diff --git a/project/images/terrains.png b/project/images/terrains.png index 246de0cb..55239f66 100644 Binary files a/project/images/terrains.png and b/project/images/terrains.png differ diff --git a/project/items.js b/project/items.js index 475f59cb..94a57ff9 100644 --- a/project/items.js +++ b/project/items.js @@ -278,13 +278,13 @@ items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "useItemEffect": { "book": "core.ui.drawBook(0);", "fly": "core.ui.drawFly(core.status.hero.flyRange.indexOf(core.status.floorId));", - "earthquake": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "pickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "icePickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "snow": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "bigKey": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "bomb": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", - "hammer": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", + "earthquake": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "pickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "icePickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "snow": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "bigKey": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "bomb": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", + "hammer": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", "centerFly": "core.clearMap('hero', 0, 0, 416, 416);\ncore.setHeroLoc('x', core.status.event.data.x);\ncore.setHeroLoc('y', core.status.event.data.y);\ncore.drawHero();\ncore.drawTip(core.material.items[itemId].name + '使用成功');", "upFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y};\ncore.changeFloor(core.status.event.data.id, null, loc, null, function (){\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.replay();\n});", "downFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y};\ncore.changeFloor(core.status.event.data.id, null, loc, null, function (){\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.replay();\n});", diff --git a/project/sounds/attack.mp3 b/project/sounds/attack.mp3 new file mode 100644 index 00000000..259b759e Binary files /dev/null and b/project/sounds/attack.mp3 differ diff --git a/project/sounds/attack.ogg b/project/sounds/attack.ogg deleted file mode 100644 index ec692100..00000000 Binary files a/project/sounds/attack.ogg and /dev/null differ diff --git a/project/sounds/door.mp3 b/project/sounds/door.mp3 new file mode 100644 index 00000000..ea6706d2 Binary files /dev/null and b/project/sounds/door.mp3 differ diff --git a/project/sounds/door.ogg b/project/sounds/door.ogg deleted file mode 100644 index 65f75ce2..00000000 Binary files a/project/sounds/door.ogg and /dev/null differ diff --git a/project/sounds/item.mp3 b/project/sounds/item.mp3 new file mode 100644 index 00000000..5d821780 Binary files /dev/null and b/project/sounds/item.mp3 differ diff --git a/project/sounds/item.ogg b/project/sounds/item.ogg deleted file mode 100644 index 469399d5..00000000 Binary files a/project/sounds/item.ogg and /dev/null differ diff --git a/project/sounds/zone.mp3 b/project/sounds/zone.mp3 new file mode 100644 index 00000000..eccf53c8 Binary files /dev/null and b/project/sounds/zone.mp3 differ diff --git a/project/sounds/zone.ogg b/project/sounds/zone.ogg deleted file mode 100644 index aef5fcbc..00000000 Binary files a/project/sounds/zone.ogg and /dev/null differ diff --git a/更新说明.txt b/更新说明.txt index a5c4c77a..0a123cf2 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -3,15 +3,17 @@ 地图编辑器可以右键复制或移动图块 √ 事件:while循环处理 √ 事件:等待用户操作并获得按键或点击信息 √ -衰弱减少攻防的比例 √ +衰弱可以减少攻防的比例 √ 地图数据统计 支持 status:x 获得当前坐标 √ 最大存档个数提到main处理 √ 新建地图可以保留楼层属性 √ -增添自定义装备的教程(个性化-自定义装备) √ -重写教程的快速上手 √ -修复转向触发事件的朝向Bug √ -部分细节优化 √ +地图编辑器可用PageUp和PageDown切换楼层 √ +道具描述过长时可以自动换行 √ +除Autotile外均可自动注册 √ +重写大部分教程,新增大量拓展描述 √ +便捷PS工具偶尔的闪退问题 +大量细节进行优化,所有已知的bug进行了修复 √ -----------------------------------------------------------------------