From a58067cd6ae27e3515954f030c0232dd648adaf0 Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 31 Dec 2017 01:35:21 +0800 Subject: [PATCH 01/11] Update V1.3 --- README.md | 19 ++- docs/api.md | 193 ++++++++++++++------- docs/element.md | 99 +++++++++-- docs/event.md | 159 +++++++++++++---- docs/img/domainenemy.png | Bin 22145 -> 0 bytes docs/img/nattack.png | Bin 0 -> 8523 bytes docs/img/ps.png | Bin 80216 -> 28629 bytes docs/img/zone.png | Bin 0 -> 13131 bytes docs/personalization.md | 134 +++++++-------- docs/start.md | 18 +- libs/core.js | 361 +++++++++++++++++++++++---------------- libs/enemys.js | 19 ++- libs/events.js | 198 +++++++++++---------- libs/floors/MT0.js | 2 + libs/floors/sample0.js | 2 + libs/floors/sample1.js | 2 + libs/floors/sample2.js | 3 +- libs/items.js | 15 +- libs/maps.js | 11 +- libs/ui.js | 84 +++------ 更新说明.txt | 1 + 21 files changed, 824 insertions(+), 496 deletions(-) delete mode 100644 docs/img/domainenemy.png create mode 100644 docs/img/nattack.png create mode 100644 docs/img/zone.png diff --git a/README.md b/README.md index bb72521e..36fb01bf 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,20 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ## 更新说明 -### 2017.12.21 +### 2017.12.31 V1.3 + +* [x] 支持全键盘操作。 +* [x] 便捷PS工具支持更改图片色相。 +* [x] 支持经验升级(进阶/境界塔)。 +* [x] 打败怪物可以进行加点(加点塔)。 +* [x] 增加阻击、N连击等属性;在怪物手册有属性显示。 +* [x] 支持九宫格领域和大范围领域。 +* [x] 增加负伤。 +* [x] 支持各种BGM的播放。 +* [x] 支持不同层使用不同的地面素材;支持多个Autotile同时存在 √ +* [x] 许多细节进行了优化,一些已知的Bug进行了修复。 + +### 2017.12.21 V1.2 * [x] 新增:本地HTTP服务器。 * [x] 新增:可视化地图编辑工具。 @@ -57,7 +70,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! * [x] 新增:更多的默认素材,现在对于大多数地图风格无需P图,直接替换即可。 * [x] 添加部分自定义事件,部分细节优化,一些已知的Bug进行了修复。 -### 2017.12.16 +### 2017.12.16 V1.1 * [x] 新增:战斗过程显示,可以在设置中关闭 * [x] 新增:勇士支持48*32(大图)的行走图 @@ -67,7 +80,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! * [x] 增添Web的Markdown文档,移除原本的doc和pdf文档。 * [x] 修复若干Bug。 -### 2017.12.9 +### 2017.12.9 V1.0 * [x] 发布初版HTML5魔塔样板 diff --git a/docs/api.md b/docs/api.md index 51973cda..d1b609f4 100644 --- a/docs/api.md +++ b/docs/api.md @@ -4,32 +4,39 @@ 可以在chrome浏览器的控制台中(`ctrl+shift+I`,找到Console)中直接进行调用,以查看效果。 +!> **`main.js`:游戏入口。所有其他JS文件都是被此文件加载。** + +``` js + +``` + !> **`core.js`:系统核心文件。所有核心逻辑处理都在此文件完成。** ``` js * core.status.floorId // 获得当前层floorId * core.status.thisMap // 获得当前层的地图信息 +* core.status.maps // 获得所有楼层的地图信息 +* core.floors // 获得所有楼层的剧本 // ------ 初始化部分 ------ core.init // 初始化 -core.showStartAnimate // 显示开始界面 -core.hideStartAnimate // 隐藏开始界面 +core.showStartAnimate // 显示游戏开始界面 +core.hideStartAnimate // 隐藏游戏开始界面 core.setStartProgressVal // 设置加载进度条进度 core.setStartLoadTipText // 设置加载进度条提示文字 core.loader // 加载图片和音频 core.loadImage // 加载图片 -core.loadSound // 加载音频 -core.loadSoundItem // 加载某一个音频 +core.loadMusic // 加载音频 core.isPlaying // 游戏是否已经开始 core.clearStatus // 清除游戏状态和数据 core.resetStatus // 重置游戏状态和初始数据 -core.startGame // 具体开始游戏 +core.startGame // 开始游戏 * core.restart // 重新开始游戏;此函数将回到标题页面 // ------ 键盘、鼠标事件 ------ core.onKeyDown // 按下某个键时 core.onKeyUp // 放开某个键时 -core.pressKey // 按住某个键不动时 +core.pressKey // 按住某个键时 core.keyDown // 根据按下键的code来执行一系列操作 core.keyUp // 根据放开键的code来执行一系列操作 core.ondown // 点击(触摸)事件按下时 @@ -37,14 +44,14 @@ core.onmove // 当在触摸屏上滑动时 core.onup // 当点击(触摸)事件放开时 core.getClickLoc // 获得点击事件相对左上角的坐标(0到12之间) core.onclick // 具体点击屏幕上(x,y)点时,执行的操作 -core.onmousewheel // 滑动鼠标滚轮时的操作(楼层传送时可用滚轮切换楼层) +core.onmousewheel // 滑动鼠标滚轮时的操作 // ------ 自动寻路代码相关 ------ core.clearAutomaticRouteNode // 清除自动寻路路线 core.stopAutomaticRoute // 停止自动寻路操作 core.continueAutomaticRoute // 继续剩下的自动寻路操作 -core.clearContinueAutomaticRoute // 清除剩下的自动寻路列表 -core.setAutomaticRoute // 设置一个自动寻路 +core.clearContinueAutomaticRoute // 清空剩下的自动寻路列表 +core.setAutomaticRoute // 设置自动寻路路线 core.automaticRoute // 自动寻路算法,找寻最优路径 core.fillPosWithPoint // 显示离散的寻路点 core.clearStepPostfix // 清除已经寻路过的部分 @@ -54,13 +61,15 @@ core.stopAutoHeroMove // 停止勇士的自动行走 core.setAutoHeroMove // 设置勇士的自动行走路线 core.autoHeroMove // 让勇士开始自动行走 core.setHeroMoveInterval // 设置行走的效果动画 -core.setHeroMoveTriggerInterval // 设置勇士行走过程中对途经事件的触发检测 -* core.turnHero(direction) // 设置勇士的方向(转向);如果指定了direction则会面向该方向,否则执行一个转向操作。 +core.setHeroMoveTriggerInterval // 设置勇士行走过程中对事件的触发检测 +* core.turnHero(direction) // 设置勇士的方向(转向) +core.canMoveHero // 勇士能否前往某方向 core.moveHero // 让勇士开始移动 +core.eventMoveHero // 使用事件让勇士移动。这个函数将不会触发任何事件。 core.moveOneStep // 每移动一格后执行的事件。中毒时在这里进行扣血判断。 core.waitHeroToStop(callback) // 停止勇士的一切行动,等待勇士行动结束后,再执行callback回调函数。 core.stopHero // 停止勇士的移动状态。 -core.drawHero // 在hero层绘制勇士。 +core.drawHero // 绘制勇士。 * core.setHeroLoc(name, value) // 设置勇士的位置。name为”direction”,”x”,”y” * core.getHeroLoc(name) // 获得勇士的位置。 * core.nextX // 获得勇士面对位置的x坐标 @@ -71,42 +80,49 @@ core.drawHero // 在hero层绘制勇士。 * core.battle(id, x, y, force, callback) // 进行战斗;force表示是否强制战斗 core.afterBattle // 战斗完毕 core.trigger(x,y) // 触发x,y点的事件 -* core.changeFloor(floorId, stair, heroLoc, time, callback) // 楼层切换floorId为目标楼层Id,stair可指定为上/下楼梯,time动画时间 -core.mapChangeAnimate // 实际切换的动画效果 -core.clearMap // 清除地图显示 +* core.changeFloor(floorId, stair, heroLoc, time, callback) // 楼层切换。floorId为目标楼层Id,stair可指定为上/下楼梯,time动画时间 +core.mapChangeAnimate // 地图切换动画效果 +core.clearMap // 清除地图 core.fillText // 在某个canvas上绘制一段文字 core.fillRect // 在某个canvas上绘制一个矩形 core.strokeRect // 在某个canvas上绘制一个矩形的边框 +core.drawLine // 在某个canvas上绘制一条线 core.setFont // 设置某个canvas的文字字体 core.setLineWidth // 设置某个canvas的线宽度 core.saveCanvas // 保存某个canvas状态 -core.loadCanvas // 读取某个canvas状态 +core.loadCanvas // 加载某个canvas状态 core.setStrokeStyle // 设置某个canvas边框属性 core.setAlpha // 设置某个canvas的alpha值 core.setOpacity // 设置某个canvas的透明度 core.setFillStyle // 设置某个canvas的绘制属性(如颜色等) * core.drawMap(mapId, callback) // 绘制某张地图。mapId为地图Id,绘制完毕将执行callback回调函数。 +core.drawAutotile // 绘制Autotile +core.drawAutotileBlock // 绘制Autotile的某一块 * core.noPassExists(x,y) // 某个点是否不可通行 core.noPass // 某个点是否在区域内且不可通行 * core.npcExists(x,y) // 某个点是否存在NPC -* core.terrainExists(x,y) // 某个点是否存在指定的地形 +* core.terrainExists(x,y) // 某个点是否存在(指定的)地形 * core.stairExists(x,y) // 某个点是否存在楼梯 * core.nearStair // 当前位置是否在楼梯边 -* core.enemyExists(x,y) // 某个点是否存在怪物 +* core.enemyExists(x,y) // 某个点是否存在(指定的)怪物 * core.getBlock(x, y, floorId, needEnable) // 获得某个点的block。floorId指定目标楼层,needEnable如果为false则即使该点的事件处于禁用状态也将被返回(否则只有事件启用的点才被返回) core.moveBlock // 显示移动某块的动画,达到{“type”:”move”}的效果 core.animateBlock // 显示/隐藏某个块时的动画效果 -core.addBlock // 将某个块从禁用变成启用状态 +core.showBlock // 将某个块从禁用变成启用状态 core.removeBlock // 将某个块从启用变成禁用状态 core.removeBlockById // 根据block的索引删除该块 core.removeBlockByIds // 一次性删除多个block core.addGlobalAnimate // 添加一个全局动画 core.removeGlobalAnimate // 删除一个或所有全局动画 core.setGlobalAnimate // 设置全局动画的显示效果 +core.syncGlobalAnimate // 同步所有的全局动画效果 core.setBoxAnimate // 显示UI层某个box的动画(如怪物手册中怪物的动画) core.drawBoxAnimate // 绘制UI层的box动画 -core.setFg // 色调渐变 -* core.updateFg // 更新全地图的显伤 +core.updateCheckBlock // 更新领域、夹击、阻击的伤害地图 +core.checkBlock // 检查并执行领域、夹击、阻击事件 +core.snipe // 阻击事件(动画效果) +core.setFg // 更改画面色调 +* core.updateFg // 更新全地图显伤 * core.itemCount // 获得某个物品的个数 * core.hasItem // 是否存在某个物品 * core.setItem // 设置某个物品的个数 @@ -114,23 +130,23 @@ core.setFg // 色调渐变 * core.useItem // 使用某个物品;直接调用items.js中的useItem函数。 * core.canUseItem // 能否使用某个物品。直接调用items.js中的canUseItem函数。 * core.addItem // 增加某个物品的个数 -* core.getItem // 获得某个物品时的事件 +core.getNextItem // 获得面前的物品(轻按) +* core.getItem // 获得某个物品 * core.drawTip // 左上角绘制一段提示 * core.drawText // 地图中间绘制一段文字 // ------ 系统机制 ------ core.replaceText // 将文字中的${和}(表达式)进行替换 core.calValue // 计算表达式的值 -core.splitText // 字符串自动换行的分割 +core.doEffect // 执行一个表达式的effect操作 +core.splitLines // 字符串自动换行的分割 core.unshift // 向某个数组前插入另一个数组或元素 core.setLocalStorage // 设置本地存储 core.getLocalStorage // 获得本地存储 core.removeLocalStorage // 移除本地存储 -core.clone // 复制一个对象 +core.clone // 深拷贝一个对象 core.formatDate // 格式化时间为字符串 core.setTwoDigits // 两位数显示 -core.win // 获胜;将直接调用events.js中的win函数 -core.lose // 失败;将直接调用events.js中的lose函数 core.debug // 进入Debug模式,攻防血和钥匙都调成很高的数值 core.checkStatus // 判断当前能否进入某个事件 core.openBook // 点击怪物手册时的打开操作 @@ -144,6 +160,7 @@ core.saveData // 存档到本地 core.loadData // 从本地读档 * core.setStatus // 设置勇士属性 * core.getStatus // 获得勇士属性 +core.getLvName // 获得某个等级的名称 * core.setFlag // 设置某个自定义变量或flag * core.getFlag // 获得某个自定义变量或flag * core.hasFlag // 是否存在某个自定义变量或flag,且值为true @@ -151,17 +168,16 @@ core.insertAction // 往当前事件列表之前插入一系列事件 * core.lockControl // 锁定状态栏,常常用于事件处理 * core.unlockControl // 解锁状态栏 * core.isset // 判断某对象是否不为undefined也不会null -* core.playSound // 播放音频 * core.playBgm // 播放背景音乐 -core.changeSoundStatus // 切换声音状态 -core.enableSound // 启用音效 -core.disableSound // 禁用音效 +* core.pauseBgm // 暂停背景音乐的播放 +* core.resumeBgm // 恢复背景音乐的播放 +* core.playSound // 播放音频 core.show // 动画显示某对象 core.hide // 动画使某对象消失 core.clearStatusBar // 清空状态栏 core.updateStatusBar // 更新状态栏 core.resize // 屏幕分辨率改变后重新自适应 -core.resetSize // 屏幕分辨率改变后重新自适应 +core.domRenderer // 渲染DOM // ------ core.js 结束 ------ ``` @@ -171,53 +187,105 @@ core.resetSize // 屏幕分辨率改变后重新自适应 !> **`enemys.js` 定义了怪物信息。** ``` js -* core.enemys.getSpecialText // 获得特殊属性的文字 +core.enemys.init // 初始化 +* core.enemys.getEnemys // 获得一个或所有怪物数据 +* core.enemys.hasSpecial // 判断是否含有某特殊属性 +* core.enemys.getSpecialText // 获得所有特殊属性的名称 +* core.enemys.getSpecialHint // 获得每个特殊属性的说明 * core.enemys.getDamage // 获得某个怪物的伤害 -* core.enemys.getExtraDamage // 获得某个怪物的额外伤害(吸血) -* core.enemys.getCritical // 计算某个怪物的临界值 -* core.enemys.getCriticalDamage // 计算某个怪物的临界减伤 -* core.enemys.getDefDamage // 计算某个怪物的1防减伤 -* core.enemys.calDamage // 实际的伤害计算公式 -core.enemys.getCurrentEnemys // 获得当前层剩下的的怪物列表 +* core.enemys.getExtraDamage // 获得某个怪物的额外伤害 +* core.enemys.getCritical // 临界值计算 +* core.enemys.getCriticalDamage // 临界减伤计算 +* core.enemys.getDefDamage // 1防减伤计算 +* core.enemys.calDamage // 具体的伤害计算公式 +core.enemys.getCurrentEnemys // 获得当前楼层的怪物列表 ``` !> **`events.js` 定义了各个事件的处理流程。** ``` js -* core.events.startGame // 开始游戏 -* core.events.win // 获胜 -* core.events.lose // 失败 -core.events.checkBlock // 检查领域、夹击事件 -core.events.afterChangeFloor // 楼层切换结束时的事件 +core.events.init // 初始化 +core.events.getEvents // 获得一个或所有系统事件类型 +core.events.startGame // 游戏开始事件 +* core.events.setInitData // 不同难度分别设置初始属性 +* core.events.win // 游戏获胜事件 +* core.events.lose // 游戏失败事件 +core.events.afterChangeFloor // 转换楼层结束的事件 core.events.doEvents // 开始执行一系列自定义事件 core.events.doAction // 执行当前自定义事件列表中的下一个事件 -core.events.insertAction // 往当前自定义事件列表前插入若干个事件 +core.events.insertAction // 往当前事件列表之前添加一个或多个事件 core.events.openShop // 打开一个全局商店 -core.events.disableQuickShop // 禁用一个快捷商店 +core.events.disableQuickShop // 禁用一个全局商店 * core.events.canUseQuickShop // 当前能否使用快捷商店 +* core.events.checkLvUp // 检查升级事件 * core.events.useItem // 尝试使用道具 +core.events.addPoint // 加点事件 core.events.afterBattle // 战斗结束后触发的事件 core.events.afterOpenDoor // 开一个门后触发的事件 core.events.passNet // 经过一个路障 -core.events.beforeSaveData // 即将存档前可以执行的操作 -core.events.afterLoadData // 读档后,载入事件前可以执行的操作 +core.events.changeLight // 改变亮灯(感叹号)的事件 +* core.events.afterChangeLight // 改变亮灯之后,可以触发的事件 +* core.events.afterUseBomb // 使用炸弹/圣锤后的事件 +* core.events.beforeSaveData // 即将存档前可以执行的操作 +* core.events.afterLoadData // 读档事件后,载入事件前,可以执行的操作 -// ------ 界面上的点击事件 ------ -core.events.clickAction // 自定义事件处理时,对用户点击的处理 -core.events.clickBook // 怪物手册打开时,对用户点击的处理 -core.events.clickFly // 楼层传送器打开时,对用户点击的处理 -core.events.clickShop // 全局商店打开时,对用户点击的处理 -core.events.clickQuickShop // 快捷商店选项打开时 -core.events.clickToolbox // 工具栏打开时 -core.events.clickSL // 存/读档界面打开时 -core.events.clickSettings // 设置页面打开时 +// ------ 点击事件和键盘事件的处理 ------ +core.events.keyDownCtrl // 按下Ctrl键时(快捷跳过对话) +core.events.clickConfirmBox // 确认框界面时的点击操作 +core.events.keyUpConfirmBox // 确认框界面时,放开某个键的操作 +core.events.clickAction // 自定义事件时的点击操作 +core.events.keyDownAction // 自定义事件时,按下某个键的操作 +core.events.keyUpAction // 自定义事件时,放开某个键的操作 +core.events.clickBook // 怪物手册界面的点击操作 +core.events.keyDownBook // 怪物手册界面时,按下某个键的操作 +core.events.keyUpBook // 怪物手册界面时,放开某个键的操作 +core.events.clickBookDetail // 怪物手册属性显示界面时的点击操作 +core.events.clickFly // 楼层传送器界面时的点击操作 +core.events.keyDownFly // 楼层传送器界面时,按下某个键的操作 +core.events.keyUpFly // 楼层传送器界面时,放开某个键的操作 +core.events.clickShop // 商店界面时的点击操作 +core.events.keyDownShop // 商店界面时,按下某个键的操作 +core.events.keyUpShop // 商店界面时,放开某个键的操作 +core.events.clickQuickShop // 快捷商店界面时的点击操作 +core.events.keyDownQuickShop // 快捷商店界面时,按下某个键的操作 +core.events.keyUpQuickShop // 快捷商店界面时,放开某个键的操作 +core.events.clickToolbox // 工具栏界面时的点击操作 +core.events.clickToolboxIndex // 选择工具栏界面中某个Index后的操作 +core.events.keyDownToolbox // 工具栏界面时,按下某个键的操作 +core.events.keyUpToolbox // 工具栏界面时,放开某个键的操作 +core.events.clickSL // 存读档界面时的点击操作 +core.events.keyDownSL // 存读档界面时,按下某个键的操作 +core.events.keyUpSL // 存读档界面时,放开某个键的操作 +core.events.clickSwitchs // 系统设置界面时的点击操作 +core.events.keyDownSwitchs // 系统设置界面时,按下某个键的操作 +core.events.keyUpSwitchs // 系统设置界面时,放开某个键的操作 +core.events.clickSettings // 系统菜单栏界面时的点击事件 +core.events.keyDownSettings // 系统菜单栏界面时,按下某个键的操作 +core.events.keyUpSettings // 系统菜单栏界面时,放开某个键的操作 +core.events.clickSyncSave // 同步存档界面时的点击操作 +core.events.keyDownSyncSave // 同步存档界面时,按下某个键的操作 +core.events.keyUpSyncSave // 同步存档界面时,放开某个键的操作 +core.events.clickAbout // “关于”界面时的点击操作 ``` -!> `maps.js` 定义了地图,以及每个数字所代表的意义。 +!> `icons.js` 定义了素材ID和它在图片上的索引的对应关系。 + +!> `items.js` 定义了每个道具的名称,以及使用效果。 + +``` js +core.items.init // 初始化 +core.items.getItems // 获得所有道具 +core.items.getItemEffect // “即捡即用类”道具的使用效果 +core.items.getItemEffectTip // “即捡即用类”道具的文字提示 +* core.items.useItem // 使用道具 +* core.items.cauUseItem // 当前能否使用道具 +``` + +!> `maps.js` 定义了数字-ID的对应关系。 ``` js core.maps.loadFloor // 加载某个楼层(从剧本或存档中) -core.maps.getBlock // 将数字替换成实际的内容 +core.maps.getBlock // 数字和ID的对应关系 core.maps.addEvent // 向该楼层添加剧本的自定义事件 core.maps.addChangeFloor // 向该楼层添加剧本的楼层转换事件 core.maps.initMaps // 初始化所有地图 @@ -232,16 +300,19 @@ core.ui.closePanel // 结束一切事件和绘制,关闭UI窗口,返回游 core.ui.drawTextBox // 绘制一个对话框 core.ui.drawChoices // 绘制一个选项界面 core.ui.drawConfirmBox // 绘制一个确认/取消的警告页面 +core.ui.drawSwitchs // 绘制系统设置界面 core.ui.drawSettings // 绘制系统菜单栏 core.ui.drawQuickShop // 绘制快捷商店选择栏 -core.ui.drawBattleAnimate // 绘制战斗过程 -core.ui.drawWaiting // 绘制一个“请稍后”页面 -core.ui.drawSyncSave // 绘制存档同步选项 +core.ui.drawBattleAnimate // 绘制战斗动画 +core.ui.drawWaiting // 绘制等待界面 +core.ui.drawSyncSave // 绘制存档同步界面 core.ui.drawPagination // 绘制分页 core.ui.drawEnemyBook // 绘制怪物手册 +core.ui.drawBookDetail // 绘制怪物属性的详细信息 core.ui.drawFly // 绘制楼层传送器 core.ui.drawToolbox // 绘制道具栏 core.ui.drawSLPanel // 绘制存档/读档界面 core.ui.drawThumbnail // 绘制一个缩略图 core.ui.drawAbout // 绘制“关于”界面 +core.ui.drawHelp // 绘制帮助界面 ``` diff --git a/docs/element.md b/docs/element.md index 668c0c2d..50459e42 100644 --- a/docs/element.md +++ b/docs/element.md @@ -40,14 +40,15 @@ ``` js enemys.prototype.getSpecialText = function (enemyId) { if (enemyId == undefined) return ""; - var special = this.enemys[enemyId].special; + var enemy = this.enemys[enemyId]; + var special = enemy.special; var text = []; if (this.hasSpecial(special, 1)) text.push("先攻"); if (this.hasSpecial(special, 2)) text.push("魔攻"); if (this.hasSpecial(special, 3)) text.push("坚固"); if (this.hasSpecial(special, 4)) text.push("2连击"); if (this.hasSpecial(special, 5)) text.push("3连击"); - if (this.hasSpecial(special, 6)) text.push("4连击"); + if (this.hasSpecial(special, 6)) text.push((enemy.n||4)+"连击"); if (this.hasSpecial(special, 7)) text.push("破甲"); if (this.hasSpecial(special, 8)) text.push("反击"); if (this.hasSpecial(special, 9)) text.push("净化"); @@ -59,22 +60,35 @@ enemys.prototype.getSpecialText = function (enemyId) { if (this.hasSpecial(special, 15)) text.push("领域"); if (this.hasSpecial(special, 16)) text.push("夹击"); if (this.hasSpecial(special, 17)) text.push("仇恨"); + if (this.hasSpecial(special, 18)) text.push("阻击"); + if (this.hasSpecial(special, 19)) text.push("自爆"); + if (this.hasSpecial(special, 20)) text.push("无敌"); return text.join(" "); } ``` -如果需要双属性,则采用100x+y的写法。例如 103 则视为同时拥有1和3的属性,即先攻且坚固。同理1314为衰弱诅咒双属性。 +多属性可采用数组的写法,比如`'special': [1,3]`视为同时拥有先攻和坚固属性;`'special': [5,10,14,18]`视为拥有3连击、魔防、诅咒、阻击四个属性。 -如果需要三属性,则采用10000x+100y+z的写法。例如71116视为同时拥有7,11和16的属性,即破甲、吸血、夹击。 +本塔支持战斗动画,在`data.js`中存在三个全局选项:`canOpenBattleAnimate`, `showBattleAnimateConfirm`, `battleAnimate`。 +- `canOpenBattleAnimate`代表是否允许用户开启战斗动画。如果你添加了一些自定义属性,且不想修改战斗界面的UI,则可以将其关闭。 +- `showBattleAnimateConfirm`代表是否在游戏开始时给用户提供开启动画的选项。对于一些偏向于萌新的塔,可以开启此项。 +- `battleAnimate`代表是否默认开启战斗动画。此项会被用户存储的设置给覆盖。 +- 如果`canOpenBattleAnimate`为false,则后面两个也强制为false。 -四个乃至更多的属性以此类推。 +怪物可以负伤,在`data.js`的全局变量`enableNegativeDamage`中指定。 -怪物的伤害计算在下面的`calDamage`函数中,如有自己需求的伤害计算公式请修改该函数的代码。 +下面的`getSpecialHint`函数则给定了每个特殊属性的详细描述。这个描述将在怪物手册中看到。 + +**打败怪物后可以进行加点操作。有关加点塔的制作可参见[加点事件](event#加点事件)。** 如果`data.js`中的enableExperience为false,即不启用经验的话,怪物手册里将不显示怪物的经验值,打败怪物也不获得任何经验。 拿到幸运金币后,打怪获得的金币将翻倍。 +N连击怪物的special是6,且我们可以为它定义n代表实际连击数。参见样板中剑王的写法。 + +![N连击](./img/nattack.png) + 吸血怪需要在怪物后添加value,代表吸血的比例。 ![怪物吸血](./img/blood.png) @@ -89,15 +103,21 @@ enemys.prototype.getSpecialText = function (enemyId) { 领域怪需要在怪物后添加value,代表领域伤害的数值。如果勇士生命值扣减到0,则直接死亡触发lose事件。 -![怪物领域](./img/domainenemy.png) +领域是十字伤害还是九宫格伤害由data.js中的全局变量`zoneSquare`设定。你也可以对该怪物自行进行设定。 -请注意如果吸血和领域同时存在,则value会冲突。**因此请勿将吸血和领域放置在同一个怪物身上。** +`range`选项可选,代表该领域怪的范围,不写则默认为1。 -本塔暂不支持阻击、激光、自爆、退化等属性。 +![怪物领域](./img/zone.png) + +阻击怪同样需要在怪物后添加value,代表领域伤害的数值。如果勇士生命值扣减到0,则直接死亡触发lose事件。 + +!> 阻击怪后退的地点不能有任何事件存在,即使是已经被禁用的自定义事件! + +请注意如果吸血、领域、阻击中任何两个同时存在,则value会冲突。**因此请勿将吸血、领域或阻击放置在同一个怪物身上。** 如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。 -### 路障、楼梯、传送门 +### 路障,楼梯,传送门 血网的伤害数值、中毒后每步伤害数值、衰弱时暂时攻防下降的数值,都在 `data.js` 的values内定义。 @@ -123,6 +143,65 @@ floorId指定的是目标楼层的唯一标识符(ID)。 ![楼层转换穿透](./img/floorset.png) +### 背景音乐 + +本塔支持BGM和SE的播放。 + +要播放音乐和音效,你需要将对应的文件放在sounds目录下,然后在main.js中进行定义 + +``` js +this.bgms = [ // 在此存放所有的bgm,和文件名一致。第一项为默认播放项 + // 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 + '058-Slow01.mid', 'bgm.mp3', 'qianjin.mid', 'star.mid' +]; +this.sounds = [ // 在此存放所有的SE,和文件名一致 + // 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 + 'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg' +] +``` + +!> 音频名不能使用中文,不能带空格或特殊字符。 + +目前BGM支持主流的音乐格式,如mp3, ogg, mid格式等。SE则不支持mid格式的播放。 + +!> mid格式是通过数学方法模拟出来的音乐效果,质量可能会和实际效果差距较大。 + +定义完毕后,我们可以调用`playBgm`/`playSound`事件来播放对应的音乐/音效,有关事件的详细介绍请参见[事件](event)。 + +**另外,考虑到用户的流量问题,将遵循如下规则:** +- **如果用户当前使用的电脑,则默认开启音乐效果,并播放默认BGM** +- **如果用户当前使用的手机,且处于Wifi状态,则默认开启音乐效果,并播放默认BGM** +- **其他情况,将默认关闭音乐效果,只有在用户在菜单栏中点击“音乐开关”后才会播放音乐** + +!> iOS平台以及部分浏览器不支持获得当前网络状态,此时即使在使用Wifi也必须要用户点击“音乐开关”才能播放音乐。 + +### 操作说明 + +本塔主要支持鼠标(触摸屏)操作和键盘操作。 + +鼠标(触摸屏)操作说明如下: +- **点状态栏中图标:** 进行对应的操作 +- **点任意块:** 寻路并移动 +- **点任意块并拖动:** 指定寻路路线 +- **单击勇士:** 转向 +- **双击勇士:** 轻按(仅在轻按开关打开时有效) + +键盘操作快捷键如下: +- **[CTRL]** 跳过对话 +- **[X]** 打开/关闭怪物手册 +- **[G]** 打开/关闭楼层传送器 +- **[S/D]** 打开/关闭存/读档页面 +- **[K]** 打开/关闭快捷商店选择列表 +- **[T]** 打开/关闭工具栏 +- **[ESC]** 打开/关闭系统菜单 +- **[H]** 打开帮助页面 +- **[SPACE]** 轻按(仅在轻按开关打开时有效) +- **[1]** 快捷使用破墙镐 +- **[2]** 快捷使用炸弹/圣锤 +- **[3]** 快捷使用中心对称飞行器 + +以上快捷键也能在游戏菜单中的操作说明中看到。 +     diff --git a/docs/event.md b/docs/event.md index f9cab896..a1525c3c 100644 --- a/docs/event.md +++ b/docs/event.md @@ -397,7 +397,9 @@ revisit常常使用在一些商人之类的地方,当用户购买物品后不 如果强制战斗失败,则会立刻生命归0并死亡,调用lose函数,接下来的事件不会再被执行。 -强制战斗没有指定loc的选项,因此战斗后需要调用hide使怪物消失(如果有必要)。强制战斗不会触发任何afterBattle里的事件。 +打败怪物后可以进行加点操作。有关加点塔的制作可参见[加点事件](#加点事件)。 + +强制战斗没有指定loc的选项,因此战斗后需要调用hide使怪物消失(如果有必要)。 ### openDoor: 开门 @@ -416,8 +418,6 @@ loc指定门的坐标,floorId指定门所在的楼层ID。如果是当前层 如果loc所在的点既不是门也不是墙壁,则忽略本事件。 -openDoor不会触发任何afterOpenDoor里的事件。 - ### changeFloor: 楼层切换 在事件中也可以对楼层进行切换。一个比较典型的例子就是TSW中,勇士在三楼的陷阱被扔到了二楼,就是一个楼层切换事件。 @@ -553,6 +553,26 @@ move完毕后移动的NPC/怪物一定会消失,只不过可以通过immediate 不过值得注意的是,用这种方式移动勇士的过程中将无视一切地形,无视一切事件,中毒状态也不会扣血。 +### playBgm: 播放背景音乐 + +使用playBgm可以播放一个背景音乐。 + +使用方法:`{"type": "playBgm", "name": "bgm.mp3"}` + +值得注意的是,额外添加进文件的背景音乐,需在main.js中this.bgms里加载它。 + +目前支持mp3/ogg/wav/mid等多种格式的音乐播放。 + +有关BGM播放的详细说明参见[背景音乐](element#背景音乐) + +### pauseBgm: 暂停背景音乐 + +使用`{"type": "pauseBgm"}`可以暂停背景音乐的播放。 + +### resumeBgm: 恢复背景音乐 + +使用`{"type": "resumeBgm"}`可以恢复背景音乐的播放。 + ### playSound: 播放音效 使用playSound可以立刻播放一个音效。 @@ -561,10 +581,6 @@ move完毕后移动的NPC/怪物一定会消失,只不过可以通过immediate 值得注意的是,如果是额外添加进文件的音效,则需在main.js中this.sounds里加载它。 -!> 自定义添加的音效名请勿包含`-`,否则将无法正常使用! - -由于考虑到用户流量问题,每个额外音效最好不超过20KB。 - ### win: 获得胜利 `{"type": "win", "reason": "xxx"}` 将会直接调用events.js中的win函数,并将reason作为参数传入。 @@ -756,6 +772,43 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用 // …… ``` +## 加点事件 + +打败怪物后可以进行加点。 + +如果要对某个怪物进行加点操作,则首先需要修改该怪物的点数值,即在怪物定义的后面添加`point`,代表怪物本身的加点数值。 + +``` js +... 'def': 0, 'money': 1, 'experience': 1, 'special': 0, 'point': 1}, // 在怪物后面添加point代表怪物的加点数 +``` + +然后在`events.js`文件中找到`addPoint`函数。它将返回一个choices事件。修改此函数为我们需要的加点项即可。 + +``` js +////// 加点 ////// +events.prototype.addPoint = function (enemy) { + var point = enemy.point; // 获得该怪物的point + if (!core.isset(point) || point<=0) return []; + + // 加点,返回一个choices事件 + return [ + {"type": "choices", + "choices": [ // 提供三个选项:对于每一点,攻击+1/防御+2/生命+200 + {"text": "攻击+"+(1*point), "action": [ + {"type": "setValue", "name": "status:atk", "value": "status:atk+"+(1*point)} + ]}, + {"text": "防御+"+(2*point), "action": [ + {"type": "setValue", "name": "status:def", "value": "status:def+"+(2*point)} + ]}, + {"text": "生命+"+(200*point), "action": [ + {"type": "setValue", "name": "status:hp", "value": "status:hp+"+(200*point)} + ]}, + ] + } + ]; +} +``` + ## 全局商店 我们可以采用上面的choices方式来给出一个商店。这样的商店确实可以有效地进行操作,但是却是"非全局"的,换句话说,只有在碰到NPC的时候才能触发商店事件。 @@ -776,7 +829,6 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用 // 上面的例子是50层商店的计算公式。你也可以写任意其他的计算公式,只要以times作为参数即可。 // 例如: "need": "25" 就是恒定需要25金币的商店; "need": "20+2*times" 就是第一次访问要20金币,以后每次递增2金币的商店。 // 如果是对于每个选项有不同的计算公式,写 "need": "-1" 即可。可参见下面的经验商店。 - "text": "勇敢的武士啊,给我${need}金币就可以:", // 显示的文字,需手动加换行符。可以使用${need}表示上面的need值。 "choices": [ // 商店的选项 {"text": "生命+800", "effect": "status:hp+=800"}, @@ -784,10 +836,12 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用 {"text": "攻击+4", "effect": "status:atk+=4"}, {"text": "防御+4", "effect": "status:def+=4"}, {"text": "魔防+10", "effect": "status:mdef+=10"} - // effect只能对status和item进行操作,不能修改flag值。且其中间只能用+=符号(也就是只能增加某个属性或道具) + // effect只能对status和item进行操作,不能修改flag值。 + // 必须是X+=Y的形式,其中Y可以是一个表达式,以status:xxx或item:xxx为参数 // 其他effect样例: // "item:yellowKey+=1" 黄钥匙+1 // "item:pickaxe+=3" 破墙镐+3 + // "status:hp+=2*(status:atk+status:def)" 将生命提升攻防和的数值的两倍 ] }, "expShop1": { // 商店唯一ID @@ -800,13 +854,13 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用 "choices": [ // 在choices中写need,可以针对每个选项都有不同的需求。 // 这里的need同样可以以times作为参数,比如 "need": "100+20*times" - {"text": "等级+1", "need": "100", "effect": "status:hp+=1000;status:atk+=7;status:def+=7"}, + {"text": "等级+1", "need": "100", "effect": "status:lv+=1;status:hp+=1000;status:atk+=7;status:def+=7"}, // 多个effect直接以分号分开即可。如上面的意思是生命+1000,攻击+7,防御+7。 {"text": "攻击+5", "need": "30", "effect": "status:atk+=5"}, {"text": "防御+5", "need": "30", "effect": "status:def+=5"}, ] - } -} + }, +}, ``` 全局商店全部定义在`data.js`中的shops一项里。 @@ -887,37 +941,70 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用 当且仅当勇士第一次到达某层时,将会触发此事件。可以利用此事件来显示一些剧情,或再让它调用 `{"type": "trigger"}` 来继续调用其他的事件。 +## 经验升级(进阶/境界塔) + +本塔也支持经验升级,即用户杀怪获得经验后,可以到达某些数值自动进阶,全面提升属性。 + +要经验升级,你需要先在`data.js`中的全局变量中启用。你需要将`enableExperience`启用经验,且`enableLevelUp`启用进阶。同时你也可以将`enableLv`置为true以在状态栏中显示当前等级(境界)。 + +同时,你还需要在`data.js`中的`levelUp`来定义每一个进阶所需要的生命值,以及进阶时的效果。 + +``` js +"levelUp": [ // 经验升级所需要的数值,是一个数组 + {}, // 第一项为初始等级,可以简单留空,也可以写name + + // 每一个里面可以含有三个参数 need, name, effect + // need为所需要的经验数值,是一个正整数。请确保need所需的依次递增 + // name为该等级的名称,也可以省略代表使用系统默认值;本项将显示在状态栏中 + // effect为本次升级所执行的操作,可由若干项组成,由分号分开 + // 其中每一项写法和上面的商店完全相同,同样必须是X+=Y的形式,Y是一个表达式,同样可以使用status:xxx或item:xxx代表勇士的某项数值/道具个数 + {"need": 20, "name": "第二级", "effect": "status:hp+=2*(status:atk+status:def);status:atk+=10;status:def+=10"}, // 先将生命提升攻防和的2倍;再将攻击+10,防御+10 + + // effect也允许写一个function,代表本次升级将会执行的操作,比如可以显示一段提示文字,或者触发一个事件 + {"need": 40, "effect": function () { + core.drawText("恭喜升级!"); + core.status.hero.hp *= 2; + core.status.hero.atk += 100; + core.status.hero.def += 100; + }}, + + // 依次往下写需要的数值即可 +] +``` + +`levelUp`是一个数组,里面分别定义了每个等级的信息。里面每一项是一个object,主要有三个参数`need`, `name`, `effect` +- `need` 该等级所需要的经验值,是一个正整数。请确保数组中的need依次递增。 +- `name` 该等级的名称,比如“佣兵下级”等。该项可以忽略,以使用系统默认的等级。该项将显示在状态栏中。 +- `effect` 为本次等级执行的操作。它有两种写法:字符串,或函数。 + - 如果`effect`为字符串,则和上面的全局商店的写法完全相同。可由分号分开,每一项为X+=Y的形式,X为你要修改的勇士属性/道具个数,Y为一个表达式。 + - 如果`effect`为函数,则也允许写一个`function`,来代表本次升级将会执行的操作。 + ## 开始,难度分歧,获胜与失败 -游戏开始时将调用`events.js`中的startGame函数。 +游戏开始时将调用`events.js`中的`startGame`函数。 -它将显示`data.js`中的startText内容(可以修改成自己的),并正式开始游戏。 +它将显示`data.js`中的startText内容(可以修改成自己的),提供战斗动画开启选择,设置初始福利,并正式开始游戏。 + +我们可以修改`setInitData`函数来对于不同难度分别设置初始属性。 其参数hard为以下三个字符串之一:`"Easy"`, `"Normal"`, `"Hard"`,分别对应三个难度。针对不同的难度,我们可以设置一些难度分歧。 ``` js -////// 游戏开始事件 ////// -events.prototype.startGame = function (hard) { - - if (core.status.isStarting) return; - core.status.isStarting = true; - - core.hideStartAnimate(function() { - core.drawText(core.clone(core.firstData.startText), function() { - core.startGame(hard); - if (hard=='Easy') { // 简单难度 - core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度 - // 可以在此设置一些初始福利,比如设置初始生命值可以调用: - // core.setStatus("hp", 10000); - } - if (hard=='Normal') { // 普通难度 - core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度 - } - if (hard=='Hard') { // 困难难度 - core.setFlag('hard', 3); // 可以用flag:hard来获得当前难度 - } - }); - }) +////// 不同难度分别设置初始属性 ////// +events.prototype.setInitData = function (hard) { + if (hard=='Easy') { // 简单难度 + core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度 + // 可以在此设置一些初始福利,比如设置初始生命值可以调用: + // core.setStatus("hp", 10000); + // 赠送一把黄钥匙可以调用 + // core.setItem("yellowKey", 1); + } + if (hard=='Normal') { // 普通难度 + core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度 + } + if (hard=='Hard') { // 困难难度 + core.setFlag('hard', 3); // 可以用flag:hard来获得当前难度 + } } ``` diff --git a/docs/img/domainenemy.png b/docs/img/domainenemy.png deleted file mode 100644 index b74eabcb1dd5d4efbc70902fa6d15993fa2e1368..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22145 zcmYhi1yCH#_XUc(26qVV1b3GZWO4W4PH##?Jlx`El02@BQy~CW4$egF8l4$x0 zujltx_+zy5RT~e${9}9I;GgsE-|*$hpRSyN!R@pXiu+7TS8V=I-;hBlrSv$7I!e#mw6887T)Ch`8Eb4^h8# zfaVsiFR@A8+mTuI^AZzjVYNiblJ-uzn;p-F$)@PAXI~_j1 zFLe;!&8FY46i8OM8tv%ld0Z`t?sfn9vzOKH<~1isjND;oSzwFQWi`wi%UW5u(nfhO zxpeC0TOUhLyTs}PKBBMdZSKL3tjiQ&%>3<|~4ojN{+1lcv>SyBl zw^IldKNZu}RboHI3H-#g6XqRGGtvWoUEtV(WV(>F3VKwy+JJbn6H;bF#JH1eE?o+jrF)BLZ11J#E8jnz} zxv-1(ySvk!iFOjn?^@MoE&h6Ho^LP_Y3{-Rb&A}VU_grFL3!metKq#O6bR140s>{R zaKH7!da+56WhFx$Rp&|&q6EU@jh^Joa=K7iyk`69pLhJtcg@+p z1%g+Wr>^Utf+fSVo^aL<`7~R`Oo}FX!WdNoTHLN*(D&JZ?qSTzOg3yqIJODKkIuzeowk==be8>VQ zoMwjc^|5zxnrBnNuMhRjOvSw#!sWE*LY7b+T?V$mOOuo$DDr|v^=Be?@mKkw_Xypg zd*27|{Z%~ip|Zvjgk}^^KyJ!PbCG1TQsG(9uuQq;KO;rY#qjY71u-v1 zvMQvbv+fOds3vkOTBM|qr&!R_D*!(bR5L5K4$tQgi#Ebe#NFNzz|?M_jNHOsQH$*Kb}W$c_G`c%m(*{h z4{&ijp4|}4e9Q{7!bLEY*0hb6yB5A%PTrh$Z)~O)7mw~X>sdZf6T#3D1E#f49Zyk` zlvE2S4?`-IAPis~;UW?ZoC|r?;bT5dRrq|b)zpVB{wPTl>5jrNzTNYg1zz^gN;>XoA2lF8vGF4i*Em>1A!^U-_X_2@A?z6_Xm5SFp$M<=1SQQE-q zsR)5r#v|?Bl1_@Ao1WvTe;wD{34dey`y}h$2kCk28lBY;lO7hkb(O8naGLba-0tdQ$U_`X6ivM;I)8rF*HAEk{Y-mk=IUY*VTlHHM|v;4lDxci>H zzFufLMxgwg-Zc+jny8G-VZ*kRgr^(f$@`{{(#MrLe-DK^W`{7!k)Qs^;+(=^AKzE~ z8CA`y!1|!$Z7HP^TNApjo=hzP=;ys#(UhfrpIy0dQ&w=AJE0W)5rrrT5$(M@cWTVU zl#{#Z854zG%3H>do7Ajd4}T>1v4B_fu#I<5$EX=OCNci^S{Aq|D5u>p2B}}b;r|{{ zJBD&ky=5aZ{(vDP*ZrJT%A|6wVsVF`57M3~dzcc{R~cEg5+9^1|=uiwX|vq1Q+YN5&!KX3Fq_E^1{f%oeHhRwv$o5LWqCtp>#%2 zLVLNi&J)ug;|dFHE_t}pGYKt?--}m}(N@7*@j!`C_`bdKCEto5QGA%v;~qO0;8P^` zrZxU5GYs3G(FhaLi^kJ5rL9(5hs6g(3wjVw&pY&pEd&xL zTM;YGc-QhtW|O-sDgS9U_RyVDkd`LiW7bMs{H4N>gu66@G0_tS-9ZbtL;bYr?_kgZ z?T+o0B?8BBjnIilpTkP~@1aUI)O&meEDx`-=|YmBMz6?$r~QeLRlW_%;Jrx0cF>ut z4W0qN2*I7Cc1!HfSgcggr~cu~mW>YwgkWG+lp&-Ibwg=2N9J1t9zz{OSq zxT;*wR(+mZBDĕ+H-0DP8cZ$aQ{ zT;N})um@Hu-E8BH5%3O}lx|`%yeO&k`4OJM@D$``BQkWK;s&?7mmj4fezEt+j4wqzfTCFJvSz6>`F&o8xo*Ih>mN1DHZPX6c1n*i&_lZ16&EpXlxl6Gs9{R zm-Z#-cSi*AVkxL|wvWvOUcf)2#aaEGQfM+KCax?kv|CE;&8xUKXYU(n(qkr26_R5$ z+B->YDuG*R$*=kl|4+9>ykYjU_)J;|o( z#|T_(EZwj~da1H)jGv-bE25Z1n3uT<`t^2+q)%yFPFMGG&!Dk{C=`x%Vy-qnFOt4H zet))Y22u6v!*SQYYKmDF+<4iT{jfjo&g4l#VnST0ItSecmdoSw80K8^^>gRu&@9N+8yeo$g9 z@GGdPh~rz#EY)H|793;hhkTGL_IyZ4vDqr8Gi<)L%dCh{i1SR}m#{5&MMk*^zpk2> z@>u~RryZ6XRZmOC=%bbW%2?GU>U(k|xZJxT z@luAEy1>8sWSrb>l93M?ze=^1i^kG9>3;q79|fLaJ47$!=5dVWwiS!`h*nXi6b_K? zPU%K|HcUJSeiH$z1FrRB%{?#nT5}QF*bwO-a*pF(0vZU#cXJso6JX6_)KIzr0XU=D zX5OgE#c%v^67JaBbDsam1RVW`KZH!kp++>Lgz&0u&KapY^6%^S;&ddS`khl1GOB91 z-k0OeBv+wbQEz-t^^veCM4>=`e@(Pu^6#?%N*zP3;_tI~8uZr%B2UX2v9%Yxd12g? zpFZQf71CM;k`dh*uE~}H73L7GpPAOc;iU8^ot9TeiJGQ{9NB+BPe~*yE*neERz~pYOHtQFevVpKg>F7M#@>W9r3sX z&n@~`las+K$Ya+XaQ01niMIOq7dj`7Bf<4eK-V3+Pov#9)-allB za~GC~+uYbPVWM9>EMQ7FtyEw`uDfePS90axgKddK#Y4gf8iJ&Aq-@CUqBLKh zy*6~Nq9B-PD?tY@t~3Ac6p^S!FP3xcNOS^OUN8%VSJt@FbqefDpNPEO0|H8=9=hN} zgS8L}0q5GWQn|_PXHE^|&XDnh^e;?0^&y>;-in3pmdY5y^UBb{mN;>%sVr}WpF3fk zYw&&o`Z|=7sIjUoW#7ad!?*XQwDrPdI!+W!e`B%<@r1}pYubd(Ac^ocqrV-g%UU+h z^-oBa21&$@pnhA;hOpo~tQjcGuadb7_<1iE2EQc;J!eRNSV088K5U&=%)B~4Va93@ zWBUmRhE9W|yW_Q;$F{U)IJOWQhxvS%d_9H@WX*R; zEY#^NYu`s7S0$oy+P3oXIA8y69ks@r#HT7el>hH-S6D9^!vKyq^cGan%a|XTs*M=7 zJWZkIv)m)vmt#kYCD>WW|%1{%c$+XRJUcwlDUpW{qDizjc2B zdXJh{*<*R|TfM?R`oE-03@;F<*}n}`fIqU>D~|V+F040LzN*|!e$)E;deOuYGFG68 zQLZJQD`nBD*z55jL)ih8> zBBxbRQZUuH`c4X*;C3HM{rI$r*T~^5+ zh;((-WSSw?`Z2$WYEO#_79kQe(d+^04s`{~QBsHynj3aTmjDg2jlj`3o#Xi+_7Gmx zJE7KVBdD4}d0OCtMlbeLf@cD~$BsdOV?_6cwj$gAxF)^vfU!B?)iGJTCq=r;`Z1V8-Hi>+^zPpJ zqx>d?gF1^gedhq$yZB!iQ!Js9_35u1Ubo|yhw3;J|MThuV?La63$&}$bE+J{U!bK! z1+{LGEsw_ziFIXj*uqF(UIyo0KHvN>HPs#u?aCN2f7?)|M@8$e6#EB8B>fmEak6C} z89CH?t4+|mjHQ#&Trq(yeGA(4eFvT8#cE{6UUk-BFjKs-_k#TpyPH*!O7WWP6 ziEW5G(c|ZD9;N1qkDRVw2ksJ?0671P5>MloADG( zkWY*b=s>pXt$$(k3jF%H+n{j_BbAS_A(A*nvDB98CQNL^Nl;lBS{<(AUAT}<(Q(69_jJB=gAQ@6 zc%xbPZ~(K2|ASJ#`R=+`Sn^nt{;Pxp$Kq0yA{P~Un`k1&utpQ%c=5-B3cW;*HA1v& zMj~GkfIz&GuKs03F`FOS{L6S8fA6iT#b!>$T1kbP&|$iYN1^aUjIrW&6!5CfN)JW^ zAH$c_q+0It4W-l7Kp>4jglUCrSb}Ga^I6I8Mvy6(GR>-kR=M)1UyQ{-0|AFPTjn^y zZ2PT#MDOzuw2E4 z#k=@z2wUh|N8+)}ypJUa@?-a}GDnzdhvx~D6jtn{sj?WIMU~@-yI*a&9TJ8f^eIT` zrZG;Ky}0x{8i#oGd*dBZhdXv`XJrJkl9&%Cv_%CRvYHR)XE3U^p7yg8FTx*`zD zsfZqoZfV;X+ASI<#zWy!K^^^~rSl$*4@4al_crTpJ(aUh5>g4EjT}|K>W_99FP&?p zCyPua68GOLwt?j;?C-!%K=R4M&vNLbex^p~-@cnK_4|3fzEe$wa_Rx{4eyf}SyYK^ zTNtjG9f;IC$}gNIU6Yx=0Ed(o9(PaCZi5!wPUf8;l67(vQZl>sT|UarQpsm9%-P3( z3qTnAXJgz(N%kvbt+UR3`NEq!P9aGhgiwZ(r}5-*X0Av8#}M`CZXZ^;9m@UpOEC3c zt`{)4cc#0YIcpl3^+3qXJCNa^Y3&(uInH7PJ6Z_r1pl@G$#B=6Fj0D z0`erg`&HO%bftfG&q>cR#UNvk(Jbc&&;p7|q1(^2^&>*#zLrgCawOZLw-E(*)*tbB zlH&H~_SpbY9vS#p4W`LDA5*l=3G$LtqKiSL+S()nO%_H{&;Vq01j-;nEWHq(j=ro~ zFFN)YN4Q4XalrcVEwx?jf+0VGEU>B&GBtVd^BN#GdfjG%xMf^xVwE zCE3?)>U~TA{EpEbOk3R{=oQUc5k*rpG%j;R*{0ChWI@}xcxU3>1w;P6xz$FZ#wW-_ z$SM$Q(5dG7+q*9~Rd5XYitfGs?MrB1q70h&b(|e;$gd)RU+YMyaKGiTu%n05B;hK( z!f`nMdnn|Al+A7A)0a?4<^>L+;WLEnQZourf=+h9?Tj*=Z)?4jd&F`?uiR9I)S{90 z8I|LQhbHU8b`DS4qHoF3?inRlgaHBK_HQlBWvxnXg)(gX7S`Dpxv4o>Yi3FTSW6rX zZ)OaWxhG=%z2D1F*C`QD!>3MI+dEY~s0BKuW$a{QdGd7L?jJRmI?gu^ zpJ@7lx4n%zKhaK6rY(4(Tee?ZET;FwTxD1F%)Z`7xPmFiLO&<-ekKY{f@74V$ z+(xf2uv{>O<^AEI9US@np~(C@zg$n50q!UXTxX$0XY53lb2nSIpzkI2G$c<8Q^d0IkX>^xuG zA^VRIQ&EpRK=qnbt?2;VS~_d{pSY@!I% zkTJdLDBqIW#Xfu>&p}O^D@|){w)d6Aj_(`ACA;$!k_*MWvytJv1XFH3uS!xbW^N6_x*9IINx^|Sp$wVi70X_r8A6v1**H_ z)w||$eey_G`a&L&*;@{uttSOn^JJIRX4Y%Ifj_Xo;x0J%J&s0=b$2wIp375(N+97tS<> z01;jrqZPidZ!3eL1!0=%#jnS1zDH(s9*7k zx?3fF6Tx~XP4kRwjnx9WaU8uO3+A2Uxx)KZ1Vz7|0=w)lrVV&8(FKVsais4Jr=fI6 z#k=IxYer!=pN! z7hN+(!9-;Hj8%}DXo+R2KSaFzF&d4vt=}oPlv6Bo!mFW)P=>xu0#_i z(1l*##eR?sn5{S}wA1xKHHE8cW2&KILOvw|{*+z~#kE^I@*Sy;5?;l-mrL2empP0_ zuTc*jE&O{dvbk&!YruBgz)awx3eDA=xLYmc-DmC7=Bxi0FyJxzz?L^E|1HjJdeCM> zfZi*B>_9PMp&W{4y?Gl3-(6c&R?8D*vvg~^1Q_C~xL+%!cNB2GbFn zi|nEGiMvVy)Z|OsBB0amOT*9o$3CPmU8QeIVu3+ldL4rl;8D?p$8)FxAx6UfnGFpL zU-1k%@uW3?#}s-#r7pI~e+~517}F} z3VS5C^n;dw8AB2)FjAB8M#Ft5(Jc;oS&%31um;U?*uiE$#82?1i+8W07hvVPHmT3% zHT=cmFTSX@ChM^nj3TNMRz42(EF@ZPn{`NvX~kd@0C}Ok;;8fO?w%8xWlmX1f{VIG zgt~QF)Whoa3&;_E-<==_l2?8Gd;GuC(CK{-p3<&yYo%T& zxKj{|v;ipNUdRJ%ph8^=6^!5=WqM#^wY4h;C&s0_VoT8a`ZT~nRR#^I?aMiXCKSws zpw8p?z&8>#iob;YsK#FXNk2L-<;Yip zG*>UeMcU!4>utRBUB^TFsomdVwY{^UCqn09Q*q47E3pc+4J==Uygtt>!d@l*3+0ChL(9T3T%?$#5&z-{X?HVzbKv6 zRXYRL(Sn8)Q{7pLNE8lv$GIG&@v~Y;O$v zo6f_+eQnam(&Ms{o9XUBD8|mQs6vX4SvPK$Ve$!2>%&V9i76g<|>7CO}J*Sf!m?Ux@^Muj6e)9>cF1lkdIO z>%tg|=~J!EAG9u9aNWvm3m+|7!!8RkM-PS7sJ4T<$nR`R9Zi=yKD-jya4w77em>#M zzpEvL=8$W*^F$#g$WV7BqhRR?wh`3&*ed%(5hy?)xzv$#4(z$6Czl+3u(-y^Iu^(7 z7;f6c(>zzWT32yLe)(CKdj>mzMv=XoYUy({$-!^%Q0$-Zw%g;=WGjCZ+||W(>@JM< z4cD32!RZXH{>iaqUW%tV-}G};I`J+iXWkVeU8gnG6&RATxo2zL6rt$~?P)0@CvfJn zL-ph!6P>M)BSrS4twt0-zS?$qJ^^FpQ}G?dvVj!9ySwKiMU87%Hobz8`iG>ynU=mo z6(RG4dw%$VygE8{qc|}FFHP#KWdQzBPw3*LNg)bw(H{hHOJY+fuT-ou zb*J3}WV?Vfug{dD6Z`#jfD={>Lj&35`u~6WDW!i=y@eDnjE@^_Pb`jbZ#e?_9mskQ z>W(z0yJM4KF_?19;}57YHyW9<4P^5gLXrlsoS@9{leQ1=V{wx9)6k_i&6J#s#SGS5 zGucc9F!eJb6b_#(hQ|hnU#PBS&R+V+K@*=%+7B9SM=@~pAw5EI2Fy|v$@wB&y&;^U zxLIY2tVB>PSJp7(ThUQ;7q_3A_N(vV(~?_)~DZRaijtngs+9bSkkovq5wtYL`+@B8v7 zsEC$-*(XhkHd_HY|M|XcK1&IlaSx8d$9jAq_gm+oNBUVgU0d{xnnNsFA&z!ikq2M2 zJQ-bX2^{5~kAik#&F?lgwmRxwmAAe)-88T~h^1Mu^-9%nNzmw(Ljk88ol&bFaa4Iys7Br{>YT z0Edw-V0wTRji(5`LXZc^zsJjntbG=F_!cC*_C7|*We6LMXpu(>PTLJmi5C{0Hi6zphm%V6Hz7 zuFm&jT(`lAKS!t$@T_zZDK5cLhz)PR^x+8Eh3@LFsXjn(g7*cE%IrGZ&Y@{vP2#-o zIF887#)JrdNpA=OMJRmu>$^=}xQ;*fSfzu_fS>a-PcMv5n=1zqZ2i?f4dR4p)&o^zTJ-x${`Xv9`(oF$_)}c9jFD_lTSz9hX z(8IFpzS&-iwFTWj`atMl*EnCTBtQB;Q==eYF?L;@^Sa zrK=Jg6*y&g7l9pJw}D2KxPEk<^?vA`zAaa)GV6&0v&%_A8*JJ_H_2I+&@?S1 z2(?#kgZ@=e!d(oavB8*K$UO&*-=gEt6vrvZ4SJ$tTVYx|m4EN$3r)u1?yA#ol2Qn2 zv{C~p3vn_R${=j=jXS4O8(P@xu;KDvd5>}!it|NnOJ2=Z{k1*5RDBy%88^C7d)dc=`i32zKdPiCauz7>Qj=Ou5eMt(E9##MjRIxS_F zk*K+6>s@G)xQI1zWnKXc$tW{h&kla@f8ke|cxzbVg#sD+ZV4C>YbA}YXMYiNpvU!5 zON5q;#kW^f9OqF`!rNvy+*w_twhJTAjEd8w}~GN`eQVVG4R z%qy4ecZzicA3JBbw7)TdFqnkRqbn$QgL=tuqAF5~i-^9B8e}gR{rF-iXjc&jxOzKo z%pj1vBAxtIkiW~D_5~j8bOZAFKc3QosZGJWwbV>(s@vCEth{!!WM&8rF65$dRV3Jj zQ6Eb86YzN6_=p0T*vDdbdo(y6Q*ReL(N$?DAvwOwII3rpL)e@6=lTl!q6UOtN&z1` zERgo?O6BgBy20H+lgt?)5QC!=V*jM3ZscYR& z@oM_(+6n9O6D{nLQ*%n(}ydYZsc^E z2J{-%_Y;dDBcN#eAY>vH1dIcAG|0U^q3X`0%U92BZnttBm8ky(98fw@cSm(im z=)c?CsXhg@0nX1^orVPTbTes5;`FU=!7-U4FFy@o0-Lu;4 zacSOT@+C*l)*8f(Ow88UUDJPc%!w+oBfxQr1YCRx@g>Grx^ct3ukQ{a|7llMn`rOP zerI`YQAau0{G@6=I`BE^y4z;4ZKQn=+wM2ELx0aWHt%<~@560! z`#n&zjy+Jpfnkq1$6)OO(buotgUcliygi_{W%DwrGOmvFRQTG#QV+40Oe62-1EqrN zuB1{UU1ny#3PQ5=6NNjJva^UR zU<ZT#p9C;5@jGvcHaBEkZoXA=sCMwC?Ev)3; z*U$=8_U{u#xC3wb1KGi5KR)C^>_gR>g(rQ*?v9 zjM*-{r?T)rmtHpQ9mRQ};F`4GFS;}l=!U!75!gA~C`@daeb>1qiTx?;>-c=gLCIxg zrhavicX2iyi(WO94a!Wu^n zG0c#iz3Or_ZVjLa|I{!0f@sf3T7k zHh|ODG)l*sN#8FMJLVUWloZ$6H23A?Wv$2a)B9F*bTJhAFr!D96k2}!U@RVb%`c{I zxt*2a5AL{pXnk8ckXMeln_jx5C`V~m*RV{pjLGX99XUiu*1e#L}ALXd%gSTZY1!6+)26>jVnfAhS0NW zd_9eJUew&s-e}^k)fj{slZraYzl=%{nH#{|eYikNZC4+mRkwp*%+#Gb?mBaJ3KmwF zZAAdf&I*u+2Hk9k^wy~;zC<>5Dq6PJ@3=hQ8`{_D7*=-AiWSSkHw?Fd4X}O9Zd$>I zw=(O^bR0Wy!ff;Bu}ArK?%T`trN!^)EJ2sG2tDd0FkpG;x1&q1(n^GA5YKNCin zKs(ZR1Rm>}&Blr3OlP*|^a0j0_QSLQCrlPjXLpv-bBf(&7o|+$y zIMOhMK19&x%{PvO{9>zLJ?E`5u$Ob@MXswox))e4Vba^%klx+oscO?gbTJE0612C- z9jdbu8og0GFH_X zUybT;enfPY5tkC?U?KJ@fj+OmL(i0+fi;605U2K@;f9SVCf5_A;Iy_ zT}hOPqxeK0y{k9Y2w@N8aWm3arU1W9l@ySQexCeC#JJp%Q#h7*y0($%JlUg+dmbcX zAx@$+*{Lu)-TO%>+CXCPTC-eTP5r!{OV1Jmo@h{ER^}SEQjK4ovC#h2ur7}rden?g zLKlB|9SmncoJA`3&56o|S6S$e1c{M@q-G!q3evh&gDk>{M!Tuv(#k!?#5>PAPmmSZ zV&@c5FZAW#?M&gSJmPR{zXPX1pVmEtLC}>KKAi84^u^%2j6?;%+-WjHH`o6$<0+ ze0$5FK|j|m`{`CyhgYzG<;4PP+@_?vC(+R-S`%{;0eYDk` zjQ4!wE5djN+|X&!!!H{cHlfX|j{qy%V=CJda+zj`QSA7 zOHYW!)0)nYVKXLrAJ2XJs8JNb*0CUB-=dCdqs{H2Me1iLf{bQGL7d4kYOs}i1Xl;9 zBY9#Fp;4g@JS)|Lz&l}&G4R^%Jc4qhQGFN1CuhT;a(s9m>ge+J7LSL@OMnK5rbPze z1{;&(`lXBg!Xdx^5jw|_2ZS~N3!;1A@ex_6i=Gl)ycycmcZAD<9p2u45F%O;fdgu%8CFr0~JYTi)R+MhIil*B&ax2(dLxJMg3V+D1~uVe zz2TTB5oZ3s`cOXpK1ET_)`V7E;QONC^6tE+TlptLP3Op*H4If{7oB%ew{>7!Fs}xo zr}l;9G5luJQ^6WF4J- zr7&ys)^M>JUMu3k>j$?Qu7nZXZ0zN_(6|V2GN;iA!}~M)cS^>Rg|S?mu-tQP13i|w zC^Y`Bj8mfnt@zVmUF@-eL$@Wm&ZFSn_vrR~`oDrbRY^u~bpPY5DrgK^@H879xvj-8NEH3w4b+@>2X07f z@YBYR$fPqBT(JQm{m|WNZ9J(AX4S0PezVcv98u1;WO~cu@!=1MR=SOAK`%C2*NPD= z>2eD30Mrm2^WlbbgBu2(Bs^{O+4QqEKyuJSdQ#Yl9-6q8GR8rP#~s6hW1cv}dw@k% zPjsOHRz%YKeR0p*k5US(Lp*=h_`Uoq*}Fd!n4OYl=}_XP*LYW)MN&hhM=W}R0;E~+ z?5PD&fN2*2$C+%Mv~*C7TPbl3|K9POvB^Vm`RKxy;^S`C%|EkWhyAw8BCCAfn}W!K zd?FilHR4589DiC8^|5S!i|;z&9Zi7?ZpeIIlTI395rTu~JMBc8wSfW;?IT+A$soFt zS-Os30(kV|j;hiDO17`|){-BA4vvwCaPYn3N~j`qxKoyW7%*a%8Fhn$G!HRTWj-nt z$-=5@Uny?Rd+4^DE70DbK^X?d`NT=Eky}gI*K4_BhOO6j9HW^4)Z{}QCXIFsr$jvG zU@o&Mi94#q8&SzmGr@`ddMuAr16XpI4LuEHS$tUV?u^Ii^1dpU^0i9Q+~;IP35hhr zDVwri|3)dLs8YS>wqF-HRAX|}ysq%Bv?W{uA0s zPz_LJGJ7(0%1M=s4o`QtgL@IG?prEwF`WH{0H+5FR{1%QJSw;jEW~mz6L702J^mBi zt0r1yXJNLx@w(B$_g6M8-q%z}VCb>;%^$gyETwQR=SfMEz&uA*J-5=>*tzsnORtz- zSsunWrt&z;M z)Nt<7P)@9SiJUJwH@|@^zMz}TzC)>YhxlKoP;%?Q9>P+cnA3&7kZ`Wv1Tv9d2qHyv z*YA|VVAx8)#XX2|b$oTI9{Hx-WJOFDo|26u5{5-EDy?sa_ zTKS zMvwP37&-|oo7=F0EE0I+G%deuu5nCkMrrh&I&iFYkdUD^;vnh8tXGDkqps0*()6&h z+)&R76{RAOcu&1$%T7+eSNE1`6O(@Chro|-^}1y3L0T%is9t`Tp?oiU`{>jA-XnIj z`TV@w0!{|cM_|DKJi0Rr=eqwEhW;ppt>8=&#wXE5ghHzOvR;3i)}PJcCSd_g7eDL} zW*I1#xMV)gb5s*HkZMe+1h*Us%3Bok$1pA!DBCAscB7G=;ut+|8u}K`$00fln+E|? zKP^qwv_;7P30E<9|C{y7z)Ag#eYflb z)d(E+;nBG?{ShtC45d3$fHLsANGyehk1o#tN_yal5hx~}-YQ^4MD?8=b#}US>`~C= z@`rcY^bZDnpVWMhFXDgS;v9Q>GABHtVMn9dWH`0?=={v`ym(I(4Wp*BuaM{dHb>Z_%v0ai zr~Bty?t3m^@4E8Utq1IknE3R1dHi^x?fD!}^zboTj+y4RlfMR|4REbhjV}x~b>a1a z@!l%^?NUy*8=)I1zcpl-_Uwp!>Gk{8vstrXX9ecrMM5+!)e1om4EkXia$-8h%K=*WysgVf-@ zU>AV9g8%!Z@G<`M>*h)aa?uJH3kNaj>NN}{+K^xF%z<|zX8C}AAH|ZJ=22+fc|z_B zC$U%(dlfUnCP`Q;LXe%W3@N}`X(0vH*2`AVu1Gvv{Ak zF|EJ&FNLL!dv8E^V1dEiMRZq3Z@N$B7nuBz1%kSuKvCxKN%#~mrO1P8>+q@FRWA~u zt|j=*{_J>bW|2o0@B1#&aR=J+7JtMG8YV(sMH=y5-zx@`JoJ%=N$Ct^V$T#wFTs33g70c)RZDMjnRwh zRH2J|(P?|0gSK9HWSW7^R$-d&(0=!Z7awX0j6O%`IWM;&FA5J-(rJeN)>3L#MCOur zf28T-|%Qbf5V0#rq!NJ2D~g+B9HN4jLSHSZe*9#<|a=%C%zA8UDcz$ z-0n1`i#FZmU7GA$y96jx{iuilI&##`5Wsn_4bc4 z);ABs7v<;ZQXlibia}SY`bDQ?+)@KPJdiy1RSQu?C3=av#9$CKis zDi1I~_N;w<1NjmTqJjT*(!kI7>n=F;{K;}17bJoY&-#o*&B5XqzQro0#n7t-UWdsj z$iyQzd4c4d-{sW1Pp|&g!Mh5OhxyNuMT&S|Wx4wn{kEO}f!A-o8<^+U(byqB-a(P| zIduXHXVEN-)IEB12Zi8N`(GFNz%_XPuTO9s3Aji=^A*E@E4lza2V&feeF(K&&8n*5 zEmu8*d!p^9j}eRmt@WSbgAxn=L4p4XR_qvE`MLjQ8!Q#x#ASk`*q!tUI7>Iiji%q? zO)Hk|T`LZ^Nz#ImBGZJcz|!bwdiiR@%l~AgLMNNslEl*K{PD|$eiYARHom=A4mJkc zI*a>~`7Zo6CkXU)DGAIId3osw7=wU*GSf`o#f2X)^hFSi=;>)*-6 z+X@7^IoGayFaodQ#=8=obZ#?Gv-DL7Bd#Y~$E$1_>{kV@+6w{skdZ^; zIrIB`f4}FiUAy+#wR3jPx$pb^df%UW#ay;(L4;k&CpeGeJKV3s=~v#c9@D2$LAitU z$uS7zsbUhcnSbSv`#qGD1Ks?@^F&cD)&2*y(-QBAt#^B073U&qCNx>9n}sQY6gB|4y!^Evxm-*7!U<&bp}jS%K_)_UC=zTN6yW8Q$ITa)qreI$B_}c+4KRtt(o;4Cl&lXo4>3N zh0dmTZkpgr0cSN96hsS0hn)3)ov~f=M1u={|t6b#>KUV6BEr31MTm)7N@GXP(iFi=*1?j+Wz;sf{qA{KztsAN`=lDn5B_ zWx+5>*Lf57<*n`)UUSLE?cAiB?g(h1k}MkfFfjs+r7_TOpdJpQXWjdP&<;>mPlih8 z^W9m}>kRCh>sh7QiDLE^uxbC{ZfA-v3{w7)`I(*Rp(XW4W~-{}L~fJq<+Vle&Wfa! z;_lnM0f^MAgVPi6QUru}$ty&Ko5h_M#F--G4_Q|8oc;3lHs~SzCC7AV!xj8Anv;6K z@P<)y@Zxun*^NaKf&OV|)JK9CF5zi!)08J(x}C_5xJb3*^kjDH#=`saLHRWIqsT>_ za+b4YPkw@q_ZKH9-WFMZ>+e$2??oBlSuJGuv#8ve@<{lG%nZs>;_$e`d}zBG1DjWL z%(r&a>hWnPP*SXXH0h63mAQBVd-&q@3cQUGRY9iNNDwmimQh03 z9f4ltBhh&)X63&AeYCKLihX_>k1MgpV5s1&JsENv;3WC|EeEYiJCTtZ_os@M2f+qu}FSh#v@h=QZaT`_hwj@>;^T(nB3Bxj`6rwa;t$rzv+_f&*6#amKXF_Is+CKJr zc151mQH9b^l%xu5^On>nYYgpF8>^KE*tqBQwoRoOU!%0%a#Xk*LK`2K8KnHM@1>Xy z6?2K{qy^L{N1Pm#>l>s=sPJaRu1}A|*>wm)+8UO1FL&oBo{_yiR%L51%_*7e4eV6q z*GgjnT{}uIb*Y**a!#cGh;>M{@;9M2wvC!lJGQ0csR5G+q)gVSDej?onFj-e$f;&J zk1hKoc|ngY!OrvL?km}MSEYdx*@qfWhf#5S63w?uTn!!!(7W5;;3*6wEvY zyRX$xK%zlnDfs|idu6wGx7YRMMXacYrh&kh?89jbuEYoDKM2;K-rHEdEK4oPJ|1BU z>dLQ5A$$&eM~AKxk{j*VZ9kWZCY9AP@8~>@Yr0;{B_0G;A8Zl37}smc3NVGqc+}o^ zR~~vh#9oxL?dN~g2q*bpH3Fy8b*bf@-U28Bk+5jmDQxMi?hX9{Nm(sO;!kAR97 zJxcXh?*tAR`V4F5B$Mng5Gkm9d+}5Ej5Vep*BQR&{o^bAm@ju&`{n85)=U92JpP6g zRT5U40g=zV?F8$%_|be`=h*DMapU(_W7MWg4&e&#x#-<2H@m|Ne6H~9IFG!sFxl&a zoD;U-TS~f!;gK}G4PPWV9o$S@OXCTfo9PDh+MF!HQE5o$LV;%cm{p)l)T(8BY3U?* z|9pj`eXJnscQ4&)1)cipQ~a_Llt{vY)-F6lTa5QDrMKzRZ#ga^Va_sl_ce;kk0I|I zb$zKBBO$~f6Faqnu~fw(BAwp#Lh>q9BP4zycw*mWGWI*M1sQZ>&ia)_R)2JC+@H@W zdaoGZX766P#avqP$qvQI58ucCB%d@o>Jv_L^Uaw26j7%H`w54Hm!hNs+K??w_xD;j zD8~n!s9RYyA9)W(rsG=B_Q)G^=5yBj#E|q1ur+s*Wz`jv;T8cTbg8vi!`-r4v5AzL zbZ#ygs>Xl~=z~cZw>p>7^3sJQUk=cBWS>i5Ic4ojWm2qZcWZ^a`+eJ+P(06|Qz0Sp%_SH?^%%Lr6HRKNR884O7~ zfR>Tl1S~y=nhdoE^Chvkw_&&ce%@Ovr=bbxv>_>OpfFnBl5*0=39j%M_OvHm&G93# zqI%$Q%EYbwi-}jnkup;()2*v;oVRmEl^ z{n=A&Yj!#c!E=v6lB%A#Gif6y6Ui`Mb{oPq!hP9x%5>TSIC6g0>RwcFi!EreYD_=y zewgq36qH_L#)suoD7w8IJ4usM&hMXfRzp?Oqo%@^Lhsf8VOi8$DIFt81$n}RMO{S( z3Z8uN-OX3?|2jgsq#D;^A{*GU3qfCDpbU>Ab!V5N)-r+ERmO zz_!j#<%kMfQs5?|>#NpRqlo1nPgG0m<7lsbsV${rrDKA2(@mJEv z)e#^&j}4!PEeWAQs@Q!WSpZee=5_*Itw4iFu?jG|rmfC_=-nS);mS0HNI+Y}r&iXw zZYdUKD#cM%Qf5Ouy=!~99V_~iDHxmm#|X=2zR||b$7=L*)lE8(leFpgr@l^4rb}C? zesN9a3ZNW&yO+y=2cJ|)^z9p9rCSmLydr^J4~zQt_;RPsbs77yu%#7oz4DEorGuRU zDzbck_4~Vj8>v6KznP`Wh?8%>+Mvp1^HB4$RNG0wRFQz|@>iCUBrc z(I-GZfI8#TA4_235I*KQ)An&F(BZd-+a$|F+yQh70JE?Fn#qGxt1S4yu7*3>e*g>V zSyOU)6nQ1A8`KY%cRWaJCxcT$U-zm z0VWXwB|@uSYzMv8hvNDypSA;k+6Rx{@-gwu#IIl8lnA>0Du3rd#detqoL)jqZ(4>-oq3KjuW>`7pvB5Kx zTU3iaS4>CBiwRY-=~VnN*gl+5GZl+xEEp`T(196!l9$hMKiZb|BXGk5hjyGAiLYGt zTrC?PkxGQ)0Id<@Y=-Z`vWUVel3W*dm~N)bdMo+>{Ly&kciQkHh_@zoK&|18hOUMxr&xVT6WxAyNH= z)IiF|;8u?!Hu2h~m$yXo=F2((KB+~7RK}$*3qC)1O=O04Zilm6G9U_T7zByPWRfz= zZvHJP`z209eDU3s!;B7M_`H2f2-&xgxzqMD?~f2JsjNuJ&3xLJ-1GR3lV4gV2VOxP z^L3YjE44iOpR4s!GObe#whETXQ}-^=w97h1Xsi0J_TfN5{*XspD%hF1G>X^e3EzMQ z7+PxV(Jv#JJf%ov4;Hu2MC2RQ*LXMG7=VQ)yrlMB!G~3J15}t|{+~KbmE><7Ms-by zApRDDb=RJ3uSOivrN;trVN!q#d*H(!(eM|n>-1__F@~8ZL~s~nSyN1c(vd%GjnTf0 zVxGm4pEq4TiDMnFzU`YaEeFLo4&Dv<)ro)T#ftpp94UmQ3z0o9BtN{%GB z`!|K@Wp2Pl{PHS#0sYYu_RqcUUl(Yo^dhctl|@iLrW=*9NMg%lXVEy(qt4cr6J)xXOS#XIfG+?}gTq5^ga0 z`z4k{T`bZx*0Wtw@NRcKuPOQLgfHL}fQc?9F9lzbB*A;wt1vjgTbqJ2TVmqG9(rip zF6*npc0ws&^Wvr_;|7FACTlw4Kot|CU4d!#oZtR&q^~Tl(pIc&r_RtghMsa=*}oL6 zojIguzGEZqY;0>vFXoAs(3WgOeoEOaWi7b!v4*gMw;Ye`qF<%>j&D?I4{aBhmW%hNO})fZ-!U3??o3O8syI za--3U=J;90B?g=w@dAfgL34~}Ir4k3l)99G)X*}(NGFiFM{?_f9~Bqe&DDoX@|WdR z?9t=JJZUD=%q@0*zn_o6)rz$D6bcR@MHDWz>0N})Toqw6mbH`NZ!;s_?^JTT0)<2R z`VH1I-tQJ1;Ox%ULlm0f^(Z8*T$2=tpj(21VOTWM0W^>;0hM=Y=KM=fN5}aUaF1xTUse(dhqO%$Uzj=j;I;z%l|0^aK=Mb0+S*BeO(4$dY$Bur{_V zzM0L$T|l2{?q^MtMeg5pm1GE{E7R^C#;$RTSy9Pez(<_KRJx&%aC-j@+9c&3 z%z4x!388Z|e>Bt-CpvJ4Qif806vY(f;=%9;WO?B}OR1z$c~3HIKylWnU5MgHru;&* zW{l?>U9o0FJs2j8!Yf`E0`HRY-l}Sin!5d#&8qCmg|VcbzaC)^V1Ys9`Xp8=y|D|l zUe_9;?WpC-u80Y47LQ4hJ{cXO?Jz+)4@m>s0PxDn?ggXv*rhg_!3$F*BXz%9#9Q!0 z_M82V_E9pShf(~+i^$xZ|H&T~V&EBP<9q<^B**ZBO{T$}n6`gf5|-me2>(33niwRm n%VR?q^ZvbdhMn)MuIRv;gm^9MS;@fISUeR4HTh~;^N{}lQKqQs diff --git a/docs/img/nattack.png b/docs/img/nattack.png new file mode 100644 index 0000000000000000000000000000000000000000..011b0c551074b4a43bba5566d749e83785335026 GIT binary patch literal 8523 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 YXmpq!_@V9^&5?{~-#1W)s@g~W7ZC|$%>V!Z literal 0 HcmV?d00001 diff --git a/docs/img/ps.png b/docs/img/ps.png index 9e0837e31326ab5b14820839f3c2ff51f6ac9487..9e28c8642f6cda8de6f75edeeff014e51f9654bc 100644 GIT binary patch literal 28629 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 z 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 eCY0@Aj=jl@_vVp@kKn(|PDxHxw(!X--~R Autotile的ID和文件名完全相同!且其ID/文件名不能含有中文、空格或特殊字符。 #### 新添加道具 如果你需要新增一个未被定义的道具: -1. 指定一个唯一的英文ID,不能和items中现有的重复。 -2. 进入icons.js,在items分类下进行添加(对应图标在图片上的位置,即index) +1. 指定一个唯一的英文ID,不能和现有的重复。 +2. 进入icons.js,在items分类下进行添加索引(对应图标在图片上的位置,即index) 3. 指定一个数字,在maps.js的getBlock下类似进行添加。 4. 在items.js中仿照其他道具,来添加道具的信息。 -``` js -if (id == 63) tmp.event = {'cls': 'items', 'id': 'moneyPocket'} // 金钱袋 -if (id == 64) tmp.event = {'cls': 'items', 'id': 'shoes'} // 绿鞋 -if (id == 65) tmp.event = {'cls': 'items', 'id': 'hammer'} // 圣锤 -// 可以在这里添加自己的数字-ID对应关系,但不能和任何已有的数字重复 -``` - 有关如何自行实现一个道具的效果,参见[自定义道具效果](#自定义道具效果)。 #### 新添加怪物 如果我们需要新添加怪物,请在enemys.png中新增一行,然后复制粘贴上四帧怪物图的**1和3帧**。 +你可以通过便捷PS工具的“更改色相”来将红头怪变成橙头怪等。 + 然后执行如下操作: 1. 指定一个唯一的英文ID,不能和enemys中现有的重复。 -2. 进入icons.js,在enemys分类下进行添加(对应图标在图片上的位置,即index) +2. 进入icons.js,在enemys分类下进行添加索引(对应图标在图片上的位置,即index) 3. 在maps.js的getBlock下继续进行添加。请注意其ID为200开始的顺序,即如果新增一行为261,依次类推 4. 在enemys.js中仿照其他怪物,来添加怪物的信息。 -``` js -if (id == 258) tmp.event = {'cls': 'enemys', 'id': 'octopus'}; -if (id == 259) tmp.event = {'cls': 'enemys', 'id': 'fairy'}; -if (id == 260) tmp.event = {'cls': 'enemys', 'id': 'greenKnight'}; -// 在此依次添加,数字要求是递增的 -``` - 有关如何自行实现一个怪物的特殊属性或伤害计算公式,参见[怪物的特殊属性](#怪物的特殊属性)。 #### 新添加NPC -类似同上,给NPC指定ID,在icons.js中指定ID-index关系,在maps.js中指定ID-数字的关系,即可。 +1. 指定一个唯一的英文ID,不能和现有的重复。 +2. 进入icons.js,在npcs分类下进行添加索引(对应图标在图片上的位置,即index) +3. 指定一个数字,在maps.js的getBlock下类似进行添加。 ### 地图生成器使用自定义素材 @@ -176,18 +189,24 @@ enemys.prototype.getExtraDamage = function (monster) { } // ... 下略 ``` -3. 免疫领域、夹击效果:在`core.js`中,找到updateCheckBlock函数,并编辑成如果有神圣盾标记,则直接返回。 +3. 免疫领域、夹击、阻击效果:在`core.js`中,找到checkBlock函数,并编辑成如果有神圣盾标记,则将伤害变成0。 ``` js -// 更新领域、显伤点 -core.prototype.updateCheckBlock = function() { - if (!core.isset(core.status.thisMap)) return; - if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap(); - core.status.checkBlock = []; - if (core.hasItem('shield5')) return; // 如拥有神圣盾则直接返回 - for (var x=0;x<13;x++) { - for (var y=0;y<13;y++) { - // 计算(x,y)点伤害 - var damage = 0; +// 检查领域、夹击、阻击事件 +core.prototype.checkBlock = function () { + var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); + var damage = core.status.checkBlock.damage[13*x+y]; + if (damage>0) { + if (core.hasFlag("shield5")) damage = 0; // 如果存在神圣盾,则将伤害变成0 + core.status.hero.hp -= damage; + + // 检查阻击事件 + var snipe = []; + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + } // ... 下略 ``` 4. 如果有更高的需求,例如想让吸血效果变成一半(如异空间),则还是在上面这些地方进行对应的修改即可。 @@ -196,42 +215,15 @@ core.prototype.updateCheckBlock = function() { 如果你对现有的怪物不满意,想自行添加怪物属性(例如让怪物拥有双属性乃至更多属性),也是可以的。具体参见`enemys.js`文件。 -你需自己指定一个special数字,修改getSpecialText函数。 +你需自己指定一个special数字,修改getSpecialText函数(属性名)和getSpecialHint函数(属性提示文字)。 如果要修改伤害计算公式,请修改下面的calDamage函数。请注意,如果无法战斗,该函数必须返回`999999999`。 -因此无敌属性可以这样设置: - -先给无敌属性指定一个数字,例如18,在getSpecialText中定义 - -``` js -// ... 上略 - if (this.hasSpecial(special, 15)) text.push("领域"); - if (this.hasSpecial(special, 16)) text.push("夹击"); - if (this.hasSpecial(special, 17)) text.push("仇恨"); - if (this.hasSpecial(special, 18)) text.push("无敌"); // 添加无敌的显示 - return text.join(" "); -} - -``` - -然后修改calDamage,如果无敌属性且勇士没有拥有十字架,则立刻返回无穷大。 - -``` js -enemys.prototype.calDamage = function (hero_atk, hero_def, hero_mdef, mon_hp, mon_atk, mon_def, mon_special) { - if (this.hasSpecial(mon_special, 18) && !core.hasItem("cross")) // 如果是无敌属性,且勇士未持有十字架 - return 999999999; // 返回无限大 - - // 魔攻 - if (this.hasSpecial(mon_special, 2)) hero_def = 0; -// ... 下略 -``` - 对于吸血怪的额外伤害计算在getExtraDamage中。 对于毒衰弱怪物的战斗后结算在`events.js`中的afterBattle函数中。 -对于领域、夹击怪物的检查在`events.js`中的checkBlock函数中。 +对于领域、夹击、阻击怪物的检查在`events.js`中的checkBlock函数中。 `getCritical`, `getCriticalDamage`和`getDefDamage`三个函数依次计算的是该怪物的临界值、临界减伤和1防减伤。也可以适当进行修改。 diff --git a/docs/start.md b/docs/start.md index 127fd819..10300b46 100644 --- a/docs/start.md +++ b/docs/start.md @@ -36,7 +36,23 @@ 然后将楼层名改为MT1,floorId改名为MT1;title可以改成任意内容,将在切换楼层时进行显示(比如可以改成“1层小塔”)。 -具体样板文件的每个要素都有详细的注释。我们最终的任务其实是,将每个楼层的剧本(地图&事件)给写完即可。 +具体样板文件的每个要素如下: +- **`floorId`** 楼层唯一标识符;必须和文件名,以及 `main.floors.xxx` 完全一致 +- **`title`** 楼层中文名,将在切换楼层时进行显示 +- **`canFlyTo`** 当前楼层可否被楼传器飞到。如果该层不能飞到,则也在该层也不允许使用楼传器。 +- **`canUseQuickShop`** 当前楼层可否使用快捷商店。 +- **`defaultGround`** 该层的背景(地面)素材。需要是在`icon.js`里`terrains`中定义的一个ID,如`ground`, `grass2`等等。 +- **`color`** 该层的画面色调。本项可选,如果不写则色调为默认值(无色调),否则是一个RGBA数组,比如`[255,0,0,0.3]`等。 +- **`bgm`** 到达该层后默认播放的BGM。本项可忽略。 +- **`map`** 本层地图,需要是13x13数组,建议使用地图生成器或者可视化地图编辑器制作。 +- **`firstArrive`** 第一次到该楼层触发的事件 +- **`events`** 该楼的所有可能事件列表 +- **`changeFloor`** 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖 +- **`afterBattle`** 战斗后可能触发的事件列表 +- **`afterGetItem`** 获得道具后可能触发的事件列表 +- **`afterOpenDoor`** 开完门后可能触发的事件列表 + +我们最终的任务其实是,将每个楼层的剧本(地图&事件)给写完即可。 换句话说,只需要简单的复制操作,我们就可以新建一个剧本了。 diff --git a/libs/core.js b/libs/core.js index e572fe5b..cef47e25 100644 --- a/libs/core.js +++ b/libs/core.js @@ -104,6 +104,7 @@ function core() { /////////// 系统事件相关 /////////// +////// 初始化 ////// core.prototype.init = function (dom, statusBar, canvas, images, bgms, sounds, floorIds, floors, coreData) { core.dom = dom; core.statusBar = statusBar; @@ -192,6 +193,7 @@ core.prototype.init = function (dom, statusBar, canvas, images, bgms, sounds, fl }); } +////// 显示游戏开始界面 ////// core.prototype.showStartAnimate = function (callback) { core.dom.startPanel.style.opacity=1; core.dom.startPanel.style.display="block"; @@ -218,6 +220,7 @@ core.prototype.showStartAnimate = function (callback) { }, 20); } +////// 隐藏游戏开始界面 ////// core.prototype.hideStartAnimate = function (callback) { var opacityVal = 1; var startAnimate = window.setInterval(function () { @@ -231,14 +234,17 @@ core.prototype.hideStartAnimate = function (callback) { }, 20); } +////// 设置加载进度条进度 ////// core.prototype.setStartProgressVal = function (val) { core.dom.startTopProgress.style.width = val + '%'; } +////// 设置加载进度条提示文字 ////// core.prototype.setStartLoadTipText = function (text) { core.dom.startTopLoadTips.innerHTML = text; } +////// 加载图片和音频 ////// core.prototype.loader = function (callback) { var loadedImageNum = 0, allImageNum = 0, allSoundNum = 0; allImageNum = core.images.length; @@ -271,6 +277,7 @@ core.prototype.loader = function (callback) { } } +////// 加载图片 ////// core.prototype.loadImage = function (imgName, callback) { try { core.setStartLoadTipText('加载图片 ' + imgName + ' 中...'); @@ -289,6 +296,7 @@ core.prototype.loadImage = function (imgName, callback) { } } +////// 加载音频 ////// core.prototype.loadMusic = function (callback) { core.bgms.forEach(function (t) { @@ -388,12 +396,14 @@ core.prototype.loadMusic = function (callback) { callback(); } +////// 游戏是否已经开始 ////// core.prototype.isPlaying = function() { if (core.isset(core.status.played) && core.status.played) return true; return false; } +////// 清除游戏状态和数据 ////// core.prototype.clearStatus = function() { // 停止各个Timeout和Interval for (var i in core.interval) { @@ -404,6 +414,7 @@ core.prototype.clearStatus = function() { core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); } +////// 重置游戏状态和初始数据 ////// core.prototype.resetStatus = function(hero, hard, floorId, maps) { // 停止各个Timeout和Interval @@ -428,6 +439,7 @@ core.prototype.resetStatus = function(hero, hard, floorId, maps) { core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); } +////// 开始游戏 ////// core.prototype.startGame = function (hard, callback) { console.log('开始游戏'); @@ -439,7 +451,7 @@ core.prototype.startGame = function (hard, callback) { }); } - +////// 重新开始游戏;此函数将回到标题页面 ////// core.prototype.restart = function() { core.showStartAnimate(); } @@ -451,6 +463,7 @@ core.prototype.restart = function() { /////////// 键盘、鼠标事件相关 /////////// +////// 按下某个键时 ////// core.prototype.onkeyDown = function(e) { if (!core.isset(core.status.holdingKeys))core.status.holdingKeys=[]; var isArrow={37:true,38:true,39:true,40:true}[e.keyCode] @@ -467,6 +480,7 @@ core.prototype.onkeyDown = function(e) { } } +////// 放开某个键时 ////// core.prototype.onkeyUp = function(e) { var isArrow={37:true,38:true,39:true,40:true}[e.keyCode] if(isArrow && !core.status.lockControl){ @@ -484,6 +498,7 @@ core.prototype.onkeyUp = function(e) { } } +////// 按住某个键时 ////// core.prototype.pressKey = function (keyCode) { if (keyCode === core.status.holdingKeys.slice(-1)[0]) { core.keyDown(keyCode); @@ -491,6 +506,7 @@ core.prototype.pressKey = function (keyCode) { } } +////// 根据按下键的code来执行一系列操作 ////// core.prototype.keyDown = function(keyCode) { if(core.status.automaticRouting || core.status.automaticRouted) { core.stopAutomaticRoute(); @@ -589,6 +605,7 @@ core.prototype.keyDown = function(keyCode) { } } +////// 根据放开键的code来执行一系列操作 ////// core.prototype.keyUp = function(keyCode) { if (core.status.lockControl) { @@ -742,6 +759,7 @@ core.prototype.keyUp = function(keyCode) { core.stopHero(); } +////// 点击(触摸)事件按下时 ////// core.prototype.ondown = function (x ,y) { if (!core.status.played || core.status.lockControl) { core.onclick(x, y, []); @@ -758,6 +776,7 @@ core.prototype.ondown = function (x ,y) { core.fillPosWithPoint(pos); } +////// 当在触摸屏上滑动时 ////// core.prototype.onmove = function (x ,y) { if (core.status.holdingPath==0){return;} core.status.mouseOutCheck =1; @@ -780,6 +799,7 @@ core.prototype.onmove = function (x ,y) { } } +////// 当点击(触摸)事件放开时 ////// core.prototype.onup = function () { core.status.holdingPath=0; if(core.status.stepPostfix.length>0){ @@ -800,6 +820,7 @@ core.prototype.onup = function () { } } +////// 获得点击事件相对左上角的坐标(0到12之间) ////// core.prototype.getClickLoc = function (x, y) { var statusBar = {'x': 0, 'y': 0}; @@ -824,6 +845,7 @@ core.prototype.getClickLoc = function (x, y) { return loc; } +////// 具体点击屏幕上(x,y)点时,执行的操作 ////// core.prototype.onclick = function (x, y, stepPostfix) { // console.log("Click: (" + x + "," + y + ")"); @@ -939,6 +961,7 @@ core.prototype.onclick = function (x, y, stepPostfix) { } +////// 滑动鼠标滚轮时的操作 ////// core.prototype.onmousewheel = function (direct) { // 向下滚动是 -1 ,向上是 1 @@ -951,8 +974,8 @@ core.prototype.onmousewheel = function (direct) { // 怪物手册 if (core.status.lockControl && core.status.event.id == 'book') { - if (direct==1) core.ui.drawEnemyBook(core.status.event.data - 1); - if (direct==-1) core.ui.drawEnemyBook(core.status.event.data + 1); + if (direct==1) core.ui.drawBook(core.status.event.data - 1); + if (direct==-1) core.ui.drawBook(core.status.event.data + 1); return; } @@ -971,11 +994,13 @@ core.prototype.onmousewheel = function (direct) { /////////// 寻路代码相关 /////////// +////// 清除自动寻路路线 ////// core.prototype.clearAutomaticRouteNode = function (x, y) { if (core.status.event.id==null) core.canvas.ui.clearRect(x * 32 + 5, y * 32 + 5, 27, 27); } +////// 停止自动寻路操作 ////// core.prototype.stopAutomaticRoute = function () { if (!core.status.played) { return; @@ -989,6 +1014,7 @@ core.prototype.stopAutomaticRoute = function () { core.canvas.ui.clearRect(0, 0, 416, 416); } +////// 继续剩下的自动寻路操作 ////// core.prototype.continueAutomaticRoute = function () { // 此函数只应由events.afterOpenDoor和events.afterBattle调用 var moveStep = core.status.moveStepBeforeStop; @@ -999,11 +1025,13 @@ core.prototype.continueAutomaticRoute = function () { core.setAutoHeroMove(moveStep); } +////// 清空剩下的自动寻路列表 ////// core.prototype.clearContinueAutomaticRoute = function () { core.canvas.ui.clearRect(0, 0, 416, 416); core.status.moveStepBeforeStop=[]; } +////// 设置自动寻路路线 ////// core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { if (!core.status.played || core.status.lockControl) { return; @@ -1118,7 +1146,8 @@ core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { core.status.automaticRoutingTemp = {'destX': 0, 'destY': 0, 'moveStep': []}; } -// BFS + +////// 自动寻路算法,找寻最优路径 ////// core.prototype.automaticRoute = function (destX, destY) { var startX = core.getHeroLoc('x'); var startY = core.getHeroLoc('y'); @@ -1217,10 +1246,12 @@ core.prototype.automaticRoute = function (destX, destY) { return ans; } +////// 显示离散的寻路点 ////// core.prototype.fillPosWithPoint = function (pos) { core.fillRect('ui', pos.x*32+12,pos.y*32+12,8,8, '#bfbfbf'); } +////// 清除已经寻路过的部分 ////// core.prototype.clearStepPostfix = function () { if(core.status.mouseOutCheck >0){ core.status.mouseOutCheck--; @@ -1241,6 +1272,7 @@ core.prototype.clearStepPostfix = function () { /////////// 自动行走 & 行走控制 /////////// +////// 停止勇士的自动行走 ////// core.prototype.stopAutoHeroMove = function () { core.status.autoHeroMove = false; core.status.automaticRouting = false; @@ -1253,6 +1285,7 @@ core.prototype.stopAutoHeroMove = function () { clearInterval(core.interval.heroAutoMoveScan); } +////// 设置勇士的自动行走路线 ////// core.prototype.setAutoHeroMove = function (steps, start) { if (steps.length == 0) { return; @@ -1272,12 +1305,14 @@ core.prototype.setAutoHeroMove = function (steps, start) { }, 80); } +////// 让勇士开始自动行走 ////// core.prototype.autoHeroMove = function (direction, step) { core.status.autoHeroMove = true; core.status.destStep = step; core.moveHero(direction); } +////// 设置行走的效果动画 ////// core.prototype.setHeroMoveInterval = function (direction, x, y, callback) { if (core.status.heroMoving) { return; @@ -1309,6 +1344,7 @@ core.prototype.setHeroMoveInterval = function (direction, x, y, callback) { }, 12.5); } +////// 设置勇士行走过程中对事件的触发检测 ////// core.prototype.setHeroMoveTriggerInterval = function () { var direction, x, y; var scan = { @@ -1322,7 +1358,7 @@ core.prototype.setHeroMoveTriggerInterval = function () { direction = core.getHeroLoc('direction'); x = core.getHeroLoc('x'); y = core.getHeroLoc('y'); - var noPass = core.noPass(x + scan[direction].x, y + scan[direction].y), canMove = core.canMove(); + var noPass = core.noPass(x + scan[direction].x, y + scan[direction].y), canMove = core.canMoveHero(); if (noPass || !canMove) { if (canMove) // 非箭头:触发 core.trigger(x + scan[direction].x, y + scan[direction].y); @@ -1365,6 +1401,7 @@ core.prototype.setHeroMoveTriggerInterval = function () { }, 50); } +////// 设置勇士的方向(转向) ////// core.prototype.turnHero = function(direction) { if (core.isset(direction)) { core.status.hero.loc.direction = direction; @@ -1378,7 +1415,8 @@ core.prototype.turnHero = function(direction) { core.canvas.ui.clearRect(0, 0, 416, 416); } -core.prototype.canMove = function() { +////// 勇士能否前往某方向 ////// +core.prototype.canMoveHero = function() { var direction = core.getHeroLoc('direction'); var nowBlock = core.getBlock(core.getHeroLoc('x'),core.getHeroLoc('y')); if (nowBlock!=null){ @@ -1416,11 +1454,13 @@ core.prototype.canMove = function() { return true; } +////// 让勇士开始移动 ////// core.prototype.moveHero = function (direction) { core.setHeroLoc('direction', direction); core.status.heroStop = false; } +/////// 使用事件让勇士移动。这个函数将不会触发任何事件 ////// core.prototype.eventMoveHero = function(steps, time, callback) { time = time || 100; @@ -1481,6 +1521,7 @@ core.prototype.eventMoveHero = function(steps, time, callback) { }, time/8); } +////// 每移动一格后执行的事件 ////// core.prototype.moveOneStep = function() { // 中毒状态 if (core.hasFlag('poison')) { @@ -1495,6 +1536,7 @@ core.prototype.moveOneStep = function() { } } +////// 停止勇士的一切行动,等待勇士行动结束后,再执行callback ////// core.prototype.waitHeroToStop = function(callback) { core.stopAutomaticRoute(); core.clearContinueAutomaticRoute(); @@ -1507,10 +1549,12 @@ core.prototype.waitHeroToStop = function(callback) { } } +////// 停止勇士的移动状态 ////// core.prototype.stopHero = function () { core.status.heroStop = true; } +////// 绘制勇士 ////// core.prototype.drawHero = function (direction, x, y, status, offsetX, offsetY) { offsetX = offsetX || 0; offsetY = offsetY || 0; @@ -1523,13 +1567,54 @@ core.prototype.drawHero = function (direction, x, y, status, offsetX, offsetY) { core.canvas.hero.drawImage(core.material.images.hero, heroIcon[status] * 32, heroIcon.loc * height, 32, height, x + offsetX, y + offsetY + 32-height, 32, height); } +////// 设置勇士的位置 ////// +core.prototype.setHeroLoc = function (itemName, itemVal) { + if (itemVal == '++') { + core.status.hero.loc[itemName]++; + return; + } + else if (itemVal == '--') { + core.status.hero.loc[itemName]--; + return; + } + core.status.hero.loc[itemName] = itemVal; +} + +////// 获得勇士的位置 ////// +core.prototype.getHeroLoc = function (itemName) { + if (!core.isset(itemName)) return core.status.hero.loc; + return core.status.hero.loc[itemName]; +} + +////// 获得勇士面对位置的x坐标 ////// +core.prototype.nextX = function() { + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + }; + return core.getHeroLoc('x')+scan[core.getHeroLoc('direction')].x; +} + +////// 获得勇士面对位置的y坐标 ////// +core.prototype.nextY = function () { + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + }; + return core.getHeroLoc('y')+scan[core.getHeroLoc('direction')].y; +} + /////////// 自动行走 & 行走控制 END /////////// /////////// 地图处理 /////////// -// 开门 +////// 开门 ////// core.prototype.openDoor = function (id, x, y, needKey, callback) { if (core.interval.openDoorAnimate!=null) return; @@ -1580,7 +1665,7 @@ core.prototype.openDoor = function (id, x, y, needKey, callback) { }, speed) } -// 战斗 +////// 战斗 ////// core.prototype.battle = function (id, x, y, force, callback) { if (core.status.moveStepBeforeStop.length==0) { core.status.moveStepBeforeStop=core.status.autoStepRoutes.slice(core.status.autoStep-1,core.status.autoStepRoutes.length); @@ -1609,6 +1694,7 @@ core.prototype.battle = function (id, x, y, force, callback) { } } +////// 战斗完毕 ////// core.prototype.afterBattle = function(id, x, y, callback) { core.status.hero.hp -= core.enemys.getDamage(id); if (core.status.hero.hp<=0) { @@ -1641,6 +1727,7 @@ core.prototype.afterBattle = function(id, x, y, callback) { } +////// 触发(x,y)点的事件 ////// core.prototype.trigger = function (x, y) { var mapBlocks = core.status.thisMap.blocks; var noPass; @@ -1667,7 +1754,7 @@ core.prototype.trigger = function (x, y) { } } -// 楼层切换 +////// 楼层切换 ////// core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback) { time = time || 800; time /= 20; @@ -1676,6 +1763,8 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback) core.stopAutomaticRoute(); core.clearContinueAutomaticRoute(); core.dom.floorNameLabel.innerHTML = core.status.maps[floorId].title; + if (!core.isset(stair) && !core.isset(heroLoc)) + heroLoc = core.status.hero.loc; if (core.isset(stair)) { if (!core.isset(heroLoc)) heroLoc={}; var blocks = core.status.maps[floorId].blocks; @@ -1710,6 +1799,11 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback) core.statusBar.floor.style.fontStyle = 'italic'; else core.statusBar.floor.style.fontStyle = 'normal'; + // 更改BGM + if (core.isset(core.floors[floorId].bgm)) { + core.playBgm(core.floors[floorId].bgm); + } + // 不存在事件时,更改画面色调 if (core.status.event.id == null) { // 默认画面色调 @@ -1750,7 +1844,7 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback) }, 50); } -// 地图切换 +////// 地图切换动画效果 ////// core.prototype.mapChangeAnimate = function (mode, time, callback) { if (mode == 'show') { core.show(core.dom.floorMsgGroup, time, function () { @@ -1764,6 +1858,7 @@ core.prototype.mapChangeAnimate = function (mode, time, callback) { } } +////// 清除地图 ////// core.prototype.clearMap = function (map, x, y, width, height) { if (map == 'all') { for (var m in core.canvas) { @@ -1775,6 +1870,7 @@ core.prototype.clearMap = function (map, x, y, width, height) { } } +////// 在某个canvas上绘制一段文字 ////// core.prototype.fillText = function (map, text, x, y, style, font) { if (core.isset(style)) { core.setFillStyle(map, style); @@ -1785,6 +1881,7 @@ core.prototype.fillText = function (map, text, x, y, style, font) { core.canvas[map].fillText(text, x, y); } +////// 在某个canvas上绘制一个矩形 ////// core.prototype.fillRect = function (map, x, y, width, height, style) { if (core.isset(style)) { core.setFillStyle(map, style); @@ -1792,6 +1889,7 @@ core.prototype.fillRect = function (map, x, y, width, height, style) { core.canvas[map].fillRect(x, y, width, height); } +////// 在某个canvas上绘制一个矩形的边框 ////// core.prototype.strokeRect = function (map, x, y, width, height, style, lineWidth) { if (core.isset(style)) { core.setStrokeStyle(map, style); @@ -1802,6 +1900,7 @@ core.prototype.strokeRect = function (map, x, y, width, height, style, lineWidth core.canvas[map].strokeRect(x, y, width, height); } +////// 在某个canvas上绘制一条线 ////// core.prototype.drawLine = function (map, x1, y1, x2, y2, style, lineWidth) { if (core.isset(style)) { core.setStrokeStyle(map, style); @@ -1815,10 +1914,12 @@ core.prototype.drawLine = function (map, x1, y1, x2, y2, style, lineWidth) { core.canvas[map].stroke(); } +////// 设置某个canvas的文字字体 ////// core.prototype.setFont = function (map, font) { core.canvas[map].font = font; } +////// 设置某个canvas的线宽度 ////// core.prototype.setLineWidth = function (map, lineWidth) { if (map == 'all') { for (var m in core.canvas) { @@ -1828,14 +1929,17 @@ core.prototype.setLineWidth = function (map, lineWidth) { core.canvas[map].lineWidth = lineWidth; } +////// 保存某个canvas状态 ////// core.prototype.saveCanvas = function (map) { core.canvas[map].save(); } +////// 加载某个canvas状态 ////// core.prototype.loadCanvas = function (map) { core.canvas[map].restore(); } +////// 设置某个canvas边框属性 ////// core.prototype.setStrokeStyle = function (map, style) { if (map == 'all') { for (var m in core.canvas) { @@ -1847,6 +1951,7 @@ core.prototype.setStrokeStyle = function (map, style) { } } +////// 设置某个canvas的alpha值 ////// core.prototype.setAlpha = function (map, alpha) { if (map == 'all') { for (var m in core.canvas) { @@ -1856,6 +1961,7 @@ core.prototype.setAlpha = function (map, alpha) { else core.canvas[map].globalAlpha = alpha; } +////// 设置某个canvas的透明度 ////// core.prototype.setOpacity = function (map, opacity) { if (map == 'all') { for (var m in core.canvas) { @@ -1865,6 +1971,7 @@ core.prototype.setOpacity = function (map, opacity) { else core.canvas[map].canvas.style.opacity = opacity; } +////// 设置某个canvas的绘制属性(如颜色等) ////// core.prototype.setFillStyle = function (map, style) { if (map == 'all') { for (var m in core.canvas) { @@ -1876,11 +1983,7 @@ core.prototype.setFillStyle = function (map, style) { } } -/** - * 地图绘制 - * @param mapName 地图ID - * @param callback 绘制完毕后的回调函数 - */ +////// 绘制某张地图 ////// core.prototype.drawMap = function (mapName, callback) { var mapData = core.status.maps[mapName]; var mapBlocks = mapData.blocks; @@ -1921,6 +2024,7 @@ core.prototype.drawMap = function (mapName, callback) { callback(); } +////// 绘制Autotile ////// core.prototype.drawAutotile = function (floorId, canvas, autotileMaps, left, top, size, autotileId) { if (!core.isset(autotileId)) { @@ -1966,6 +2070,7 @@ core.prototype.drawAutotile = function (floorId, canvas, autotileMaps, left, top } } +////// 绘制Autotile的某一块 ////// core.prototype.drawAutotileBlock = function (floorId, map, x, y, size, autotile, index) { var canvas = core.canvas[map]; var groundId = core.floors[floorId].defaultGround || "ground"; @@ -2049,51 +2154,53 @@ core.prototype.drawAutotileBlock = function (floorId, map, x, y, size, autotile, } } -core.prototype.autotileExists = function (x, y, floorId) { - var block = core.getBlock(x,y,floorId); - if (block==null) return false; - return block.block.event.cls == 'autotile'; -} - +////// 某个点是否不可通行 ////// core.prototype.noPassExists = function (x, y, floorId) { var block = core.getBlock(x,y,floorId); if (block==null) return false; return core.isset(block.block.event.noPass) && block.block.event.noPass; } +////// 某个点是否在区域内且不可通行 ////// core.prototype.noPass = function (x, y) { return x<0 || x>12 || y<0 || y>12 || core.noPassExists(x,y); } +////// 某个点是否存在NPC ////// core.prototype.npcExists = function (x, y, floorId) { var block = core.getBlock(x,y,floorId); if (block==null) return false; return block.block.event.cls == 'npcs'; } +////// 某个点是否存在(指定的)地形 ////// core.prototype.terrainExists = function (x, y, id, floorId) { var block = core.getBlock(x,y,floorId); if (block==null) return false; - return block.block.event.cls=='terrains' && block.block.event.id==id; + return block.block.event.cls=='terrains' && (core.isset(id)?block.block.event.id==id:true); } +////// 某个点是否存在楼梯 ////// core.prototype.stairExists = function (x, y, floorId) { var block = core.getBlock(x,y,floorId); if (block==null) return false; return block.block.event.cls=='terrains' && (block.block.event.id=='upFloor' || block.block.event.id=='downFloor'); } +////// 当前位置是否在楼梯边 ////// core.prototype.nearStair = function() { var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); return core.stairExists(x,y) || core.stairExists(x-1,y) || core.stairExists(x,y-1) || core.stairExists(x+1,y) || core.stairExists(x,y+1); } +////// 某个点是否存在(指定的)怪物 ////// core.prototype.enemyExists = function (x, y, id,floorId) { var block = core.getBlock(x,y,floorId); if (block==null) return false; return block.block.event.cls=='enemys' && (core.isset(id)?block.block.event.id==id:true); } +////// 获得某个点的block ////// core.prototype.getBlock = function (x, y, floorId, needEnable) { if (!core.isset(floorId)) floorId=core.status.floorId; if (!core.isset(needEnable)) needEnable=true; @@ -2107,6 +2214,7 @@ core.prototype.getBlock = function (x, y, floorId, needEnable) { return null; } +////// 显示移动某块的动画,达到{“type”:”move”}的效果 ////// core.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) { time = time || 500; @@ -2206,6 +2314,7 @@ core.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) { }, time/16); } +////// 显示/隐藏某个块时的动画效果 ////// core.prototype.animateBlock = function (x,y,type,time,callback) { if (type!='hide') type='show'; @@ -2248,8 +2357,8 @@ core.prototype.animateBlock = function (x,y,type,time,callback) { }, time/10); } -// 显示一个事件 -core.prototype.addBlock = function(x,y,floodId) { +////// 将某个块从禁用变成启用状态 ////// +core.prototype.showBlock = function(x, y, floodId) { floodId = floodId || core.status.floorId; var block = core.getBlock(x,y,floodId,false); if (block==null) return; // 不存在 @@ -2268,6 +2377,7 @@ core.prototype.addBlock = function(x,y,floodId) { } } +////// 将某个块从启用变成禁用状态 ////// core.prototype.removeBlock = function (x, y, floorId) { floorId = floorId || core.status.floorId; @@ -2287,7 +2397,7 @@ core.prototype.removeBlock = function (x, y, floorId) { core.updateFg(); } - +////// 根据block的索引删除该块 ////// core.prototype.removeBlockById = function (index, floorId) { var blocks = core.status.maps[floorId].blocks; @@ -2306,12 +2416,14 @@ core.prototype.removeBlockById = function (index, floorId) { blocks[index].enable = false; } +////// 一次性删除多个block ////// core.prototype.removeBlockByIds = function (floorId, ids) { ids.sort(function (a,b) {return b-a}).forEach(function (id) { core.removeBlockById(id, floorId); }); } +////// 添加一个全局动画 ////// core.prototype.addGlobalAnimate = function (animateMore, x, y, loc, image) { if (animateMore == 2) { core.status.twoAnimateObjs.push({ @@ -2333,6 +2445,7 @@ core.prototype.addGlobalAnimate = function (animateMore, x, y, loc, image) { } } +////// 删除一个或所有全局动画 ////// core.prototype.removeGlobalAnimate = function (x, y, all) { if (all == true) { core.status.twoAnimateObjs = []; @@ -2352,6 +2465,7 @@ core.prototype.removeGlobalAnimate = function (x, y, all) { } } +////// 设置全局动画的显示效果 ////// core.prototype.setGlobalAnimate = function (speed) { clearInterval(core.interval.twoAnimate); clearInterval(core.interval.fourAnimate); @@ -2380,6 +2494,7 @@ core.prototype.setGlobalAnimate = function (speed) { }, speed / 2); } +////// 同步所有的全局动画效果 ////// core.prototype.syncGlobalAnimate = function () { core.status.twoAnimateObjs.forEach(function (t) { t.status=0; @@ -2389,6 +2504,7 @@ core.prototype.syncGlobalAnimate = function () { }) } +////// 显示UI层某个box的动画 ////// core.prototype.setBoxAnimate = function () { clearInterval(core.interval.boxAnimate); if (core.status.boxAnimateObjs.length > 0) { @@ -2400,6 +2516,7 @@ core.prototype.setBoxAnimate = function () { } } +////// 绘制UI层的box动画 ////// core.prototype.drawBoxAnimate = function (background) { for (var a = 0; a < core.status.boxAnimateObjs.length; a++) { var obj = core.status.boxAnimateObjs[a]; @@ -2411,7 +2528,7 @@ core.prototype.drawBoxAnimate = function (background) { } } -// 更新领域、显伤 +////// 更新领域、夹击、阻击的伤害地图 ////// core.prototype.updateCheckBlock = function() { core.status.checkBlock = {}; if (!core.isset(core.status.thisMap)) return; @@ -2505,8 +2622,8 @@ core.prototype.updateCheckBlock = function() { } } +////// 检查并执行领域、夹击、阻击事件 ////// core.prototype.checkBlock = function () { - // 检查领域、夹击事件 var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); var damage = core.status.checkBlock.damage[13*x+y]; if (damage>0) { @@ -2532,14 +2649,14 @@ core.prototype.checkBlock = function () { } } - if (core.status.checkBlock.betweenAttack[13*x+y]) { + if (core.status.checkBlock.betweenAttack[13*x+y] && damage>0) { core.drawTip('受到夹击,生命变成一半'); } // 阻击 - else if (snipe.length>0) { + else if (snipe.length>0 && damage>0) { core.drawTip('受到阻击伤害'+damage+'点'); } - else { + else if (damage>0) { core.drawTip('受到领域伤害'+damage+'点'); } if (core.status.hero.hp<=0) { @@ -2560,6 +2677,7 @@ core.prototype.checkBlock = function () { } } +////// 阻击事件(动画效果) ////// core.prototype.snipe = function (snipes) { core.waitHeroToStop(function() { core.lockControl(); @@ -2664,6 +2782,7 @@ core.prototype.snipe = function (snipes) { }); } +////// 更改画面色调 ////// core.prototype.setFg = function(color, time, callback) { if (!core.isset(time)) time=750; if (time<=0) time=0; @@ -2718,47 +2837,7 @@ core.prototype.setFg = function(color, time, callback) { } - -core.prototype.setHeroLoc = function (itemName, itemVal) { - if (itemVal == '++') { - core.status.hero.loc[itemName]++; - return; - } - else if (itemVal == '--') { - core.status.hero.loc[itemName]--; - return; - } - core.status.hero.loc[itemName] = itemVal; -} - -core.prototype.getHeroLoc = function (itemName) { - if (!core.isset(itemName)) return core.status.hero.loc; - return core.status.hero.loc[itemName]; -} - -core.prototype.nextX = function() { - var scan = { - 'up': {'x': 0, 'y': -1}, - 'left': {'x': -1, 'y': 0}, - 'down': {'x': 0, 'y': 1}, - 'right': {'x': 1, 'y': 0} - }; - return core.getHeroLoc('x')+scan[core.getHeroLoc('direction')].x; -} - -core.prototype.nextY = function () { - var scan = { - 'up': {'x': 0, 'y': -1}, - 'left': {'x': -1, 'y': 0}, - 'down': {'x': 0, 'y': 1}, - 'right': {'x': 1, 'y': 0} - }; - return core.getHeroLoc('y')+scan[core.getHeroLoc('direction')].y; -} - -/** - * 更新显伤 - */ +////// 更新全地图显伤 ////// core.prototype.updateFg = function () { if (!core.isset(core.status.thisMap) || !core.isset(core.status.thisMap.blocks)) return; @@ -2821,9 +2900,7 @@ core.prototype.updateFg = function () { } } -/** - * 物品处理 start - */ +////// 获得某个物品的个数 ////// core.prototype.itemCount = function (itemId) { if (!core.isset(itemId) || !core.isset(core.material.items[itemId])) return 0; var itemCls = core.material.items[itemId].cls; @@ -2831,10 +2908,12 @@ core.prototype.itemCount = function (itemId) { return core.isset(core.status.hero.items[itemCls][itemId]) ? core.status.hero.items[itemCls][itemId] : 0; } +////// 是否存在某个物品 ////// core.prototype.hasItem = function (itemId) { return core.itemCount(itemId) > 0; } +////// 设置某个物品的个数 ////// core.prototype.setItem = function (itemId, itemNum) { var itemCls = core.material.items[itemId].cls; if (itemCls == 'items') return; @@ -2844,6 +2923,7 @@ core.prototype.setItem = function (itemId, itemNum) { core.status.hero.items[itemCls][itemId] = itemNum; } +////// 删除某个物品 ////// core.prototype.removeItem = function (itemId) { if (!core.hasItem(itemId)) return false; var itemCls = core.material.items[itemId].cls; @@ -2855,15 +2935,18 @@ core.prototype.removeItem = function (itemId) { return true; } +////// 使用某个物品 ////// core.prototype.useItem = function (itemId) { core.items.useItem(itemId); return; } +////// 能否使用某个物品 ////// core.prototype.canUseItem = function (itemId) { return core.items.canUseItem(itemId); } +////// 增加某个物品的个数 ////// core.prototype.addItem = function (itemId, itemNum) { var itemData = core.material.items[itemId]; var itemCls = itemData.cls; @@ -2878,6 +2961,7 @@ core.prototype.addItem = function (itemId, itemNum) { core.status.hero.items[itemCls][itemId] += itemNum; } +////// 获得面前的物品(轻按) ////// core.prototype.getNextItem = function() { if (!core.status.heroStop || !core.flags.enableGentleClick) return; var nextX = core.nextX(), nextY = core.nextY(); @@ -2888,6 +2972,7 @@ core.prototype.getNextItem = function() { } } +////// 获得某个物品 ////// core.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) { // core.getItemAnimate(itemId, itemNum, itemX, itemY); core.playSound('item.ogg'); @@ -2909,6 +2994,7 @@ core.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) { else if (core.isset(callback)) callback(); } +////// 左上角绘制一段提示 ////// core.prototype.drawTip = function (text, itemIcon) { var textX, textY, width, height, hide = false, opacityVal = 0; clearInterval(core.interval.tipAnimate); @@ -2964,6 +3050,7 @@ core.prototype.drawTip = function (text, itemIcon) { }, 30); } +////// 地图中间绘制一段文字 ////// core.prototype.drawText = function (contents, callback) { if (core.isset(contents)) { if (typeof contents == 'string') { @@ -3006,18 +3093,19 @@ core.prototype.drawText = function (contents, callback) { /////////// 地图相关 END /////////// -/** - * 系统机制 start - */ -// 替换文本中的数为实际值 + + +/////////// 系统机制 /////////// + +////// 将文字中的${和}(表达式)进行替换 ////// core.prototype.replaceText = function (text) { return text.replace(/\${([^}]+)}/g, function (word, value) { return core.calValue(value); }); } - +////// 计算表达式的值 ////// core.prototype.calValue = function (value) { value=value.replace(/status:([\w\d_]+)/g, "core.getStatus('$1')"); value=value.replace(/item:([\w\d_]+)/g, "core.itemCount('$1')"); @@ -3025,6 +3113,7 @@ core.prototype.calValue = function (value) { return eval(value); } +////// 执行一个表达式的effect操作 ////// core.prototype.doEffect = function (expression) { // 必须使用"+=" var arr = expression.split("+="); @@ -3040,6 +3129,7 @@ core.prototype.doEffect = function (expression) { } } +////// 字符串自动换行的分割 ////// core.prototype.splitLines = function(canvas, text, maxLength, font) { if (core.isset(font)) core.setFont(canvas, font); @@ -3064,6 +3154,7 @@ core.prototype.splitLines = function(canvas, text, maxLength, font) { return contents; } +////// 向某个数组前插入另一个数组或元素 ////// core.prototype.unshift = function (a,b) { if (!(a instanceof Array) || !core.isset(b)) return; if (b instanceof Array) { @@ -3075,6 +3166,7 @@ core.prototype.unshift = function (a,b) { return a; } +////// 设置本地存储 ////// core.prototype.setLocalStorage = function(key, value) { try { localStorage.setItem(core.firstData.name + "_" + key, JSON.stringify(value)); @@ -3085,16 +3177,20 @@ core.prototype.setLocalStorage = function(key, value) { return false; } } + +////// 获得本地存储 ////// core.prototype.getLocalStorage = function(key, defaultValue) { var value = localStorage.getItem(core.firstData.name+"_"+key); if (core.isset(value)) return JSON.parse(value); return defaultValue; } +////// 移除本地存储 ////// core.prototype.removeLocalStorage = function (key) { localStorage.removeItem(core.firstData.name+"_"+key); } +////// 深拷贝一个对象 ////// core.prototype.clone = function (data) { if (!core.isset(data)) return data; // date @@ -3129,25 +3225,19 @@ core.prototype.clone = function (data) { return data; } +////// 格式化时间为字符串 ////// core.prototype.formatDate = function(date) { if (!core.isset(date)) return ""; return date.getFullYear()+"-"+core.setTwoDigits(date.getMonth()+1)+"-"+core.setTwoDigits(date.getDate())+" " +core.setTwoDigits(date.getHours())+":"+core.setTwoDigits(date.getMinutes())+":"+core.setTwoDigits(date.getSeconds()); } +////// 两位数显示 ////// core.prototype.setTwoDigits = function (x) { return parseInt(x)<10?"0"+x:x; } -core.prototype.win = function(reason) { - core.events.win(reason); -} - -core.prototype.lose = function(reason) { - core.events.lose(reason); -} - -// 作弊 +////// 作弊 ////// core.prototype.debug = function() { core.setStatus('hp', 999999); core.setStatus('atk', 10000); @@ -3167,9 +3257,10 @@ core.prototype.debug = function() { core.drawTip("作弊成功"); } -core.prototype.checkStatus = function (name, need, item, clearData) { +////// 判断当前能否进入某个事件 ////// +core.prototype.checkStatus = function (name, need, item) { if (need && core.status.event.id == name) { - core.ui.closePanel(clearData); + core.ui.closePanel(); return false; } @@ -3189,12 +3280,14 @@ core.prototype.checkStatus = function (name, need, item, clearData) { return true; } +////// 点击怪物手册时的打开操作 ////// core.prototype.openBook = function (need) { - if (!core.checkStatus('book', need, true, true)) + if (!core.checkStatus('book', need, true)) return; core.useItem('book'); } +////// 点击楼层传送器时的打开操作 ////// core.prototype.useFly = function (need) { if (!core.checkStatus('fly', need, true)) return; @@ -3216,18 +3309,21 @@ core.prototype.useFly = function (need) { return; } +////// 点击工具栏时的打开操作 ////// core.prototype.openToolbox = function (need) { if (!core.checkStatus('toolbox', need)) return; core.ui.drawToolbox(); } +////// 点击保存按钮时的打开操作 ////// core.prototype.save = function(need) { if (!core.checkStatus('save', need)) return; core.ui.drawSLPanel(core.status.saveIndex); } +////// 点击读取按钮时的打开操作 ////// core.prototype.load = function (need) { // 游戏开始前读档 @@ -3244,6 +3340,7 @@ core.prototype.load = function (need) { core.ui.drawSLPanel(core.status.saveIndex); } +////// 实际进行存读档事件 ////// core.prototype.doSL = function (id, type) { core.status.saveIndex=id; if (type=='save') { @@ -3277,6 +3374,7 @@ core.prototype.doSL = function (id, type) { } } +////// 存档同步操作 ////// core.prototype.syncSave = function(type) { if (type=='save') { core.status.event.selection=1; @@ -3405,6 +3503,7 @@ core.prototype.syncSave = function(type) { } +////// 存档到本地 ////// core.prototype.saveData = function(dataId) { var data = { 'floorId': core.status.floorId, @@ -3427,6 +3526,7 @@ core.prototype.saveData = function(dataId) { return core.setLocalStorage(dataId, data); } +////// 从本地读档 ////// core.prototype.loadData = function (data, callback) { core.resetStatus(data.hero, data.hard, data.floorId, core.maps.load(data.maps)); @@ -3445,24 +3545,29 @@ core.prototype.loadData = function (data, callback) { }); } +////// 设置勇士属性 ////// core.prototype.setStatus = function (statusName, statusVal) { core.status.hero[statusName] = statusVal; } +////// 获得勇士属性 ////// core.prototype.getStatus = function (statusName) { return core.status.hero[statusName]; } +////// 获得某个等级的名称 ////// core.prototype.getLvName = function () { if (core.status.hero.lv>core.firstData.levelUp.length) return core.status.hero.lv; return core.firstData.levelUp[core.status.hero.lv-1].name || core.status.hero.lv; } +////// 设置某个自定义变量或flag ////// core.prototype.setFlag = function(flag, value) { if (!core.isset(core.status.hero)) return; core.status.hero.flags[flag]=value; } +////// 获得某个自定义变量或flag ////// core.prototype.getFlag = function(flag, defaultValue) { if (!core.isset(core.status.hero)) return defaultValue; var value = core.status.hero.flags[flag]; @@ -3470,24 +3575,28 @@ core.prototype.getFlag = function(flag, defaultValue) { return defaultValue; } -// 只有不为0或false时才会返回true +////// 是否存在某个自定义变量或flag,且值为true ////// core.prototype.hasFlag = function(flag) { if (core.getFlag(flag)) return true; return false; } +////// 往当前事件列表之前插入一系列事件 ////// core.prototype.insertAction = function (list) { core.events.insertAction(list); } +////// 锁定状态栏,常常用于事件处理 ////// core.prototype.lockControl = function () { core.status.lockControl = true; } +////// 解锁状态栏 ////// core.prototype.unLockControl = function () { core.status.lockControl = false; } +////// 判断某对象是否不为undefined也不会null ////// core.prototype.isset = function (val) { if (val == undefined || val == null) { return false; @@ -3495,6 +3604,7 @@ core.prototype.isset = function (val) { return true } +////// 播放背景音乐 ////// core.prototype.playBgm = function (bgm) { // 如果不允许播放 @@ -3530,6 +3640,7 @@ core.prototype.playBgm = function (bgm) { } } +////// 暂停背景音乐的播放 ////// core.prototype.pauseBgm = function () { // 直接暂停播放 try { @@ -3544,7 +3655,12 @@ core.prototype.pauseBgm = function () { } } +////// 恢复背景音乐的播放 ////// core.prototype.resumeBgm = function () { + + // 如果不允许播放 + if (!core.musicStatus.bgmStatus) return; + // 恢复BGM try { if (core.isset(core.musicStatus.playingBgm)) { @@ -3564,6 +3680,7 @@ core.prototype.resumeBgm = function () { } } +////// 播放音频 ////// core.prototype.playSound = function (sound) { // 如果不允许播放 @@ -3597,27 +3714,7 @@ core.prototype.playSound = function (sound) { } } -core.prototype.changeSoundStatus = function () { - if (core.musicStatus.soundStatus) { - main.core.disabledSound(); - } - else { - main.core.enabledSound(); - } -} - -core.prototype.enabledSound = function () { - core.musicStatus.soundStatus = true; - core.playBgm('bgm', 'mp3'); - core.setLocalStorage('soundStatus', true); -} - -core.prototype.disabledSound = function () { - core.musicStatus.playedBgm.pause(); - core.musicStatus.soundStatus = false; - core.setLocalStorage('soundStatus', false); -} - +////// 动画显示某对象 ////// core.prototype.show = function (obj, speed, callback) { if (!core.isset(speed)) { obj.style.display = 'block'; @@ -3638,6 +3735,7 @@ core.prototype.show = function (obj, speed, callback) { }, speed); } +////// 动画使某对象消失 ////// core.prototype.hide = function (obj, speed, callback) { if (!core.isset(speed)) { obj.style.display = 'none'; @@ -3658,8 +3756,7 @@ core.prototype.hide = function (obj, speed, callback) { } -////// 状态栏相关 ////// - +////// 清空状态栏 ////// core.prototype.clearStatusBar = function() { var statusList = ['floor', 'lv', 'hp', 'atk', 'def', 'mdef', 'money', 'experience', 'up', 'yellowKey', 'blueKey', 'redKey', 'poison', 'weak', 'curse', 'hard']; statusList.forEach(function (e) { @@ -3669,13 +3766,11 @@ core.prototype.clearStatusBar = function() { core.statusBar.image.fly.style.opacity = 0.3; } -/** - * 更新状态栏 - */ +////// 更新状态栏 ////// core.prototype.updateStatusBar = function () { // 检查等级 - core.checkLvUp(); + core.events.checkLvUp(); // 检查HP上限 if (core.values.HPMAX>0) { @@ -3725,32 +3820,7 @@ core.prototype.updateStatusBar = function () { core.updateFg(); } -core.prototype.checkLvUp = function () { - if (!core.flags.enableLevelUp || core.status.hero.lv>=core.firstData.levelUp.length) return; - // 计算下一个所需要的数值 - var need=core.firstData.levelUp[core.status.hero.lv].need; - if (!core.isset(need)) return; - if (core.status.hero.experience>=need) { - // 升级 - core.status.hero.lv++; - var effect = core.firstData.levelUp[core.status.hero.lv-1].effect; - if (typeof effect == "string") { - if (effect.indexOf("function")==0) { - eval("("+effect+")()"); - } - else { - effect.split(";").forEach(function (t) { - core.doEffect(t); - }); - } - } - else if (effect instanceof Function) { - effect(); - } - core.checkLvUp(); - } -} - +////// 屏幕分辨率改变后重新自适应 ////// core.prototype.resize = function(clientWidth, clientHeight) { // 默认画布大小 @@ -4055,6 +4125,7 @@ core.prototype.resize = function(clientWidth, clientHeight) { core.domRenderer(); } +////// 渲染DOM ////// core.prototype.domRenderer = function(){ core.dom.statusBar.style.display = 'block'; diff --git a/libs/enemys.js b/libs/enemys.js index f9e29705..1738102d 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -2,6 +2,7 @@ function enemys() { } +////// 初始化 ////// enemys.prototype.init = function () { // 怪物属性初始化定义: this.enemys = { @@ -68,17 +69,20 @@ enemys.prototype.init = function () { } } +////// 获得一个或所有怪物数据 ////// enemys.prototype.getEnemys = function (enemyId) { - if (enemyId == undefined) { + if (!core.isset(enemyId)) { return this.enemys; } return this.enemys[enemyId]; } +////// 判断是否含有某特殊属性 ////// enemys.prototype.hasSpecial = function (special, test) { return (special instanceof Array)?special.indexOf(test)>=0:(special!=0&&(special%100==test||this.hasSpecial(parseInt(special/100), test))); } +////// 获得所有特殊属性的名称 ////// enemys.prototype.getSpecialText = function (enemyId) { if (enemyId == undefined) return ""; var enemy = this.enemys[enemyId]; @@ -107,7 +111,7 @@ enemys.prototype.getSpecialText = function (enemyId) { return text; } -////// 获得每个属性的文字提示 ////// +////// 获得每个特殊属性的说明 ////// enemys.prototype.getSpecialHint = function (enemy, special) { if (!core.isset(special)) { var hints = []; @@ -147,6 +151,7 @@ enemys.prototype.getSpecialHint = function (enemy, special) { return "" } +////// 获得某个怪物的伤害 ////// enemys.prototype.getDamage = function (monsterId) { var monster = core.material.enemys[monsterId]; var hero_atk = core.status.hero.atk, hero_def = core.status.hero.def, hero_mdef = core.status.hero.mdef; @@ -156,6 +161,7 @@ enemys.prototype.getDamage = function (monsterId) { return damage + this.getExtraDamage(monster); } +////// 获得某个怪物的额外伤害 ////// enemys.prototype.getExtraDamage = function (monster) { var extra_damage = 0; if (this.hasSpecial(monster.special, 11)) { // 吸血 @@ -169,7 +175,7 @@ enemys.prototype.getExtraDamage = function (monster) { return extra_damage; } -// 临界值计算 +////// 临界值计算 ////// enemys.prototype.getCritical = function (monsterId) { var monster = core.material.enemys[monsterId]; if (this.hasSpecial(monster.special, 3) || this.hasSpecial(monster.special, 10)) return "???"; @@ -187,7 +193,7 @@ enemys.prototype.getCritical = function (monsterId) { return 0; } -// 临界减伤计算 +////// 临界减伤计算 ////// enemys.prototype.getCriticalDamage = function (monsterId) { var c = this.getCritical(monsterId); if (c == '???') return '???'; @@ -201,7 +207,7 @@ enemys.prototype.getCriticalDamage = function (monsterId) { monster.hp, monster.atk, monster.def, monster.special, monster.n); } -// 1防减伤计算 +////// 1防减伤计算 ////// enemys.prototype.getDefDamage = function (monsterId) { var monster = core.material.enemys[monsterId]; var nowDamage = this.calDamage(core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, @@ -212,6 +218,7 @@ enemys.prototype.getDefDamage = function (monsterId) { return nowDamage - nextDamage; } +////// 具体的伤害计算公式 ////// enemys.prototype.calDamage = function (hero_atk, hero_def, hero_mdef, mon_hp, mon_atk, mon_def, mon_special, n) { if (this.hasSpecial(mon_special, 20) && !core.hasItem("cross")) // 如果是无敌属性,且勇士未持有十字架 @@ -254,7 +261,7 @@ enemys.prototype.calDamage = function (hero_atk, hero_def, hero_mdef, mon_hp, mo return core.flags.enableNegativeDamage?ans:Math.max(0, ans); } -// 获得当前楼层的怪物列表 +////// 获得当前楼层的怪物列表 ////// enemys.prototype.getCurrentEnemys = function () { var enemys = []; var used = {}; diff --git a/libs/events.js b/libs/events.js index cd866e90..cf66d51e 100644 --- a/libs/events.js +++ b/libs/events.js @@ -2,6 +2,7 @@ function events() { } +////// 初始化 ////// events.prototype.init = function () { this.events = { 'battle': function (data, core, callback) { @@ -45,9 +46,9 @@ events.prototype.init = function () { } } -// 初始化 +////// 获得一个或所有系统事件类型 ////// events.prototype.getEvents = function (eventName) { - if (eventName == undefined) { + if (!core.isset(eventName)) { return this.events; } return this.events[eventName]; @@ -87,12 +88,14 @@ events.prototype.startGame = function (hard) { }) } -////// 简单难度设置初始福利 ////// +////// 不同难度分别设置初始属性 ////// events.prototype.setInitData = function (hard) { if (hard=='Easy') { // 简单难度 core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度 // 可以在此设置一些初始福利,比如设置初始生命值可以调用: // core.setStatus("hp", 10000); + // 赠送一把黄钥匙可以调用 + // core.setItem("yellowKey", 1); } if (hard=='Normal') { // 普通难度 core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度 @@ -102,9 +105,8 @@ events.prototype.setInitData = function (hard) { } } -////// 游戏结束事件 ////// +////// 游戏获胜事件 ////// events.prototype.win = function(reason) { - // 获胜 core.waitHeroToStop(function() { core.removeGlobalAnimate(0,0,true); core.clearMap('all'); // 清空全地图 @@ -116,8 +118,8 @@ events.prototype.win = function(reason) { }); } +////// 游戏失败事件 ////// events.prototype.lose = function(reason) { - // 失败 core.waitHeroToStop(function() { core.drawText([ "\t[结局1]你死了。\n如题。" @@ -133,20 +135,9 @@ events.prototype.afterChangeFloor = function (floorId) { this.doEvents(core.floors[floorId].firstArrive); core.setFlag("visited_"+floorId, true); } - - // 播放BGM - if (floorId == 'sample0') { - core.playBgm('bgm.mp3'); - } - if (floorId == 'sample1') { - core.playBgm('star.mid'); - } - if (floorId == 'sample2') { - core.playBgm('qianjin.mid'); - } } -////// 实际事件的处理 ////// +////// 开始执行一系列自定义事件 ////// events.prototype.doEvents = function (list, x, y, callback) { // 停止勇士 core.waitHeroToStop(function() { @@ -162,6 +153,7 @@ events.prototype.doEvents = function (list, x, y, callback) { }); } +////// 执行当前自定义事件列表中的下一个事件 ////// events.prototype.doAction = function() { // 清空boxAnimate和UI层 clearInterval(core.interval.boxAnimate); @@ -172,7 +164,7 @@ events.prototype.doAction = function() { if (core.status.event.data.list.length==0) { if (core.isset(core.status.event.data.callback)) core.status.event.data.callback(); - core.ui.closePanel(false); + core.ui.closePanel(); return; } @@ -201,12 +193,12 @@ events.prototype.doAction = function() { case "show": // 显示 if (core.isset(data.time) && data.time>0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) { core.animateBlock(data.loc[0],data.loc[1],'show', data.time, function () { - core.addBlock(data.loc[0],data.loc[1],data.floorId); + core.showBlock(data.loc[0],data.loc[1],data.floorId); core.events.doAction(); }); } else { - core.addBlock(data.loc[0],data.loc[1],data.floorId) + core.showBlock(data.loc[0],data.loc[1],data.floorId) this.doAction(); } break; @@ -418,7 +410,7 @@ events.prototype.insertAction = function (action) { } } -////// 打开商店 ////// +////// 打开一个全局商店 ////// events.prototype.openShop = function(shopId, needVisited) { var shop = core.status.shops[shopId]; shop.times = shop.times || 0; @@ -460,35 +452,11 @@ events.prototype.openShop = function(shopId, needVisited) { core.ui.drawChoices(content, choices); } +////// 禁用一个全局商店 ////// events.prototype.disableQuickShop = function (shopId) { core.status.shops[shopId].visited = false; } -////// 降低难度 ////// - -events.prototype.decreaseHard = function() { - core.drawTip("本塔不支持降低难度!"); - /* - if (core.status.hard == 0) { - core.drawTip("当前已是难度0,不能再降低难度了"); - return; - } - var add = 100, x=core.status.hard; - while (x<10) { - x++; add*=2; - } - core.ui.drawConfirmBox("本次操作可生命+" + add + ",确定吗?", function () { - core.status.hero.hp += add; - core.status.hard--; - core.updateStatusBar(); - core.ui.closePanel(); - core.drawTip("降低难度成功,生命+" + add); - }, function () { - core.ui.drawSettings(false); - }); - */ -} - ////// 能否使用快捷商店 ////// events.prototype.canUseQuickShop = function(shopIndex) { if (core.isset(core.floors[core.status.floorId].canUseQuickShop) && !core.isset(core.floors[core.status.floorId].canUseQuickShop)) @@ -497,9 +465,36 @@ events.prototype.canUseQuickShop = function(shopIndex) { return null; } +////// 检查升级事件 ////// +events.prototype.checkLvUp = function () { + if (!core.flags.enableLevelUp || core.status.hero.lv>=core.firstData.levelUp.length) return; + // 计算下一个所需要的数值 + var need=core.firstData.levelUp[core.status.hero.lv].need; + if (!core.isset(need)) return; + if (core.status.hero.experience>=need) { + // 升级 + core.status.hero.lv++; + var effect = core.firstData.levelUp[core.status.hero.lv-1].effect; + if (typeof effect == "string") { + if (effect.indexOf("function")==0) { + eval("("+effect+")()"); + } + else { + effect.split(";").forEach(function (t) { + core.doEffect(t); + }); + } + } + else if (effect instanceof Function) { + effect(); + } + this.checkLvUp(); + } +} + ////// 尝试使用道具 ////// events.prototype.useItem = function(itemId) { - core.ui.closePanel(false); + core.ui.closePanel(); if (itemId=='book') { core.openBook(false); @@ -522,7 +517,7 @@ events.prototype.useItem = function(itemId) { else core.drawTip("当前无法使用"+core.material.items[itemId].name); } -////// 加点 ////// +////// 加点事件 ////// events.prototype.addPoint = function (enemy) { var point = enemy.point; if (!core.isset(point) || point<=0) return []; @@ -531,22 +526,21 @@ events.prototype.addPoint = function (enemy) { return [ {"type": "choices", "choices": [ - {"text": "生命+"+(200*point), "action": [ - {"type": "setValue", "name": "status:hp", "value": "status:hp+"+(200*point)} - ]}, {"text": "攻击+"+(1*point), "action": [ {"type": "setValue", "name": "status:atk", "value": "status:atk+"+(1*point)} ]}, {"text": "防御+"+(2*point), "action": [ {"type": "setValue", "name": "status:def", "value": "status:def+"+(2*point)} ]}, + {"text": "生命+"+(200*point), "action": [ + {"type": "setValue", "name": "status:hp", "value": "status:hp+"+(200*point)} + ]}, ] } ]; - } -/****** 打完怪物 ******/ +////// 战斗结束后触发的事件 ////// events.prototype.afterBattle = function(enemyId,x,y,callback) { // 毒衰咒的处理 @@ -607,7 +601,7 @@ events.prototype.afterBattle = function(enemyId,x,y,callback) { } -/****** 开完门 ******/ +////// 开一个门后触发的事件 ////// events.prototype.afterOpenDoor = function(doorId,x,y,callback) { var todo = []; @@ -628,7 +622,7 @@ events.prototype.afterOpenDoor = function(doorId,x,y,callback) { if (core.isset(callback)) callback(); } -/****** 经过路障 ******/ +////// 经过一个路障 ////// events.prototype.passNet = function (data) { // 有鞋子 if (core.hasItem('shoes')) return; @@ -659,6 +653,7 @@ events.prototype.passNet = function (data) { core.updateStatusBar(); } +////// 改变亮灯(感叹号)的事件 ////// events.prototype.changeLight = function(x, y) { var block = core.getBlock(x, y); if (block==null) return; @@ -675,32 +670,33 @@ events.prototype.changeLight = function(x, y) { this.afterChangeLight(x,y); } -// 改变灯后的事件 +////// 改变亮灯之后,可以触发的事件 ////// events.prototype.afterChangeLight = function(x,y) { } -// 使用炸弹/圣锤后的事件 +////// 使用炸弹/圣锤后的事件 ////// events.prototype.afterUseBomb = function () { } -// 存档事件前一刻的处理 +////// 即将存档前可以执行的操作 ////// events.prototype.beforeSaveData = function(data) { } -// 读档事件后,载入事件前,对数据的处理 +////// 读档事件后,载入事件前,可以执行的操作 ////// events.prototype.afterLoadData = function(data) { } -/******************************************/ -/*********** 界面上的点击事件 ***************/ -/******************************************/ +/****************************************/ +/********** 点击事件、键盘事件 ************/ +/****************************************/ +////// 按下Ctrl键时(快捷跳过对话) ////// events.prototype.keyDownCtrl = function () { if (core.status.event.id=='text') { core.drawText(); @@ -712,6 +708,7 @@ events.prototype.keyDownCtrl = function () { } } +////// 点击确认框时 ////// events.prototype.clickConfirmBox = function (x,y) { if ((x == 4 || x == 5) && y == 7 && core.isset(core.status.event.data.yes)) core.status.event.data.yes(); @@ -719,6 +716,7 @@ events.prototype.clickConfirmBox = function (x,y) { core.status.event.data.no(); } +////// 键盘操作确认框时 ////// events.prototype.keyUpConfirmBox = function (keycode) { if (keycode==37) { core.status.event.selection=0; @@ -742,7 +740,7 @@ events.prototype.keyUpConfirmBox = function (keycode) { } } -// 正在处理事件时的点击操作... +////// 自定义事件时的点击操作 ////// events.prototype.clickAction = function (x,y) { if (core.status.event.data.type=='text') { @@ -765,6 +763,7 @@ events.prototype.clickAction = function (x,y) { } } +////// 自定义事件时,按下某个键的操作 ////// events.prototype.keyDownAction = function (keycode) { if (core.status.event.data.type=='choices') { var data = core.status.event.data.current; @@ -784,6 +783,7 @@ events.prototype.keyDownAction = function (keycode) { } } +////// 自定义事件时,放开某个键的操作 ////// events.prototype.keyUpAction = function (keycode) { if (core.status.event.data.type=='text' && (keycode==13 || keycode==32 || keycode==67)) { this.doAction(); @@ -801,48 +801,49 @@ events.prototype.keyUpAction = function (keycode) { } } -// 怪物手册 +////// 怪物手册界面的点击操作 ////// events.prototype.clickBook = function(x,y) { // 上一页 if ((x == 3 || x == 4) && y == 12) { - core.ui.drawEnemyBook(core.status.event.data - 6); + core.ui.drawBook(core.status.event.data - 6); return; } // 下一页 if ((x == 8 || x == 9) && y == 12) { - core.ui.drawEnemyBook(core.status.event.data + 6); + core.ui.drawBook(core.status.event.data + 6); return; } // 返回 if (x>=10 && x<=12 && y==12) { - core.ui.closePanel(true); + core.ui.closePanel(); return; } // 怪物信息 - // var index = parseInt(y/2); var data = core.status.event.data; if (core.isset(data) && y<12) { var page=parseInt(data/6); var index=6*page+parseInt(y/2); - core.ui.drawEnemyBook(index); + core.ui.drawBook(index); core.ui.drawBookDetail(index); } return; } +////// 怪物手册界面时,按下某个键的操作 ////// events.prototype.keyDownBook = function (keycode) { - if (keycode==37) core.ui.drawEnemyBook(core.status.event.data-6); - if (keycode==38) core.ui.drawEnemyBook(core.status.event.data-1); - if (keycode==39) core.ui.drawEnemyBook(core.status.event.data+6); - if (keycode==40) core.ui.drawEnemyBook(core.status.event.data+1); - if (keycode==33) core.ui.drawEnemyBook(core.status.event.data-6); - if (keycode==34) core.ui.drawEnemyBook(core.status.event.data+6); + if (keycode==37) core.ui.drawBook(core.status.event.data-6); + if (keycode==38) core.ui.drawBook(core.status.event.data-1); + if (keycode==39) core.ui.drawBook(core.status.event.data+6); + if (keycode==40) core.ui.drawBook(core.status.event.data+1); + if (keycode==33) core.ui.drawBook(core.status.event.data-6); + if (keycode==34) core.ui.drawBook(core.status.event.data+6); return; } +////// 怪物手册界面时,放开某个键的操作 ////// events.prototype.keyUpBook = function (keycode) { if (keycode==27 || keycode==88) { - core.ui.closePanel(true); + core.ui.closePanel(); return; } if (keycode==13 || keycode==32 || keycode==67) { @@ -854,13 +855,13 @@ events.prototype.keyUpBook = function (keycode) { } } -events.prototype.clickBookDetail = function (x,y) { +////// 怪物手册属性显示界面时的点击操作 ////// +events.prototype.clickBookDetail = function () { core.clearMap('data', 0, 0, 416, 416); - core.status.event.id = 'book'; - } +////// 楼层传送器界面时的点击操作 ////// events.prototype.clickFly = function(x,y) { if ((x==10 || x==11) && y==9) core.ui.drawFly(core.status.event.data-1); if ((x==10 || x==11) && y==5) core.ui.drawFly(core.status.event.data+1); @@ -875,12 +876,14 @@ events.prototype.clickFly = function(x,y) { return; } +////// 楼层传送器界面时,按下某个键的操作 ////// events.prototype.keyDownFly = function (keycode) { if (keycode==37 || keycode==38) core.ui.drawFly(core.status.event.data+1); else if (keycode==39 || keycode==40) core.ui.drawFly(core.status.event.data-1); return; } +////// 楼层传送器界面时,放开某个键的操作 ////// events.prototype.keyUpFly = function (keycode) { if (keycode==71 || keycode==27 || keycode==88) core.ui.closePanel(); @@ -889,7 +892,7 @@ events.prototype.keyUpFly = function (keycode) { return; } -// 商店 +////// 商店界面时的点击操作 ////// events.prototype.clickShop = function(x,y) { var shop = core.status.event.data.shop; var choices = shop.choices; @@ -936,6 +939,7 @@ events.prototype.clickShop = function(x,y) { } } +////// 商店界面时,按下某个键的操作 ////// events.prototype.keyDownShop = function (keycode) { var shop = core.status.event.data.shop; var choices = shop.choices; @@ -951,6 +955,7 @@ events.prototype.keyDownShop = function (keycode) { } } +////// 商店界面时,放开某个键的操作 ////// events.prototype.keyUpShop = function (keycode) { if (keycode==27 || keycode==88) { if (core.status.event.data.fromList) { @@ -971,7 +976,7 @@ events.prototype.keyUpShop = function (keycode) { return; } -// 快捷商店 +////// 快捷商店界面时的点击操作 ////// events.prototype.clickQuickShop = function(x, y) { var shopList = core.status.shops, keys = Object.keys(shopList); if (x >= 5 && x <= 7) { @@ -992,6 +997,7 @@ events.prototype.clickQuickShop = function(x, y) { } } +////// 快捷商店界面时,按下某个键的操作 ////// events.prototype.keyDownQuickShop = function (keycode) { var shopList = core.status.shops, keys = Object.keys(shopList); if (keycode==38) { @@ -1006,6 +1012,7 @@ events.prototype.keyDownQuickShop = function (keycode) { } } +////// 快捷商店界面时,放开某个键的操作 ////// events.prototype.keyUpQuickShop = function (keycode) { if (keycode==27 || keycode==75 || keycode==88) { core.ui.closePanel(); @@ -1019,11 +1026,11 @@ events.prototype.keyUpQuickShop = function (keycode) { return; } -// 工具栏 +////// 工具栏界面时的点击操作 ////// events.prototype.clickToolbox = function(x,y) { // 返回 if (x>=10 && x<=12 && y==12) { - core.ui.closePanel(false); + core.ui.closePanel(); return; } var index=0; @@ -1033,6 +1040,7 @@ events.prototype.clickToolbox = function(x,y) { this.clickToolboxIndex(index); } +////// 选择工具栏界面中某个Index后的操作 ////// events.prototype.clickToolboxIndex = function(index) { var items = null; var ii=index; @@ -1053,6 +1061,7 @@ events.prototype.clickToolboxIndex = function(index) { } } +////// 工具栏界面时,按下某个键的操作 ////// events.prototype.keyDownToolbox = function (keycode) { if (!core.isset(core.status.event.data)) return; @@ -1116,6 +1125,7 @@ events.prototype.keyDownToolbox = function (keycode) { } } +////// 工具栏界面时,放开某个键的操作 ////// events.prototype.keyUpToolbox = function (keycode) { if (keycode==84 || keycode==27 || keycode==88) { core.ui.closePanel(); @@ -1129,7 +1139,7 @@ events.prototype.keyUpToolbox = function (keycode) { } } -// 存读档 +////// 存读档界面时的点击操作 ////// events.prototype.clickSL = function(x,y) { // 上一页 if ((x == 3 || x == 4) && y == 12) { @@ -1141,7 +1151,7 @@ events.prototype.clickSL = function(x,y) { } // 返回 if (x>=10 && x<=12 && y==12) { - core.ui.closePanel(false); + core.ui.closePanel(); if (!core.isPlaying()) { core.showStartAnimate(); } @@ -1162,6 +1172,7 @@ events.prototype.clickSL = function(x,y) { } } +////// 存读档界面时,按下某个键的操作 ////// events.prototype.keyDownSL = function(keycode) { if (keycode==37) { // left core.ui.drawSLPanel(core.status.event.data - 1); @@ -1189,6 +1200,7 @@ events.prototype.keyDownSL = function(keycode) { } } +////// 存读档界面时,放开某个键的操作 ////// events.prototype.keyUpSL = function (keycode) { if (keycode==27 || keycode==88 || (core.status.event.id == 'save' && keycode==83) || (core.status.event.id == 'load' && keycode==68)) { core.ui.closePanel(); @@ -1203,6 +1215,7 @@ events.prototype.keyUpSL = function (keycode) { } } +////// 系统设置界面时的点击操作 ////// events.prototype.clickSwitchs = function (x,y) { if (x<5 || x>7) return; var choices = [ @@ -1256,6 +1269,7 @@ events.prototype.clickSwitchs = function (x,y) { } } +////// 系统设置界面时,按下某个键的操作 ////// events.prototype.keyDownSwitchs = function (keycode) { var choices = [ "背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单" @@ -1272,6 +1286,7 @@ events.prototype.keyDownSwitchs = function (keycode) { } } +////// 系统设置界面时,放开某个键的操作 ////// events.prototype.keyUpSwitchs = function (keycode) { if (keycode==27 || keycode==88) { core.status.event.selection=0; @@ -1288,7 +1303,7 @@ events.prototype.keyUpSwitchs = function (keycode) { } -// 菜单栏 +////// 系统菜单栏界面时的点击事件 ////// events.prototype.clickSettings = function (x,y) { if (x<5 || x>7) return; var choices = [ @@ -1335,6 +1350,7 @@ events.prototype.clickSettings = function (x,y) { return; } +////// 系统菜单栏界面时,按下某个键的操作 ////// events.prototype.keyDownSettings = function (keycode) { var choices = [ "系统设置", "快捷商店", "同步存档", "重新开始", "操作帮助", "关于本塔", "返回游戏" @@ -1351,6 +1367,7 @@ events.prototype.keyDownSettings = function (keycode) { } } +////// 系统菜单栏界面时,放开某个键的操作 ////// events.prototype.keyUpSettings = function (keycode) { if (keycode==27 || keycode==88) { core.ui.closePanel(); @@ -1365,6 +1382,7 @@ events.prototype.keyUpSettings = function (keycode) { } } +////// 同步存档界面时的点击操作 ////// events.prototype.clickSyncSave = function (x,y) { if (x<5 || x>7) return; var choices = [ @@ -1400,6 +1418,7 @@ events.prototype.clickSyncSave = function (x,y) { return; } +////// 同步存档界面时,按下某个键的操作 ////// events.prototype.keyDownSyncSave = function (keycode) { var choices = [ "同步存档到服务器", "从服务器加载存档", "清空本地存档", "返回主菜单" @@ -1416,6 +1435,7 @@ events.prototype.keyDownSyncSave = function (keycode) { } } +////// 同步存档界面时,放开某个键的操作 ////// events.prototype.keyUpSyncSave = function (keycode) { if (keycode==27 || keycode==88) { core.status.event.selection=2; @@ -1431,11 +1451,11 @@ events.prototype.keyUpSyncSave = function (keycode) { } } +////// “关于”界面时的点击操作 ////// events.prototype.clickAbout = function () { if (core.isPlaying()) - core.ui.closePanel(false); + core.ui.closePanel(); else core.showStartAnimate(); } -/*********** 点击事件 END ***************/ diff --git a/libs/floors/MT0.js b/libs/floors/MT0.js index c8d90ad4..fad21c7d 100644 --- a/libs/floors/MT0.js +++ b/libs/floors/MT0.js @@ -8,6 +8,8 @@ main.floors.MT0 = { "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canUseQuickShop": true, // 该层是否允许使用快捷商店 "defaultGround": "ground", // 默认地面的图块ID(terrains中) + // "color": [0,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 + // "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 ], diff --git a/libs/floors/sample0.js b/libs/floors/sample0.js index 1fab84e8..17e80550 100644 --- a/libs/floors/sample0.js +++ b/libs/floors/sample0.js @@ -8,6 +8,8 @@ main.floors.sample0 = { "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canUseQuickShop": true, // 该层是否允许使用快捷商店 "defaultGround": "ground", // 默认地面的图块ID(terrains中) + // "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 + "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 [0, 0, 220, 0, 0, 20, 87, 3, 65, 64, 44, 43, 42], [0, 246, 0, 246, 0, 20, 0, 3, 58, 59, 60, 61, 41], diff --git a/libs/floors/sample1.js b/libs/floors/sample1.js index 3934514b..153b1732 100644 --- a/libs/floors/sample1.js +++ b/libs/floors/sample1.js @@ -8,6 +8,8 @@ main.floors.sample1 = { "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canUseQuickShop": true, // 该层是否允许使用快捷商店 "defaultGround": "grass", // 默认地面的图块ID(terrains中) + // "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 + // "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 "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], diff --git a/libs/floors/sample2.js b/libs/floors/sample2.js index 0dcff5ab..a312ec93 100644 --- a/libs/floors/sample2.js +++ b/libs/floors/sample2.js @@ -8,7 +8,8 @@ main.floors.sample2 = { "canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canUseQuickShop": true, // 该层是否允许使用快捷商店 "defaultGround": "snowGround", // 默认地面的图块ID(terrains中) - "color": [255,0,0,0.3], // 可以设置该层的默认背景色调(RGBA);本项可省略 + "color": [255,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 + "bgm": "qianjin.mid", // 到达该层后默认播放的BGM。本项可忽略。 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 [5, 5, 5, 5, 5, 5, 87, 5, 5, 5, 5, 5, 5], [5, 4, 4, 4, 4, 1, 0, 1, 4, 4, 4, 4, 5], diff --git a/libs/items.js b/libs/items.js index ae21b209..e603d3a4 100644 --- a/libs/items.js +++ b/libs/items.js @@ -2,6 +2,7 @@ function items() { } +////// 初始化 ////// items.prototype.init = function () { this.items = { // 钥匙 @@ -59,7 +60,7 @@ items.prototype.init = function () { } } -// 初始化道具 +////// 获得所有道具 ////// items.prototype.getItems = function () { // 大黄门钥匙?钥匙盒? if (core.flags.bigKeyIsBox) @@ -74,7 +75,7 @@ items.prototype.getItems = function () { main.instance.items = new items(); - +////// “即捡即用类”道具的使用效果 ////// items.prototype.getItemEffect = function(itemId, itemNum) { var itemCls = core.material.items[itemId].cls; // 消耗品 @@ -115,6 +116,7 @@ items.prototype.getItemEffect = function(itemId, itemNum) { } } +////// “即捡即用类”道具的文字提示 ////// items.prototype.getItemEffectTip = function(itemId) { if (itemId === 'redJewel') return ",攻击+"+core.values.redJewel; if (itemId === 'blueJewel') return ",防御+"+core.values.blueJewel; @@ -140,14 +142,12 @@ items.prototype.getItemEffectTip = function(itemId) { return ""; } - - +////// 使用道具 ////// items.prototype.useItem = function (itemId) { - // 使用道具 if (!this.canUseItem(itemId)) return; var itemCls = core.material.items[itemId].cls; - if (itemId=='book') core.ui.drawEnemyBook(0); + if (itemId=='book') core.ui.drawBook(0); if (itemId=='fly') core.ui.drawFly(core.status.hero.flyRange.indexOf(core.status.floorId)); if (itemId == 'earthquake' || itemId == 'bomb' || itemId == 'pickaxe' || itemId=='icePickaxe' || itemId == 'snow' || itemId == 'hammer' || itemId=='bigKey') { @@ -198,12 +198,11 @@ items.prototype.useItem = function (itemId) { delete core.status.hero.items[itemCls][itemId]; } +////// 当前能否使用道具 ////// items.prototype.canUseItem = function (itemId) { // 没有道具 if (!core.hasItem(itemId)) return false; - var itemCls = core.material.items[itemId].cls; - if (itemId == 'book') return true; if (itemId == 'fly') return core.status.hero.flyRange.indexOf(core.status.floorId)>=0; if (itemId == 'pickaxe') { diff --git a/libs/maps.js b/libs/maps.js index 0557f07a..6c9e8453 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -1,6 +1,7 @@ function maps() {} maps.prototype.init = function() {} +////// 加载某个楼层(从剧本或存档中) ////// maps.prototype.loadFloor = function (floorId, map) { var floor = core.floors[floorId]; var content = {}; @@ -44,6 +45,7 @@ maps.prototype.loadFloor = function (floorId, map) { return content; } +////// 数字和ID的对应关系 ////// maps.prototype.getBlock = function (x, y, id) { var enable=null; id = ""+id; @@ -80,11 +82,11 @@ maps.prototype.getBlock = function (x, y, id) { if (id == 14) tmp.event = {'cls': 'animates', 'id': 'curseNet', 'noPass': false, 'trigger': 'passNet'}; // 咒网 if (id == 15) tmp.event = {'cls': 'animates', 'id': 'water', 'noPass': true}; // 水 // 在这里添加更多地形 - // 如果空地不足,可以从180以后开始继续放,只要不和现有的数字冲突即可 + // 如果空位不足,可以从180以后开始继续放,只要不和现有的数字冲突即可 // Autotile if (id == 20) tmp.event = {'cls': 'autotile', 'id': 'autotile', 'noPass': true}; // autotile - // 更多的autotile从151到160,只要不和现有的数字冲突即可 + // 更多的autotile从151到160等,只要不和现有的数字冲突即可 if (id == 151) tmp.event = {'cls': 'autotile', 'id': 'autotile1', 'noPass': true}; if (id == 152) tmp.event = {'cls': 'autotile', 'id': 'autotile2', 'noPass': true}; if (id == 153) tmp.event = {'cls': 'autotile', 'id': 'autotile3', 'noPass': true}; @@ -256,6 +258,7 @@ maps.prototype.getBlock = function (x, y, id) { return tmp; } +////// 向该楼层添加剧本的自定义事件 ////// maps.prototype.addEvent = function (block, x, y, event, ground) { if (!core.isset(event)) return; if (!core.isset(block.event)) { // 本身是空地? @@ -291,11 +294,13 @@ maps.prototype.addEvent = function (block, x, y, event, ground) { } } +////// 向该楼层添加剧本的楼层转换事件 ////// maps.prototype.addChangeFloor = function (block, x, y, event, ground) { if (!core.isset(event)) return; this.addEvent(block, x, y, {"trigger": "changeFloor", "data": event}, ground); } +////// 初始化所有地图 ////// maps.prototype.initMaps = function (floorIds) { var maps = {}; for (var i=0;i', 270, top+height-13, '#CCCCCC', '13px Verdana'); } -// 绘制选项事件 +////// 绘制一个选项界面 ////// ui.prototype.drawChoices = function(content, choices) { var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); @@ -273,12 +263,7 @@ ui.prototype.drawChoices = function(content, choices) { return; } -/** - * 绘制确认/取消警告 - * @param text - * @param yesCallback - * @param noCallback - */ +////// 绘制一个确认/取消的警告页面 ////// ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { core.lockControl(); @@ -327,10 +312,8 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { } -////// 绘制开关界面 ////// +////// 绘制系统设置界面 ////// ui.prototype.drawSwitchs = function() { - // 背景音乐、背景音效、战斗动画、怪物显伤、领域显伤、返回 - core.status.event.id = 'switchs'; var choices = [ @@ -345,10 +328,7 @@ ui.prototype.drawSwitchs = function() { } -/** - * 绘制菜单栏 - * @param need - */ +////// 绘制系统菜单栏 ////// ui.prototype.drawSettings = function (need) { if (!core.checkStatus('settings', need)) return; @@ -358,6 +338,7 @@ ui.prototype.drawSettings = function (need) { ]); } +////// 绘制快捷商店选择栏 ////// ui.prototype.drawQuickShop = function (need) { if (core.isset(need) && !core.checkStatus('selectShop', need)) return; @@ -374,7 +355,7 @@ ui.prototype.drawQuickShop = function (need) { this.drawChoices(null, choices); } - +////// 绘制战斗动画 ////// ui.prototype.drawBattleAnimate = function(monsterId, callback) { // UI层 @@ -662,10 +643,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { }, 500); } -/** - * 绘制“请等候...” - * @param text - */ +////// 绘制等待界面 ////// ui.prototype.drawWaiting = function(text) { core.lockControl(); @@ -685,9 +663,7 @@ ui.prototype.drawWaiting = function(text) { } -/** - * 绘制“存档同步”选项 - */ +////// 绘制存档同步界面 ////// ui.prototype.drawSyncSave = function () { core.status.event.id = 'syncSave'; @@ -698,11 +674,7 @@ ui.prototype.drawSyncSave = function () { } -/** - * 绘制“分页” - * @param page - * @param totalPage - */ +////// 绘制分页 ////// ui.prototype.drawPagination = function (page, totalPage) { core.setFont('ui', 'bold 15px Verdana'); @@ -724,11 +696,8 @@ ui.prototype.drawPagination = function (page, totalPage) { } -/** - * 绘制怪物手册 - * @param index 怪物索引 - */ -ui.prototype.drawEnemyBook = function (index) { +////// 绘制怪物手册 ////// +ui.prototype.drawBook = function (index) { var enemys = core.enemys.getCurrentEnemys(); var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); @@ -844,6 +813,7 @@ ui.prototype.drawEnemyBook = function (index) { this.drawPagination(page, totalPage); } +////// 绘制怪物属性的详细信息 ////// ui.prototype.drawBookDetail = function (index) { var enemys = core.enemys.getCurrentEnemys(); if (enemys.length==0) return; @@ -906,10 +876,7 @@ ui.prototype.drawBookDetail = function (index) { core.fillText('data', '<点击任意位置继续>', 270, top+height-13, '#CCCCCC', '13px Verdana'); } -/** - * 绘制楼传器 - * @param page - */ +////// 绘制楼层传送器 ////// ui.prototype.drawFly = function(page) { if (page<0) page=0; @@ -935,6 +902,7 @@ ui.prototype.drawFly = function(page) { this.drawThumbnail(floorId, 'ui', core.status.maps[floorId].blocks, 20, 100, 273); } +////// 绘制道具栏 ////// ui.prototype.drawToolbox = function(index) { var tools = Object.keys(core.status.hero.items.tools).sort(); @@ -1049,7 +1017,7 @@ ui.prototype.drawToolbox = function(index) { core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px Verdana'); } - +////// 绘制存档/读档界面 ////// ui.prototype.drawSLPanel = function(index) { if (!core.isset(index)) index=1; if (index<=0) index=1; @@ -1103,6 +1071,7 @@ ui.prototype.drawSLPanel = function(index) { this.drawPagination(page+1, 30); } +////// 绘制一个缩略图 ////// ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroLoc) { core.clearMap(canvas, x, y, size, size); var groundId = core.floors[floorId].defaultGround || "ground"; @@ -1140,9 +1109,7 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL } } -/** - * 绘制"关于" - */ +////// 绘制“关于”界面 ////// ui.prototype.drawAbout = function() { if (!core.isPlaying()) { @@ -1168,18 +1135,9 @@ ui.prototype.drawAbout = function() { core.fillText('ui', "作者: 艾之葵", text_start, top + 80, "#FFFFFF", "bold 17px Verdana"); core.fillText('ui', 'HTML5魔塔交流群:539113091', text_start, top+112); // TODO: 写自己的“关于”页面 - /* - core.fillText('ui', "原作: ss433_2", text_start, top + 112, "#FFFFFF", "bold 17px Verdana"); - core.fillText('ui', "制作工具: WebStorm", text_start, top + 144, "#FFFFFF", "bold 17px Verdana"); - core.fillText('ui', "测试平台: Chrome/微信/iOS", text_start, top + 176, "#FFFFFF", "bold 17px Verdana"); - core.fillText('ui', '特别鸣谢: ss433_2', text_start, top+208); - var len = core.canvas.ui.measureText('特别鸣谢: ').width; - core.fillText('ui', 'iEcho', text_start+len, top+240); - core.fillText('ui', '打Dota的喵', text_start+len, top+272); - core.fillText('ui', 'HTML5魔塔交流群:539113091', text_start, top+304); - */ } +////// 绘制帮助页面 ////// ui.prototype.drawHelp = function () { core.drawText([ "\t[键盘快捷键列表]"+ diff --git a/更新说明.txt b/更新说明.txt index 83a62ff8..6437085b 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,4 +1,5 @@ 全键盘操作 √ +便捷PS工具支持更改图片色相 √ 经验升级(进阶) √ 增加阻击、多连击等属性;属性显示;加点; √ 九宫格领域、大范围领域 √ From 7b3d37ee60624041554ad00b7ce8a2a2d462719e Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 31 Dec 2017 01:38:58 +0800 Subject: [PATCH 02/11] Update V1.3 --- .../autotile1.png | Bin 0 -> 2896 bytes .../autotile2.png | Bin 0 -> 7481 bytes .../autotile3.png | Bin 0 -> 3829 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/常用素材:如需使用请直接替换目录中的对应文件/autotile1.png create mode 100644 images/常用素材:如需使用请直接替换目录中的对应文件/autotile2.png create mode 100644 images/常用素材:如需使用请直接替换目录中的对应文件/autotile3.png diff --git a/images/常用素材:如需使用请直接替换目录中的对应文件/autotile1.png b/images/常用素材:如需使用请直接替换目录中的对应文件/autotile1.png new file mode 100644 index 0000000000000000000000000000000000000000..2dacd883d751939559351f12edec3c7d264fbd5a GIT binary patch literal 2896 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 NVPtUm0$blP@;|E8VTb?# literal 0 HcmV?d00001 From bb479f04eec0542c46293c97fce31155827675ee Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 31 Dec 2017 01:41:48 +0800 Subject: [PATCH 03/11] Update V1.3 --- docs/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.html b/docs/index.html index e445274a..8065a5e4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2,7 +2,7 @@ - + HTML5魔塔样板 @@ -15,7 +15,7 @@ window.$docsify = { homepage: 'index.md', loadSidebar: true, - name: 'H5魔塔样板', + name: 'HTML5魔塔样板', repo: 'https://github.com/ckcz123/mota-js', // basepath: '../docs/', From d695380d1a3ea90a03d4f62f4b79d55348d90d68 Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 31 Dec 2017 01:44:24 +0800 Subject: [PATCH 04/11] Update V1.3 --- 更新说明.txt | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/更新说明.txt b/更新说明.txt index 6437085b..e1b02558 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,13 +1,39 @@ -全键盘操作 √ -便捷PS工具支持更改图片色相 √ -经验升级(进阶) √ -增加阻击、多连击等属性;属性显示;加点; √ -九宫格领域、大范围领域 √ -Ctrl快速跳过对话 √ -增加负伤 √ -背景音乐 √ -支持不同层使用不同的地面素材 √ -支持多个Autotile同时存在 √ -直接内嵌了诸多默认的terrains素材 √ -自动定位到上次存/读档位置 √ -每一层可以默认色调 √ +HTML5魔塔样板V1.3: + +支持全键盘操作。 +便捷PS工具支持更改图片色相。 +支持经验升级(进阶/境界塔)。 +打败怪物可以进行加点(加点塔)。 +增加阻击、N连击等属性;在怪物手册有属性显示。 +支持九宫格领域和大范围领域。 +增加负伤。 +支持各种BGM的播放。 +支持不同层使用不同的地面素材;支持多个Autotile同时存在 √ +许多细节进行了优化,一些已知的Bug进行了修复。 + +----------------------------------------------------------------------- + +HTML5魔塔样板V1.2: + +新增:本地HTTP服务器。 +新增:可视化地图编辑工具。 +新增:便捷PS工具。 +移除了meaning.txt,现在“地图生成器”将直接从js文件中读取数字和图块对应关系。 +新增:对Autotile图块的支持。 +新增:怪物支持多种属性;添加仇恨属性。 +移除了不再支持的checkBlock,现在对于领域和夹击无需再手动指定可能的点了。 +新增:单向箭头、感叹号(单次通行)的支持。 +新增:更多的默认素材,现在对于大多数地图风格无需P图,直接替换即可。 +添加部分自定义事件,部分细节优化,一些已知的Bug进行了修复。 + +----------------------------------------------------------------------- + +HTML5魔塔样板V1.1: + +新增:战斗过程显示,可以在设置中关闭 +新增:勇士支持48*32(大图)的行走图 +新增:更改画面色调 +新增:文字显示支持自动换行 +部分修改状态栏UI +增添Web的Markdown文档,移除原本的doc和pdf文档。 +修复若干Bug。 From 8979c1ddcf0350e7ac92624ff80dbf77e561c86b Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 31 Dec 2017 01:45:28 +0800 Subject: [PATCH 05/11] Update V1.3 --- README.md | 2 +- 更新说明.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 36fb01bf..68a5c0d2 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! * [x] 支持九宫格领域和大范围领域。 * [x] 增加负伤。 * [x] 支持各种BGM的播放。 -* [x] 支持不同层使用不同的地面素材;支持多个Autotile同时存在 √ +* [x] 支持不同层使用不同的地面素材;支持多个Autotile同时存在。 * [x] 许多细节进行了优化,一些已知的Bug进行了修复。 ### 2017.12.21 V1.2 diff --git a/更新说明.txt b/更新说明.txt index e1b02558..a1f801b8 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -8,7 +8,7 @@ 支持九宫格领域和大范围领域。 增加负伤。 支持各种BGM的播放。 -支持不同层使用不同的地面素材;支持多个Autotile同时存在 √ +支持不同层使用不同的地面素材;支持多个Autotile同时存在。 许多细节进行了优化,一些已知的Bug进行了修复。 ----------------------------------------------------------------------- From 334e215009950c98f95a2aafaea8117e29bcc155 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Sun, 31 Dec 2017 14:58:35 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E8=87=AA=E5=B7=B1=E7=9A=84=E5=9B=BE=E7=89=87=E7=B4=A0=E6=9D=90?= =?UTF-8?q?=E4=BD=9C=E4=B8=BA=E8=83=8C=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/core.js | 62 +++++++++++++++++++++++++++++------------- libs/floors/MT0.js | 1 + libs/floors/sample0.js | 1 + libs/floors/sample1.js | 1 + libs/floors/sample2.js | 1 + libs/maps.js | 12 +++++--- libs/ui.js | 17 ++++++++++-- main.js | 54 ++++++++++++++++++++---------------- 8 files changed, 100 insertions(+), 49 deletions(-) diff --git a/libs/core.js b/libs/core.js index cef47e25..a8419715 100644 --- a/libs/core.js +++ b/libs/core.js @@ -7,6 +7,7 @@ function core() { this.statusBar = {}; this.canvas = {}; this.images = []; + this.pngs = []; this.bgms = []; this.sounds = []; this.floorIds = []; @@ -105,11 +106,12 @@ function core() { /////////// 系统事件相关 /////////// ////// 初始化 ////// -core.prototype.init = function (dom, statusBar, canvas, images, bgms, sounds, floorIds, floors, coreData) { +core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, sounds, floorIds, floors, coreData) { core.dom = dom; core.statusBar = statusBar; core.canvas = canvas; core.images = images; + core.pngs = pngs; core.bgms = bgms; core.sounds = sounds; core.floorIds = floorIds; @@ -138,8 +140,6 @@ core.prototype.init = function (dom, statusBar, canvas, images, bgms, sounds, fl core.material.icons = core.icons.getIcons(); core.material.events = core.events.getEvents(); - - if (location.protocol.indexOf("http")==0) { window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext; try { @@ -259,18 +259,29 @@ core.prototype.loader = function (callback) { core.setStartLoadTipText(imgName + ' 加载完毕...'); core.setStartProgressVal(loadedImageNum * (100 / allImageNum)); if (loadedImageNum == allImageNum) { - - // 加载Autotile - core.material.images.autotile={}; - var autotileIds = Object.keys(core.material.icons.autotile); - for (var x=0;x Date: Sun, 31 Dec 2017 15:25:45 +0800 Subject: [PATCH 07/11] Update Doc --- docs/event.md | 28 ++++++++++++++++++++++++++-- docs/personalization.md | 36 +++++++++++++++++++++++++++++++++++- images/yewai.png | Bin 0 -> 39551 bytes main.js | 2 +- 4 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 images/yewai.png diff --git a/docs/event.md b/docs/event.md index a1525c3c..2f283b69 100644 --- a/docs/event.md +++ b/docs/event.md @@ -29,6 +29,7 @@ "x,y": { "trigger": "action", // 触发的trigger, action代表自定义事件 "enable": true, // 该事件初始状态下是否处于启用状态 + "noPass": true, // 该点是否不可通行。true代表不可通行,false代表可通行。 "data": [ // 实际执行的事件列表 // 事件1 // 事件2 @@ -53,6 +54,7 @@ "x,y": { // 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略 "enable": true, // 该事件初始状态下是否处于启用状态 + "noPass": true, // 该点是否不可通行。true代表不可通行,false代表可通行。 "data": [ // 实际执行的事件列表 // 事件1 // 事件2 @@ -71,6 +73,28 @@ "x,y": { // 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略 // 该事件初始状态下是启用状态,则可以省略"enable": true;如果是禁用状态则必须加上"enable": false + "noPass": true, // 该点是否不可通行。true代表不可通行,false代表可通行。 + "data": [ // 实际执行的事件列表 + // 事件1 + // 事件2 + // ... + ] + } +} +``` + +`"noPass"`为该点是否可通行的标记。`true`代表该点不可通行,`false`代表该点可通行。 + +对于目前所有的素材,都存在默认的是否可通行状态。如果你在该点指定`noPass`,则原本的可通行状态会被覆盖。 + +因此,除非你想覆盖默认的可通行选项(比如将一个空地设为不可通行),否则该项可以忽略。 + +``` js +"events": { // 该楼的所有可能事件列表 + "x,y": { + // 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略 + // 该事件初始状态下是启用状态,则可以省略"enable": true;如果是禁用状态则必须加上"enable": false + // 除非你想覆盖系统默认的可通行状态,否则"noPass"项可以忽略 "data": [ // 实际执行的事件列表 // 事件1 // 事件2 @@ -86,7 +110,7 @@ ``` js "events": { // 该楼的所有可能事件列表 - // 如果大括号里只有"data"项(没有"action"或"enable"),则可以省略到只剩下中括号 + // 如果大括号里只有"data"项(没有"action", "enable"或"noPass"),则可以省略到只剩下中括号 "x,y": [ // 实际执行的事件列表 // 事件1 // 事件2 @@ -97,7 +121,7 @@ 这种简写方式可以极大方便地造塔者进行造塔。 -!> **请注意:如果该点初始的`enable`为`false`,或者该点本身有系统默认事件且需要覆盖(`trigger`),则必须采用上面那种大括号写的方式来定义。** +!> **请注意:如果该点初始的`enable`为`false`,或者该点本身有系统默认事件且需要覆盖(`trigger`),或者你想覆盖该点的默认通行状态,则必须采用上面那种大括号写的方式来定义。**   diff --git a/docs/personalization.md b/docs/personalization.md index d63c4883..8e5eca3f 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -21,6 +21,41 @@ 如果你需要某个素材已经存在,则可以直接将其覆盖images目录下的同名文件,就能看到效果。 +### 使用自己的图片作为某层楼的背景素材 + +由于HTML5功能(素材)有限,导致了对很多比较复杂的素材(比如房子内)等无法有着较好的绘图方式。 + +为了解决这个问题,我们允许用户自己放置一张图片作为某一层的背景素材。 + +要启用这个功能,我们首先需要在`main.js`中将可能的图片进行加载。 + +``` js +this.pngs = [ // 在此存放所有可能的背景图片;背景图片最好是416*416像素,其他分辨率会被强制缩放成416*416 + // 建议对于较大的图片,在网上使用在线的“图片压缩工具”来进行压缩,以节省流量 + "bg.png", // "yewai.png", +]; +``` + +!> 背景素材只支持png格式,且会被强制缩放到416*416。 + +!> 请使用网上的一些[在线图片压缩工具](http://www.asqql.com/gifzip/)对png图片进行压缩,以节省流量。一张500KB的png图片可以被压缩到20-30KB,显示效果不会有太大差异。 + +之后,我们可以在每层剧本的`"png": "xxx"`里来定义该层的默认背景图片素材。 + +``` js +"png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。 +``` + +你的图片背景素材将会覆盖原来本身的背景层。 + +**如果你需要让某些点不可通行(比如你建了个房子,墙壁和家具等位置不让通行),则需在`events`中指定`{"noPass": false}`,参见[自定义事件](event#自定义事件)的写法。 + +``` js +"events": { + "x,y": {"noPass": true} // (x,y)点不可通行 +} +``` + ### 使用便捷PS工具生成素材 如果我们有更多的素材要求,我们可以使用“便捷PS工具”进行处理。 @@ -52,7 +87,6 @@ 如果需要添加一个素材到游戏,则必须为其分配一个唯一标识符,并同时修改`icons.js`和`maps.js`两个文件。 - #### 新添加自定义地形(路面、墙壁等) 如果你在terrains.png中新增了一行: diff --git a/images/yewai.png b/images/yewai.png new file mode 100644 index 0000000000000000000000000000000000000000..ca42c6186c375e71f86f37486300b529753785d4 GIT binary patch literal 39551 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 Date: Sun, 31 Dec 2017 15:27:57 +0800 Subject: [PATCH 08/11] Update Doc --- README.md | 2 ++ 更新说明.txt | 1 + 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index 68a5c0d2..bf22c60d 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! │ └─ *.png # 对应的某个具体的图片素材 ├── /libs/ # JS源代码目录 │ ├─ /floors/ # 剧本文件,记录了每个地图的数据和事件 +│ ├─ /thirdparty/ # 游戏所用到的第三方库文件 │ ├─ core.js # 系统核心文件 │ ├─ data.js # 记录了勇士的初始化信息、各个全局变量和全局Flag值 │ ├─ enemys.js # 记录了怪物的信息,包括怪物的数据和特殊属性、伤害计算公式、临界值计算等。 @@ -47,6 +48,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ### 2017.12.31 V1.3 * [x] 支持全键盘操作。 +* [x] 支持将某个图片作为某层的背景素材。 * [x] 便捷PS工具支持更改图片色相。 * [x] 支持经验升级(进阶/境界塔)。 * [x] 打败怪物可以进行加点(加点塔)。 diff --git a/更新说明.txt b/更新说明.txt index a1f801b8..6ee14efa 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,6 +1,7 @@ HTML5魔塔样板V1.3: 支持全键盘操作。 +支持将某个图片作为某层的背景素材。 便捷PS工具支持更改图片色相。 支持经验升级(进阶/境界塔)。 打败怪物可以进行加点(加点塔)。 From 81727e1e712093b3121278659cd183705f487183 Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 31 Dec 2017 16:25:49 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E6=88=98=E5=89=8D=E5=89=A7=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/event.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ libs/core.js | 18 +++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/docs/event.md b/docs/event.md index 2f283b69..08d0fe91 100644 --- a/docs/event.md +++ b/docs/event.md @@ -965,6 +965,54 @@ events.prototype.addPoint = function (enemy) { 当且仅当勇士第一次到达某层时,将会触发此事件。可以利用此事件来显示一些剧情,或再让它调用 `{"type": "trigger"}` 来继续调用其他的事件。 +## 战前剧情 + +有时候光战后事件`afterBattle`是不够的,我们可能还需要战前剧情,例如Boss战之前和Boss进行一段对话。 + +要使用战前剧情,首先你需要覆盖该店的系统默认事件,改成你自己的自定义事件,然后在战前剧情后调用`{"type": "battle"}`强制战斗。 + +``` js +"x,y": { // (x,y)为该怪物坐标 + "trigger": "action", // 覆盖该点本身默认事件,变成自定义事件 + "data": [ // 该点的自定义事件列表 + // ... 战前剧情 + {"type": "battle", "id": "xxx"}, // 强制战斗 + // ... 战后剧情;请注意上面的强制战斗不会使怪物消失,如有需要请调动{"type": "hide"} + ] +} +``` + +这种方式可以实现战前剧情。 + +**值得注意的是,如果一个怪物本身的系统默认事件被覆盖,则地图上也不会有显伤!** + +要想让被自定义事件覆盖的怪物也有显伤显示,则需要在`core.js`的`updateFg`函数中进行一些的修改: + +``` js +// ... 上略 + +// 非系统默认的战斗事件(被覆盖):无显伤 +if (mapBlocks[b].event.trigger != 'battle') { + + var shouldDisplayDamage = false; + + // 部分特殊的点(例如战前剧情)需要显伤的可类似在这里手动添加 + /* + if (core.status.floorId='???' && x=? && y=?) + shouldDisplayDamage = true; + */ + + if (!shouldDisplayDamage) + continue; +} + +// ... 下略 +``` + +即手动指定一下哪些层的哪些点上被覆盖的怪物也需要显伤。 + +!> 如果想让所有怪物都有显伤,也可以简单直接删除或注释这一段。 + ## 经验升级(进阶/境界塔) 本塔也支持经验升级,即用户杀怪获得经验后,可以到达某些数值自动进阶,全面提升属性。 diff --git a/libs/core.js b/libs/core.js index a8419715..1e3956fa 100644 --- a/libs/core.js +++ b/libs/core.js @@ -2876,8 +2876,24 @@ core.prototype.updateFg = function () { core.canvas.fg.textAlign = 'left'; for (var b = 0; b < mapBlocks.length; b++) { var x = mapBlocks[b].x, y = mapBlocks[b].y; - if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls == 'enemys' && mapBlocks[b].event.trigger == 'battle' + if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls == 'enemys' && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)) { + + // 非系统默认的战斗事件(被覆盖):无显伤 + if (mapBlocks[b].event.trigger != 'battle') { + + var shouldDisplayDamage = false; + + // 部分特殊的点(例如战前剧情)需要显伤的可类似在这里手动添加 + /* + if (core.status.floorId='???' && x=? && y=?) + shouldDisplayDamage = true; + */ + + if (!shouldDisplayDamage) + continue; + } + var id = mapBlocks[b].event.id; var damage = core.enemys.getDamage(id); From e1fdfa3da5f3a1ba858fe05a0e9fdf8071abdfe6 Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 31 Dec 2017 16:54:58 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E6=88=98=E5=89=8D=E5=89=A7=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/event.md | 31 +++---------------------------- libs/core.js | 19 +++++++------------ libs/floors/sample2.js | 24 ++++++++++++++++++++---- 3 files changed, 30 insertions(+), 44 deletions(-) diff --git a/docs/event.md b/docs/event.md index 08d0fe91..c82682f9 100644 --- a/docs/event.md +++ b/docs/event.md @@ -971,9 +971,12 @@ events.prototype.addPoint = function (enemy) { 要使用战前剧情,首先你需要覆盖该店的系统默认事件,改成你自己的自定义事件,然后在战前剧情后调用`{"type": "battle"}`强制战斗。 +值得注意的是,使用这种自定义事件来覆盖系统的默认战斗事件时,可以增加`displayDamage`代表该点是否需要显伤。此项可省略,默认为有显伤。 + ``` js "x,y": { // (x,y)为该怪物坐标 "trigger": "action", // 覆盖该点本身默认事件,变成自定义事件 + "displayDamage": true, // 覆盖后,该点是否有显伤;此项可忽略,默认为有。 "data": [ // 该点的自定义事件列表 // ... 战前剧情 {"type": "battle", "id": "xxx"}, // 强制战斗 @@ -982,34 +985,6 @@ events.prototype.addPoint = function (enemy) { } ``` -这种方式可以实现战前剧情。 - -**值得注意的是,如果一个怪物本身的系统默认事件被覆盖,则地图上也不会有显伤!** - -要想让被自定义事件覆盖的怪物也有显伤显示,则需要在`core.js`的`updateFg`函数中进行一些的修改: - -``` js -// ... 上略 - -// 非系统默认的战斗事件(被覆盖):无显伤 -if (mapBlocks[b].event.trigger != 'battle') { - - var shouldDisplayDamage = false; - - // 部分特殊的点(例如战前剧情)需要显伤的可类似在这里手动添加 - /* - if (core.status.floorId='???' && x=? && y=?) - shouldDisplayDamage = true; - */ - - if (!shouldDisplayDamage) - continue; -} - -// ... 下略 -``` - -即手动指定一下哪些层的哪些点上被覆盖的怪物也需要显伤。 !> 如果想让所有怪物都有显伤,也可以简单直接删除或注释这一段。 diff --git a/libs/core.js b/libs/core.js index 1e3956fa..51df3aa5 100644 --- a/libs/core.js +++ b/libs/core.js @@ -2879,19 +2879,14 @@ core.prototype.updateFg = function () { if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls == 'enemys' && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)) { - // 非系统默认的战斗事件(被覆盖):无显伤 + // 非系统默认的战斗事件(被覆盖) if (mapBlocks[b].event.trigger != 'battle') { - - var shouldDisplayDamage = false; - - // 部分特殊的点(例如战前剧情)需要显伤的可类似在这里手动添加 - /* - if (core.status.floorId='???' && x=? && y=?) - shouldDisplayDamage = true; - */ - - if (!shouldDisplayDamage) - continue; + // 判断显伤 + var event = core.floors[core.status.floorId].events[x+","+y]; + if (core.isset(event) && !(event instanceof Array)) { + if (core.isset(event.displayDamage) && !event.displayDamage) + continue; + } } var id = mapBlocks[b].event.id; diff --git a/libs/floors/sample2.js b/libs/floors/sample2.js index acb6b881..5e440aa4 100644 --- a/libs/floors/sample2.js +++ b/libs/floors/sample2.js @@ -202,10 +202,26 @@ main.floors.sample2 = { {"type": "trigger", "loc": [6,6]} // 立刻触发妖精事件 ] }, - "4,3": {"trigger":"action","enable":false}, // 四个角的大法师,添加trigger:action可避免该点出现显伤 - "8,3": {"trigger":"action","enable":false}, // 四个角的大法师 - "4,6": {"trigger":"action","enable":false}, // 四个角的大法师 - "8,6": {"trigger":"action","enable":false}, // 四个角的大法师 + "4,3": { // 四个角的大法师, + "trigger": "action", + "displayDamage": false, + "enable":false + }, + "8,3": { // 四个角的大法师, + "trigger": "action", + "displayDamage": false, + "enable":false + }, + "4,6": { // 四个角的大法师, + "trigger": "action", + "displayDamage": false, + "enable":false + }, + "8,6": { // 四个角的大法师, + "trigger": "action", + "displayDamage": false, + "enable":false + }, "6,6": { // 妖精 "enable":false, // 初始时禁用状态 From bfda12df04a3fb61ce8a10a6b5fca8bee8e8e1f2 Mon Sep 17 00:00:00 2001 From: Zhang Chen Date: Sun, 31 Dec 2017 17:04:48 +0800 Subject: [PATCH 11/11] Update event.md --- docs/event.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/event.md b/docs/event.md index c82682f9..b1ec932b 100644 --- a/docs/event.md +++ b/docs/event.md @@ -985,9 +985,6 @@ events.prototype.addPoint = function (enemy) { } ``` - -!> 如果想让所有怪物都有显伤,也可以简单直接删除或注释这一段。 - ## 经验升级(进阶/境界塔) 本塔也支持经验升级,即用户杀怪获得经验后,可以到达某些数值自动进阶,全面提升属性。