Update ReadMe

This commit is contained in:
oc 2017-12-21 19:22:24 +08:00
parent 9d07b2ba22
commit fa954f590d
9 changed files with 133 additions and 53 deletions

View File

@ -10,6 +10,36 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
![样板](./docs/img/sample0.png) ![样板](./docs/img/sample0.png)
## 目录结构
``` bash
├── /docs/ # 文档目录
├── /images/ # 所有图片素材目录
│ ├─ /常用素材/ # 可以被直接替换的素材
│ └─ *.png # 对应的某个具体的图片素材
├── /libs/ # JS源代码目录
│ ├─ /floors/ # 剧本文件,记录了每个地图的数据和事件
│ ├─ core.js # 系统核心文件,处理了所有逻辑等事件
│ ├─ data.js # 记录了勇士的初始化信息、各个全局变量和全局Flag值
│ ├─ enemys.js # 记录了怪物的信息,包括怪物的数据和特殊属性、伤害计算公式、临界值计算等。
│ ├─ events.js # 处理事件的文件,所有系统或自定义事件都会在此文件中进行处理
│ ├─ icons.js # 记录了图标信息将元件的ID和images目录下的素材图标对应起来
│ ├─ items.js # 记录了道具的信息,包括道具说明、道具效果等。
│ ├─ maps.js # 记录了地图信息负责将数字与元件的ID一一对应起来。
│ └─ ui.js # UI绘制信息主要负责绘制各个UI窗口。
├── /sounds/ # 音效目录
├── /常用工具/ # 一些常用工具,可以辅助造塔
│ ├─ JS代码压缩工具.exe # 能对Javascript代码进行压缩和整合从而减少IO请求量
│ ├─ 便捷PS工具.exe # 能只用复制和粘贴来快速对素材进行PS操作
│ ├─ 地图生成器.exe # 能从一张截图识别出来具体的数字数组,方便复刻已有的塔
│ └─ 伤害和临界值计算器.exe # 一个能帮助计算怪物的伤害和临界值的小工具
├── drawMapGUI.html # 可视化地图编辑工具,能简单地在界面上绘制地图
├── index.html # 主程序,游戏的入口
├── main.js # JS程序的入口将动态对所需JS进行加载
├── style.css # 游戏所需要用到的样式表
└── 启动服务.exe # 一个本地的HTTP服务器也能支撑前端的一些POST请求从而能拓展JS的IO功能。
```
## 更新说明 ## 更新说明
### 2017.12.20 ### 2017.12.20

View File

@ -215,6 +215,18 @@
![调试](./img/eventdebug.png) ![调试](./img/eventdebug.png)
### tip显示一段提示文字
`{"type": "tip"}`可以在左上角显示一段提示文字。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "tip", "text": "这段话将在左上角以气泡形式显示"}
]
```
值得注意的是提示的text内容是可以使用`${ }`来计算表达式的值的。
### setValue设置勇士的某个属性、道具个数或某个变量/Flag的值 ### setValue设置勇士的某个属性、道具个数或某个变量/Flag的值
`{"type": "setValue"}` 能修改勇士的某个属性、道具个数、或某个自定义变量或`Flag`的值。 `{"type": "setValue"}` 能修改勇士的某个属性、道具个数、或某个自定义变量或`Flag`的值。
@ -245,6 +257,7 @@ value是一个表达式将通过这个表达式计算出的结果赋值给nam
] ]
``` ```
另外注意一点的是如果hp被设置成了0或以下将触发lose事件直接死亡。
### show: 将一个禁用事件启用 ### show: 将一个禁用事件启用
@ -456,14 +469,15 @@ time为可选的指定的话将作为楼层切换动画的时间。
``` js ``` js
"x,y": [ // 实际执行的事件列表 "x,y": [ // 实际执行的事件列表
{"type": "setFg", "color": [255,255,255], "time": 1000}, // 更改画面色调为纯白动画时间1000毫秒 {"type": "setFg", "color": [255,255,255,0.6], "time": 1000}, // 更改画面色调为纯白不透明度0.6动画时间1000毫秒
{"type": "setFg", "color": [0,0,0]}, // 更改画面色调为纯黑,不指定动画时间(使用默认时间) {"type": "setFg", "color": [0,0,0]}, // 更改画面色调为纯黑,不透明度1指定动画时间(使用默认时间)
{"type": "setFg"} // 如果不指定color则恢复原样。 {"type": "setFg"} // 如果不指定color则恢复原样。
] ]
``` ```
color为需要更改画面色调的颜色。它是一个三元数组分别指定目标颜色的R,G,B值。 color为需要更改画面色调的颜色。它是一个数组分别指定目标颜色的R,G,B,A值。
- 常见颜色: 纯黑[0,0,0],纯白[255,255,255],纯红[255,0,0],等等。 - 常见RGB颜色 纯黑[0,0,0],纯白[255,255,255],纯红[255,0,0],等等。
- 第四元为Alpha值即不透明度为一个0到1之间的数。可以不指定则默认为Alpha=1
如果color不指定则恢复原样。 如果color不指定则恢复原样。
@ -535,7 +549,7 @@ move完毕后移动的NPC/怪物一定会消失只不过可以通过immediate
] ]
``` ```
可以看到和上面的move事件几乎完全相同除了少了immediateHide选项。 可以看到和上面的move事件几乎完全相同除了不能指定loc少了immediateHide选项。
不过值得注意的是,用这种方式移动勇士的过程中将无视一切地形,无视一切事件,中毒状态也不会扣血。 不过值得注意的是,用这种方式移动勇士的过程中将无视一切地形,无视一切事件,中毒状态也不会扣血。

View File

@ -527,7 +527,8 @@ core.prototype.keyUp = function(keyCode) {
} }
break; break;
case 50: // 快捷键2 case 50: // 快捷键2
if (core.status.heroStop && core.hasItem('bomb')) { if (core.status.heroStop) {
if (core.hasItem('bomb')) {
if (core.canUseItem('bomb')) { if (core.canUseItem('bomb')) {
core.useItem('bomb'); core.useItem('bomb');
} }
@ -535,6 +536,16 @@ core.prototype.keyUp = function(keyCode) {
core.drawTip('当前不能使用炸弹'); core.drawTip('当前不能使用炸弹');
} }
} }
else if (core.hasItem('hammer')) {
if (core.canUseItem('hammer')) {
core.useItem('hammer');
}
else {
core.drawTip('当前不能使用圣锤');
}
}
}
break; break;
case 51: // 快捷键3 case 51: // 快捷键3
if (core.status.heroStop && core.hasItem('centerFly')) { if (core.status.heroStop && core.hasItem('centerFly')) {
@ -1164,6 +1175,7 @@ core.prototype.setHeroMoveTriggerInterval = function () {
core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
} }
core.trigger(core.getHeroLoc('x'), core.getHeroLoc('y')); core.trigger(core.getHeroLoc('x'), core.getHeroLoc('y'));
core.checkBlock();
clearInterval(core.interval.heroMoveInterval); clearInterval(core.interval.heroMoveInterval);
core.status.heroMoving = false; core.status.heroMoving = false;
}); });
@ -1299,24 +1311,6 @@ core.prototype.moveOneStep = function() {
} }
core.updateStatusBar(); core.updateStatusBar();
} }
// 检查领域、夹击事件
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
if (core.status.checkBlock[13*x+y]>0) {
core.status.hero.hp -= core.status.checkBlock[13*x+y];
if (core.hasBetweenAttack(x,y)) {
core.drawTip('受到夹击,生命变成一半');
}
else if (core.hasZone(x,y)) {
core.drawTip('受到领域伤害'+core.status.checkBlock[13*x+y]+'点');
}
if (core.status.hero.hp<=0) {
core.status.hero.hp=0;
core.updateStatusBar();
core.events.lose('zone');
return;
}
core.updateStatusBar();
}
} }
core.prototype.waitHeroToStop = function(callback) { core.prototype.waitHeroToStop = function(callback) {
@ -2233,19 +2227,23 @@ core.prototype.updateCheckBlock = function() {
}) })
var leftValue = core.status.hero.hp - damage; var leftValue = core.status.hero.hp - damage;
if (leftValue>=0) { if (leftValue>1) {
var has = false;
// 夹击 // 夹击
if (x>0 && x<12) { if (x>0 && x<12) {
var id1=parseInt(core.status.checkBlockMap[13*(x-1)+y]/1000000), var id1=parseInt(core.status.checkBlockMap[13*(x-1)+y]/1000000),
id2=parseInt(core.status.checkBlockMap[13*(x+1)+y]/1000000); id2=parseInt(core.status.checkBlockMap[13*(x+1)+y]/1000000);
if (id1>0 && id1==id2) if (id1>0 && id1==id2)
damage += parseInt(leftValue/2); has = true;
} }
else if (y>0 && y<12) { if (y>0 && y<12) {
var id1=parseInt(core.status.checkBlockMap[13*x+y-1]/1000000), var id1=parseInt(core.status.checkBlockMap[13*x+y-1]/1000000),
id2=parseInt(core.status.checkBlockMap[13*x+y+1]/1000000); id2=parseInt(core.status.checkBlockMap[13*x+y+1]/1000000);
if (id1>0 && id1==id2) if (id1>0 && id1==id2)
damage += parseInt(leftValue/2); has = true;
}
if (has) {
damage += parseInt((leftValue+1) / 2);
} }
} }
} }
@ -2254,6 +2252,27 @@ core.prototype.updateCheckBlock = function() {
} }
} }
core.prototype.checkBlock = function () {
// 检查领域、夹击事件
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
if (core.status.checkBlock[13*x+y]>0) {
core.status.hero.hp -= core.status.checkBlock[13*x+y];
if (core.hasBetweenAttack(x,y)) {
core.drawTip('受到夹击,生命变成一半');
}
else if (core.hasZone(x,y)) {
core.drawTip('受到领域伤害'+core.status.checkBlock[13*x+y]+'点');
}
if (core.status.hero.hp<=0) {
core.status.hero.hp=0;
core.updateStatusBar();
core.events.lose('zone');
return;
}
core.updateStatusBar();
}
}
core.prototype.hasZone = function (x,y) { core.prototype.hasZone = function (x,y) {
if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap(); if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap();
var isZone = false; var isZone = false;
@ -2289,28 +2308,30 @@ core.prototype.setFg = function(color, time, callback) {
time = time || 750; time = time || 750;
core.setOpacity('fg', 1); core.setOpacity('fg', 1);
var fromAlpha = 0; var reset = false;
if (core.isset(core.status.event.data.currentColor)) {
fromAlpha = 1; if (!core.isset(core.status.event.data.currentColor)) {
} core.status.event.data.currentColor = [0,0,0,0];
else {
core.status.event.data.currentColor = [0,0,0];
} }
var fromColor = core.status.event.data.currentColor; var fromColor = core.status.event.data.currentColor;
var toAlpha = 1;
if (!core.isset(color)) { if (!core.isset(color)) {
color = [0,0,0]; color = [0,0,0,0];
toAlpha=0; reset = true;
} }
if (color.length==3) {
color.push(1);
}
if (color[3]<0) color[3]=0;
if (color[3]>1) color[3]=1;
var step=0; var step=0;
var changeAnimate = setInterval(function() { var changeAnimate = setInterval(function() {
step++; step++;
core.clearMap('fg', 0, 0, 416, 416); core.clearMap('fg', 0, 0, 416, 416);
var nowAlpha = fromAlpha+(toAlpha-fromAlpha)*step/25; var nowAlpha = fromColor[3]+(color[3]-fromColor[3])*step/25;
var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/25); var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/25);
var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/25); var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/25);
var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/25); var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/25);
@ -2324,7 +2345,7 @@ core.prototype.setFg = function(color, time, callback) {
if (step>=25) { if (step>=25) {
clearInterval(changeAnimate); clearInterval(changeAnimate);
if (toAlpha==0) { if (reset) {
core.clearMap('fg', 0, 0, 416, 416); core.clearMap('fg', 0, 0, 416, 416);
delete core.status.event.data.currentColor; delete core.status.event.data.currentColor;
core.setAlpha('fg', 1); core.setAlpha('fg', 1);
@ -2383,6 +2404,7 @@ core.prototype.updateFg = function () {
// 如果存在颜色 // 如果存在颜色
if (core.isset(core.status.event.data) && core.isset(core.status.event.data.currentColor)) { if (core.isset(core.status.event.data) && core.isset(core.status.event.data.currentColor)) {
var color=core.status.event.data.currentColor; var color=core.status.event.data.currentColor;
core.setAlpha('fg', color[3]);
core.fillRect("fg",0,0,416,416,"#"+((1<<24)+(color[0]<<16)+(color[1]<<8)+color[2]).toString(16).slice(1)); core.fillRect("fg",0,0,416,416,"#"+((1<<24)+(color[0]<<16)+(color[1]<<8)+color[2]).toString(16).slice(1));
return; return;
} }

View File

@ -124,6 +124,7 @@ data.prototype.init = function() {
/****** 道具相关 ******/ /****** 道具相关 ******/
"flyNearStair": true, // 是否需要在楼梯边使用传送器 "flyNearStair": true, // 是否需要在楼梯边使用传送器
"pickaxeFourDirections": true, // 使用破墙镐是否四个方向都破坏如果false则只破坏面前的墙壁 "pickaxeFourDirections": true, // 使用破墙镐是否四个方向都破坏如果false则只破坏面前的墙壁
"bombFourDirections": true, // 使用炸弹是否四个方向都会炸如果false则只炸面前的怪物即和圣锤等价
"bigKeyIsBox": false, // 如果此项为true则视为钥匙盒红黄蓝钥匙+1若为false则视为大黄门钥匙 "bigKeyIsBox": false, // 如果此项为true则视为钥匙盒红黄蓝钥匙+1若为false则视为大黄门钥匙
/****** 系统相关 ******/ /****** 系统相关 ******/
"startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面 "startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面

View File

@ -163,6 +163,9 @@ events.prototype.doAction = function() {
case "text": // 文字/对话 case "text": // 文字/对话
core.ui.drawTextBox(data.data); core.ui.drawTextBox(data.data);
break; break;
case "tip":
core.drawTip(core.replaceText(data.text));
core.events.doAction();
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 () {
@ -301,8 +304,16 @@ events.prototype.doAction = function() {
} }
} }
catch (e) {console.log(e)} catch (e) {console.log(e)}
if (core.status.hero.hp<=0) {
core.status.hero.hp=0;
core.updateStatusBar();
core.events.lose('damage');
}
else {
core.updateStatusBar(); core.updateStatusBar();
this.doAction(); this.doAction();
}
break; break;
case "if": // 条件判断 case "if": // 条件判断
if (core.calValue(data.condition)) if (core.calValue(data.condition))

View File

@ -59,9 +59,8 @@ main.floors.sample0 = {
"\t[老人,magician]模仿、吸血、中毒、衰弱、诅咒。\n\n请注意吸血怪需要设置value为吸血数值可参见样板中黑暗大法师的写法。", "\t[老人,magician]模仿、吸血、中毒、衰弱、诅咒。\n\n请注意吸血怪需要设置value为吸血数值可参见样板中黑暗大法师的写法。",
{"type": "hide", "time": 500} {"type": "hide", "time": 500}
], ],
"2,3": [ // 守着第三批怪物老人 "2,3": [ // 守着第三批怪物老人
"\t[老人,magician]领域、夹击。\n请注意领域怪需要设置value为伤害数值可参见样板中初级巫师的写法。", "\t[老人,magician]领域、夹击。\n请注意领域怪需要设置value为伤害数值可参见样板中初级巫师的写法。",
"\t[老人,magician]出于游戏性能的考虑,我们不可能每走一步都对领域和夹击进行检查。\n因此我们需要在本楼层的 checkBlock 中指明哪些点可能会触发领域和夹击事件,在这些点才会对领域和夹击进行检查和处理。\n具体可参见本层 checkBlock 的写法。",
"\t[老人,magician]夹击和领域同时发生时先计算领域,再夹击。\n自动寻路同样会尽量绕过你设置的这些点。\n\n另本塔不支持阻击怪。", "\t[老人,magician]夹击和领域同时发生时先计算领域,再夹击。\n自动寻路同样会尽量绕过你设置的这些点。\n\n另本塔不支持阻击怪。",
{"type": "hide", "time": 500} {"type": "hide", "time": 500}
], ],
@ -99,7 +98,7 @@ main.floors.sample0 = {
], ],
"10,5": ["破墙镐是破面前的墙壁还是四个方向的墙壁由data.js中的系统Flag所决定。"], "10,5": ["破墙镐是破面前的墙壁还是四个方向的墙壁由data.js中的系统Flag所决定。"],
"8,4": [ "8,4": [
"炸弹可以炸四个方向的怪物。\n如只需要炸前方怪物请使用上面的圣锤。\n不能被炸的怪物在enemys中可以定义可参见样板里黑衣魔王和黑暗大法师的写法。", "炸弹是只能炸面前的怪物还是四个方向的怪物由data.js中的系统Flag所决定。\n如只能炸前方怪物则和上面的圣锤等价。\n不能被炸的怪物在enemys中可以定义可参见样板里黑衣魔王和黑暗大法师的写法。",
], ],
"10,4": ["“上楼”和“下楼”的目标层由 main.js 的 floorIds顺序所决定。"], "10,4": ["“上楼”和“下楼”的目标层由 main.js 的 floorIds顺序所决定。"],
"10,3": ["十字架目前未被定义,可能需要自行实现功能。\n有关如何实现一个道具功能参见doc文档。"], "10,3": ["十字架目前未被定义,可能需要自行实现功能。\n有关如何实现一个道具功能参见doc文档。"],

View File

@ -13,7 +13,7 @@ main.floors.sample1 = {
[2, 2, 2, 2, 121, 2, 2, 2, 0, 0, 229, 0, 0], [2, 2, 2, 2, 121, 2, 2, 2, 0, 0, 229, 0, 0],
[43, 33, 44, 1, 0, 0, 0, 2, 165, 161, 0, 163, 165], [43, 33, 44, 1, 0, 0, 0, 2, 165, 161, 0, 163, 165],
[21, 22, 21, 1, 0, 0, 0, 2, 166, 165, 0, 165, 166], [21, 22, 21, 1, 0, 0, 0, 2, 166, 165, 0, 165, 166],
[1, 245, 1, 1, 219, 87, 0, 2, 2, 2, 85, 2, 2], [1, 245, 1, 1, 0, 87, 0, 2, 2, 2, 85, 2, 2],
[0, 246, 0, 1, 0, 0, 0, 2, 2, 221, 0, 221, 2], [0, 246, 0, 1, 0, 0, 0, 2, 2, 221, 0, 221, 2],
[246, 0, 246, 1, 0, 0, 0, 121, 85, 0, 0, 0, 2], [246, 0, 246, 1, 0, 0, 0, 121, 85, 0, 0, 0, 2],
[1, 246, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2], [1, 246, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2],
@ -30,7 +30,7 @@ main.floors.sample1 = {
"4,10": [ // 走到中间时的提示 "4,10": [ // 走到中间时的提示
"\t[样板提示]本层楼将会对各类事件进行介绍。", "\t[样板提示]本层楼将会对各类事件进行介绍。",
"左边是一个仿50层的陷阱做法上方是商店、快捷商店的使用方法右上是一个典型的杀怪开门的例子右下是各类可能的NPC事件。", "左边是一个仿50层的陷阱做法上方是商店、快捷商店的使用方法右上是一个典型的杀怪开门的例子右下是各类可能的NPC事件。",
"本样板目前支持的事件列表大致有:\ntext: 显示一段文字(比如你现在正在看到的)\nshow: 使一个事件有效(可见、可被交互)\nhide: 使一个事件失效(不可见、不可被交互)\ntrigger: 触发另一个地点的事件\nbattle: 强制和某怪物战斗\nopenDoor: 无需钥匙开门(例如机关门、暗墙)\nopenShop: 打开一个全局商店\ndisableShop: 禁用一个全局商店\nchangeFloor: 传送勇士到某层某位置\nchangePos: 传送勇士到当层某位置;转向\nsetFg: 更改画面色调", "本样板目前支持的事件列表大致有:\ntext: 显示一段文字(比如你现在正在看到的)\ntip: 左上角显示提示\nshow: 使一个事件有效(可见、可被交互)\nhide: 使一个事件失效(不可见、不可被交互)\ntrigger: 触发另一个地点的事件\nbattle: 强制和某怪物战斗\nopenDoor: 无需钥匙开门(例如机关门、暗墙)\nopenShop: 打开一个全局商店\ndisableShop: 禁用一个全局商店\nchangeFloor: 传送勇士到某层某位置\nchangePos: 传送勇士到当层某位置;转向\nsetFg: 更改画面色调",
"move: 移动事件效果\nmoveHero: 移动勇士效果\nplaySound: 播放某个音频\nif: 条件判断\nchoices: 提供选项\nsetValue: 设置勇士属性道具,或某个变量/flag\nupdate: 更新状态栏和地图显伤\nwin: 获得胜利(游戏通关)\nlose: 游戏失败\nsleep: 等待多少毫秒\nexit: 立刻结束当前事件\nrevisit: 立刻结束事件并重新触发\nfunction: 自定义JS脚本\n更多支持的事件还在编写中欢迎您宝贵的意见。", "move: 移动事件效果\nmoveHero: 移动勇士效果\nplaySound: 播放某个音频\nif: 条件判断\nchoices: 提供选项\nsetValue: 设置勇士属性道具,或某个变量/flag\nupdate: 更新状态栏和地图显伤\nwin: 获得胜利(游戏通关)\nlose: 游戏失败\nsleep: 等待多少毫秒\nexit: 立刻结束当前事件\nrevisit: 立刻结束事件并重新触发\nfunction: 自定义JS脚本\n更多支持的事件还在编写中欢迎您宝贵的意见。",
"有关各事件的样例可参见本层一些NPC的写法。\n所有事件样例本层都有介绍。\n\n一个自定义事件处理完后需要调用{\"type\": \"hide\"}该事件才不会再次出现。", "有关各事件的样例可参见本层一些NPC的写法。\n所有事件样例本层都有介绍。\n\n一个自定义事件处理完后需要调用{\"type\": \"hide\"}该事件才不会再次出现。",
{"type": "hide"} {"type": "hide"}

View File

@ -46,7 +46,7 @@ items.prototype.init = function () {
'steelKey': {'cls': 'tools', 'name': '铁门钥匙', 'text': '可以打开一扇铁门'}, 'steelKey': {'cls': 'tools', 'name': '铁门钥匙', 'text': '可以打开一扇铁门'},
'pickaxe': {'cls': 'tools', 'name': '破墙镐', 'text': '可以破坏勇士面前的墙'}, 'pickaxe': {'cls': 'tools', 'name': '破墙镐', 'text': '可以破坏勇士面前的墙'},
'icePickaxe': {'cls': 'tools', 'name': '破冰镐', 'text': '可以破坏勇士面前的一堵冰墙'}, 'icePickaxe': {'cls': 'tools', 'name': '破冰镐', 'text': '可以破坏勇士面前的一堵冰墙'},
'bomb': {'cls': 'tools', 'name': '炸弹', 'text': '可以炸掉勇士四周的怪物'}, 'bomb': {'cls': 'tools', 'name': '炸弹', 'text': '可以炸掉勇士面前的怪物'},
'centerFly': {'cls': 'tools', 'name': '中心对称飞行器', 'text': '可以飞向当前楼层中心对称的位置'}, 'centerFly': {'cls': 'tools', 'name': '中心对称飞行器', 'text': '可以飞向当前楼层中心对称的位置'},
'upFly': {'cls': 'tools', 'name': '上楼器', 'text': '可以飞往楼上的相同位置'}, 'upFly': {'cls': 'tools', 'name': '上楼器', 'text': '可以飞往楼上的相同位置'},
'downFly': {'cls': 'tools', 'name': '下楼器', 'text': '可以飞往楼下的相同位置'}, 'downFly': {'cls': 'tools', 'name': '下楼器', 'text': '可以飞往楼下的相同位置'},
@ -67,6 +67,8 @@ items.prototype.getItems = function () {
// 面前的墙?四周的墙? // 面前的墙?四周的墙?
if (core.flags.pickaxeFourDirections) if (core.flags.pickaxeFourDirections)
this.items.pickaxe.text = "可以破坏勇士四周的墙"; this.items.pickaxe.text = "可以破坏勇士四周的墙";
if (core.flags.bombFourDirections)
this.items.bomb.text = "可以炸掉勇士四周的怪物";
return this.items; return this.items;
} }
@ -247,6 +249,7 @@ items.prototype.canUseItem = function (itemId) {
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls == 'enemys' && Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) { if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls == 'enemys' && Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) {
var enemy = core.material.enemys[block.event.id]; var enemy = core.material.enemys[block.event.id];
if (core.isset(enemy.bomb) && !enemy.bomb) continue; if (core.isset(enemy.bomb) && !enemy.bomb) continue;
if (core.flags.bombFourDirections || (block.x==core.nextX() && block.y==core.nextY()))
ids.push(i); ids.push(i);
} }
} }

View File

@ -382,7 +382,7 @@ ui.prototype.drawQuickShop = function (need) {
core.fillText('ui', shopList[keys[i]].textInList, 208, top + 56 + 32 * i, "#FFFFFF", "bold 17px Verdana"); core.fillText('ui', shopList[keys[i]].textInList, 208, top + 56 + 32 * i, "#FFFFFF", "bold 17px Verdana");
} }
core.fillText('ui', "返回游戏", 208, top + bottom - 40); core.fillText('ui', "返回游戏", 208, top + bottom - 40, "#FFFFFF", "bold 17px Verdana");
} }
ui.prototype.drawBattleAnimate = function(monsterId, callback) { ui.prototype.drawBattleAnimate = function(monsterId, callback) {