Update V1.3

This commit is contained in:
oc 2017-12-31 01:35:21 +08:00
parent 2d9278f8f6
commit a58067cd6a
21 changed files with 824 additions and 496 deletions

View File

@ -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] 新增本地HTTP服务器。
* [x] 新增:可视化地图编辑工具。 * [x] 新增:可视化地图编辑工具。
@ -57,7 +70,7 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
* [x] 新增更多的默认素材现在对于大多数地图风格无需P图直接替换即可。 * [x] 新增更多的默认素材现在对于大多数地图风格无需P图直接替换即可。
* [x] 添加部分自定义事件部分细节优化一些已知的Bug进行了修复。 * [x] 添加部分自定义事件部分细节优化一些已知的Bug进行了修复。
### 2017.12.16 ### 2017.12.16 V1.1
* [x] 新增:战斗过程显示,可以在设置中关闭 * [x] 新增:战斗过程显示,可以在设置中关闭
* [x] 新增勇士支持48*32大图的行走图 * [x] 新增勇士支持48*32大图的行走图
@ -67,7 +80,7 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
* [x] 增添Web的Markdown文档移除原本的doc和pdf文档。 * [x] 增添Web的Markdown文档移除原本的doc和pdf文档。
* [x] 修复若干Bug。 * [x] 修复若干Bug。
### 2017.12.9 ### 2017.12.9 V1.0
* [x] 发布初版HTML5魔塔样板 * [x] 发布初版HTML5魔塔样板

View File

@ -4,32 +4,39 @@
可以在chrome浏览器的控制台中`ctrl+shift+I`找到Console中直接进行调用以查看效果。 可以在chrome浏览器的控制台中`ctrl+shift+I`找到Console中直接进行调用以查看效果。
!> **`main.js`游戏入口。所有其他JS文件都是被此文件加载。**
``` js
```
!> **`core.js`:系统核心文件。所有核心逻辑处理都在此文件完成。** !> **`core.js`:系统核心文件。所有核心逻辑处理都在此文件完成。**
``` js ``` js
* core.status.floorId // 获得当前层floorId * core.status.floorId // 获得当前层floorId
* core.status.thisMap // 获得当前层的地图信息 * core.status.thisMap // 获得当前层的地图信息
* core.status.maps // 获得所有楼层的地图信息
* core.floors // 获得所有楼层的剧本
// ------ 初始化部分 ------ // ------ 初始化部分 ------
core.init // 初始化 core.init // 初始化
core.showStartAnimate // 显示开始界面 core.showStartAnimate // 显示游戏开始界面
core.hideStartAnimate // 隐藏开始界面 core.hideStartAnimate // 隐藏游戏开始界面
core.setStartProgressVal // 设置加载进度条进度 core.setStartProgressVal // 设置加载进度条进度
core.setStartLoadTipText // 设置加载进度条提示文字 core.setStartLoadTipText // 设置加载进度条提示文字
core.loader // 加载图片和音频 core.loader // 加载图片和音频
core.loadImage // 加载图片 core.loadImage // 加载图片
core.loadSound // 加载音频 core.loadMusic // 加载音频
core.loadSoundItem // 加载某一个音频
core.isPlaying // 游戏是否已经开始 core.isPlaying // 游戏是否已经开始
core.clearStatus // 清除游戏状态和数据 core.clearStatus // 清除游戏状态和数据
core.resetStatus // 重置游戏状态和初始数据 core.resetStatus // 重置游戏状态和初始数据
core.startGame // 具体开始游戏 core.startGame // 开始游戏
* core.restart // 重新开始游戏;此函数将回到标题页面 * core.restart // 重新开始游戏;此函数将回到标题页面
// ------ 键盘、鼠标事件 ------ // ------ 键盘、鼠标事件 ------
core.onKeyDown // 按下某个键时 core.onKeyDown // 按下某个键时
core.onKeyUp // 放开某个键时 core.onKeyUp // 放开某个键时
core.pressKey // 按住某个键不动 core.pressKey // 按住某个键时
core.keyDown // 根据按下键的code来执行一系列操作 core.keyDown // 根据按下键的code来执行一系列操作
core.keyUp // 根据放开键的code来执行一系列操作 core.keyUp // 根据放开键的code来执行一系列操作
core.ondown // 点击(触摸)事件按下时 core.ondown // 点击(触摸)事件按下时
@ -37,14 +44,14 @@ core.onmove // 当在触摸屏上滑动时
core.onup // 当点击(触摸)事件放开时 core.onup // 当点击(触摸)事件放开时
core.getClickLoc // 获得点击事件相对左上角的坐标0到12之间 core.getClickLoc // 获得点击事件相对左上角的坐标0到12之间
core.onclick // 具体点击屏幕上(x,y)点时,执行的操作 core.onclick // 具体点击屏幕上(x,y)点时,执行的操作
core.onmousewheel // 滑动鼠标滚轮时的操作(楼层传送时可用滚轮切换楼层) core.onmousewheel // 滑动鼠标滚轮时的操作
// ------ 自动寻路代码相关 ------ // ------ 自动寻路代码相关 ------
core.clearAutomaticRouteNode // 清除自动寻路路线 core.clearAutomaticRouteNode // 清除自动寻路路线
core.stopAutomaticRoute // 停止自动寻路操作 core.stopAutomaticRoute // 停止自动寻路操作
core.continueAutomaticRoute // 继续剩下的自动寻路操作 core.continueAutomaticRoute // 继续剩下的自动寻路操作
core.clearContinueAutomaticRoute // 清剩下的自动寻路列表 core.clearContinueAutomaticRoute // 清剩下的自动寻路列表
core.setAutomaticRoute // 设置一个自动寻路 core.setAutomaticRoute // 设置自动寻路路线
core.automaticRoute // 自动寻路算法,找寻最优路径 core.automaticRoute // 自动寻路算法,找寻最优路径
core.fillPosWithPoint // 显示离散的寻路点 core.fillPosWithPoint // 显示离散的寻路点
core.clearStepPostfix // 清除已经寻路过的部分 core.clearStepPostfix // 清除已经寻路过的部分
@ -54,13 +61,15 @@ core.stopAutoHeroMove // 停止勇士的自动行走
core.setAutoHeroMove // 设置勇士的自动行走路线 core.setAutoHeroMove // 设置勇士的自动行走路线
core.autoHeroMove // 让勇士开始自动行走 core.autoHeroMove // 让勇士开始自动行走
core.setHeroMoveInterval // 设置行走的效果动画 core.setHeroMoveInterval // 设置行走的效果动画
core.setHeroMoveTriggerInterval // 设置勇士行走过程中对途经事件的触发检测 core.setHeroMoveTriggerInterval // 设置勇士行走过程中对事件的触发检测
* core.turnHero(direction) // 设置勇士的方向转向如果指定了direction则会面向该方向否则执行一个转向操作。 * core.turnHero(direction) // 设置勇士的方向(转向)
core.canMoveHero // 勇士能否前往某方向
core.moveHero // 让勇士开始移动 core.moveHero // 让勇士开始移动
core.eventMoveHero // 使用事件让勇士移动。这个函数将不会触发任何事件。
core.moveOneStep // 每移动一格后执行的事件。中毒时在这里进行扣血判断。 core.moveOneStep // 每移动一格后执行的事件。中毒时在这里进行扣血判断。
core.waitHeroToStop(callback) // 停止勇士的一切行动等待勇士行动结束后再执行callback回调函数。 core.waitHeroToStop(callback) // 停止勇士的一切行动等待勇士行动结束后再执行callback回调函数。
core.stopHero // 停止勇士的移动状态。 core.stopHero // 停止勇士的移动状态。
core.drawHero // 在hero层绘制勇士。 core.drawHero // 绘制勇士。
* core.setHeroLoc(name, value) // 设置勇士的位置。name为”direction”,”x”,”y” * core.setHeroLoc(name, value) // 设置勇士的位置。name为”direction”,”x”,”y”
* core.getHeroLoc(name) // 获得勇士的位置。 * core.getHeroLoc(name) // 获得勇士的位置。
* core.nextX // 获得勇士面对位置的x坐标 * core.nextX // 获得勇士面对位置的x坐标
@ -71,42 +80,49 @@ core.drawHero // 在hero层绘制勇士。
* core.battle(id, x, y, force, callback) // 进行战斗force表示是否强制战斗 * core.battle(id, x, y, force, callback) // 进行战斗force表示是否强制战斗
core.afterBattle // 战斗完毕 core.afterBattle // 战斗完毕
core.trigger(x,y) // 触发x,y点的事件 core.trigger(x,y) // 触发x,y点的事件
* core.changeFloor(floorId, stair, heroLoc, time, callback) // 楼层切换floorId为目标楼层Idstair可指定为上/下楼梯time动画时间 * core.changeFloor(floorId, stair, heroLoc, time, callback) // 楼层切换floorId为目标楼层Idstair可指定为上/下楼梯time动画时间
core.mapChangeAnimate // 实际切换的动画效果 core.mapChangeAnimate // 地图切换动画效果
core.clearMap // 清除地图显示 core.clearMap // 清除地图
core.fillText // 在某个canvas上绘制一段文字 core.fillText // 在某个canvas上绘制一段文字
core.fillRect // 在某个canvas上绘制一个矩形 core.fillRect // 在某个canvas上绘制一个矩形
core.strokeRect // 在某个canvas上绘制一个矩形的边框 core.strokeRect // 在某个canvas上绘制一个矩形的边框
core.drawLine // 在某个canvas上绘制一条线
core.setFont // 设置某个canvas的文字字体 core.setFont // 设置某个canvas的文字字体
core.setLineWidth // 设置某个canvas的线宽度 core.setLineWidth // 设置某个canvas的线宽度
core.saveCanvas // 保存某个canvas状态 core.saveCanvas // 保存某个canvas状态
core.loadCanvas // 读取某个canvas状态 core.loadCanvas // 加载某个canvas状态
core.setStrokeStyle // 设置某个canvas边框属性 core.setStrokeStyle // 设置某个canvas边框属性
core.setAlpha // 设置某个canvas的alpha值 core.setAlpha // 设置某个canvas的alpha值
core.setOpacity // 设置某个canvas的透明度 core.setOpacity // 设置某个canvas的透明度
core.setFillStyle // 设置某个canvas的绘制属性如颜色等 core.setFillStyle // 设置某个canvas的绘制属性如颜色等
* core.drawMap(mapId, callback) // 绘制某张地图。mapId为地图Id绘制完毕将执行callback回调函数。 * core.drawMap(mapId, callback) // 绘制某张地图。mapId为地图Id绘制完毕将执行callback回调函数。
core.drawAutotile // 绘制Autotile
core.drawAutotileBlock // 绘制Autotile的某一块
* core.noPassExists(x,y) // 某个点是否不可通行 * core.noPassExists(x,y) // 某个点是否不可通行
core.noPass // 某个点是否在区域内且不可通行 core.noPass // 某个点是否在区域内且不可通行
* core.npcExists(x,y) // 某个点是否存在NPC * core.npcExists(x,y) // 某个点是否存在NPC
* core.terrainExists(x,y) // 某个点是否存在指定的地形 * core.terrainExists(x,y) // 某个点是否存在指定的地形
* core.stairExists(x,y) // 某个点是否存在楼梯 * core.stairExists(x,y) // 某个点是否存在楼梯
* core.nearStair // 当前位置是否在楼梯边 * core.nearStair // 当前位置是否在楼梯边
* core.enemyExists(x,y) // 某个点是否存在怪物 * core.enemyExists(x,y) // 某个点是否存在(指定的)怪物
* core.getBlock(x, y, floorId, needEnable) // 获得某个点的block。floorId指定目标楼层needEnable如果为false则即使该点的事件处于禁用状态也将被返回否则只有事件启用的点才被返回 * core.getBlock(x, y, floorId, needEnable) // 获得某个点的block。floorId指定目标楼层needEnable如果为false则即使该点的事件处于禁用状态也将被返回否则只有事件启用的点才被返回
core.moveBlock // 显示移动某块的动画,达到{“type”:”move”}的效果 core.moveBlock // 显示移动某块的动画,达到{“type”:”move”}的效果
core.animateBlock // 显示/隐藏某个块时的动画效果 core.animateBlock // 显示/隐藏某个块时的动画效果
core.addBlock // 将某个块从禁用变成启用状态 core.showBlock // 将某个块从禁用变成启用状态
core.removeBlock // 将某个块从启用变成禁用状态 core.removeBlock // 将某个块从启用变成禁用状态
core.removeBlockById // 根据block的索引删除该块 core.removeBlockById // 根据block的索引删除该块
core.removeBlockByIds // 一次性删除多个block core.removeBlockByIds // 一次性删除多个block
core.addGlobalAnimate // 添加一个全局动画 core.addGlobalAnimate // 添加一个全局动画
core.removeGlobalAnimate // 删除一个或所有全局动画 core.removeGlobalAnimate // 删除一个或所有全局动画
core.setGlobalAnimate // 设置全局动画的显示效果 core.setGlobalAnimate // 设置全局动画的显示效果
core.syncGlobalAnimate // 同步所有的全局动画效果
core.setBoxAnimate // 显示UI层某个box的动画如怪物手册中怪物的动画 core.setBoxAnimate // 显示UI层某个box的动画如怪物手册中怪物的动画
core.drawBoxAnimate // 绘制UI层的box动画 core.drawBoxAnimate // 绘制UI层的box动画
core.setFg // 色调渐变 core.updateCheckBlock // 更新领域、夹击、阻击的伤害地图
* core.updateFg // 更新全地图的显伤 core.checkBlock // 检查并执行领域、夹击、阻击事件
core.snipe // 阻击事件(动画效果)
core.setFg // 更改画面色调
* core.updateFg // 更新全地图显伤
* core.itemCount // 获得某个物品的个数 * core.itemCount // 获得某个物品的个数
* core.hasItem // 是否存在某个物品 * core.hasItem // 是否存在某个物品
* core.setItem // 设置某个物品的个数 * core.setItem // 设置某个物品的个数
@ -114,23 +130,23 @@ core.setFg // 色调渐变
* core.useItem // 使用某个物品直接调用items.js中的useItem函数。 * core.useItem // 使用某个物品直接调用items.js中的useItem函数。
* core.canUseItem // 能否使用某个物品。直接调用items.js中的canUseItem函数。 * core.canUseItem // 能否使用某个物品。直接调用items.js中的canUseItem函数。
* core.addItem // 增加某个物品的个数 * core.addItem // 增加某个物品的个数
* core.getItem // 获得某个物品时的事件 core.getNextItem // 获得面前的物品(轻按)
* core.getItem // 获得某个物品
* core.drawTip // 左上角绘制一段提示 * core.drawTip // 左上角绘制一段提示
* core.drawText // 地图中间绘制一段文字 * core.drawText // 地图中间绘制一段文字
// ------ 系统机制 ------ // ------ 系统机制 ------
core.replaceText // 将文字中的${和}(表达式)进行替换 core.replaceText // 将文字中的${和}(表达式)进行替换
core.calValue // 计算表达式的值 core.calValue // 计算表达式的值
core.splitText // 字符串自动换行的分割 core.doEffect // 执行一个表达式的effect操作
core.splitLines // 字符串自动换行的分割
core.unshift // 向某个数组前插入另一个数组或元素 core.unshift // 向某个数组前插入另一个数组或元素
core.setLocalStorage // 设置本地存储 core.setLocalStorage // 设置本地存储
core.getLocalStorage // 获得本地存储 core.getLocalStorage // 获得本地存储
core.removeLocalStorage // 移除本地存储 core.removeLocalStorage // 移除本地存储
core.clone // 复制一个对象 core.clone // 深拷贝一个对象
core.formatDate // 格式化时间为字符串 core.formatDate // 格式化时间为字符串
core.setTwoDigits // 两位数显示 core.setTwoDigits // 两位数显示
core.win // 获胜将直接调用events.js中的win函数
core.lose // 失败将直接调用events.js中的lose函数
core.debug // 进入Debug模式攻防血和钥匙都调成很高的数值 core.debug // 进入Debug模式攻防血和钥匙都调成很高的数值
core.checkStatus // 判断当前能否进入某个事件 core.checkStatus // 判断当前能否进入某个事件
core.openBook // 点击怪物手册时的打开操作 core.openBook // 点击怪物手册时的打开操作
@ -144,6 +160,7 @@ core.saveData // 存档到本地
core.loadData // 从本地读档 core.loadData // 从本地读档
* core.setStatus // 设置勇士属性 * core.setStatus // 设置勇士属性
* core.getStatus // 获得勇士属性 * core.getStatus // 获得勇士属性
core.getLvName // 获得某个等级的名称
* core.setFlag // 设置某个自定义变量或flag * core.setFlag // 设置某个自定义变量或flag
* core.getFlag // 获得某个自定义变量或flag * core.getFlag // 获得某个自定义变量或flag
* core.hasFlag // 是否存在某个自定义变量或flag且值为true * core.hasFlag // 是否存在某个自定义变量或flag且值为true
@ -151,17 +168,16 @@ core.insertAction // 往当前事件列表之前插入一系列事件
* core.lockControl // 锁定状态栏,常常用于事件处理 * core.lockControl // 锁定状态栏,常常用于事件处理
* core.unlockControl // 解锁状态栏 * core.unlockControl // 解锁状态栏
* core.isset // 判断某对象是否不为undefined也不会null * core.isset // 判断某对象是否不为undefined也不会null
* core.playSound // 播放音频
* core.playBgm // 播放背景音乐 * core.playBgm // 播放背景音乐
core.changeSoundStatus // 切换声音状态 * core.pauseBgm // 暂停背景音乐的播放
core.enableSound // 启用音效 * core.resumeBgm // 恢复背景音乐的播放
core.disableSound // 禁用音效 * core.playSound // 播放音频
core.show // 动画显示某对象 core.show // 动画显示某对象
core.hide // 动画使某对象消失 core.hide // 动画使某对象消失
core.clearStatusBar // 清空状态栏 core.clearStatusBar // 清空状态栏
core.updateStatusBar // 更新状态栏 core.updateStatusBar // 更新状态栏
core.resize // 屏幕分辨率改变后重新自适应 core.resize // 屏幕分辨率改变后重新自适应
core.resetSize // 屏幕分辨率改变后重新自适应 core.domRenderer // 渲染DOM
// ------ core.js 结束 ------ // ------ core.js 结束 ------
``` ```
@ -171,53 +187,105 @@ core.resetSize // 屏幕分辨率改变后重新自适应
!> **`enemys.js` 定义了怪物信息。** !> **`enemys.js` 定义了怪物信息。**
``` 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.getDamage // 获得某个怪物的伤害
* core.enemys.getExtraDamage // 获得某个怪物的额外伤害(吸血) * core.enemys.getExtraDamage // 获得某个怪物的额外伤害
* core.enemys.getCritical // 计算某个怪物的临界值 * core.enemys.getCritical // 临界值计算
* core.enemys.getCriticalDamage // 计算某个怪物的临界减伤 * core.enemys.getCriticalDamage // 临界减伤计算
* core.enemys.getDefDamage // 计算某个怪物的1防减伤 * core.enemys.getDefDamage // 1防减伤计算
* core.enemys.calDamage // 实际的伤害计算公式 * core.enemys.calDamage // 具体的伤害计算公式
core.enemys.getCurrentEnemys // 获得当前层剩下的的怪物列表 core.enemys.getCurrentEnemys // 获得当前层的怪物列表
``` ```
!> **`events.js` 定义了各个事件的处理流程。** !> **`events.js` 定义了各个事件的处理流程。**
``` js ``` js
* core.events.startGame // 开始游戏 core.events.init // 初始化
* core.events.win // 获胜 core.events.getEvents // 获得一个或所有系统事件类型
* core.events.lose // 失败 core.events.startGame // 游戏开始事件
core.events.checkBlock // 检查领域、夹击事件 * core.events.setInitData // 不同难度分别设置初始属性
core.events.afterChangeFloor // 楼层切换结束时的事件 * core.events.win // 游戏获胜事件
* core.events.lose // 游戏失败事件
core.events.afterChangeFloor // 转换楼层结束的事件
core.events.doEvents // 开始执行一系列自定义事件 core.events.doEvents // 开始执行一系列自定义事件
core.events.doAction // 执行当前自定义事件列表中的下一个事件 core.events.doAction // 执行当前自定义事件列表中的下一个事件
core.events.insertAction // 往当前自定义事件列表前插入若干个事件 core.events.insertAction // 往当前事件列表之前添加一个或多个事件
core.events.openShop // 打开一个全局商店 core.events.openShop // 打开一个全局商店
core.events.disableQuickShop // 禁用一个快捷商店 core.events.disableQuickShop // 禁用一个全局商店
* core.events.canUseQuickShop // 当前能否使用快捷商店 * core.events.canUseQuickShop // 当前能否使用快捷商店
* core.events.checkLvUp // 检查升级事件
* core.events.useItem // 尝试使用道具 * core.events.useItem // 尝试使用道具
core.events.addPoint // 加点事件
core.events.afterBattle // 战斗结束后触发的事件 core.events.afterBattle // 战斗结束后触发的事件
core.events.afterOpenDoor // 开一个门后触发的事件 core.events.afterOpenDoor // 开一个门后触发的事件
core.events.passNet // 经过一个路障 core.events.passNet // 经过一个路障
core.events.beforeSaveData // 即将存档前可以执行的操作 core.events.changeLight // 改变亮灯(感叹号)的事件
core.events.afterLoadData // 读档后,载入事件前可以执行的操作 * core.events.afterChangeLight // 改变亮灯之后,可以触发的事件
* core.events.afterUseBomb // 使用炸弹/圣锤后的事件
* core.events.beforeSaveData // 即将存档前可以执行的操作
* core.events.afterLoadData // 读档事件后,载入事件前,可以执行的操作
// ------ 界面上的点击事件 ------ // ------ 点击事件和键盘事件的处理 ------
core.events.clickAction // 自定义事件处理时,对用户点击的处理 core.events.keyDownCtrl // 按下Ctrl键时快捷跳过对话
core.events.clickBook // 怪物手册打开时,对用户点击的处理 core.events.clickConfirmBox // 确认框界面时的点击操作
core.events.clickFly // 楼层传送器打开时,对用户点击的处理 core.events.keyUpConfirmBox // 确认框界面时,放开某个键的操作
core.events.clickShop // 全局商店打开时,对用户点击的处理 core.events.clickAction // 自定义事件时的点击操作
core.events.clickQuickShop // 快捷商店选项打开时 core.events.keyDownAction // 自定义事件时,按下某个键的操作
core.events.clickToolbox // 工具栏打开时 core.events.keyUpAction // 自定义事件时,放开某个键的操作
core.events.clickSL // 存/读档界面打开时 core.events.clickBook // 怪物手册界面的点击操作
core.events.clickSettings // 设置页面打开时 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 ``` js
core.maps.loadFloor // 加载某个楼层(从剧本或存档中) core.maps.loadFloor // 加载某个楼层(从剧本或存档中)
core.maps.getBlock // 将数字替换成实际的内容 core.maps.getBlock // 数字和ID的对应关系
core.maps.addEvent // 向该楼层添加剧本的自定义事件 core.maps.addEvent // 向该楼层添加剧本的自定义事件
core.maps.addChangeFloor // 向该楼层添加剧本的楼层转换事件 core.maps.addChangeFloor // 向该楼层添加剧本的楼层转换事件
core.maps.initMaps // 初始化所有地图 core.maps.initMaps // 初始化所有地图
@ -232,16 +300,19 @@ core.ui.closePanel // 结束一切事件和绘制关闭UI窗口返回游
core.ui.drawTextBox // 绘制一个对话框 core.ui.drawTextBox // 绘制一个对话框
core.ui.drawChoices // 绘制一个选项界面 core.ui.drawChoices // 绘制一个选项界面
core.ui.drawConfirmBox // 绘制一个确认/取消的警告页面 core.ui.drawConfirmBox // 绘制一个确认/取消的警告页面
core.ui.drawSwitchs // 绘制系统设置界面
core.ui.drawSettings // 绘制系统菜单栏 core.ui.drawSettings // 绘制系统菜单栏
core.ui.drawQuickShop // 绘制快捷商店选择栏 core.ui.drawQuickShop // 绘制快捷商店选择栏
core.ui.drawBattleAnimate // 绘制战斗过程 core.ui.drawBattleAnimate // 绘制战斗动画
core.ui.drawWaiting // 绘制一个“请稍后”页 core.ui.drawWaiting // 绘制等待界
core.ui.drawSyncSave // 绘制存档同步选项 core.ui.drawSyncSave // 绘制存档同步界面
core.ui.drawPagination // 绘制分页 core.ui.drawPagination // 绘制分页
core.ui.drawEnemyBook // 绘制怪物手册 core.ui.drawEnemyBook // 绘制怪物手册
core.ui.drawBookDetail // 绘制怪物属性的详细信息
core.ui.drawFly // 绘制楼层传送器 core.ui.drawFly // 绘制楼层传送器
core.ui.drawToolbox // 绘制道具栏 core.ui.drawToolbox // 绘制道具栏
core.ui.drawSLPanel // 绘制存档/读档界面 core.ui.drawSLPanel // 绘制存档/读档界面
core.ui.drawThumbnail // 绘制一个缩略图 core.ui.drawThumbnail // 绘制一个缩略图
core.ui.drawAbout // 绘制“关于”界面 core.ui.drawAbout // 绘制“关于”界面
core.ui.drawHelp // 绘制帮助界面
``` ```

View File

@ -40,14 +40,15 @@
``` js ``` js
enemys.prototype.getSpecialText = function (enemyId) { enemys.prototype.getSpecialText = function (enemyId) {
if (enemyId == undefined) return ""; if (enemyId == undefined) return "";
var special = this.enemys[enemyId].special; var enemy = this.enemys[enemyId];
var special = enemy.special;
var text = []; var text = [];
if (this.hasSpecial(special, 1)) text.push("先攻"); if (this.hasSpecial(special, 1)) text.push("先攻");
if (this.hasSpecial(special, 2)) text.push("魔攻"); if (this.hasSpecial(special, 2)) text.push("魔攻");
if (this.hasSpecial(special, 3)) text.push("坚固"); if (this.hasSpecial(special, 3)) text.push("坚固");
if (this.hasSpecial(special, 4)) text.push("2连击"); if (this.hasSpecial(special, 4)) text.push("2连击");
if (this.hasSpecial(special, 5)) text.push("3连击"); 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, 7)) text.push("破甲");
if (this.hasSpecial(special, 8)) text.push("反击"); if (this.hasSpecial(special, 8)) text.push("反击");
if (this.hasSpecial(special, 9)) 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, 15)) text.push("领域");
if (this.hasSpecial(special, 16)) text.push("夹击"); if (this.hasSpecial(special, 16)) text.push("夹击");
if (this.hasSpecial(special, 17)) 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(" "); 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即不启用经验的话怪物手册里将不显示怪物的经验值打败怪物也不获得任何经验。 如果`data.js`中的enableExperience为false即不启用经验的话怪物手册里将不显示怪物的经验值打败怪物也不获得任何经验。
拿到幸运金币后,打怪获得的金币将翻倍。 拿到幸运金币后,打怪获得的金币将翻倍。
N连击怪物的special是6且我们可以为它定义n代表实际连击数。参见样板中剑王的写法。
![N连击](./img/nattack.png)
吸血怪需要在怪物后添加value代表吸血的比例。 吸血怪需要在怪物后添加value代表吸血的比例。
![怪物吸血](./img/blood.png) ![怪物吸血](./img/blood.png)
@ -89,15 +103,21 @@ enemys.prototype.getSpecialText = function (enemyId) {
领域怪需要在怪物后添加value代表领域伤害的数值。如果勇士生命值扣减到0则直接死亡触发lose事件。 领域怪需要在怪物后添加value代表领域伤害的数值。如果勇士生命值扣减到0则直接死亡触发lose事件。
![怪物领域](./img/domainenemy.png) 领域是十字伤害还是九宫格伤害由data.js中的全局变量`zoneSquare`设定。你也可以对该怪物自行进行设定。
请注意如果吸血和领域同时存在则value会冲突。**因此请勿将吸血和领域放置在同一个怪物身上。** `range`选项可选代表该领域怪的范围不写则默认为1。
本塔暂不支持阻击、激光、自爆、退化等属性。 ![怪物领域](./img/zone.png)
阻击怪同样需要在怪物后添加value代表领域伤害的数值。如果勇士生命值扣减到0则直接死亡触发lose事件。
!> 阻击怪后退的地点不能有任何事件存在,即使是已经被禁用的自定义事件!
请注意如果吸血、领域、阻击中任何两个同时存在则value会冲突。**因此请勿将吸血、领域或阻击放置在同一个怪物身上。**
如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。 如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。
### 路障、楼梯、传送门 ### 路障,楼梯,传送门
血网的伤害数值、中毒后每步伤害数值、衰弱时暂时攻防下降的数值,都在 `data.js` 的values内定义。 血网的伤害数值、中毒后每步伤害数值、衰弱时暂时攻防下降的数值,都在 `data.js` 的values内定义。
@ -123,6 +143,65 @@ floorId指定的是目标楼层的唯一标识符ID
![楼层转换穿透](./img/floorset.png) ![楼层转换穿透](./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]** 快捷使用中心对称飞行器
以上快捷键也能在游戏菜单中的操作说明中看到。
   
   

View File

@ -397,7 +397,9 @@ revisit常常使用在一些商人之类的地方当用户购买物品后不
如果强制战斗失败则会立刻生命归0并死亡调用lose函数接下来的事件不会再被执行。 如果强制战斗失败则会立刻生命归0并死亡调用lose函数接下来的事件不会再被执行。
强制战斗没有指定loc的选项因此战斗后需要调用hide使怪物消失如果有必要。强制战斗不会触发任何afterBattle里的事件。 打败怪物后可以进行加点操作。有关加点塔的制作可参见[加点事件](#加点事件)。
强制战斗没有指定loc的选项因此战斗后需要调用hide使怪物消失如果有必要
### openDoor: 开门 ### openDoor: 开门
@ -416,8 +418,6 @@ loc指定门的坐标floorId指定门所在的楼层ID。如果是当前层
如果loc所在的点既不是门也不是墙壁则忽略本事件。 如果loc所在的点既不是门也不是墙壁则忽略本事件。
openDoor不会触发任何afterOpenDoor里的事件。
### changeFloor: 楼层切换 ### changeFloor: 楼层切换
在事件中也可以对楼层进行切换。一个比较典型的例子就是TSW中勇士在三楼的陷阱被扔到了二楼就是一个楼层切换事件。 在事件中也可以对楼层进行切换。一个比较典型的例子就是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: 播放音效
使用playSound可以立刻播放一个音效。 使用playSound可以立刻播放一个音效。
@ -561,10 +581,6 @@ move完毕后移动的NPC/怪物一定会消失只不过可以通过immediate
值得注意的是如果是额外添加进文件的音效则需在main.js中this.sounds里加载它。 值得注意的是如果是额外添加进文件的音效则需在main.js中this.sounds里加载它。
!> 自定义添加的音效名请勿包含`-`,否则将无法正常使用!
由于考虑到用户流量问题每个额外音效最好不超过20KB。
### win: 获得胜利 ### win: 获得胜利
`{"type": "win", "reason": "xxx"}` 将会直接调用events.js中的win函数并将reason作为参数传入。 `{"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的时候才能触发商店事件。 我们可以采用上面的choices方式来给出一个商店。这样的商店确实可以有效地进行操作但是却是"非全局"的换句话说只有在碰到NPC的时候才能触发商店事件。
@ -776,7 +829,6 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用
// 上面的例子是50层商店的计算公式。你也可以写任意其他的计算公式只要以times作为参数即可。 // 上面的例子是50层商店的计算公式。你也可以写任意其他的计算公式只要以times作为参数即可。
// 例如: "need": "25" 就是恒定需要25金币的商店 "need": "20+2*times" 就是第一次访问要20金币以后每次递增2金币的商店。 // 例如: "need": "25" 就是恒定需要25金币的商店 "need": "20+2*times" 就是第一次访问要20金币以后每次递增2金币的商店。
// 如果是对于每个选项有不同的计算公式,写 "need": "-1" 即可。可参见下面的经验商店。 // 如果是对于每个选项有不同的计算公式,写 "need": "-1" 即可。可参见下面的经验商店。
"text": "勇敢的武士啊,给我${need}金币就可以:", // 显示的文字,需手动加换行符。可以使用${need}表示上面的need值。 "text": "勇敢的武士啊,给我${need}金币就可以:", // 显示的文字,需手动加换行符。可以使用${need}表示上面的need值。
"choices": [ // 商店的选项 "choices": [ // 商店的选项
{"text": "生命+800", "effect": "status:hp+=800"}, {"text": "生命+800", "effect": "status:hp+=800"},
@ -784,10 +836,12 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用
{"text": "攻击+4", "effect": "status:atk+=4"}, {"text": "攻击+4", "effect": "status:atk+=4"},
{"text": "防御+4", "effect": "status:def+=4"}, {"text": "防御+4", "effect": "status:def+=4"},
{"text": "魔防+10", "effect": "status:mdef+=10"} {"text": "魔防+10", "effect": "status:mdef+=10"}
// effect只能对status和item进行操作不能修改flag值。且其中间只能用+=符号(也就是只能增加某个属性或道具) // effect只能对status和item进行操作不能修改flag值。
// 必须是X+=Y的形式其中Y可以是一个表达式以status:xxx或item:xxx为参数
// 其他effect样例 // 其他effect样例
// "item:yellowKey+=1" 黄钥匙+1 // "item:yellowKey+=1" 黄钥匙+1
// "item:pickaxe+=3" 破墙镐+3 // "item:pickaxe+=3" 破墙镐+3
// "status:hp+=2*(status:atk+status:def)" 将生命提升攻防和的数值的两倍
] ]
}, },
"expShop1": { // 商店唯一ID "expShop1": { // 商店唯一ID
@ -800,13 +854,13 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用
"choices": [ "choices": [
// 在choices中写need可以针对每个选项都有不同的需求。 // 在choices中写need可以针对每个选项都有不同的需求。
// 这里的need同样可以以times作为参数比如 "need": "100+20*times" // 这里的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。 // 多个effect直接以分号分开即可。如上面的意思是生命+1000攻击+7防御+7。
{"text": "攻击+5", "need": "30", "effect": "status:atk+=5"}, {"text": "攻击+5", "need": "30", "effect": "status:atk+=5"},
{"text": "防御+5", "need": "30", "effect": "status:def+=5"}, {"text": "防御+5", "need": "30", "effect": "status:def+=5"},
] ]
} },
} },
``` ```
全局商店全部定义在`data.js`中的shops一项里。 全局商店全部定义在`data.js`中的shops一项里。
@ -887,28 +941,63 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用
当且仅当勇士第一次到达某层时,将会触发此事件。可以利用此事件来显示一些剧情,或再让它调用 `{"type": "trigger"}` 来继续调用其他的事件。 当且仅当勇士第一次到达某层时,将会触发此事件。可以利用此事件来显示一些剧情,或再让它调用 `{"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"`,分别对应三个难度。针对不同的难度,我们可以设置一些难度分歧。 其参数hard为以下三个字符串之一`"Easy"`, `"Normal"`, `"Hard"`,分别对应三个难度。针对不同的难度,我们可以设置一些难度分歧。
``` js ``` js
////// 游戏开始事件 ////// ////// 不同难度分别设置初始属性 //////
events.prototype.startGame = function (hard) { events.prototype.setInitData = 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') { // 简单难度 if (hard=='Easy') { // 简单难度
core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度 core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度
// 可以在此设置一些初始福利,比如设置初始生命值可以调用: // 可以在此设置一些初始福利,比如设置初始生命值可以调用:
// core.setStatus("hp", 10000); // core.setStatus("hp", 10000);
// 赠送一把黄钥匙可以调用
// core.setItem("yellowKey", 1);
} }
if (hard=='Normal') { // 普通难度 if (hard=='Normal') { // 普通难度
core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度 core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度
@ -916,8 +1005,6 @@ events.prototype.startGame = function (hard) {
if (hard=='Hard') { // 困难难度 if (hard=='Hard') { // 困难难度
core.setFlag('hard', 3); // 可以用flag:hard来获得当前难度 core.setFlag('hard', 3); // 可以用flag:hard来获得当前难度
} }
});
})
} }
``` ```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/img/nattack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/img/zone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -6,7 +6,7 @@
所有素材的图片都在`images`目录下。 所有素材的图片都在`images`目录下。
- `animates.png` 为所有动画效果。主要是星空熔岩,开门,毒网,传送门之类的效果。为四帧。 - `animates.png` 为所有动画效果。主要是星空熔岩,开门,毒网,传送门之类的效果。为四帧。
- `autotile.png` 为Autotile块。全塔只支持一种Autotile其ID为20。 - `autotile.png` 为Autotile块。
- `enemys.png` 为所有怪物的图片。其对应的数字从上至下依次是会从201开始计算绿色史莱姆为201小蝙蝠为205依次类推。请注意动画效果为两帧一般是原始四帧中的1和3。四帧中12相同34相同因此只取1和3即可 - `enemys.png` 为所有怪物的图片。其对应的数字从上至下依次是会从201开始计算绿色史莱姆为201小蝙蝠为205依次类推。请注意动画效果为两帧一般是原始四帧中的1和3。四帧中12相同34相同因此只取1和3即可
- `heros.png` 为勇士行走图。 - `heros.png` 为勇士行走图。
- `items.png` 为所有道具的图标。 - `items.png` 为所有道具的图标。
@ -17,7 +17,7 @@
### 使用预定义的素材 ### 使用预定义的素材
在images目录的“默认素材”下给定了若干预定义的自定义素材。包括野外(草地),星空,木板等等都已经被预先给定。 在images目录的“默认素材”下给定了若干预定义的自定义素材。
如果你需要某个素材已经存在则可以直接将其覆盖images目录下的同名文件就能看到效果。 如果你需要某个素材已经存在则可以直接将其覆盖images目录下的同名文件就能看到效果。
@ -29,6 +29,8 @@
我们可以打开有需求改变的素材和我们需要被替换的素材然后简单的Ctrl+C和Ctrl+V操作即可。 我们可以打开有需求改变的素材和我们需要被替换的素材然后简单的Ctrl+C和Ctrl+V操作即可。
便捷PS工具同样支持图片色相的修改和RMXP几乎完全相同。
用这种方式,我们能极快地替换或素材,包括需要新增的怪物。 用这种方式,我们能极快地替换或素材,包括需要新增的怪物。
### 添加素材到游戏 ### 添加素材到游戏
@ -37,63 +39,74 @@
这是因为,该素材没有被定义,无法被游戏所识别。 这是因为,该素材没有被定义,无法被游戏所识别。
#### 素材的机制
本塔所有的素材都拥有三个属性:**ID****索引****数字**。
- **ID** 为该素材的唯一标识符任何两个素材的ID都不能相同。
- **索引** 为该素材的在对应图片上的图标索引,即该素材是图片上的第几个。
- **数字** 为该素材的对应数字,以方便地图的生成和存储。
**`ID-索引` 对应关系定义在icons.js文件中。该文件将唯一确定一个ID在图片上所在的位置。**
**`ID-数字` 对应关系定义在maps.js文件的getBlock函数中。该函数将唯一确定一个ID对应的数字是多少。**
如果需要添加一个素材到游戏,则必须为其分配一个唯一标识符,并同时修改`icons.js`和`maps.js`两个文件。
#### 新添加自定义地形(路面、墙壁等) #### 新添加自定义地形(路面、墙壁等)
如果你在terrains.png中新增了一行 如果你在terrains.png中新增了一行
1. 指定一个唯一的英文ID不能和terrains中现有的重复。 1. 指定一个唯一的英文ID不能和现有的重复。
2. 进入icons.js在terrains分类下进行添加对应图标在图片上的位置即index 2. 进入icons.js在terrains分类下进行添加索引对应图标在图片上的位置即index
3. 指定一个数字在maps.js的getBlock下类似进行添加。
``` js **如果你无须在游戏内使用本地形,而仅仅是将其作为“背景图”使用,则操作如下:**
if (id == 13) tmp.event = {'cls': 'animates', 'id': 'weakNet', 'noPass': false, 'trigger': 'passNet'}; // 衰网 3. 修改对应楼层的剧本文件的`defaultGround`项改成新的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}; // 水 **如果你要在游戏内使用本地形,则操作如下:**
// 可以在此处类似添加数字-ID对应关系但不能和任何已有的数字重复 3. 指定一个数字在maps.js的getBlock函数下类似进行添加。
// autotile: 20
if (id == 20) tmp.event = {'cls': 'autotile', 'id': 'autotile', 'noPass': true}; // autotile #### 新添加Autotile
```
如果你需要新增一个Autotile
1. 将新的Autotile图片复制到images目录下。
2. 进入icons.js在autotile分类下进行添加该文件的名称索引简单的写0。
3. 指定一个数字在maps.js的getBlock函数下类似进行添加。
!> Autotile的ID和文件名完全相同且其ID/文件名不能含有中文、空格或特殊字符。
#### 新添加道具 #### 新添加道具
如果你需要新增一个未被定义的道具: 如果你需要新增一个未被定义的道具:
1. 指定一个唯一的英文ID不能和items中现有的重复。 1. 指定一个唯一的英文ID不能和现有的重复。
2. 进入icons.js在items分类下进行添加对应图标在图片上的位置即index 2. 进入icons.js在items分类下进行添加索引对应图标在图片上的位置即index
3. 指定一个数字在maps.js的getBlock下类似进行添加。 3. 指定一个数字在maps.js的getBlock下类似进行添加。
4. 在items.js中仿照其他道具来添加道具的信息。 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帧**。 如果我们需要新添加怪物请在enemys.png中新增一行然后复制粘贴上四帧怪物图的**1和3帧**。
你可以通过便捷PS工具的“更改色相”来将红头怪变成橙头怪等。
然后执行如下操作: 然后执行如下操作:
1. 指定一个唯一的英文ID不能和enemys中现有的重复。 1. 指定一个唯一的英文ID不能和enemys中现有的重复。
2. 进入icons.js在enemys分类下进行添加对应图标在图片上的位置即index 2. 进入icons.js在enemys分类下进行添加索引对应图标在图片上的位置即index
3. 在maps.js的getBlock下继续进行添加。请注意其ID为200开始的顺序即如果新增一行为261依次类推 3. 在maps.js的getBlock下继续进行添加。请注意其ID为200开始的顺序即如果新增一行为261依次类推
4. 在enemys.js中仿照其他怪物来添加怪物的信息。 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
类似同上给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 ``` js
// 更新领域、显伤点 // 检查领域、夹击、阻击事件
core.prototype.updateCheckBlock = function() { core.prototype.checkBlock = function () {
if (!core.isset(core.status.thisMap)) return; var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap(); var damage = core.status.checkBlock.damage[13*x+y];
core.status.checkBlock = []; if (damage>0) {
if (core.hasItem('shield5')) return; // 如拥有神圣盾则直接返回 if (core.hasFlag("shield5")) damage = 0; // 如果存在神圣盾则将伤害变成0
for (var x=0;x<13;x++) { core.status.hero.hp -= damage;
for (var y=0;y<13;y++) {
// 计算(x,y)点伤害 // 检查阻击事件
var damage = 0; 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. 如果有更高的需求,例如想让吸血效果变成一半(如异空间),则还是在上面这些地方进行对应的修改即可。 4. 如果有更高的需求,例如想让吸血效果变成一半(如异空间),则还是在上面这些地方进行对应的修改即可。
@ -196,42 +215,15 @@ core.prototype.updateCheckBlock = function() {
如果你对现有的怪物不满意,想自行添加怪物属性(例如让怪物拥有双属性乃至更多属性),也是可以的。具体参见`enemys.js`文件。 如果你对现有的怪物不满意,想自行添加怪物属性(例如让怪物拥有双属性乃至更多属性),也是可以的。具体参见`enemys.js`文件。
你需自己指定一个special数字修改getSpecialText函数。 你需自己指定一个special数字修改getSpecialText函数属性名和getSpecialHint函数属性提示文字
如果要修改伤害计算公式请修改下面的calDamage函数。请注意如果无法战斗该函数必须返回`999999999`。 如果要修改伤害计算公式请修改下面的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中。 对于吸血怪的额外伤害计算在getExtraDamage中。
对于毒衰弱怪物的战斗后结算在`events.js`中的afterBattle函数中。 对于毒衰弱怪物的战斗后结算在`events.js`中的afterBattle函数中。
对于领域、夹击怪物的检查在`events.js`中的checkBlock函数中。 对于领域、夹击、阻击怪物的检查在`events.js`中的checkBlock函数中。
`getCritical`, `getCriticalDamage`和`getDefDamage`三个函数依次计算的是该怪物的临界值、临界减伤和1防减伤。也可以适当进行修改。 `getCritical`, `getCriticalDamage`和`getDefDamage`三个函数依次计算的是该怪物的临界值、临界减伤和1防减伤。也可以适当进行修改。

View File

@ -36,7 +36,23 @@
然后将楼层名改为MT1floorId改名为MT1title可以改成任意内容将在切换楼层时进行显示比如可以改成“1层小塔” 然后将楼层名改为MT1floorId改名为MT1title可以改成任意内容将在切换楼层时进行显示比如可以改成“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`** 开完门后可能触发的事件列表
我们最终的任务其实是,将每个楼层的剧本(地图&事件)给写完即可。
换句话说,只需要简单的复制操作,我们就可以新建一个剧本了。 换句话说,只需要简单的复制操作,我们就可以新建一个剧本了。

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@ function enemys() {
} }
////// 初始化 //////
enemys.prototype.init = function () { enemys.prototype.init = function () {
// 怪物属性初始化定义: // 怪物属性初始化定义:
this.enemys = { this.enemys = {
@ -68,17 +69,20 @@ enemys.prototype.init = function () {
} }
} }
////// 获得一个或所有怪物数据 //////
enemys.prototype.getEnemys = function (enemyId) { enemys.prototype.getEnemys = function (enemyId) {
if (enemyId == undefined) { if (!core.isset(enemyId)) {
return this.enemys; return this.enemys;
} }
return this.enemys[enemyId]; return this.enemys[enemyId];
} }
////// 判断是否含有某特殊属性 //////
enemys.prototype.hasSpecial = function (special, test) { 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))); return (special instanceof Array)?special.indexOf(test)>=0:(special!=0&&(special%100==test||this.hasSpecial(parseInt(special/100), test)));
} }
////// 获得所有特殊属性的名称 //////
enemys.prototype.getSpecialText = function (enemyId) { enemys.prototype.getSpecialText = function (enemyId) {
if (enemyId == undefined) return ""; if (enemyId == undefined) return "";
var enemy = this.enemys[enemyId]; var enemy = this.enemys[enemyId];
@ -107,7 +111,7 @@ enemys.prototype.getSpecialText = function (enemyId) {
return text; return text;
} }
////// 获得每个属性的文字提示 ////// ////// 获得每个特殊属性的说明 //////
enemys.prototype.getSpecialHint = function (enemy, special) { enemys.prototype.getSpecialHint = function (enemy, special) {
if (!core.isset(special)) { if (!core.isset(special)) {
var hints = []; var hints = [];
@ -147,6 +151,7 @@ enemys.prototype.getSpecialHint = function (enemy, special) {
return "" return ""
} }
////// 获得某个怪物的伤害 //////
enemys.prototype.getDamage = function (monsterId) { enemys.prototype.getDamage = function (monsterId) {
var monster = core.material.enemys[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; 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); return damage + this.getExtraDamage(monster);
} }
////// 获得某个怪物的额外伤害 //////
enemys.prototype.getExtraDamage = function (monster) { enemys.prototype.getExtraDamage = function (monster) {
var extra_damage = 0; var extra_damage = 0;
if (this.hasSpecial(monster.special, 11)) { // 吸血 if (this.hasSpecial(monster.special, 11)) { // 吸血
@ -169,7 +175,7 @@ enemys.prototype.getExtraDamage = function (monster) {
return extra_damage; return extra_damage;
} }
// 临界值计算 ////// 临界值计算 //////
enemys.prototype.getCritical = function (monsterId) { enemys.prototype.getCritical = function (monsterId) {
var monster = core.material.enemys[monsterId]; var monster = core.material.enemys[monsterId];
if (this.hasSpecial(monster.special, 3) || this.hasSpecial(monster.special, 10)) return "???"; if (this.hasSpecial(monster.special, 3) || this.hasSpecial(monster.special, 10)) return "???";
@ -187,7 +193,7 @@ enemys.prototype.getCritical = function (monsterId) {
return 0; return 0;
} }
// 临界减伤计算 ////// 临界减伤计算 //////
enemys.prototype.getCriticalDamage = function (monsterId) { enemys.prototype.getCriticalDamage = function (monsterId) {
var c = this.getCritical(monsterId); var c = this.getCritical(monsterId);
if (c == '???') return '???'; if (c == '???') return '???';
@ -201,7 +207,7 @@ enemys.prototype.getCriticalDamage = function (monsterId) {
monster.hp, monster.atk, monster.def, monster.special, monster.n); monster.hp, monster.atk, monster.def, monster.special, monster.n);
} }
// 1防减伤计算 ////// 1防减伤计算 //////
enemys.prototype.getDefDamage = function (monsterId) { enemys.prototype.getDefDamage = function (monsterId) {
var monster = core.material.enemys[monsterId]; var monster = core.material.enemys[monsterId];
var nowDamage = this.calDamage(core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, 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; return nowDamage - nextDamage;
} }
////// 具体的伤害计算公式 //////
enemys.prototype.calDamage = function (hero_atk, hero_def, hero_mdef, mon_hp, mon_atk, mon_def, mon_special, n) { 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")) // 如果是无敌属性,且勇士未持有十字架 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); return core.flags.enableNegativeDamage?ans:Math.max(0, ans);
} }
// 获得当前楼层的怪物列表 ////// 获得当前楼层的怪物列表 //////
enemys.prototype.getCurrentEnemys = function () { enemys.prototype.getCurrentEnemys = function () {
var enemys = []; var enemys = [];
var used = {}; var used = {};

View File

@ -2,6 +2,7 @@ function events() {
} }
////// 初始化 //////
events.prototype.init = function () { events.prototype.init = function () {
this.events = { this.events = {
'battle': function (data, core, callback) { 'battle': function (data, core, callback) {
@ -45,9 +46,9 @@ events.prototype.init = function () {
} }
} }
// 初始化 ////// 获得一个或所有系统事件类型 //////
events.prototype.getEvents = function (eventName) { events.prototype.getEvents = function (eventName) {
if (eventName == undefined) { if (!core.isset(eventName)) {
return this.events; return this.events;
} }
return this.events[eventName]; return this.events[eventName];
@ -87,12 +88,14 @@ events.prototype.startGame = function (hard) {
}) })
} }
////// 简单难度设置初始福利 ////// ////// 不同难度分别设置初始属性 //////
events.prototype.setInitData = function (hard) { events.prototype.setInitData = function (hard) {
if (hard=='Easy') { // 简单难度 if (hard=='Easy') { // 简单难度
core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度 core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度
// 可以在此设置一些初始福利,比如设置初始生命值可以调用: // 可以在此设置一些初始福利,比如设置初始生命值可以调用:
// core.setStatus("hp", 10000); // core.setStatus("hp", 10000);
// 赠送一把黄钥匙可以调用
// core.setItem("yellowKey", 1);
} }
if (hard=='Normal') { // 普通难度 if (hard=='Normal') { // 普通难度
core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度 core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度
@ -102,9 +105,8 @@ events.prototype.setInitData = function (hard) {
} }
} }
////// 游戏结束事件 ////// ////// 游戏获胜事件 //////
events.prototype.win = function(reason) { events.prototype.win = function(reason) {
// 获胜
core.waitHeroToStop(function() { core.waitHeroToStop(function() {
core.removeGlobalAnimate(0,0,true); core.removeGlobalAnimate(0,0,true);
core.clearMap('all'); // 清空全地图 core.clearMap('all'); // 清空全地图
@ -116,8 +118,8 @@ events.prototype.win = function(reason) {
}); });
} }
////// 游戏失败事件 //////
events.prototype.lose = function(reason) { events.prototype.lose = function(reason) {
// 失败
core.waitHeroToStop(function() { core.waitHeroToStop(function() {
core.drawText([ core.drawText([
"\t[结局1]你死了。\n如题。" "\t[结局1]你死了。\n如题。"
@ -133,20 +135,9 @@ events.prototype.afterChangeFloor = function (floorId) {
this.doEvents(core.floors[floorId].firstArrive); this.doEvents(core.floors[floorId].firstArrive);
core.setFlag("visited_"+floorId, true); 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) { events.prototype.doEvents = function (list, x, y, callback) {
// 停止勇士 // 停止勇士
core.waitHeroToStop(function() { core.waitHeroToStop(function() {
@ -162,6 +153,7 @@ events.prototype.doEvents = function (list, x, y, callback) {
}); });
} }
////// 执行当前自定义事件列表中的下一个事件 //////
events.prototype.doAction = function() { events.prototype.doAction = function() {
// 清空boxAnimate和UI层 // 清空boxAnimate和UI层
clearInterval(core.interval.boxAnimate); clearInterval(core.interval.boxAnimate);
@ -172,7 +164,7 @@ events.prototype.doAction = function() {
if (core.status.event.data.list.length==0) { if (core.status.event.data.list.length==0) {
if (core.isset(core.status.event.data.callback)) if (core.isset(core.status.event.data.callback))
core.status.event.data.callback(); core.status.event.data.callback();
core.ui.closePanel(false); core.ui.closePanel();
return; return;
} }
@ -201,12 +193,12 @@ events.prototype.doAction = function() {
case "show": // 显示 case "show": // 显示
if (core.isset(data.time) && data.time>0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) { 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.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(); core.events.doAction();
}); });
} }
else { else {
core.addBlock(data.loc[0],data.loc[1],data.floorId) core.showBlock(data.loc[0],data.loc[1],data.floorId)
this.doAction(); this.doAction();
} }
break; break;
@ -418,7 +410,7 @@ events.prototype.insertAction = function (action) {
} }
} }
////// 打开商店 ////// ////// 打开一个全局商店 //////
events.prototype.openShop = function(shopId, needVisited) { events.prototype.openShop = function(shopId, needVisited) {
var shop = core.status.shops[shopId]; var shop = core.status.shops[shopId];
shop.times = shop.times || 0; shop.times = shop.times || 0;
@ -460,35 +452,11 @@ events.prototype.openShop = function(shopId, needVisited) {
core.ui.drawChoices(content, choices); core.ui.drawChoices(content, choices);
} }
////// 禁用一个全局商店 //////
events.prototype.disableQuickShop = function (shopId) { events.prototype.disableQuickShop = function (shopId) {
core.status.shops[shopId].visited = false; 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) { events.prototype.canUseQuickShop = function(shopIndex) {
if (core.isset(core.floors[core.status.floorId].canUseQuickShop) && !core.isset(core.floors[core.status.floorId].canUseQuickShop)) 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; 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) { events.prototype.useItem = function(itemId) {
core.ui.closePanel(false); core.ui.closePanel();
if (itemId=='book') { if (itemId=='book') {
core.openBook(false); core.openBook(false);
@ -522,7 +517,7 @@ events.prototype.useItem = function(itemId) {
else core.drawTip("当前无法使用"+core.material.items[itemId].name); else core.drawTip("当前无法使用"+core.material.items[itemId].name);
} }
////// 加点 ////// ////// 加点事件 //////
events.prototype.addPoint = function (enemy) { events.prototype.addPoint = function (enemy) {
var point = enemy.point; var point = enemy.point;
if (!core.isset(point) || point<=0) return []; if (!core.isset(point) || point<=0) return [];
@ -531,22 +526,21 @@ events.prototype.addPoint = function (enemy) {
return [ return [
{"type": "choices", {"type": "choices",
"choices": [ "choices": [
{"text": "生命+"+(200*point), "action": [
{"type": "setValue", "name": "status:hp", "value": "status:hp+"+(200*point)}
]},
{"text": "攻击+"+(1*point), "action": [ {"text": "攻击+"+(1*point), "action": [
{"type": "setValue", "name": "status:atk", "value": "status:atk+"+(1*point)} {"type": "setValue", "name": "status:atk", "value": "status:atk+"+(1*point)}
]}, ]},
{"text": "防御+"+(2*point), "action": [ {"text": "防御+"+(2*point), "action": [
{"type": "setValue", "name": "status:def", "value": "status:def+"+(2*point)} {"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) { 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) { events.prototype.afterOpenDoor = function(doorId,x,y,callback) {
var todo = []; var todo = [];
@ -628,7 +622,7 @@ events.prototype.afterOpenDoor = function(doorId,x,y,callback) {
if (core.isset(callback)) callback(); if (core.isset(callback)) callback();
} }
/****** 经过路障 ******/ ////// 经过一个路障 //////
events.prototype.passNet = function (data) { events.prototype.passNet = function (data) {
// 有鞋子 // 有鞋子
if (core.hasItem('shoes')) return; if (core.hasItem('shoes')) return;
@ -659,6 +653,7 @@ events.prototype.passNet = function (data) {
core.updateStatusBar(); core.updateStatusBar();
} }
////// 改变亮灯(感叹号)的事件 //////
events.prototype.changeLight = function(x, y) { events.prototype.changeLight = function(x, y) {
var block = core.getBlock(x, y); var block = core.getBlock(x, y);
if (block==null) return; if (block==null) return;
@ -675,32 +670,33 @@ events.prototype.changeLight = function(x, y) {
this.afterChangeLight(x,y); this.afterChangeLight(x,y);
} }
// 改变灯后的事件 ////// 改变,可以触发的事件 //////
events.prototype.afterChangeLight = function(x,y) { events.prototype.afterChangeLight = function(x,y) {
} }
// 使用炸弹/圣锤后的事件 ////// 使用炸弹/圣锤后的事件 //////
events.prototype.afterUseBomb = function () { events.prototype.afterUseBomb = function () {
} }
// 存档事件前一刻的处理 ////// 即将存档前可以执行的操作 //////
events.prototype.beforeSaveData = function(data) { events.prototype.beforeSaveData = function(data) {
} }
// 读档事件后,载入事件前,对数据的处理 ////// 读档事件后,载入事件前,可以执行的操作 //////
events.prototype.afterLoadData = function(data) { events.prototype.afterLoadData = function(data) {
} }
/******************************************/ /****************************************/
/*********** 界面上的点击事件 ***************/ /********** 点击事件、键盘事件 ************/
/******************************************/ /****************************************/
////// 按下Ctrl键时快捷跳过对话 //////
events.prototype.keyDownCtrl = function () { events.prototype.keyDownCtrl = function () {
if (core.status.event.id=='text') { if (core.status.event.id=='text') {
core.drawText(); core.drawText();
@ -712,6 +708,7 @@ events.prototype.keyDownCtrl = function () {
} }
} }
////// 点击确认框时 //////
events.prototype.clickConfirmBox = function (x,y) { events.prototype.clickConfirmBox = function (x,y) {
if ((x == 4 || x == 5) && y == 7 && core.isset(core.status.event.data.yes)) if ((x == 4 || x == 5) && y == 7 && core.isset(core.status.event.data.yes))
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(); core.status.event.data.no();
} }
////// 键盘操作确认框时 //////
events.prototype.keyUpConfirmBox = function (keycode) { events.prototype.keyUpConfirmBox = function (keycode) {
if (keycode==37) { if (keycode==37) {
core.status.event.selection=0; core.status.event.selection=0;
@ -742,7 +740,7 @@ events.prototype.keyUpConfirmBox = function (keycode) {
} }
} }
// 正在处理事件时的点击操作... ////// 自定义事件时的点击操作 //////
events.prototype.clickAction = function (x,y) { events.prototype.clickAction = function (x,y) {
if (core.status.event.data.type=='text') { if (core.status.event.data.type=='text') {
@ -765,6 +763,7 @@ events.prototype.clickAction = function (x,y) {
} }
} }
////// 自定义事件时,按下某个键的操作 //////
events.prototype.keyDownAction = function (keycode) { events.prototype.keyDownAction = function (keycode) {
if (core.status.event.data.type=='choices') { if (core.status.event.data.type=='choices') {
var data = core.status.event.data.current; var data = core.status.event.data.current;
@ -784,6 +783,7 @@ events.prototype.keyDownAction = function (keycode) {
} }
} }
////// 自定义事件时,放开某个键的操作 //////
events.prototype.keyUpAction = function (keycode) { events.prototype.keyUpAction = function (keycode) {
if (core.status.event.data.type=='text' && (keycode==13 || keycode==32 || keycode==67)) { if (core.status.event.data.type=='text' && (keycode==13 || keycode==32 || keycode==67)) {
this.doAction(); this.doAction();
@ -801,48 +801,49 @@ events.prototype.keyUpAction = function (keycode) {
} }
} }
// 怪物手册 ////// 怪物手册界面的点击操作 //////
events.prototype.clickBook = function(x,y) { events.prototype.clickBook = function(x,y) {
// 上一页 // 上一页
if ((x == 3 || x == 4) && y == 12) { if ((x == 3 || x == 4) && y == 12) {
core.ui.drawEnemyBook(core.status.event.data - 6); core.ui.drawBook(core.status.event.data - 6);
return; return;
} }
// 下一页 // 下一页
if ((x == 8 || x == 9) && y == 12) { if ((x == 8 || x == 9) && y == 12) {
core.ui.drawEnemyBook(core.status.event.data + 6); core.ui.drawBook(core.status.event.data + 6);
return; return;
} }
// 返回 // 返回
if (x>=10 && x<=12 && y==12) { if (x>=10 && x<=12 && y==12) {
core.ui.closePanel(true); core.ui.closePanel();
return; return;
} }
// 怪物信息 // 怪物信息
// var index = parseInt(y/2);
var data = core.status.event.data; var data = core.status.event.data;
if (core.isset(data) && y<12) { if (core.isset(data) && y<12) {
var page=parseInt(data/6); var page=parseInt(data/6);
var index=6*page+parseInt(y/2); var index=6*page+parseInt(y/2);
core.ui.drawEnemyBook(index); core.ui.drawBook(index);
core.ui.drawBookDetail(index); core.ui.drawBookDetail(index);
} }
return; return;
} }
////// 怪物手册界面时,按下某个键的操作 //////
events.prototype.keyDownBook = function (keycode) { events.prototype.keyDownBook = function (keycode) {
if (keycode==37) core.ui.drawEnemyBook(core.status.event.data-6); if (keycode==37) core.ui.drawBook(core.status.event.data-6);
if (keycode==38) core.ui.drawEnemyBook(core.status.event.data-1); if (keycode==38) core.ui.drawBook(core.status.event.data-1);
if (keycode==39) core.ui.drawEnemyBook(core.status.event.data+6); if (keycode==39) core.ui.drawBook(core.status.event.data+6);
if (keycode==40) core.ui.drawEnemyBook(core.status.event.data+1); if (keycode==40) core.ui.drawBook(core.status.event.data+1);
if (keycode==33) core.ui.drawEnemyBook(core.status.event.data-6); if (keycode==33) core.ui.drawBook(core.status.event.data-6);
if (keycode==34) core.ui.drawEnemyBook(core.status.event.data+6); if (keycode==34) core.ui.drawBook(core.status.event.data+6);
return; return;
} }
////// 怪物手册界面时,放开某个键的操作 //////
events.prototype.keyUpBook = function (keycode) { events.prototype.keyUpBook = function (keycode) {
if (keycode==27 || keycode==88) { if (keycode==27 || keycode==88) {
core.ui.closePanel(true); core.ui.closePanel();
return; return;
} }
if (keycode==13 || keycode==32 || keycode==67) { 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.clearMap('data', 0, 0, 416, 416);
core.status.event.id = 'book'; core.status.event.id = 'book';
} }
////// 楼层传送器界面时的点击操作 //////
events.prototype.clickFly = function(x,y) { 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==9) core.ui.drawFly(core.status.event.data-1);
if ((x==10 || x==11) && y==5) 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; return;
} }
////// 楼层传送器界面时,按下某个键的操作 //////
events.prototype.keyDownFly = function (keycode) { events.prototype.keyDownFly = function (keycode) {
if (keycode==37 || keycode==38) core.ui.drawFly(core.status.event.data+1); 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); else if (keycode==39 || keycode==40) core.ui.drawFly(core.status.event.data-1);
return; return;
} }
////// 楼层传送器界面时,放开某个键的操作 //////
events.prototype.keyUpFly = function (keycode) { events.prototype.keyUpFly = function (keycode) {
if (keycode==71 || keycode==27 || keycode==88) if (keycode==71 || keycode==27 || keycode==88)
core.ui.closePanel(); core.ui.closePanel();
@ -889,7 +892,7 @@ events.prototype.keyUpFly = function (keycode) {
return; return;
} }
// 商店 ////// 商店界面时的点击操作 //////
events.prototype.clickShop = function(x,y) { events.prototype.clickShop = function(x,y) {
var shop = core.status.event.data.shop; var shop = core.status.event.data.shop;
var choices = shop.choices; var choices = shop.choices;
@ -936,6 +939,7 @@ events.prototype.clickShop = function(x,y) {
} }
} }
////// 商店界面时,按下某个键的操作 //////
events.prototype.keyDownShop = function (keycode) { events.prototype.keyDownShop = function (keycode) {
var shop = core.status.event.data.shop; var shop = core.status.event.data.shop;
var choices = shop.choices; var choices = shop.choices;
@ -951,6 +955,7 @@ events.prototype.keyDownShop = function (keycode) {
} }
} }
////// 商店界面时,放开某个键的操作 //////
events.prototype.keyUpShop = function (keycode) { events.prototype.keyUpShop = function (keycode) {
if (keycode==27 || keycode==88) { if (keycode==27 || keycode==88) {
if (core.status.event.data.fromList) { if (core.status.event.data.fromList) {
@ -971,7 +976,7 @@ events.prototype.keyUpShop = function (keycode) {
return; return;
} }
// 快捷商店 ////// 快捷商店界面时的点击操作 //////
events.prototype.clickQuickShop = function(x, y) { events.prototype.clickQuickShop = function(x, y) {
var shopList = core.status.shops, keys = Object.keys(shopList); var shopList = core.status.shops, keys = Object.keys(shopList);
if (x >= 5 && x <= 7) { if (x >= 5 && x <= 7) {
@ -992,6 +997,7 @@ events.prototype.clickQuickShop = function(x, y) {
} }
} }
////// 快捷商店界面时,按下某个键的操作 //////
events.prototype.keyDownQuickShop = function (keycode) { events.prototype.keyDownQuickShop = function (keycode) {
var shopList = core.status.shops, keys = Object.keys(shopList); var shopList = core.status.shops, keys = Object.keys(shopList);
if (keycode==38) { if (keycode==38) {
@ -1006,6 +1012,7 @@ events.prototype.keyDownQuickShop = function (keycode) {
} }
} }
////// 快捷商店界面时,放开某个键的操作 //////
events.prototype.keyUpQuickShop = function (keycode) { events.prototype.keyUpQuickShop = function (keycode) {
if (keycode==27 || keycode==75 || keycode==88) { if (keycode==27 || keycode==75 || keycode==88) {
core.ui.closePanel(); core.ui.closePanel();
@ -1019,11 +1026,11 @@ events.prototype.keyUpQuickShop = function (keycode) {
return; return;
} }
// 工具栏 ////// 工具栏界面时的点击操作 //////
events.prototype.clickToolbox = function(x,y) { events.prototype.clickToolbox = function(x,y) {
// 返回 // 返回
if (x>=10 && x<=12 && y==12) { if (x>=10 && x<=12 && y==12) {
core.ui.closePanel(false); core.ui.closePanel();
return; return;
} }
var index=0; var index=0;
@ -1033,6 +1040,7 @@ events.prototype.clickToolbox = function(x,y) {
this.clickToolboxIndex(index); this.clickToolboxIndex(index);
} }
////// 选择工具栏界面中某个Index后的操作 //////
events.prototype.clickToolboxIndex = function(index) { events.prototype.clickToolboxIndex = function(index) {
var items = null; var items = null;
var ii=index; var ii=index;
@ -1053,6 +1061,7 @@ events.prototype.clickToolboxIndex = function(index) {
} }
} }
////// 工具栏界面时,按下某个键的操作 //////
events.prototype.keyDownToolbox = function (keycode) { events.prototype.keyDownToolbox = function (keycode) {
if (!core.isset(core.status.event.data)) return; if (!core.isset(core.status.event.data)) return;
@ -1116,6 +1125,7 @@ events.prototype.keyDownToolbox = function (keycode) {
} }
} }
////// 工具栏界面时,放开某个键的操作 //////
events.prototype.keyUpToolbox = function (keycode) { events.prototype.keyUpToolbox = function (keycode) {
if (keycode==84 || keycode==27 || keycode==88) { if (keycode==84 || keycode==27 || keycode==88) {
core.ui.closePanel(); core.ui.closePanel();
@ -1129,7 +1139,7 @@ events.prototype.keyUpToolbox = function (keycode) {
} }
} }
// 存读档 ////// 存读档界面时的点击操作 //////
events.prototype.clickSL = function(x,y) { events.prototype.clickSL = function(x,y) {
// 上一页 // 上一页
if ((x == 3 || x == 4) && y == 12) { if ((x == 3 || x == 4) && y == 12) {
@ -1141,7 +1151,7 @@ events.prototype.clickSL = function(x,y) {
} }
// 返回 // 返回
if (x>=10 && x<=12 && y==12) { if (x>=10 && x<=12 && y==12) {
core.ui.closePanel(false); core.ui.closePanel();
if (!core.isPlaying()) { if (!core.isPlaying()) {
core.showStartAnimate(); core.showStartAnimate();
} }
@ -1162,6 +1172,7 @@ events.prototype.clickSL = function(x,y) {
} }
} }
////// 存读档界面时,按下某个键的操作 //////
events.prototype.keyDownSL = function(keycode) { events.prototype.keyDownSL = function(keycode) {
if (keycode==37) { // left if (keycode==37) { // left
core.ui.drawSLPanel(core.status.event.data - 1); core.ui.drawSLPanel(core.status.event.data - 1);
@ -1189,6 +1200,7 @@ events.prototype.keyDownSL = function(keycode) {
} }
} }
////// 存读档界面时,放开某个键的操作 //////
events.prototype.keyUpSL = 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)) { if (keycode==27 || keycode==88 || (core.status.event.id == 'save' && keycode==83) || (core.status.event.id == 'load' && keycode==68)) {
core.ui.closePanel(); core.ui.closePanel();
@ -1203,6 +1215,7 @@ events.prototype.keyUpSL = function (keycode) {
} }
} }
////// 系统设置界面时的点击操作 //////
events.prototype.clickSwitchs = function (x,y) { events.prototype.clickSwitchs = function (x,y) {
if (x<5 || x>7) return; if (x<5 || x>7) return;
var choices = [ var choices = [
@ -1256,6 +1269,7 @@ events.prototype.clickSwitchs = function (x,y) {
} }
} }
////// 系统设置界面时,按下某个键的操作 //////
events.prototype.keyDownSwitchs = function (keycode) { events.prototype.keyDownSwitchs = function (keycode) {
var choices = [ var choices = [
"背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单" "背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单"
@ -1272,6 +1286,7 @@ events.prototype.keyDownSwitchs = function (keycode) {
} }
} }
////// 系统设置界面时,放开某个键的操作 //////
events.prototype.keyUpSwitchs = function (keycode) { events.prototype.keyUpSwitchs = function (keycode) {
if (keycode==27 || keycode==88) { if (keycode==27 || keycode==88) {
core.status.event.selection=0; core.status.event.selection=0;
@ -1288,7 +1303,7 @@ events.prototype.keyUpSwitchs = function (keycode) {
} }
// 菜单栏 ////// 系统菜单栏界面时的点击事件 //////
events.prototype.clickSettings = function (x,y) { events.prototype.clickSettings = function (x,y) {
if (x<5 || x>7) return; if (x<5 || x>7) return;
var choices = [ var choices = [
@ -1335,6 +1350,7 @@ events.prototype.clickSettings = function (x,y) {
return; return;
} }
////// 系统菜单栏界面时,按下某个键的操作 //////
events.prototype.keyDownSettings = function (keycode) { events.prototype.keyDownSettings = function (keycode) {
var choices = [ var choices = [
"系统设置", "快捷商店", "同步存档", "重新开始", "操作帮助", "关于本塔", "返回游戏" "系统设置", "快捷商店", "同步存档", "重新开始", "操作帮助", "关于本塔", "返回游戏"
@ -1351,6 +1367,7 @@ events.prototype.keyDownSettings = function (keycode) {
} }
} }
////// 系统菜单栏界面时,放开某个键的操作 //////
events.prototype.keyUpSettings = function (keycode) { events.prototype.keyUpSettings = function (keycode) {
if (keycode==27 || keycode==88) { if (keycode==27 || keycode==88) {
core.ui.closePanel(); core.ui.closePanel();
@ -1365,6 +1382,7 @@ events.prototype.keyUpSettings = function (keycode) {
} }
} }
////// 同步存档界面时的点击操作 //////
events.prototype.clickSyncSave = function (x,y) { events.prototype.clickSyncSave = function (x,y) {
if (x<5 || x>7) return; if (x<5 || x>7) return;
var choices = [ var choices = [
@ -1400,6 +1418,7 @@ events.prototype.clickSyncSave = function (x,y) {
return; return;
} }
////// 同步存档界面时,按下某个键的操作 //////
events.prototype.keyDownSyncSave = function (keycode) { events.prototype.keyDownSyncSave = function (keycode) {
var choices = [ var choices = [
"同步存档到服务器", "从服务器加载存档", "清空本地存档", "返回主菜单" "同步存档到服务器", "从服务器加载存档", "清空本地存档", "返回主菜单"
@ -1416,6 +1435,7 @@ events.prototype.keyDownSyncSave = function (keycode) {
} }
} }
////// 同步存档界面时,放开某个键的操作 //////
events.prototype.keyUpSyncSave = function (keycode) { events.prototype.keyUpSyncSave = function (keycode) {
if (keycode==27 || keycode==88) { if (keycode==27 || keycode==88) {
core.status.event.selection=2; core.status.event.selection=2;
@ -1431,11 +1451,11 @@ events.prototype.keyUpSyncSave = function (keycode) {
} }
} }
////// “关于”界面时的点击操作 //////
events.prototype.clickAbout = function () { events.prototype.clickAbout = function () {
if (core.isPlaying()) if (core.isPlaying())
core.ui.closePanel(false); core.ui.closePanel();
else else
core.showStartAnimate(); core.showStartAnimate();
} }
/*********** 点击事件 END ***************/

View File

@ -8,6 +8,8 @@ main.floors.MT0 = {
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
"canUseQuickShop": true, // 该层是否允许使用快捷商店 "canUseQuickShop": true, // 该层是否允许使用快捷商店
"defaultGround": "ground", // 默认地面的图块IDterrains中 "defaultGround": "ground", // 默认地面的图块IDterrains中
// "color": [0,0,0,0.3], // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。
// "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
"map": [ // 地图数据需要是13x13建议使用地图生成器来生成 "map": [ // 地图数据需要是13x13建议使用地图生成器来生成
], ],

View File

@ -8,6 +8,8 @@ main.floors.sample0 = {
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
"canUseQuickShop": true, // 该层是否允许使用快捷商店 "canUseQuickShop": true, // 该层是否允许使用快捷商店
"defaultGround": "ground", // 默认地面的图块IDterrains中 "defaultGround": "ground", // 默认地面的图块IDterrains中
// "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。
"bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
"map": [ // 地图数据需要是13x13建议使用地图生成器来生成 "map": [ // 地图数据需要是13x13建议使用地图生成器来生成
[0, 0, 220, 0, 0, 20, 87, 3, 65, 64, 44, 43, 42], [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], [0, 246, 0, 246, 0, 20, 0, 3, 58, 59, 60, 61, 41],

View File

@ -8,6 +8,8 @@ main.floors.sample1 = {
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
"canUseQuickShop": true, // 该层是否允许使用快捷商店 "canUseQuickShop": true, // 该层是否允许使用快捷商店
"defaultGround": "grass", // 默认地面的图块IDterrains中 "defaultGround": "grass", // 默认地面的图块IDterrains中
// "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。
// "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
"map": [ // 地图数据需要是13x13建议使用地图生成器来生成 "map": [ // 地图数据需要是13x13建议使用地图生成器来生成
[7, 131, 8, 152, 9, 130, 10, 152, 166, 165, 132, 165, 166], [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], [0, 0, 0, 0, 0, 0, 0, 152, 165, 164, 0, 162, 165],

View File

@ -8,7 +8,8 @@ main.floors.sample2 = {
"canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
"canUseQuickShop": true, // 该层是否允许使用快捷商店 "canUseQuickShop": true, // 该层是否允许使用快捷商店
"defaultGround": "snowGround", // 默认地面的图块IDterrains中 "defaultGround": "snowGround", // 默认地面的图块IDterrains中
"color": [255,0,0,0.3], // 可以设置该层的默认背景色调RGBA本项可省略 "color": [255,0,0,0.3], // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。
"bgm": "qianjin.mid", // 到达该层后默认播放的BGM。本项可忽略。
"map": [ // 地图数据需要是13x13建议使用地图生成器来生成 "map": [ // 地图数据需要是13x13建议使用地图生成器来生成
[5, 5, 5, 5, 5, 5, 87, 5, 5, 5, 5, 5, 5], [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], [5, 4, 4, 4, 4, 1, 0, 1, 4, 4, 4, 4, 5],

View File

@ -2,6 +2,7 @@ function items() {
} }
////// 初始化 //////
items.prototype.init = function () { items.prototype.init = function () {
this.items = { this.items = {
// 钥匙 // 钥匙
@ -59,7 +60,7 @@ items.prototype.init = function () {
} }
} }
// 初始化道具 ////// 获得所有道具 //////
items.prototype.getItems = function () { items.prototype.getItems = function () {
// 大黄门钥匙?钥匙盒? // 大黄门钥匙?钥匙盒?
if (core.flags.bigKeyIsBox) if (core.flags.bigKeyIsBox)
@ -74,7 +75,7 @@ items.prototype.getItems = function () {
main.instance.items = new items(); main.instance.items = new items();
////// “即捡即用类”道具的使用效果 //////
items.prototype.getItemEffect = function(itemId, itemNum) { items.prototype.getItemEffect = function(itemId, itemNum) {
var itemCls = core.material.items[itemId].cls; var itemCls = core.material.items[itemId].cls;
// 消耗品 // 消耗品
@ -115,6 +116,7 @@ items.prototype.getItemEffect = function(itemId, itemNum) {
} }
} }
////// “即捡即用类”道具的文字提示 //////
items.prototype.getItemEffectTip = function(itemId) { items.prototype.getItemEffectTip = function(itemId) {
if (itemId === 'redJewel') return ",攻击+"+core.values.redJewel; if (itemId === 'redJewel') return ",攻击+"+core.values.redJewel;
if (itemId === 'blueJewel') return ",防御+"+core.values.blueJewel; if (itemId === 'blueJewel') return ",防御+"+core.values.blueJewel;
@ -140,14 +142,12 @@ items.prototype.getItemEffectTip = function(itemId) {
return ""; return "";
} }
////// 使用道具 //////
items.prototype.useItem = function (itemId) { items.prototype.useItem = function (itemId) {
// 使用道具
if (!this.canUseItem(itemId)) return; if (!this.canUseItem(itemId)) return;
var itemCls = core.material.items[itemId].cls; 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=='fly') core.ui.drawFly(core.status.hero.flyRange.indexOf(core.status.floorId));
if (itemId == 'earthquake' || itemId == 'bomb' || itemId == 'pickaxe' || itemId=='icePickaxe' if (itemId == 'earthquake' || itemId == 'bomb' || itemId == 'pickaxe' || itemId=='icePickaxe'
|| itemId == 'snow' || itemId == 'hammer' || itemId=='bigKey') { || itemId == 'snow' || itemId == 'hammer' || itemId=='bigKey') {
@ -198,12 +198,11 @@ items.prototype.useItem = function (itemId) {
delete core.status.hero.items[itemCls][itemId]; delete core.status.hero.items[itemCls][itemId];
} }
////// 当前能否使用道具 //////
items.prototype.canUseItem = function (itemId) { items.prototype.canUseItem = function (itemId) {
// 没有道具 // 没有道具
if (!core.hasItem(itemId)) return false; if (!core.hasItem(itemId)) return false;
var itemCls = core.material.items[itemId].cls;
if (itemId == 'book') return true; if (itemId == 'book') return true;
if (itemId == 'fly') return core.status.hero.flyRange.indexOf(core.status.floorId)>=0; if (itemId == 'fly') return core.status.hero.flyRange.indexOf(core.status.floorId)>=0;
if (itemId == 'pickaxe') { if (itemId == 'pickaxe') {

View File

@ -1,6 +1,7 @@
function maps() {} function maps() {}
maps.prototype.init = function() {} maps.prototype.init = function() {}
////// 加载某个楼层(从剧本或存档中) //////
maps.prototype.loadFloor = function (floorId, map) { maps.prototype.loadFloor = function (floorId, map) {
var floor = core.floors[floorId]; var floor = core.floors[floorId];
var content = {}; var content = {};
@ -44,6 +45,7 @@ maps.prototype.loadFloor = function (floorId, map) {
return content; return content;
} }
////// 数字和ID的对应关系 //////
maps.prototype.getBlock = function (x, y, id) { maps.prototype.getBlock = function (x, y, id) {
var enable=null; var enable=null;
id = ""+id; 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 == 14) tmp.event = {'cls': 'animates', 'id': 'curseNet', 'noPass': false, 'trigger': 'passNet'}; // 咒网
if (id == 15) tmp.event = {'cls': 'animates', 'id': 'water', 'noPass': true}; // 水 if (id == 15) tmp.event = {'cls': 'animates', 'id': 'water', 'noPass': true}; // 水
// 在这里添加更多地形 // 在这里添加更多地形
// 如果空不足可以从180以后开始继续放只要不和现有的数字冲突即可 // 如果空不足可以从180以后开始继续放只要不和现有的数字冲突即可
// Autotile // Autotile
if (id == 20) tmp.event = {'cls': 'autotile', 'id': 'autotile', 'noPass': true}; // 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 == 151) tmp.event = {'cls': 'autotile', 'id': 'autotile1', 'noPass': true};
if (id == 152) tmp.event = {'cls': 'autotile', 'id': 'autotile2', 'noPass': true}; if (id == 152) tmp.event = {'cls': 'autotile', 'id': 'autotile2', 'noPass': true};
if (id == 153) tmp.event = {'cls': 'autotile', 'id': 'autotile3', '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; return tmp;
} }
////// 向该楼层添加剧本的自定义事件 //////
maps.prototype.addEvent = function (block, x, y, event, ground) { maps.prototype.addEvent = function (block, x, y, event, ground) {
if (!core.isset(event)) return; if (!core.isset(event)) return;
if (!core.isset(block.event)) { // 本身是空地? 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) { maps.prototype.addChangeFloor = function (block, x, y, event, ground) {
if (!core.isset(event)) return; if (!core.isset(event)) return;
this.addEvent(block, x, y, {"trigger": "changeFloor", "data": event}, ground); this.addEvent(block, x, y, {"trigger": "changeFloor", "data": event}, ground);
} }
////// 初始化所有地图 //////
maps.prototype.initMaps = function (floorIds) { maps.prototype.initMaps = function (floorIds) {
var maps = {}; var maps = {};
for (var i=0;i<floorIds.length;i++) { for (var i=0;i<floorIds.length;i++) {
@ -305,6 +310,7 @@ maps.prototype.initMaps = function (floorIds) {
return maps; return maps;
} }
////// 将当前地图重新变成数字,以便于存档 //////
maps.prototype.save = function(maps, floorId) { maps.prototype.save = function(maps, floorId) {
if (!core.isset(floorId)) { if (!core.isset(floorId)) {
var map = {}; var map = {};
@ -334,6 +340,7 @@ maps.prototype.save = function(maps, floorId) {
return blocks; return blocks;
} }
////// 将存档中的地图信息重新读取出来 //////
maps.prototype.load = function (data, floorId) { maps.prototype.load = function (data, floorId) {
if (floorId == undefined) { if (floorId == undefined) {
var map = {}; var map = {};

View File

@ -12,17 +12,12 @@ ui.prototype.init = function () {
main.instance.ui = new ui(); main.instance.ui = new ui();
/** ////// 结束一切事件和绘制关闭UI窗口返回游戏进程 //////
* 关闭一切UI窗口 ui.prototype.closePanel = function () {
* @param clearData 是否同时清掉data层
*/
ui.prototype.closePanel = function (clearData) {
core.status.boxAnimateObjs = []; core.status.boxAnimateObjs = [];
core.setBoxAnimate(); core.setBoxAnimate();
core.clearMap('ui', 0, 0, 416, 416); core.clearMap('ui', 0, 0, 416, 416);
core.setAlpha('ui', 1.0); core.setAlpha('ui', 1.0);
if (core.isset(clearData) && clearData)
core.clearMap('data', 0, 0, 416, 416);
core.unLockControl(); core.unLockControl();
core.status.event.data = null; core.status.event.data = null;
core.status.event.id = null; core.status.event.id = null;
@ -30,12 +25,7 @@ ui.prototype.closePanel = function (clearData) {
core.status.event.ui = null; core.status.event.ui = null;
} }
////// 绘制一个对话框 //////
/**
* 绘制对话框
* @param content
* @param id
*/
ui.prototype.drawTextBox = function(content) { ui.prototype.drawTextBox = function(content) {
// 获得name, image, icon // 获得name, image, icon
@ -137,7 +127,7 @@ ui.prototype.drawTextBox = function(content) {
core.fillText('ui', '<点击任意位置继续>', 270, top+height-13, '#CCCCCC', '13px Verdana'); core.fillText('ui', '<点击任意位置继续>', 270, top+height-13, '#CCCCCC', '13px Verdana');
} }
// 绘制选项事件 ////// 绘制一个选项界面 //////
ui.prototype.drawChoices = function(content, choices) { ui.prototype.drawChoices = function(content, choices) {
var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
@ -273,12 +263,7 @@ ui.prototype.drawChoices = function(content, choices) {
return; return;
} }
/** ////// 绘制一个确认/取消的警告页面 //////
* 绘制确认/取消警告
* @param text
* @param yesCallback
* @param noCallback
*/
ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
core.lockControl(); core.lockControl();
@ -327,10 +312,8 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
} }
////// 绘制开关界面 ////// ////// 绘制系统设置界面 //////
ui.prototype.drawSwitchs = function() { ui.prototype.drawSwitchs = function() {
// 背景音乐、背景音效、战斗动画、怪物显伤、领域显伤、返回
core.status.event.id = 'switchs'; core.status.event.id = 'switchs';
var choices = [ var choices = [
@ -345,10 +328,7 @@ ui.prototype.drawSwitchs = function() {
} }
/** ////// 绘制系统菜单栏 //////
* 绘制菜单栏
* @param need
*/
ui.prototype.drawSettings = function (need) { ui.prototype.drawSettings = function (need) {
if (!core.checkStatus('settings', need)) if (!core.checkStatus('settings', need))
return; return;
@ -358,6 +338,7 @@ ui.prototype.drawSettings = function (need) {
]); ]);
} }
////// 绘制快捷商店选择栏 //////
ui.prototype.drawQuickShop = function (need) { ui.prototype.drawQuickShop = function (need) {
if (core.isset(need) && !core.checkStatus('selectShop', need)) if (core.isset(need) && !core.checkStatus('selectShop', need))
return; return;
@ -374,7 +355,7 @@ ui.prototype.drawQuickShop = function (need) {
this.drawChoices(null, choices); this.drawChoices(null, choices);
} }
////// 绘制战斗动画 //////
ui.prototype.drawBattleAnimate = function(monsterId, callback) { ui.prototype.drawBattleAnimate = function(monsterId, callback) {
// UI层 // UI层
@ -662,10 +643,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
}, 500); }, 500);
} }
/** ////// 绘制等待界面 //////
* 绘制请等候...
* @param text
*/
ui.prototype.drawWaiting = function(text) { ui.prototype.drawWaiting = function(text) {
core.lockControl(); core.lockControl();
@ -685,9 +663,7 @@ ui.prototype.drawWaiting = function(text) {
} }
/** ////// 绘制存档同步界面 //////
* 绘制存档同步选项
*/
ui.prototype.drawSyncSave = function () { ui.prototype.drawSyncSave = function () {
core.status.event.id = 'syncSave'; core.status.event.id = 'syncSave';
@ -698,11 +674,7 @@ ui.prototype.drawSyncSave = function () {
} }
/** ////// 绘制分页 //////
* 绘制分页
* @param page
* @param totalPage
*/
ui.prototype.drawPagination = function (page, totalPage) { ui.prototype.drawPagination = function (page, totalPage) {
core.setFont('ui', 'bold 15px Verdana'); core.setFont('ui', 'bold 15px Verdana');
@ -724,11 +696,8 @@ ui.prototype.drawPagination = function (page, totalPage) {
} }
/** ////// 绘制怪物手册 //////
* 绘制怪物手册 ui.prototype.drawBook = function (index) {
* @param index 怪物索引
*/
ui.prototype.drawEnemyBook = function (index) {
var enemys = core.enemys.getCurrentEnemys(); var enemys = core.enemys.getCurrentEnemys();
var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
@ -844,6 +813,7 @@ ui.prototype.drawEnemyBook = function (index) {
this.drawPagination(page, totalPage); this.drawPagination(page, totalPage);
} }
////// 绘制怪物属性的详细信息 //////
ui.prototype.drawBookDetail = function (index) { ui.prototype.drawBookDetail = function (index) {
var enemys = core.enemys.getCurrentEnemys(); var enemys = core.enemys.getCurrentEnemys();
if (enemys.length==0) return; if (enemys.length==0) return;
@ -906,10 +876,7 @@ ui.prototype.drawBookDetail = function (index) {
core.fillText('data', '<点击任意位置继续>', 270, top+height-13, '#CCCCCC', '13px Verdana'); core.fillText('data', '<点击任意位置继续>', 270, top+height-13, '#CCCCCC', '13px Verdana');
} }
/** ////// 绘制楼层传送器 //////
* 绘制楼传器
* @param page
*/
ui.prototype.drawFly = function(page) { ui.prototype.drawFly = function(page) {
if (page<0) page=0; 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); this.drawThumbnail(floorId, 'ui', core.status.maps[floorId].blocks, 20, 100, 273);
} }
////// 绘制道具栏 //////
ui.prototype.drawToolbox = function(index) { ui.prototype.drawToolbox = function(index) {
var tools = Object.keys(core.status.hero.items.tools).sort(); 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'); core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px Verdana');
} }
////// 绘制存档/读档界面 //////
ui.prototype.drawSLPanel = function(index) { ui.prototype.drawSLPanel = function(index) {
if (!core.isset(index)) index=1; if (!core.isset(index)) index=1;
if (index<=0) index=1; if (index<=0) index=1;
@ -1103,6 +1071,7 @@ ui.prototype.drawSLPanel = function(index) {
this.drawPagination(page+1, 30); this.drawPagination(page+1, 30);
} }
////// 绘制一个缩略图 //////
ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroLoc) { ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroLoc) {
core.clearMap(canvas, x, y, size, size); core.clearMap(canvas, x, y, size, size);
var groundId = core.floors[floorId].defaultGround || "ground"; 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() { ui.prototype.drawAbout = function() {
if (!core.isPlaying()) { 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', "作者: 艾之葵", text_start, top + 80, "#FFFFFF", "bold 17px Verdana");
core.fillText('ui', 'HTML5魔塔交流群539113091', text_start, top+112); core.fillText('ui', 'HTML5魔塔交流群539113091', text_start, top+112);
// TODO: 写自己的“关于”页面 // 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 () { ui.prototype.drawHelp = function () {
core.drawText([ core.drawText([
"\t[键盘快捷键列表]"+ "\t[键盘快捷键列表]"+

View File

@ -1,4 +1,5 @@
全键盘操作 √ 全键盘操作 √
便捷PS工具支持更改图片色相 √
经验升级(进阶) √ 经验升级(进阶) √
增加阻击、多连击等属性;属性显示;加点; √ 增加阻击、多连击等属性;属性显示;加点; √
九宫格领域、大范围领域 √ 九宫格领域、大范围领域 √