Merge pull request #1 from ckcz123/master

seems that this is the easiest way to update
This commit is contained in:
tocque 2018-11-24 14:22:10 +08:00 committed by GitHub
commit 806ed32f60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 1680 additions and 793 deletions

5
B站视频教程.url Normal file
View File

@ -0,0 +1,5 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2
[InternetShortcut]
IDList=
URL=https://www.bilibili.com/video/av32781473/

View File

@ -2,4 +2,4 @@
Prop3=19,2
[InternetShortcut]
IDList=
URL=https://ckcz123.github.io/mota-js/
URL=https://h5mota.com/games/template/docs/

View File

@ -53,6 +53,23 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
## 更新说明
### 2018.11.21 V2.5.1
* [x] 新增事件type:insert可以插入另一个地点的事件执行公共事件
* [x] 可以使用\r来控制剧情文本部分文字的颜色
* [x] 新增事件type:switch多重分歧
* [x] 绘制前景/背景层时淡化其他图层
* [x] 追加素材的自动调整(如白底、不规范的素材)
* [x] 浏览地图时:左上角/V开启显伤右上角/Z查看当前层大地图
* [x] 允许在受到领域夹击等伤害后禁用快捷商店
* [x] 升级的扣除模式,即不显示经验值,只显示升级的所需剩余值
* [x] 装备增加可装备条件判定
* [x] 选项界面可以使用1-9快速选择
* [x] 未开启状态的快捷商店用灰色显示
* [x] 修复不能在背景/前景层绘图的Bug
* [x] 手机端的地图编辑器也能有报错信息了
* [x] 部分其他细节优化
### 2018.10.31 V2.5
* [x] 添加绘图模式支持;可以用户手动绘图和保存

View File

@ -1,78 +0,0 @@
这只是一个最简单的造塔流程,更为详细的还是请参见视频或教程文档。
1. 打开启动服务,地图编辑器。
2. 切换到MT0层然后开始绘制地图。可以在上面放置墙、门、道具或怪物等。
如果提示“该素材未被定义”请参见第7点。
如果要从RMXP中复刻已有的塔的地图请参见第11点。
3. 切换到楼层属性一项一项仔细进行楼层属性的编辑如楼层名firstArrive等等。
将鼠标移动到表格的中间可以查看详细信息。
firstArrive为初次到达楼层的事件可以双击进行事件的编辑。有关事件请详见文档。
3. 输入怪物数据:点击右边怪物,然后左边写怪物的攻防血等数值。
将鼠标移动到表格的中间可以查看详细信息。
如果是特殊属性怪物直接写特殊编号,多个特殊属性可以用 [1,2] 来表示。
4. 在中间的下拉框切换全塔属性,一项一项仔细进行根据需求编辑。
请注意"name"一项必须修改为“字母、数字、下划线组成的字符串”,否则会出现串档问题。
startText初始剧情、shops全局商店、levelUp升级等都是可以双击方框进行编辑的。
有关全局商店和升级等信息详见 教程文档 - 事件
5. 给地图添加事件可以给地图上的NPC增加事件或者战斗/开门事件等。
点击地图上的某个点,在左边进行编辑。
event -- 该点的自定义事件例如NPC商店等等
changeFloor -- 该点的楼层传送事件(楼梯/传送门)
afterBattle -- 该点战斗后触发的战后事件
afterOpenDoor -- 该点开门后触发的事件
afterGetItem -- 该点获得道具后触发的事件
等等。
有关事件详细内容请参见 文档 - 事件。
6. 新建楼层切换到地图编辑然后在框内输入新楼层的floorId点击新建地图即可保存。
创建的floorId必须是字母、数字和下划线组成且不能以数字开头。
不能为空白不能和任何已有楼层的floorId重复。
保存成功后刷新页面。
删除楼层同理,不过请注意删除的会是当前的楼层而不是框中的内容。
7. 关于素材未被定义的问题如果点击某个怪物或NPC提示该素材未被定义请在左边进行素材的注册。
输入该素材的唯一ID不能和其他素材的ID重复和素材的唯一数字1000以内不能和其他的数字重复
保存并刷新,即注册成功。
8. 添加新素材请打开启动服务的便捷PS工具然后左边读取你要添加到的图片比如怪物是enemys.png道具是items.png
右边读取你要导入的怪物素材通过复制粘贴进行导入再保存刷新页面后按照第7点来进行素材的注册。
9. 道具的自定义效果:如果需要自定义道具效果,请仿照其他的几个道具来写,更多信息详见文档。
10. 报错处理:有时候刷新后可能页面变成空白,即无法正确加载。
出现这种问题的原因往往是手动错误编辑了文件、新建楼层使用了不合法的floorId比如中文或数字、楼层floorId定义重复等等。
出现这种问题在Chrome浏览器中请按Ctrl+Shift+I打开控制台找到Console查看报错。
一般都会具体到哪个楼层文件出错。
解决方式哪个楼层文件出错请使用VSCode等打开project目录下的data.js文件并将出错的那个楼层定义删除。
举例,比如我在新建地图中写了 “水潭边” 这样一个楼层名(中文),然后新建并保存,刷新会出错。
此时打开控制台Ctrl+Shift+I的Console并查看报错发现是该楼层错误。
那么打开data.js文件并将 "floorIds": [..., "水潭边"] 这里对它的楼层定义删除,再刷新即可。
11. 从RMXP中导入已有的塔的地图。
如果你想复刻老塔,则需使用启动服务的地图生成器。
请确保老地图中的所有使用素材(地面/墙壁/门/道具/怪物等等都已经被注册过参见第7点
打开windows自带的截图工具并对地图进行截图。
截图时请注意必须截刚好13x13范围大小的地图尽量对其边缘进行截取。
如果不是13x13的范围大小可能会导致地图生成器无响应。
截图完毕后请复制到剪切板然后在地图生成器中点加载图片。等1-2秒就可以看到截图被识别。
点“复制地图”,然后在地图编辑器中切换到“地图编辑”,并粘贴到左边的框内,即可。
如果存在个别识别问题,可以对这个别素材再进行重新绘制。
如果出现大量识别问题,比如基本全是错的,则代表你的截图方式有问题。
由于地图生成器的识别以左上角的图块为基准来找寻截图偏移量,请确保左上角一定要是一个能被很好识别的图块。
建议在RM的图层第三层左上角放一个岩浆再进行截图保证截图的13x13的左上角是岩浆从而可以确保定位
识别后再复制到地图编辑器中进行绘制。
--------------------------------
HTML5魔塔交流群539113091如果有问题请加群提问。

View File

@ -192,6 +192,7 @@ action
| show_s
| hide_s
| trigger_s
| insert_s
| revisit_s
| exit_s
| setBlock_s
@ -238,6 +239,7 @@ action
| win_s
| lose_s
| if_s
| switch_s
| while_s
| break_s
| continue_s
@ -480,6 +482,20 @@ var code = '{"type": "trigger", "loc": ['+PosString_0+','+PosString_1+']},\n';
return code;
*/;
insert_s
: '插入事件' 'x' PosString ',' 'y' PosString '楼层' IdString? Newline
/* insert_s
tooltip : insert: 立即插入另一个地点的事件执行,当前事件不会中断,事件坐标不会改变
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=insert%ef%bc%9a%e6%8f%92%e5%85%a5%e5%8f%a6%e4%b8%80%e4%b8%aa%e5%9c%b0%e7%82%b9%e7%9a%84%e4%ba%8b%e4%bb%b6
default : ["0","0",""]
colour : this.eventColor
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
var code = '{"type": "insert", "loc": ['+PosString_0+','+PosString_1+']'+IdString_0+'},\n';
return code;
*/;
revisit_s
: '重启当前事件' Newline
@ -1236,6 +1252,33 @@ var code = ['{"type": "if", "condition": "',expression_0,'",\n',
return code;
*/;
switch_s
: '多重分歧 条件判定' ':' expression BGNL? Newline switchCase+ BEND Newline
/* switch_s
tooltip : switch: 多重条件分歧
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=switch%EF%BC%9A%E5%A4%9A%E9%87%8D%E6%9D%A1%E4%BB%B6%E5%88%86%E6%AD%A7
default : ["判别值"]
colour : this.eventColor
var code = ['{"type": "switch", "condition": "',expression_0,'", "caseList": [\n',
switchCase_0,
'], },\n'].join('');
return code;
*/;
switchCase
: '如果是' expression '的场合' BGNL? Newline action+
/* switchCase
tooltip : 选项的选择
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=switch%EF%BC%9A%E5%A4%9A%E9%87%8D%E6%9D%A1%E4%BB%B6%E5%88%86%E6%AD%A7
colour : this.subColor
var code = '{"case": "'+expression_0+'", "action": [\n'+action_0+']},\n';
return code;
*/;
choices_s
: '选项' ':' EvalString? BGNL? '标题' EvalString? '图像' IdString? BGNL? Newline choicesContext+ BEND Newline
@ -1938,6 +1981,10 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['trigger_s'].xmlText([
data.loc[0],data.loc[1],this.next]);
break;
case "insert": // 强制插入另一个点的事件在当前事件列表执行,当前坐标和楼层不会改变
this.next = MotaActionBlocks['insert_s'].xmlText([
data.loc[0],data.loc[1],data.floorId||'',this.next]);
break;
case "playSound":
this.next = MotaActionBlocks['playSound_s'].xmlText([
data.name,this.next]);
@ -1983,6 +2030,15 @@ ActionParser.prototype.parseAction = function() {
this.insertActionList(data["false"]),
this.next]);
break;
case "switch": // 多重条件分歧
var case_caseList = null;
for(var ii=data.caseList.length-1,caseNow;caseNow=data.caseList[ii];ii--) {
case_caseList=MotaActionBlocks['switchCase'].xmlText([
this.isset(caseNow.case)?MotaActionBlocks['evalString_e'].xmlText([caseNow.case]):"值",this.insertActionList(caseNow.action),case_caseList]);
}
this.next = MotaActionBlocks['switch_s'].xmlText([
MotaActionBlocks['evalString_e'].xmlText([data.condition]),case_caseList,this.next]);
break;
case "choices": // 提供选项
var text_choices = null;
for(var ii=data.choices.length-1,choice;choice=data.choices[ii];ii--) {

View File

@ -49,28 +49,35 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_type": "textarea",
"_string": true,
"_lint": true,
"_data": "cls为items的即捡即用类物品的效果。"
"_data": "即捡即用类物品的效果仅对cls为items有效。"
},
"itemEffectTip": {
"_leaf": true,
"_type": "textarea",
"_string": true,
"_lint": true,
"_data": "cls为items的即捡即用类物品在获得时左上角额外显示的文字。"
"_data": "即捡即用类物品在获得时提示的文字仅对cls为items有效。"
},
"useItemEffect": {
"_leaf": true,
"_type": "textarea",
"_string": true,
"_lint": true,
"_data": "cls为tools或constants时的使用物品效果。"
"_data": "道具效果仅对cls为tools或constants有效。"
},
"canUseItemEffect": {
"_leaf": true,
"_type": "textarea",
"_string": true,
"_lint": true,
"_data": "cls为tools或constants时对当前能否使用该物品的判断。"
"_data": "当前能否使用该道具仅对cls为tools或constants有效。"
},
"canEquip":{
"_leaf": true,
"_type": "textarea",
"_string": true,
"_lint": true,
"_data": "当前能否装备某个装备仅对cls为equips有效。\n与canUseItemEffect不同这里null代表可以装备。"
}
}
},
@ -119,54 +126,54 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_leaf": true,
"_type": "textarea",
"_range": "thiseval==null || thiseval instanceof Array || (thiseval==~~thiseval && thiseval>=0)",
"_data": "特殊属性\n\n0:无,1:先攻,2:魔攻,3:坚固,4:2连击,\n5:3连击,6:n连击,7:破甲,8:反击,9:净化,\n10:模仿,11:吸血,12:中毒,13:衰弱,14:诅咒,\n15:领域,16:夹击,17:仇恨,18:阻击,19:自爆,\n20:无敌,21:退化,22:固伤,23:重生,24:激光\n\n多个属性例如用[1,4,11]表示先攻2连击吸血\n模仿怪的攻防设为0就好"
"_data": "特殊属性\n\n0:无,1:先攻,2:魔攻,3:坚固,4:2连击,\n5:3连击,6:n连击,7:破甲,8:反击,9:净化,\n10:模仿,11:吸血,12:中毒,13:衰弱,14:诅咒,\n15:领域,16:夹击,17:仇恨,18:阻击,19:自爆,\n20:无敌,21:退化,22:固伤,23:重生,24:激光,25:光环\n\n多个属性例如用[1,4,11]表示先攻2连击吸血"
},
"value": {
"_leaf": true,
"_type": "textarea",
"_data": "特殊属性的数值\n领域怪需要加value表示领域伤害的数值\n吸血怪需要在后面添加value代表吸血比例"
"_data": "特殊属性的数值\n如:领域/阻激/激光怪的伤害值;吸血怪的吸血比例;光环怪增加生命的比例"
},
"zoneSquare": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "领域怪zoneSquare代表是否九宫格伤害"
"_data": "领域怪是否九宫格伤害"
},
"range": {
"_leaf": true,
"_type": "textarea",
"_range": "(thiseval==~~thiseval && thiseval>0)||thiseval==null",
"_data": "range可选代表领域伤害的范围不加默认为1"
"_data": "领域伤害的范围不加默认为1"
},
"notBomb": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "加入 \"notBomb\": true 代表该怪物不可被炸弹或圣锤炸掉"
"_data": "该怪物不可被炸"
},
"n": {
"_leaf": true,
"_type": "textarea",
"_range": "(thiseval==~~thiseval && thiseval>0)||thiseval==null",
"_data": "多连击需要在后面指定n代表是几连击"
"_data": "多连击的连击数"
},
"add": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "代表吸血后是否加到自身"
"_data": "吸血后是否加到自身;光环是否叠加"
},
"atkValue": {
"_leaf": true,
"_type": "textarea",
"_range": "thiseval==~~thiseval||thiseval==null",
"_data": "退化时勇士下降的攻击力点数"
"_data": "退化时勇士下降的攻击力点数;光环怪增加攻击的比例"
},
"defValue": {
"_leaf": true,
"_type": "textarea",
"_range": "thiseval==~~thiseval||thiseval==null",
"_data": "退化时勇士下降的防御力点数"
"_data": "退化时勇士下降的防御力点数;光环怪增加防御的比例"
},
"damage": {
"_leaf": true,

View File

@ -424,6 +424,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_bool": "bool",
"_data": "是否允许等级提升进阶如果上面enableExperience为false则此项恒视为false"
},
"levelUpLeftMode": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "进阶使用扣除模式即在状态栏显示距离下个等级所需要的经验值只有enableExperience和enableLevelUp均开启时才有效。"
},
"enableKeys": {
"_leaf": true,
"_type": "checkbox",
@ -612,6 +618,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_bool": "bool",
"_data": "是否允许查看未开启状态的快捷商店内容;如果此项为真,则对于未开启状态的商店允许查看其内容(但不能购买)"
},
"disableShopOnDamage": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "是否在经过领域/夹击/路障等伤害后禁用快捷商店。"
}
}
}
}

View File

@ -3,6 +3,30 @@ function editor() {
this.brushMod = "line";//["line","rectangle","tileset"]
this.layerMod = "map";//["fgmap","map","bgmap"]
this.isMobile = false;
window.onerror = function (msg, url, lineNo, columnNo, error) {
var string = msg.toLowerCase();
var substring = "script error";
var message;
if (string.indexOf(substring) > -1){
message = 'Script Error: See Browser Console for Detail';
} else {
message = [
'Message: ' + msg,
'URL: ' + url,
'Line: ' + lineNo,
'Column: ' + columnNo,
'Error object: ' + JSON.stringify(error)
].join(' - ');
// alert(message);
}
try {
printe(message)
} catch (e) {
alert(message);
}
return false;
};
}
/*
@ -1079,19 +1103,33 @@ editor.prototype.listen = function () {
editor.brushMod=brushMod3.value;
}
var bgc = document.getElementById('bg'), fgc = document.getElementById('fg'),
evc = document.getElementById('event'), ev2c = document.getElementById('event2');
var layerMod=document.getElementById('layerMod');
layerMod.onchange=function(){
editor.layerMod=layerMod.value;
[bgc,fgc,evc,ev2c].forEach(function (x) {
x.style.opacity = 1;
});
}
var layerMod2=document.getElementById('layerMod2');
if(layerMod2)layerMod2.onchange=function(){
editor.layerMod=layerMod2.value;
[fgc,evc,ev2c].forEach(function (x) {
x.style.opacity = 0.3;
});
bgc.style.opacity = 1;
}
var layerMod3=document.getElementById('layerMod3');
if(layerMod3)layerMod3.onchange=function(){
editor.layerMod=layerMod3.value;
[bgc,evc,ev2c].forEach(function (x) {
x.style.opacity = 0.3;
});
fgc.style.opacity = 1;
}
var viewportButtons=document.getElementById('viewportButtons');

View File

@ -108,6 +108,11 @@ editor_blockly = function () {
],
'事件控制':[
MotaActionBlocks['if_s'].xmlText(),
MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [
{"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]},
{"action": []},
{"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行default事件"}]},
]}),
MotaActionBlocks['while_s'].xmlText(),
MotaActionBlocks['break_s'].xmlText(),
MotaActionBlocks['continue_s'].xmlText(),
@ -121,6 +126,7 @@ editor_blockly = function () {
MotaActionBlocks['hideBgFgMap_s'].xmlText(),
MotaActionBlocks['setBgFgBlock_s'].xmlText(),
MotaActionBlocks['trigger_s'].xmlText(),
MotaActionBlocks['insert_s'].xmlText(),
MotaActionBlocks['move_s'].xmlText(),
MotaActionBlocks['jump_s'].xmlText(),
MotaActionBlocks['disableShop_s'].xmlText(),
@ -415,7 +421,7 @@ document.getElementById('blocklyDiv').onmousewheel = function(e){
var type = args.type;
if (!type) return false;
editor_blockly.id = id_;
codeAreaHL.setValue(input.value);
codeAreaHL.setValue(input.value.replace(/\\r/g,'\\\\r'));
document.getElementById('entryType').value = type;
editor_blockly.parse();
editor_blockly.show();

View File

@ -556,6 +556,90 @@ editor_mode = function (editor) {
}
selectAppend.onchange();
var getPixel=function(imgData, x, y) {
var offset = (x + y * imgData.width) * 4;
var r = imgData.data[offset+0];
var g = imgData.data[offset+1];
var b = imgData.data[offset+2];
var a = imgData.data[offset+3];
return [r,g,b,a];
}
var setPixel=function(imgData, x, y, rgba) {
var offset = (x + y * imgData.width) * 4;
imgData.data[offset+0]=rgba[0];
imgData.data[offset+1]=rgba[1];
imgData.data[offset+2]=rgba[2];
imgData.data[offset+3]=rgba[3];
}
var autoAdjust = function (image, callback) {
var changed = false;
// Step 1: 检测白底
var tempCanvas = document.createElement('canvas').getContext('2d');
tempCanvas.canvas.width = image.width;
tempCanvas.canvas.height = image.height;
tempCanvas.mozImageSmoothingEnabled = false;
tempCanvas.webkitImageSmoothingEnabled = false;
tempCanvas.msImageSmoothingEnabled = false;
tempCanvas.imageSmoothingEnabled = false;
tempCanvas.drawImage(image, 0, 0);
var imgData = tempCanvas.getImageData(0, 0, image.width, image.height);
var trans = 0, white = 0;
for (var i=0;i<image.width;i++) {
for (var j=0;j<image.height;j++) {
var pixel = getPixel(imgData, i, j);
if (pixel[3]==0) trans++;
if (pixel[0]==255 && pixel[1]==255 && pixel[2]==255 && pixel[3]==255) white++;
}
}
if (white>trans*10 && confirm("看起来这张图片是以白色为底色,是否自动调整为透明底色?")) {
for (var i=0;i<image.width;i++) {
for (var j=0;j<image.height;j++) {
var pixel = getPixel(imgData, i, j);
if (pixel[0]==255 && pixel[1]==255 && pixel[2]==255 && pixel[3]==255) {
setPixel(imgData, i, j, [0,0,0,0]);
}
}
}
tempCanvas.clearRect(0, 0, image.width, image.height);
tempCanvas.putImageData(imgData, 0, 0);
changed = true;
}
// Step 2: 检测长宽比
var ysize = selectAppend.value.indexOf('48') === -1 ? 32 : 48;
if ((image.width%32!=0 || image.height%ysize!=0) && (image.width<=128 && image.height<=ysize*4)
&& confirm("目标长宽不符合条件,是否自动进行调整?")) {
var ncanvas = document.createElement('canvas').getContext('2d');
ncanvas.canvas.width = 128;
ncanvas.canvas.height = 4*ysize;
ncanvas.mozImageSmoothingEnabled = false;
ncanvas.webkitImageSmoothingEnabled = false;
ncanvas.msImageSmoothingEnabled = false;
ncanvas.imageSmoothingEnabled = false;
var w = image.width / 4, h = image.height / 4;
for (var i=0;i<4;i++) {
for (var j=0;j<4;j++) {
ncanvas.drawImage(tempCanvas.canvas, i*w, j*h, w, h, i*32 + (32-w)/2, j*ysize + (ysize-h)/2, w, h);
}
}
tempCanvas = ncanvas;
changed = true;
}
if (!changed) {
callback(image);
}
else {
var nimg = new Image();
nimg.onload = function () {
callback(nimg);
};
nimg.src = tempCanvas.canvas.toDataURL();
}
}
var selectFileBtn = document.getElementById('selectFileBtn');
selectFileBtn.onclick = function () {
var loadImage = function (content, callback) {
@ -576,48 +660,50 @@ editor_mode = function (editor) {
}
core.readFile(function (content) {
loadImage(content, function (image) {
editor_mode.appendPic.img = image;
editor_mode.appendPic.width = image.width;
editor_mode.appendPic.height = image.height;
autoAdjust(image, function (image) {
editor_mode.appendPic.img = image;
editor_mode.appendPic.width = image.width;
editor_mode.appendPic.height = image.height;
if (selectAppend.value == 'autotile') {
for (var ii = 0; ii < 3; ii++) {
var newsprite = appendPicCanvas.children[ii];
newsprite.style.width = (newsprite.width = image.width) / ratio + 'px';
newsprite.style.height = (newsprite.height = image.height) / ratio + 'px';
if (selectAppend.value == 'autotile') {
for (var ii = 0; ii < 3; ii++) {
var newsprite = appendPicCanvas.children[ii];
newsprite.style.width = (newsprite.width = image.width) / ratio + 'px';
newsprite.style.height = (newsprite.height = image.height) / ratio + 'px';
}
sprite_ctx.clearRect(0, 0, sprite.width, sprite.height);
sprite_ctx.drawImage(image, 0, 0);
}
sprite_ctx.clearRect(0, 0, sprite.width, sprite.height);
sprite_ctx.drawImage(image, 0, 0);
}
else {
var ysize = selectAppend.value.indexOf('48') === -1 ? 32 : 48;
for (var ii = 0; ii < 3; ii++) {
var newsprite = appendPicCanvas.children[ii];
newsprite.style.width = (newsprite.width = Math.floor(image.width / 32) * 32) / ratio + 'px';
newsprite.style.height = (newsprite.height = Math.floor(image.height / ysize) * ysize) / ratio + 'px';
else {
var ysize = selectAppend.value.indexOf('48') === -1 ? 32 : 48;
for (var ii = 0; ii < 3; ii++) {
var newsprite = appendPicCanvas.children[ii];
newsprite.style.width = (newsprite.width = Math.floor(image.width / 32) * 32) / ratio + 'px';
newsprite.style.height = (newsprite.height = Math.floor(image.height / ysize) * ysize) / ratio + 'px';
}
}
}
//画灰白相间的格子
var bgc = bg.getContext('2d');
var colorA = ["#f8f8f8", "#cccccc"];
var colorIndex;
var sratio = 4;
for (var ii = 0; ii < image.width / 32 * sratio; ii++) {
colorIndex = 1 - ii % 2;
for (var jj = 0; jj < image.height / 32 * sratio; jj++) {
bgc.fillStyle = colorA[colorIndex];
colorIndex = 1 - colorIndex;
bgc.fillRect(ii * 32 / sratio, jj * 32 / sratio, 32 / sratio, 32 / sratio);
//画灰白相间的格子
var bgc = bg.getContext('2d');
var colorA = ["#f8f8f8", "#cccccc"];
var colorIndex;
var sratio = 4;
for (var ii = 0; ii < image.width / 32 * sratio; ii++) {
colorIndex = 1 - ii % 2;
for (var jj = 0; jj < image.height / 32 * sratio; jj++) {
bgc.fillStyle = colorA[colorIndex];
colorIndex = 1 - colorIndex;
bgc.fillRect(ii * 32 / sratio, jj * 32 / sratio, 32 / sratio, 32 / sratio);
}
}
}
//把导入的图片画出
source_ctx.drawImage(image, 0, 0);
editor_mode.appendPic.sourceImageData=source_ctx.getImageData(0,0,image.width,image.height);
//把导入的图片画出
source_ctx.drawImage(image, 0, 0);
editor_mode.appendPic.sourceImageData=source_ctx.getImageData(0,0,image.width,image.height);
//重置临时变量
selectAppend.onchange();
//重置临时变量
selectAppend.onchange();
});
});
}, null, 'img');
@ -630,21 +716,6 @@ editor_mode = function (editor) {
var imgData=editor_mode.appendPic.sourceImageData;
var nimgData=new ImageData(imgData.width,imgData.height);
// ImageData .data 形如一维数组,依次排着每个点的 R(0~255) G(0~255) B(0~255) A(0~255)
var getPixel=function(imgData, x, y) {
var offset = (x + y * imgData.width) * 4;
var r = imgData.data[offset+0];
var g = imgData.data[offset+1];
var b = imgData.data[offset+2];
var a = imgData.data[offset+3];
return [r,g,b,a];
}
var setPixel=function(imgData, x, y, rgba) {
var offset = (x + y * imgData.width) * 4;
imgData.data[offset+0]=rgba[0];
imgData.data[offset+1]=rgba[1];
imgData.data[offset+2]=rgba[2];
imgData.data[offset+3]=rgba[3];
}
var convert=function(rgba,delta){
var round=Math.round;
// rgbToHsl hue2rgb hslToRgb from https://github.com/carloscabo/colz.git
@ -857,19 +928,23 @@ editor_mode = function (editor) {
}
var ysize = selectAppend.value.indexOf('48') === -1 ? 32 : 48;
var height = editor_mode.appendPic.toImg.height;
for (var ii = 0, v; v = editor_mode.appendPic.selectPos[ii]; ii++) {
var imgData = source_ctx.getImageData(v.x * 32, v.y * ysize, 32, ysize);
sprite_ctx.putImageData(imgData, ii * 32, height);
// var imgData = source_ctx.getImageData(v.x * 32, v.y * ysize, 32, ysize);
// sprite_ctx.putImageData(imgData, ii * 32, sprite.height - ysize);
// sprite_ctx.drawImage(editor_mode.appendPic.img, v.x * 32, v.y * ysize, 32, ysize, ii * 32, height, 32, ysize)
sprite_ctx.drawImage(source_ctx.canvas, v.x*32, v.y*ysize, 32, ysize, 32*ii, sprite.height - ysize, 32, ysize);
}
var dt = sprite_ctx.getImageData(0, 0, sprite.width, sprite.height);
var imgbase64 = sprite.toDataURL().split(',')[1];
fs.writeFile('./project/images/' + editor_mode.appendPic.imageName + '.png', imgbase64, 'base64', function (err, data) {
if (err) {
printe(err);
throw(err)
}
printe('追加素材成功,请F5刷新编辑器');
printe('追加素材成功请F5刷新编辑器或继续追加当前素材');
sprite.style.height = (sprite.height = (sprite.height+ysize)) + "px";
sprite_ctx.putImageData(dt, 0, 0);
});
}

View File

@ -1,6 +1,6 @@
# V2.0版本介绍
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
目前样板已经更新到V2.0版本以上本章将对V2.0的一些内容进行介绍。

View File

@ -1,6 +1,6 @@
# 附录: API列表
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
**这里只列出所有可能会被造塔者用到的常用API更多的有关内容请在代码内进行查询。**

View File

@ -1,6 +1,6 @@
# 元件说明
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
@ -262,6 +262,17 @@ floorId指定的是目标楼层的唯一标识符ID
**从2.1.1开始,楼层属性中提供了`upFloor`和`downFloor`两项。如果设置此项(比如`"upFloor": [2,3]`则写stair:upFloor或者楼传器的落点将用此点来替换楼梯位置即类似于RM中的上箭头。**
## 剧情文本控制
在写剧情文本时,可以:
- 使用`\t[...]`来给文字加上标题和图标。如`\t[老人,man]`。
- 使用`\b[...]`来制作对话框效果,如`\b[up,3,2]`。
- 使用`\r[...]`来动态修改局部文本的颜色,如`\r[red]`。
- 使用`${}`来计算一个表达式的值,如`${status:atk+status:def}`。
详细信息请参见[剧情文本控制](event#text显示一段文字剧情)中的说明。
## 大地图
从V2.4开始H5魔塔开始支持大地图。

View File

@ -1,6 +1,6 @@
# 事件
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
本章内将对样板所支持的事件进行介绍。
@ -237,6 +237,15 @@
!> `\t[...]`必须在`\b[...]`前面!不然两者都无法正常显示。
还可以使用`\r[...]`来调整剧情文本的颜色。
``` js
"x,y": [ // 实际执行的事件列表
"这句话是默认颜色,\r[red]将颜色变成红色,\r[blue]将颜色变成蓝色",
"\r[#FF00FF]还可以使用RGB值来控制颜色\r如果不加中括号则回到默认颜色",
"\t[hero]\b[up,hero]啊啊啊,别过来,\r[red]别过来!!!\n\r你到底是什么东西"
]
```
另外值得一提的是,我们是可以在文字中计算一个表达式的值的。只需要将表达式用 `${ }`整个括起来就可以。
@ -468,6 +477,32 @@ NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}`
例如上面这个例子,下面的文字将不会再被显示,而是直接跳转到`"3,6"`对应的事件列表从头执行。
### insert插入另一个地点的事件
`{"type":"insert"}` 会插入另一个地点的事件执行。
其基本写法如下:
``` js
"x,y": [ // 实际执行的事件列表
{"type": "insert", "loc": [3,6]}, // 插入[3,6]点的事件并执行
{"type": "insert", "loc": [10,10], "floorId": "MT1"}, // 插入MT1层[10,10]点的事件并执行
"上面的插入事件执行完毕后会接着继续执行后面的事件"
]
```
loc是必须的代表另一个地点的坐标。
floorId可选代表另一个地点所在的楼层如果不写则默认为当前层。
和`type:trigger`不同的是,**`type:trigger`是立刻将当前事件结束剩下所有内容都忽略然后重新启动另一个地点的action事件。**
但是`type:insert`不会结束当前事件,而是直接将另一个地点的事件列表“插入”到当前事件列表中执行。
**这个过程中,当前事件不会被结束,当前的楼层和事件坐标不会发生改变。** 插入的事件执行完毕后,会继续执行接下来的内容。
我们某个事件写在某个角落的墙上然后远程调用,从而达到“公共事件”的效果。
### revisit立即重启当前事件
revisit和trigger完全相同只不过是立刻触发的还是本地点的事件
@ -1190,6 +1225,70 @@ text为提示文字可以在这里给输入提示文字。这里同样可以
- if可以不断进行嵌套一层套一层如成立的场合再进行另一个if判断等。
- if语句内的内容执行完毕后将接着其后面的语句继续执行。
### switch多重条件分歧
使用`{"type": "switch"}`可以比较判别值和不同分支的条件,根据判断结果选择不同的分支执行。
其大致写法如下:
``` js
"x,y": [ // 实际执行的事件列表
{"type": "switch", "condition": "...", // 计算某个表达式
"caseList": [
{"case": "a", "action": [// 若表达式的值等于a则执行该处事件
],
{"case": "b", "action": [// 若表达式的值等于b则执行该处事件
],
{"case": "default", "action": [ // 没有条件成立则执行该处里的事件
]
]
},
]
```
我们可以在condition中给出一个表达式能将`status:xxx`, `item:xxx`, `flag:xxx`来作为参数),并计算它的值
如果某条件中的值与其相等,则将执行其对应的列表事件内容。
如果没有符合的值,则将执行`default`中的列表事件内容。
例如下面这个例子,将检查当前游戏难度并赠送不同属性。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "switch", "condition": "flag:hard", // 判断当前游戏难度
"caseList": [
{"case": "0", "action": [// 若表达式的值等于0则执行该处事件
"当前为简单难度赠送100点攻防",
{"type": "setValue", "name": "status:atk", "value": "status:atk+100"},
{"type": "setValue", "name": "status:def", "value": "status:def+100"},
],
{"case": "1", "action": [// 若表达式的值等于1则执行该处事件
"当前为普通难度赠送50点攻防",
{"type": "setValue", "name": "status:atk", "value": "status:atk+50"},
{"type": "setValue", "name": "status:def", "value": "status:def+50"},
],
{"case": "default", "action": [ // 其他难度下不赠送属性
]
]
},
]
```
需要额外注意的几点:
- 各个条件分支的判断是顺序执行的,因此若多个分支的条件都满足,将只执行最靠前的分支,同理,请不要在`default`分支后添加分支,这些分支将不可能被执行。
- `default`分支并不是必要的,如果删除,则在没有满足条件的分支时将不执行任何事件。
- 即使某个场合不执行事件对应的action数组也需要存在不过简单的留空就好。
- switch可以不断进行嵌套一层套一层如某条件成立的场合再进行另一个switch判断等。
- switch语句内的内容执行完毕后将接着其后面的语句继续执行。
### choices给用户提供选项
choices是一个很麻烦的事件它将弹出一个列表供用户进行选择。

View File

@ -1,6 +1,6 @@
# HTML5 魔塔样板说明文档
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
众所周知魔塔的趋势是向移动端发展贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中NekoRPG有着比较大的局限性游戏感较差更是完全没法在iOS上运行。而一些APP的魔塔虽然可用但是必须要下载安装对于Android和iOS还必须开发不同的版本非常麻烦。

View File

@ -1,6 +1,6 @@
# 个性化
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
@ -521,6 +521,15 @@ case 89: // 使用该按键的keyCode比如Y键就是89
## 公共事件
从2.5.1开始H5提供了`{"type":"insert"}`事件,完美支持了公共事件的写法。
我们只需要将需要的公共事件放在某个角落的墙上(或者甚至单独弄一层专门摆放公共事件),并使用“插入事件”,即可进行调用。
具体详见[插入另一个地点的事件](event#insert插入另一个地点的事件)。
当然,继续使用**插件**的写法也是可以的。具体参见“脚本编辑 - 插件编写”。
<!--
在RM中存在公共事件的说法也就是通过某个指令来调用一系列事件的触发。
在H5中我们可以使用“插件”的形式来达成这个效果。具体参见“脚本编辑 - 插件编写”。
@ -547,51 +556,48 @@ this.myfunc = function(x) {
然后比如我们在某个道具的使用效果 `useItemEffect` 中写 `core.plugin.myfunc(2)` 即可调用此公共事件(插件)。也可以在战后事件或自定义脚本等位置来写。
通过这种将脚本和自定义事件混用的方式可以达到和RM中公共事件类似的效果即一个调用触发一系列事件。
<!--
-->
## 自定义状态栏(新增显示项)
在V2.2以后,我们可以自定义状态栏背景图(全塔属性 - statusLeftBackground等等。
但是,如果我们还想新增其他项目的显示,比如技能塔所需要的魔力值(气息),该怎么办?
但是,如果我们还想新增其他项目的显示,比如攻速或者暴击,该怎么办?
需要进行如下几个操作:
1. 定义图标ID比如魔力我就定义mana气息可以简单的定义qixi你也可以定义其他的ID但是不能和已有的重复。这里以mana为例。
1. 定义ID比如攻速我就定义speed暴击可以简单的定义baoji你也可以定义其他的ID但是不能和已有的重复。这里以speed为例。
2. 在index.html的statusBar中44行起进行该状态栏项的定义。仿照其他几项插在其应当显示的位置注意替换掉相应的ID。
``` html
<div class="status" id="manaCol">
<img id="img-mana">
<p class='statusLabel' id='mana'></p>
<div class="status" id="speedCol">
<img id="img-speed">
<p class='statusLabel' id='speed'></p>
</div>
```
3. 在editor.html中的statusBar317行起仿照第二点同样添加这一项如果不进行则会地图编辑器报错。editor-mobile.html同理。
4. 使用便捷PS工具打开icons.png新增一行并将魔力的图标P上去记下其索引比如24从0开始数
3. 在editor.html中的statusBar323行起仿照第二点同样添加这一项如果不进行则会地图编辑器报错。editor-mobile.html同理。
4. 使用便捷PS工具打开icons.png新增一行并将魔力的图标P上去记下其索引比如30从0开始数
5. 在main.js的this.statusBar中增加图片、图标和内容的定义。
``` js
this.statusBar = {
'images': {
// ...其他略
'mana': document.getElementById("img-mana"), // 图片的定义
'speed': document.getElementById("img-speed"), // 图片的定义
},
'icons': {
// ...其他略
'mana': 24, // 图标的定义这里对应的是icons.png中的索引
'speed': 24, // 图标的定义这里对应的是icons.png中的索引
},
// ...其他略
'mana': document.getElementById('mana'), // 显示内容(数据)的定义
'speed': document.getElementById('speed'), // 显示内容(数据)的定义
}
```
6. 显示内容的设置。在脚本编辑的updateStatusBar函数可以对该状态栏显示内容进行设置下面是几个例子。
``` js
core.statusBar.mana.innerHTML = core.getFlag('mana', 0); // 设置其显示内容为flag:mana值。
core.statusBar.mana.innerHTML = core.getFlag('mana', 0) + '/' + core.getFlag('manaMax', 0); // 显示内容将类似 "32/60" 这样。
core.statusBar.mana.style.fontStyle = 'normal'; // 这一行会取消斜体。如果是汉字(比如技能名)的话,斜体起来会非常难看,可以通过这一句取消。
// 设置其显示内容为status:speed值需要在project/data.js中firstData的hero那里新增初始值`"speed": 0`。
core.statusBar.speed.innerHTML = core.getStatus('speed');
// 设置其显示内容为flag:speed值无需额外进行定义。
core.statusBar.speed.innerHTML = core.getFlag('speed', 0);
```
-->
## 技能塔的支持
其实在HTML5上制作技能塔是完全可行的。

View File

@ -1,6 +1,6 @@
# 快速上手
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!

View File

@ -767,6 +767,12 @@ actions.prototype.clickAction = function (x,y) {
////// 自定义事件时,按下某个键的操作 //////
actions.prototype.keyDownAction = function (keycode) {
// 视为无效
var startTime = core.status.event.data.startTime||0;
if (startTime>0 && new Date().getTime()-startTime<250)
return;
core.status.event.data.startTime = 0;
if (core.status.event.data.type=='choices') {
var data = core.status.event.data.current;
var choices = data.choices;
@ -809,6 +815,15 @@ actions.prototype.keyUpAction = function (keycode) {
core.insertAction(choices[core.status.event.selection].action);
core.doAction();
}
// 数字键快速选择
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<choices.length) {
core.status.route.push("choices:"+index);
core.insertAction(choices[index].action);
core.doAction();
}
}
}
}
}
@ -930,6 +945,16 @@ actions.prototype.clickViewMaps = function (x,y) {
core.ui.drawMaps(index, cx, cy);
return;
}
if (x==0 && y==12) {
core.status.event.data.paint = !core.status.event.data.paint;
core.ui.drawMaps(index, cx, cy);
return;
}
if (x==12 && y==0) {
core.status.event.data.all = !core.status.event.data.all;
core.ui.drawMaps(index, cx, cy);
return;
}
if (x>=2 && x<=10 && y<=1 && mh>13) {
core.ui.drawMaps(index, cx, cy-1);
@ -1002,6 +1027,11 @@ actions.prototype.keyUpViewMaps = function (keycode) {
core.ui.drawMaps(core.status.event.data);
return;
}
if (keycode==90) {
core.status.event.data.all = !core.status.event.data.all;
core.ui.drawMaps(core.status.event.data);
return;
}
if (keycode==77) {
core.status.event.data.paint = !core.status.event.data.paint;
core.ui.drawMaps(core.status.event.data);
@ -1122,6 +1152,14 @@ actions.prototype.keyUpShop = function (keycode) {
var topIndex = 6 - parseInt(choices.length / 2);
this.clickShop(6, topIndex+core.status.event.selection);
}
// 数字键快速选择
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<=choices.length) {
var topIndex = 6 - parseInt(choices.length / 2);
this.clickShop(6, topIndex+index);
}
}
return;
}
@ -1169,6 +1207,13 @@ actions.prototype.keyUpQuickShop = function (keycode) {
var topIndex = 6 - parseInt(keys.length / 2);
this.clickQuickShop(6, topIndex+core.status.event.selection);
}
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<=keys.length) {
var topIndex = 6 - parseInt(keys.length / 2);
this.clickQuickShop(6, topIndex+index);
}
}
return;
}
@ -1774,10 +1819,16 @@ actions.prototype.clickSwitchs = function (x,y) {
core.ui.drawSwitchs();
break;
case 8:
window.open(core.platform.isPC?"editor.html":"editor-mobile.html", "_blank");
if (core.platform.isPC)
window.open("editor.html", "_blank");
else
window.location.href = "editor-mobile.html";
break;
case 9:
window.open(core.firstData.name+".zip", "_blank");
if (core.platform.isPC)
window.open(core.firstData.name+".zip");
else
window.location.href = core.firstData.name+".zip";
break;
case 10:
core.status.event.selection=0;
@ -1811,6 +1862,14 @@ actions.prototype.keyUpSwitchs = function (keycode) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickSwitchs(6, topIndex+core.status.event.selection);
}
// 数字键快速选择
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<choices.length) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickSwitchs(6, topIndex+index);
}
}
}
@ -1891,6 +1950,14 @@ actions.prototype.keyUpSettings = function (keycode) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickSettings(6, topIndex+core.status.event.selection);
}
// 数字键快速选择
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<choices.length) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickSettings(6, topIndex+index);
}
}
}
////// 同步存档界面时的点击操作 //////
@ -1969,7 +2036,7 @@ actions.prototype.clickSyncSave = function (x,y) {
core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5route", JSON.stringify({
'name': core.firstData.name,
'hard': core.status.hard,
'seed': core.getFlag('seed'),
'seed': core.getFlag('__seed__'),
'route': core.encodeRoute(core.status.route)
}));
break;
@ -2011,6 +2078,14 @@ actions.prototype.keyUpSyncSave = function (keycode) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickSyncSave(6, topIndex+core.status.event.selection);
}
// 数字键快速选择
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<choices.length) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickSyncSave(6, topIndex+index);
}
}
}
////// 同步存档选择界面时的点击操作 //////
@ -2060,6 +2135,14 @@ actions.prototype.keyUpSyncSelect = function (keycode) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickSyncSelect(6, topIndex+core.status.event.selection);
}
// 数字键快速选择
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<choices.length) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickSyncSelect(6, topIndex+index);
}
}
}
////// 存档下载界面时的点击操作 //////
@ -2133,6 +2216,14 @@ actions.prototype.keyUpLocalSaveSelect = function (keycode) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickLocalSaveSelect(6, topIndex+core.status.event.selection);
}
// 数字键快速选择
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<choices.length) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickLocalSaveSelect(6, topIndex+index);
}
}
}
////// 存档删除界面时的点击操作 //////
@ -2219,6 +2310,14 @@ actions.prototype.keyUpStorageRemove = function (keycode) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickStorageRemove(6, topIndex+core.status.event.selection);
}
// 数字键快速选择
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<choices.length) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickStorageRemove(6, topIndex+index);
}
}
}
////// 回放选择界面时的点击操作 //////
@ -2234,7 +2333,7 @@ actions.prototype.clickReplay = function (x, y) {
case 0:
{
core.ui.closePanel();
var hard=core.status.hard, seed = core.getFlag('seed');
var hard=core.status.hard, seed = core.getFlag('__seed__');
core.startGame(hard, seed, core.clone(core.status.route));
break;
}
@ -2258,7 +2357,7 @@ actions.prototype.clickReplay = function (x, y) {
core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5route", JSON.stringify({
'name': core.firstData.name,
'hard': core.status.hard,
'seed': core.getFlag('seed'),
'seed': core.getFlag('__seed__'),
'route': core.encodeRoute(core.status.route)
}));
break;
@ -2293,6 +2392,14 @@ actions.prototype.keyUpReplay = function (keycode) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickReplay(6, topIndex+core.status.event.selection);
}
// 数字键快速选择
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<choices.length) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickReplay(6, topIndex+index);
}
}
}
////// “虚拟键盘”界面时的点击操作 //////

View File

@ -1245,6 +1245,14 @@ control.prototype.checkBlock = function () {
if (damage>0) {
core.playSound('zone.mp3');
core.drawAnimate("zone", x, y);
// 禁用快捷商店
if (core.flags.disableShopOnDamage) {
for (var shopId in core.status.shops) {
core.status.shops[shopId].visited = false;
}
}
}
core.status.hero.statistics.extraDamage += damage;
@ -1511,7 +1519,9 @@ control.prototype.updateDamage = function (floorId, canvas) {
core.clearMap('damage');
}
// if (!core.isset(core.status.thisMap) || !core.isset(core.status.thisMap.blocks)) return;
// 正在开始游戏中
if (core.status.isStarting) return;
// 更新显伤
var mapBlocks = core.status.maps[floorId].blocks;
// 没有怪物手册
@ -1526,15 +1536,9 @@ control.prototype.updateDamage = function (floorId, canvas) {
if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls.indexOf('enemy')==0
&& !mapBlocks[b].disable) {
// 非系统默认的战斗事件(被覆盖)
if (mapBlocks[b].event.trigger != 'battle') {
// 判断显伤
var event = core.floors[floorId].events[x+","+y];
if (core.isset(event) && !(event instanceof Array)) {
if (event.displayDamage === false)
continue;
}
}
// 判定是否显伤
if (mapBlocks[b].event.displayDamage === false)
continue;
var id = mapBlocks[b].event.id;
@ -1590,7 +1594,7 @@ control.prototype.updateDamage = function (floorId, canvas) {
}
}
// 如果是领域&夹击
if (core.flags.displayExtraDamage) {
if (core.flags.displayExtraDamage && core.isset((core.status.checkBlock||{}).damage)) {
canvas.textAlign = 'center';
// 临时改变
@ -1913,7 +1917,7 @@ control.prototype.replay = function () {
core.status.event.data = {"toolsPage":Math.floor(index/12)+1, "constantsPage":1, "selectId":null};
index = index%12;
}
else if (index=constants.indexOf(itemId)>=0) {
else if ((index=constants.indexOf(itemId))>=0) {
core.status.event.data = {"toolsPage":1, "constantsPage":Math.floor(index/12)+1, "selectId":null};
index = index%12+12;
}
@ -2246,7 +2250,7 @@ control.prototype.doSL = function (id, type) {
if (data.version != core.firstData.version) {
// core.drawTip("存档版本不匹配");
if (confirm("存档版本不匹配!\n你想回放此存档的录像吗\n可以随时停止录像播放以继续游戏。")) {
core.startGame(data.hard, data.hero.flags.seed, core.decodeRoute(data.route));
core.startGame(data.hard, data.hero.flags.__seed__, core.decodeRoute(data.route));
}
return;
}
@ -2285,7 +2289,7 @@ control.prototype.doSL = function (id, type) {
return;
}
var route = core.subarray(core.status.route, core.decodeRoute(data.route));
if (!core.isset(route) || data.hero.flags.seed!=core.getFlag('seed')) {
if (!core.isset(route) || data.hero.flags.__seed__!=core.getFlag('__seed__')) {
core.drawTip("无法从此存档回放录像");
return;
}
@ -2778,6 +2782,7 @@ control.prototype.resize = function(clientWidth, clientHeight) {
if (!core.flags.enableMoney) count--;
if (!core.flags.enableExperience) count--;
if (!core.flags.enableLevelUp) count--;
if (core.flags.levelUpLeftMode) count--;
if (!core.flags.enableDebuff) count--;
if (!core.flags.enableKeys) count--;
if (!core.flags.enablePZF) count--;
@ -2785,6 +2790,8 @@ control.prototype.resize = function(clientWidth, clientHeight) {
if (!core.flags.enableMana) count--;
if (!core.flags.enableSkill) count--;
if (count>12) alert("当前状态栏数目("+count+")大于12请调整到不超过12以避免手机端出现显示问题。");
var statusLineHeight = BASE_LINEHEIGHT * 9 / count;
var statusLineFontSize = DEFAULT_FONT_SIZE;
if (count>9) statusLineFontSize = statusLineFontSize * 9 / count;
@ -3084,7 +3091,7 @@ control.prototype.resize = function(clientWidth, clientHeight) {
{
id: 'expCol',
rules: {
display: core.flags.enableExperience ? 'block': 'none'
display: core.flags.enableExperience && !core.flags.levelUpLeftMode ? 'block': 'none'
}
},
{

View File

@ -148,7 +148,7 @@ function core() {
},
'textAttribute': {
'position': "center",
"offset": 20,
"offset": 0,
"title": [255,215,0,1],
"background": [0,0,0,0.85],
"text": [255,255,255,1],
@ -183,6 +183,8 @@ core.prototype.init = function (coreData, callback) {
if (!core.flags.enableExperience)
core.flags.enableLevelUp = false;
if (!core.flags.enableLevelUp)
core.flags.levelUpLeftMode = false;
if (!core.flags.canOpenBattleAnimate) {
core.flags.showBattleAnimateConfirm = false;
core.flags.battleAnimate = false;
@ -201,6 +203,11 @@ core.prototype.init = function (coreData, callback) {
document.getElementById("startLogo").innerHTML = core.firstData.title;
core.material.items = core.clone(core.items.getItems());
core.material.enemys = core.clone(core.enemys.getEnemys());
if (main.mode == 'play') {
for (var enemyId in core.material.enemys) {
core.material.enemys[enemyId].id = enemyId;
}
}
core.material.icons = core.icons.getIcons();
core.material.events = core.events.getEvents();

View File

@ -260,22 +260,17 @@ enemys.prototype.getCurrentEnemys = function (floorId) {
var critical = this.nextCriticals(enemyId);
if (critical.length>0) critical=critical[0];
enemys.push({
'id': enemyId,
'name': enemy.name,
'hp': enemyInfo.hp,
'atk': enemyInfo.atk,
'def': enemyInfo.def,
'money': enemyInfo.money||0,
'experience': enemyInfo.experience||0,
'point': enemyInfo.point||0, // 加点
'special': specialText,
'damage': this.getDamage(enemyId,null,null,floorId),
'critical': critical[0],
'criticalDamage': critical[1],
'defDamage': this.getDefDamage(enemyId,1,null,null,floorId)
});
var e = core.clone(enemy);
for (var x in enemyInfo) {
e[x] = enemyInfo[x];
}
e.id = enemyId;
e.specialText = specialText;
e.damage = this.getDamage(enemyId, null, null, floorId);
e.critical = critical[0];
e.criticalDamage = critical[1];
e.defDamage = this.getDefDamage(enemyId,1,null,null,floorId);
enemys.push(e);
used[enemyId] = true;
}
}

View File

@ -88,8 +88,8 @@ events.prototype.startGame = function (hard, seed, route, callback) {
core.status.isStarting = true;
if (core.isset(seed)) {
core.setFlag('seed', seed);
core.setFlag('rand', seed);
core.setFlag('__seed__', seed);
core.setFlag('__rand__', seed);
}
else core.utils.__init_seed();
@ -195,7 +195,7 @@ events.prototype.gameOver = function (ending, fromReplay, norank) {
'name': core.firstData.name,
'version': core.firstData.version,
'hard': core.status.hard,
'seed': core.getFlag('seed'),
'seed': core.getFlag('__seed__'),
'route': core.encodeRoute(core.status.route)
}
core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5route", JSON.stringify(obj));
@ -238,7 +238,7 @@ events.prototype.gameOver = function (ending, fromReplay, norank) {
formData.append('experience', core.status.hero.experience);
formData.append('steps', core.status.hero.steps);
formData.append('norank', norank||0);
formData.append('seed', core.getFlag('seed'));
formData.append('seed', core.getFlag('__seed__'));
formData.append('totalTime', Math.floor(core.status.hero.statistics.totalTime/1000));
formData.append('route', core.encodeRoute(core.status.route));
formData.append('base64', 1);
@ -316,7 +316,7 @@ events.prototype.doEvents = function (list, x, y, callback) {
core.status.event = {'id': 'action', 'data': {
'list': [
{"todo": core.clone(list), "total": core.clone(list), "condition": "false"}
], 'x': x, 'y': y, 'callback': callback
], 'x': x, 'y': y, 'callback': callback, 'startTime': new Date().getTime()
}}
// 停止勇士
@ -702,12 +702,12 @@ events.prototype.doAction = function() {
case "setFg": // 颜色渐变
if (data.async) {
core.setFg(data.color, data.time);
core.setFlag('color', data.color||null);
core.setFlag('__color__', data.color||null);
this.doAction();
}
else {
core.setFg(data.color, data.time, function() {
core.setFlag('color', data.color||null);
core.setFlag('__color__', data.color||null);
core.events.doAction();
});
}
@ -715,8 +715,8 @@ events.prototype.doAction = function() {
case "setWeather": // 更改天气
core.setWeather(data.name, data.level);
if (core.isset(data.name))
core.setFlag('weather', [data.name, data.level]);
else core.setFlag('weather', null);
core.setFlag('__weather__', [data.name, data.level]);
else core.setFlag('__weather__', null);
this.doAction();
break;
case "openDoor": // 开一个门,包括暗墙
@ -774,6 +774,15 @@ events.prototype.doAction = function() {
this.doAction();
break;
}
case "insert":
{
var toX=core.calValue(data.loc[0]), toY=core.calValue(data.loc[1]);
var floorId = data.floorId || core.status.floorId;
var event = core.floors[floorId].events[toX+","+toY];
if (core.isset(event)) core.insertAction(event);
this.doAction();
break;
}
case "playSound":
if (!core.status.replay.replaying)
core.playSound(data.name);
@ -810,7 +819,7 @@ events.prototype.doAction = function() {
var value=core.calValue(data.value);
// 属性
if (data.name.indexOf("status:")==0) {
value=parseFloat(value);
// value=parseFloat(value);
core.setStatus(data.name.substring(7), value);
}
// 道具
@ -907,6 +916,16 @@ events.prototype.doAction = function() {
core.events.insertAction(data["false"])
this.doAction();
break;
case "switch": // 条件选择
var key = core.calValue(data.condition)
for (var i = 0; i < data.caseList.length; i++) {
if (data.caseList[i].case=="default" || core.calValue(data.caseList[i].case) == key) {
core.events.insertAction(data.caseList[i].action);
break;
}
}
this.doAction();
break;
case "choices": // 提供选项
if (core.status.replay.replaying) {
if (core.status.replay.toReplay.length==0) { // 回放完毕
@ -1326,7 +1345,7 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback
}
// 不存在事件时,更改画面色调
var color = core.getFlag('color', null);
var color = core.getFlag('__color__', null);
if (!core.isset(color) && core.isset(core.status.maps[floorId].color)) {
color = core.status.maps[floorId].color;
}
@ -1346,7 +1365,7 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback
}
// 更改天气
var weather = core.getFlag('weather', null);
var weather = core.getFlag('__weather__', null);
if (!core.isset(weather) && core.isset(core.status.maps[floorId].weather)) {
weather = core.status.maps[floorId].weather;
}
@ -1631,8 +1650,8 @@ events.prototype.openShop = function(shopId, needVisited) {
var choice = shop.choices[i];
var text = choice.text;
if (core.isset(choice.need))
text += ""+eval(choice.need)+use+""
choices.push(text);
text += ""+eval(choice.need)+use+"";
choices.push({"text": text, "color":shop.visited?null:"#999999"});
}
choices.push("离开");
core.ui.drawChoices(content, choices);
@ -1902,7 +1921,7 @@ events.prototype.uploadCurrent = function (username) {
formData.append('money', core.status.hero.money);
formData.append('experience', core.status.hero.experience);
formData.append('steps', core.status.hero.steps);
formData.append('seed', core.getFlag('seed'));
formData.append('seed', core.getFlag('__seed__'));
formData.append('totalTime', Math.floor(core.status.hero.statistics.totalTime/1000));
formData.append('route', core.encodeRoute(core.status.route));
formData.append('deler', 'current');

View File

@ -9,6 +9,10 @@ items.prototype.init = function () {
this.itemEffectTip = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.itemEffectTip;
this.useItemEffect = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.useItemEffect;
this.canUseItemEffect = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canUseItemEffect;
if (!core.isset(items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip))
items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip = {};
this.canEquip = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip;
//delete(items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a);
}
@ -162,13 +166,21 @@ items.prototype.loadEquip = function (equipId, callback) {
if (!core.isset(core.status.hero.equipment)) core.status.hero.equipment = [];
core.playSound('equip.mp3');
var loadEquip = core.material.items[equipId];
if (!core.isset(loadEquip)) {
if (core.isset(callback)) callback();
return;
}
var can = this.canEquip[equipId];
if (core.isset(can) && !eval(can)) {
core.drawTip("当前不可换上"+loadEquip.name);
if (core.isset(callback)) callback();
return;
}
core.playSound('equip.mp3');
var loadEquipType = loadEquip.equip.type;
var unloadEquipId = core.status.hero.equipment[loadEquipType];
@ -285,9 +297,19 @@ items.prototype.quickLoadEquip = function (index) {
for (var i=0;i<equipSize;i++) {
var v = current[i];
if (core.isset(v) && !core.hasItem(v) && !core.hasEquip(v)) {
core.drawTip("你当前没有"+((core.material.items[v]||{}).name||"未知装备")+",无法换装");
return;
}
if (core.isset(v)) {
if (!core.hasItem(v) && !core.hasEquip(v)) {
core.drawTip("你当前没有"+((core.material.items[v]||{}).name||"未知装备")+",无法换装");
return;
}
var can = this.canEquip[v];
if (core.isset(can) && !eval(can)) {
core.drawTip("当前不可换上"+((core.material.items[v]||{}).name||"未知装备"));
return;
}
}
}
// 快速换装
if (!core.isset(core.status.hero.equipment)) core.status.hero.equipment = [];

View File

@ -123,28 +123,20 @@ maps.prototype.addEvent = function (block, x, y, event) {
if (!core.isset(event.data))
event.data = [];
// 覆盖noPass
if (core.isset(event.noPass))
block.event.noPass = event.noPass;
// 覆盖enable
if (!core.isset(block.disable) && core.isset(event.enable)) {
block.disable=!event.enable;
}
// 覆盖trigger
if (!core.isset(block.event.trigger)) {
if (core.isset(event.trigger)) block.event.trigger=event.trigger;
else block.event.trigger='action';
}
else if (core.isset(event.trigger) && event.trigger!='checkBlock') {
block.event.trigger=event.trigger;
}
// 覆盖其他属性
// 覆盖所有属性
for (var key in event) {
if (key!="disable" && key!="trigger" && key!="noPass" && core.isset(event[key])) {
if (key!="enable" && core.isset(event[key])) {
block.event[key]=core.clone(event[key]);
}
}
// 给无trigger的增加trigger:action
if (!core.isset(block.event.trigger)) {
block.event.trigger = 'action';
}
}
////// 向该楼层添加剧本的楼层转换事件 //////
@ -386,7 +378,7 @@ maps.prototype.getBgFgMapArray = function (floorId, name) {
var width = core.floors[floorId].width || 13;
var height = core.floors[floorId].height || 13;
if (core.isset(core.status[name+"maps"][floorId]))
if (main.mode!='editor' && core.isset(core.status[name+"maps"][floorId]))
return core.status[name+"maps"][floorId];
var arr = core.clone(core.floors[floorId][name+"map"] || []);
@ -409,18 +401,12 @@ maps.prototype.drawBgFgMap = function (floorId, canvas, name) {
var width = core.floors[floorId].width || 13;
var height = core.floors[floorId].height || 13;
var groundId = (core.status.maps||core.floors)[floorId].defaultGround || "ground";
var blockIcon = core.material.icons.terrains[groundId];
var blockImage = core.material.images.terrains;
if (!core.isset(core.status[name+"maps"]))
core.status[name+"maps"] = {};
var arr = this.getBgFgMapArray(floorId, name);
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
if (name=='bg')
canvas.drawImage(blockImage, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32);
if (arr[y][x]>0) {
var block = core.maps.initBlock(x, y, arr[y][x]);
if (core.isset(block.event)) {
@ -454,9 +440,16 @@ maps.prototype.drawMap = function (mapName, callback) {
core.removeGlobalAnimate(null, null, true);
var drawBg = function(){
var width = core.floors[mapName].width || 13;
var height = core.floors[mapName].height || 13;
core.maps.drawBgFgMap(mapName, core.canvas.bg, "bg");
core.maps.drawBgFgMap(mapName, core.canvas.fg, "fg");
var groundId = (core.status.maps||core.floors)[mapName].defaultGround || "ground";
var blockIcon = core.material.icons.terrains[groundId];
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
core.canvas.bg.drawImage(core.material.images.terrains, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32);
}
}
var images = [];
if (core.isset(core.status.maps[mapName].images)) {
@ -466,6 +459,7 @@ maps.prototype.drawMap = function (mapName, callback) {
}
}
images.forEach(function (t) {
if (typeof t == 'string') t = [0,0,t];
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2];
if (core.isset(dx) && core.isset(dy) &&
!core.hasFlag("floorimg_"+mapName+"_"+dx+"_"+dy) &&
@ -496,7 +490,10 @@ maps.prototype.drawMap = function (mapName, callback) {
32*dx, 32*dy + image.height - 32, image.width, 32);
}
}
})
});
core.maps.drawBgFgMap(mapName, core.canvas.bg, "bg");
core.maps.drawBgFgMap(mapName, core.canvas.fg, "fg");
}
if (main.mode=='editor'){

View File

@ -283,6 +283,64 @@ ui.prototype.drawText = function (contents, callback) {
// core.drawTextBox(content);
}
ui.prototype.getTitleAndIcon = function (content) {
var id=null, name=null, image=null, icon=null, iconHeight=32, animate=null;
var getInfo = function (v) {
["enemy48", "enemys", "npc48", "npcs"].forEach(function (x) {
if (core.isset(core.material.icons[x][v])) {
image = core.material.images[x];
icon = core.material.icons[x][v];
if (x.indexOf("48")>=0) {
iconHeight = 48;
animate = 4;
}
else {
iconHeight = 32;
animate = 2;
}
}
});
};
if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) {
var index = content.indexOf("]");
if (index>=0) {
var str=content.substring(2, index);
if (content.indexOf("\\t[")==0) str=content.substring(3, index);
content=content.substring(index+1);
var ss=str.split(",");
if (ss.length==1) {
id=ss[0];
if (id=='hero') name = core.status.hero.name;
else if (core.isset(core.material.enemys[id])) {
name = core.material.enemys[id].name;
getInfo(id);
}
else {
name=id;
id='npc';
}
}
else {
name=ss[0];
id = 'npc';
if (ss[1]=='hero') id = 'hero';
else getInfo(ss[1]);
}
}
}
return {
"content": content,
"id": id,
"name": name,
"image": image,
"icon": icon,
"iconHeight": iconHeight,
"animate": animate
};
}
////// 绘制一个对话框 //////
ui.prototype.drawTextBox = function(content, showAll) {
@ -294,78 +352,9 @@ ui.prototype.drawTextBox = function(content, showAll) {
core.status.event.interval = null;
// 获得name, image, icon
var id=null, name=null, image=null, icon=null, iconHeight=32, animate=null;
if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) {
var index = content.indexOf("]");
if (index>=0) {
var str=content.substring(2, index);
if (content.indexOf("\\t[")==0) str=content.substring(3, index);
content=content.substring(index+1);
var ss=str.split(",");
if (ss.length==1) {
// id
id=ss[0];
if (id=='hero') {
name = core.status.hero.name;
}
else {
if (core.isset(core.material.enemys[id])) {
name = core.material.enemys[id].name;
if (core.isset(core.material.icons.enemy48[id])) {
image = core.material.images.enemy48;
icon = core.material.icons.enemy48[id];
iconHeight = 48;
animate=4;
}
else {
image = core.material.images.enemys;
icon = core.material.icons.enemys[id];
iconHeight = 32;
animate=2;
}
}
else {
name=id;
id='npc';
image=null;
icon=null;
}
}
}
else {
name=ss[0];
id = 'npc';
if (ss[1]=='hero') {
id = 'hero';
}
else if (core.isset(core.material.icons.npc48[ss[1]])) {
image = core.material.images.npc48;
icon = core.material.icons.npc48[ss[1]];
iconHeight = 48;
animate=4;
}
else if (core.isset(core.material.icons.npcs[ss[1]])){
image = core.material.images.npcs;
icon = core.material.icons.npcs[ss[1]];
iconHeight = 32;
animate=2;
}
else if (core.isset(core.material.icons.enemy48[ss[1]])) {
image = core.material.images.enemy48;
icon = core.material.icons.enemy48[ss[1]];
iconHeight = 48;
animate=4;
}
else if (core.isset(core.material.icons.enemys[ss[1]])) {
image = core.material.images.enemys;
icon = core.material.icons.enemys[ss[1]];
iconHeight = 32;
animate=2;
}
}
}
}
var info = this.getTitleAndIcon(content);
content = info.content;
var id=info.id, name=info.name, image=info.image, icon=info.icon, iconHeight=info.iconHeight, animate=info.animate;
// 获得位置信息
@ -415,16 +404,17 @@ ui.prototype.drawTextBox = function(content, showAll) {
// var contents = content.split('\n');
// var contents = core.splitLines('ui', content, );
var left=10, right=416-2*left;
var left=7, right=416-2*left;
var content_left = left + 25;
if (id=='hero' || core.isset(icon)) content_left=left+63;
var validWidth = right-(content_left-left)-13;
var font = textfont + 'px Verdana';
if (textAttribute.bold) font = "bold "+font;
var contents = core.splitLines("ui", content, validWidth, font);
var realContent = content.replace(/(\r|\\r)(\[.*?])?/g, "");
var height = 20 + (textfont+5)*(contents.length+1) + (id=='hero'?core.material.icons.hero.height-10:core.isset(name)?iconHeight-10:0);
var height = 20 + (textfont+5)*(core.splitLines("ui", realContent, validWidth, font).length+1)
+ (id=='hero'?core.material.icons.hero.height-10:core.isset(name)?iconHeight-10:0);
var xoffset = 6, yoffset = 22;
@ -434,20 +424,16 @@ ui.prototype.drawTextBox = function(content, showAll) {
top = parseInt((416 - height) / 2);
}
else if (position=='up') {
if (px==null || py==null) {
if (px==null || py==null)
top = 5 + offset;
}
else {
else
top = 32 * py - height - ydelta - yoffset;
}
}
else if (position=='down') {
if (px==null || py==null) {
if (px==null || py==null)
top = 416 - height - 5 - offset;
}
else {
else
top = 32 * py + 32 + yoffset;
}
}
// var left = 97, top = 64, right = 416 - 2 * left, bottom = 416 - 2 * top;
@ -459,11 +445,10 @@ ui.prototype.drawTextBox = function(content, showAll) {
core.setFillStyle('ui', core.arrayToRGB(textAttribute.background));
core.setStrokeStyle('ui', borderColor);
core.fillRect('ui', left, top, right, height);
core.strokeRect('ui', left - 1, top - 1, right + 1, height + 1, borderColor, 2);
var xoffset = 9;
var xoffset = 10;
// draw triangle
if (position=='up' && core.isset(px) && core.isset(py)) {
@ -534,32 +519,66 @@ ui.prototype.drawTextBox = function(content, showAll) {
}
}
var defaultColor = core.arrayToRGB(textAttribute.text);
var offsetx = content_left, offsety = content_top;
core.setFont('ui', font);
core.setAlpha('ui', textAttribute.text[3]);
core.setFillStyle('ui', defaultColor);
var index = 0, currcolor = defaultColor, changed = false;
var drawContent = function (content) {
core.clearMap("ui", content_left, content_top - 18, validWidth, top + height - content_top + 10);
core.setAlpha('ui', textAttribute.background[3]);
core.setFillStyle('ui', core.arrayToRGB(textAttribute.background));
core.fillRect("ui", content_left, content_top - 18, validWidth, top + height - content_top + 11);
core.setAlpha('ui', textAttribute.text[3]);
core.setFillStyle('ui', core.arrayToRGB(textAttribute.text));
var contents = core.splitLines("ui", content, validWidth, font);
for (var i=0;i<contents.length;i++) {
core.fillText('ui', contents[i], content_left, content_top + (textfont+5)*i, null, font);
var drawNext = function () {
if (index >= content.length) return false;
if (changed) {
core.setFillStyle('ui', currcolor);
changed = false;
}
}
// get next character
var char = content.charAt(index++);
// \n, \\n
if (char == '\n' || (char=='\\' && content.charAt(index)=='n')) {
offsetx = content_left;
offsety += textfont+5;
if (char=='\\') index++;
return drawNext();
}
// \r, \\r
if (char == '\r' || (char=='\\' && content.charAt(index)=='r')) {
if (char == '\\') index++;
changed = true;
// 检查是不是 []
var index2;
if (content.charAt(index) == '[' && ((index2=content.indexOf(']', index))>=0)) {
// 变色
var str = content.substring(index+1, index2);
if (str=="") currcolor = defaultColor;
else currcolor = str;
index = index2+1;
}
else currcolor = defaultColor;
return drawNext();
}
// 检查是不是自动换行
var charwidth = core.canvas.ui.measureText(char).width;
if (offsetx + charwidth > content_left + validWidth) {
index--;
offsetx = content_left;
offsety += textfont+5;
return drawNext();
}
// 输出
core.fillText('ui', char, offsetx, offsety);
offsetx += charwidth;
return true;
};
if (showAll || textAttribute.time<=0 || core.status.event.id!='action') {
drawContent(content);
while (drawNext());
}
else {
var index=0;
core.status.event.interval = setInterval(function () {
drawContent(content.substring(0, ++index));
if (index==content.length) {
changed = true;
if (!drawNext()) {
clearInterval(core.status.event.interval);
core.status.event.interval = null;
}
@ -604,82 +623,13 @@ ui.prototype.drawChoices = function(content, choices) {
if (core.isset(content)) {
// 获得name, image, icon
if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) {
var index = content.indexOf("]");
if (index>=0) {
var str=content.substring(2, index);
if (content.indexOf("\\t[")==0) str=content.substring(3, index);
content=content.substring(index+1);
var ss=str.split(",");
if (ss.length==1) {
// id
id=ss[0];
if (id=='hero') {
name = core.status.hero.name;
}
else {
if (core.isset(core.material.enemys[id])) {
name = core.material.enemys[id].name;
if (core.isset(core.material.icons.enemy48[id])) {
image = core.material.images.enemy48;
icon = core.material.icons.enemy48[id];
iconHeight = 48;
animate=4;
}
else {
image = core.material.images.enemys;
icon = core.material.icons.enemys[id];
iconHeight = 32;
animate=2;
}
}
else {
name=id;
id='npc';
image=null;
icon=null;
}
}
}
else {
name=ss[0];
id = 'npc';
if (ss[1]=='hero') {
id = 'hero';
}
else if (core.isset(core.material.icons.npc48[ss[1]])) {
image = core.material.images.npc48;
icon = core.material.icons.npc48[ss[1]];
iconHeight = 48;
animate=4;
}
else if (core.isset(core.material.icons.npcs[ss[1]])){
image = core.material.images.npcs;
icon = core.material.icons.npcs[ss[1]];
iconHeight = 32;
animate=2;
}
else if (core.isset(core.material.icons.enemy48[ss[1]])) {
image = core.material.images.enemy48;
icon = core.material.icons.enemy48[ss[1]];
iconHeight = 48;
animate=4;
}
else if (core.isset(core.material.icons.enemys[ss[1]])) {
image = core.material.images.enemys;
icon = core.material.icons.enemys[ss[1]];
iconHeight = 32;
animate=2;
}
}
}
}
content = core.replaceText(content);
// 获得name, image, icon
var info = this.getTitleAndIcon(content);
content = core.replaceText(info.content);
id=info.id; name=info.name; image=info.image;
icon=info.icon; iconHeight=info.iconHeight; animate=info.animate;
if (id=='hero' || core.isset(icon))
content_left = left+60;
contents = core.splitLines('ui', content, width-(content_left-left)-10, 'bold 15px Verdana');
// content部分高度
@ -746,7 +696,8 @@ ui.prototype.drawChoices = function(content, choices) {
// 选项
core.canvas.ui.textAlign = "center";
for (var i = 0; i < choices.length; i++) {
core.fillText('ui', core.replaceText(choices[i].text || choices[i]), 208, choice_top + 32 * i, "#FFFFFF", "bold 17px Verdana");
core.setFillStyle('ui', choices[i].color || "#FFFFFF");
core.fillText('ui', core.replaceText(choices[i].text || choices[i]), 208, choice_top + 32 * i, null, "bold 17px Verdana");
}
if (choices.length>0) {
@ -846,7 +797,9 @@ ui.prototype.drawQuickShop = function () {
core.status.event.id = 'selectShop';
var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) {return shopList[shopId].visited || !shopList[shopId].mustEnable});
var choices = keys.map(function (shopId) {return shopList[shopId].textInList});
var choices = keys.map(function (shopId) {
return {"text": shopList[shopId].textInList, "color": shopList[shopId].visited?null:"#999999"};
});
choices.push("返回游戏");
this.drawChoices(null, choices);
@ -1340,25 +1293,25 @@ ui.prototype.drawBook = function (index) {
// 数据
core.canvas.ui.textAlign = "center";
if (enemy.special=='') {
if (enemy.specialText=='') {
core.fillText('ui', enemy.name, 115, 62 * i + 47, '#DDDDDD', 'bold 17px Verdana');
}
else {
core.fillText('ui', enemy.name, 115, 62 * i + 40, '#DDDDDD', 'bold 17px Verdana');
core.fillText('ui', enemy.special, 115, 62 * i + 62, '#FF6A6A', 'bold 15px Verdana');
core.fillText('ui', enemy.specialText, 115, 62 * i + 62, '#FF6A6A', 'bold 15px Verdana');
}
core.canvas.ui.textAlign = "left";
core.fillText('ui', '生命', 165, 62 * i + 32, '#DDDDDD', '13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.hp), 195, 62 * i + 32, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.hp||0), 195, 62 * i + 32, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', '攻击', 255, 62 * i + 32, '#DDDDDD', '13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.atk), 285, 62 * i + 32, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.atk||0), 285, 62 * i + 32, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', '防御', 335, 62 * i + 32, '#DDDDDD', '13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.def), 365, 62 * i + 32, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.def||0), 365, 62 * i + 32, '#DDDDDD', 'bold 13px Verdana');
var expOffset = 165, line_cnt=0;
if (core.flags.enableMoney) {
core.fillText('ui', '金币', 165, 62 * i + 50, '#DDDDDD', '13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.money), 195, 62 * i + 50, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.money||0), 195, 62 * i + 50, '#DDDDDD', 'bold 13px Verdana');
expOffset = 255;
line_cnt++;
}
@ -1367,7 +1320,7 @@ ui.prototype.drawBook = function (index) {
if (core.flags.enableAddPoint) {
core.canvas.ui.textAlign = "left";
core.fillText('ui', '加点', expOffset, 62 * i + 50, '#DDDDDD', '13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.point), expOffset + 30, 62 * i + 50, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.point||0), expOffset + 30, 62 * i + 50, '#DDDDDD', 'bold 13px Verdana');
expOffset = 255;
line_cnt++;
}
@ -1375,7 +1328,7 @@ ui.prototype.drawBook = function (index) {
if (core.flags.enableExperience && line_cnt<2) {
core.canvas.ui.textAlign = "left";
core.fillText('ui', '经验', expOffset, 62 * i + 50, '#DDDDDD', '13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.experience), expOffset + 30, 62 * i + 50, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.experience||0), expOffset + 30, 62 * i + 50, '#DDDDDD', 'bold 13px Verdana');
line_cnt++;
}
@ -1396,14 +1349,14 @@ ui.prototype.drawBook = function (index) {
if (damage<=0) color = '#00FF00';
damage = core.formatBigNumber(damage);
if (core.enemys.hasSpecial(core.material.enemys[enemy.id], 19))
if (core.enemys.hasSpecial(enemy, 19))
damage += "+";
if (core.enemys.hasSpecial(core.material.enemys[enemy.id], 21))
if (core.enemys.hasSpecial(enemy, 21))
damage += "-";
if (core.enemys.hasSpecial(core.material.enemys[enemy.id], 11))
if (core.enemys.hasSpecial(enemy, 11))
damage += "^";
}
if (core.material.enemys[enemy.id].notBomb)
if (enemy.notBomb)
damage += "[b]";
core.fillText('ui', damage, damageOffset, 62 * i + 50, color, 'bold 13px Verdana');
@ -1411,11 +1364,11 @@ ui.prototype.drawBook = function (index) {
core.canvas.ui.textAlign = "left";
core.fillText('ui', '临界', 165, 62 * i + 68, '#DDDDDD', '13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.critical), 195, 62 * i + 68, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.critical||0), 195, 62 * i + 68, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', '减伤', 255, 62 * i + 68, '#DDDDDD', '13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.criticalDamage), 285, 62 * i + 68, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.criticalDamage||0), 285, 62 * i + 68, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', '1防', 335, 62 * i + 68, '#DDDDDD', '13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.defDamage), 365, 62 * i + 68, '#DDDDDD', 'bold 13px Verdana');
core.fillText('ui', core.formatBigNumber(enemy.defDamage||0), 365, 62 * i + 68, '#DDDDDD', 'bold 13px Verdana');
if (index == start+i) {
core.strokeRect('ui', 10, 62 * i + 13, 416-10*2, 62, '#FFD700');
@ -1436,8 +1389,7 @@ ui.prototype.drawBookDetail = function (index) {
if (index<0) index=0;
if (index>=enemys.length) index=enemys.length-1;
var enemyId=enemys[index].id;
var enemy = core.material.enemys[enemyId];
var enemy = enemys[index], enemyId = enemy.id;
var hints=core.enemys.getSpecialHint(enemy);
if (hints.length==0)
@ -1619,6 +1571,13 @@ ui.prototype.drawMaps = function (index, x, y) {
core.fillText('ui', "上移地图 [W]", 208, 38, '#FFD700', '20px Arial');
core.fillText('ui', "下移地图 [S]", 208, 390);
core.strokeRect('ui', 2, 2, 28, 28);
core.fillText('ui', 'V', 16, 24);
core.strokeRect('ui', 2, 416-30, 28, 28);
core.fillText('ui', 'M', 16, 408);
core.strokeRect('ui', 416-30, 2, 28, 28);
core.fillText('ui', 'Z', 400, 24);
var top = 150;
core.fillText('ui', "左", 32, top);
core.fillText('ui', "移", 32, top+32);
@ -1636,6 +1595,7 @@ ui.prototype.drawMaps = function (index, x, y) {
core.fillText('ui', "退出 [ESC / ENTER]", 208, 208+8);
core.fillText('ui', "[X] 可查看怪物手册", 285, 208+40, null, '13px Arial');
return;
}
@ -1643,8 +1603,10 @@ ui.prototype.drawMaps = function (index, x, y) {
core.setOpacity('animate', 1);
var damage = (core.status.event.data||{}).damage, paint = (core.status.event.data||{}).paint;
var all = (core.status.event.data||{}).all;
if (core.isset(index.damage)) damage=index.damage;
if (core.isset(index.paint)) paint=index.paint;
if (core.isset(index.all)) all=index.all;
if (core.isset(index.index)) {
x=index.x;
@ -1662,7 +1624,7 @@ ui.prototype.drawMaps = function (index, x, y) {
if (y<6) y=6;
if (y>mh-7) y=mh-7;
core.status.event.data = {"index": index, "x": x, "y": y, "damage": damage, "paint": paint};
core.status.event.data = {"index": index, "x": x, "y": y, "damage": damage, "paint": paint, "all": all};
clearTimeout(core.interval.tipAnimate);
core.clearMap('ui');
@ -1684,7 +1646,7 @@ ui.prototype.drawMaps = function (index, x, y) {
core.setFont('data', '16px Arial');
var text = core.status.maps[floorId].title;
if (mw>13 || mh>13) text+=" ["+(x-6)+","+(y-6)+"]";
if (!all && (mw>13 || mh>13)) text+=" ["+(x-6)+","+(y-6)+"]";
var textX = 16, textY = 18, width = textX + core.canvas.data.measureText(text).width + 16, height = 42;
core.fillRect('data', 5, 5, width, height, '#000');
core.setOpacity('data', 0.4);
@ -2113,8 +2075,13 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
tempCanvas.canvas.height = tempHeight;
tempCanvas.clearRect(0, 0, tempWidth, tempHeight);
// background map
core.maps.drawBgFgMap(floorId, tempCanvas, "bg");
var groundId = (core.status.maps||core.floors)[floorId].defaultGround || "ground";
var blockIcon = core.material.icons.terrains[groundId];
for (var i = 0; i < mw; i++) {
for (var j = 0; j < mh; j++) {
tempCanvas.drawImage(core.material.images.terrains, 0, blockIcon * 32, 32, 32, i * 32, j * 32, 32, 32);
}
}
// background image
var images = [];
@ -2125,6 +2092,7 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
}
}
images.forEach(function (t) {
if (typeof t == 'string') t = [0,0,t];
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2];
if (core.isset(dx) && core.isset(dy) &&
!core.hasFlag("floorimg_"+floorId+"_"+dx+"_"+dy) &&
@ -2137,6 +2105,10 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
32 * dx, 32 * dy + image.height - 32, image.width, 32);
}
})
// background map
core.maps.drawBgFgMap(floorId, tempCanvas, "bg");
// draw block
var mapArray = core.maps.getMapArray(blocks,mw,mh);
for (var b in blocks) {
@ -2172,8 +2144,6 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
var height = core.material.images.images[heroIcon].height/4;
tempCanvas.drawImage(core.material.images.images[heroIcon], icon.stop * 32, icon.loc * height, 32, height, 32*heroLoc.x, 32*heroLoc.y+32-height, 32, height);
}
// foreground map
core.maps.drawBgFgMap(floorId, tempCanvas, "fg");
// draw fg
images.forEach(function (t) {
@ -2190,6 +2160,9 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
}
})
// foreground map
core.maps.drawBgFgMap(floorId, tempCanvas, "fg");
// draw damage
if (core.status.event.id=='viewMaps' && (core.status.event.data||{}).damage)
core.control.updateDamage(floorId, tempCanvas);
@ -2199,9 +2172,28 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
if (!core.isset(centerX)) centerX=parseInt(mw/2);
if (!core.isset(centerY)) centerY=parseInt(mh/2);
var offsetX = core.clamp(centerX-6, 0, mw-13), offsetY = core.clamp(centerY-6, 0, mh-13);
// offsetX~offsetX+12; offsetY~offsetY+12
core.canvas[canvas].drawImage(tempCanvas.canvas, offsetX*32, offsetY*32, 416, 416, x, y, size, size);
// 如果是浏览地图的全模式
if (core.status.event.id=='viewMaps' && (core.status.event.data||{}).all) {
if (tempWidth<=tempHeight) {
var realHeight = 416, realWidth = realHeight * tempWidth / tempHeight;
var side = (416 - realWidth) / 2;
core.fillRect(canvas, 0, 0, side, realHeight, '#000000');
core.fillRect(canvas, 416-side, 0, side, realHeight);
core.canvas[canvas].drawImage(tempCanvas.canvas, 0, 0, tempWidth, tempHeight, side, 0, realWidth, realHeight);
}
else {
var realWidth = 416, realHeight = realWidth * tempHeight / tempWidth;
var side = (416 - realHeight) / 2;
core.fillRect(canvas, 0, 0, realWidth, side, '#000000');
core.fillRect(canvas, 0, 416-side, realWidth, side);
core.canvas[canvas].drawImage(tempCanvas.canvas, 0, 0, tempWidth, tempHeight, 0, side, realWidth, realHeight);
}
}
else {
var offsetX = core.clamp(centerX-6, 0, mw-13), offsetY = core.clamp(centerY-6, 0, mh-13);
// offsetX~offsetX+12; offsetY~offsetY+12
core.canvas[canvas].drawImage(tempCanvas.canvas, offsetX*32, offsetY*32, 416, 416, x, y, size, size);
}
}
ui.prototype.drawKeyBoard = function () {

View File

@ -4,16 +4,41 @@ utils.js 工具类
*/
function utils() {
this.init();
}
utils.prototype.init = function () {
// 定义Object.assign
if (typeof Object.assign != "function") {
Object.assign = function(target, varArgs) { // .length of function is 2
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
};
}
}
////// 将文字中的${和}(表达式)进行替换 //////
utils.prototype.replaceText = function (text) {
return text.replace(/\${([^}]+)}/g, function (word, value) {
return text.replace(/\${(.*?)}/g, function (word, value) {
return core.calValue(value);
});
}
@ -486,8 +511,8 @@ utils.prototype.__init_seed = function () {
rand = this.__next_rand(rand);
rand = this.__next_rand(rand);
rand = this.__next_rand(rand);
core.setFlag('seed', rand);
core.setFlag('rand', rand);
core.setFlag('__seed__', rand);
core.setFlag('__rand__', rand);
}
utils.prototype.__next_rand = function (_rand) {
@ -497,9 +522,9 @@ utils.prototype.__next_rand = function (_rand) {
}
utils.prototype.rand = function (num) {
var rand = core.getFlag('rand');
var rand = core.getFlag('__rand__');
rand = this.__next_rand(rand);
core.setFlag('rand', rand);
core.setFlag('__rand__', rand);
var ans = rand/2147483647;
if (core.isset(num) && num>0)
return Math.floor(ans*num);
@ -800,12 +825,12 @@ utils.prototype.decodeCanvas = function (arr, width, height) {
}
utils.prototype.consoleOpened = function () {
if (window.Firebug && window.Firebug.chrome && window.Firebug.chrome.isInitialized)
return true;
var threshold = 160;
var widthThreshold = window.outerWidth - window.innerWidth > threshold;
var heightThreshold = window.outerHeight - window.innerHeight > threshold;
return !(heightThreshold && widthThreshold) &&
((window.Firebug && window.Firebug.chrome && window.Firebug.chrome.isInitialized)
|| widthThreshold || heightThreshold);
var zoom = Math.min(window.outerWidth/window.innerWidth, window.outerHeight/window.innerHeight);
return window.outerWidth - zoom*window.innerWidth > threshold
|| window.outerHeight - zoom*window.innerHeight > threshold;
}
utils.prototype.hashCode = function (obj) {

11
main.js
View File

@ -2,7 +2,7 @@ function main() {
//------------------------ 用户修改内容 ------------------------//
this.version = "2.5"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.version = "2.5.1"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.useCompress = false; // 是否使用压缩文件
// 当你即将发布你的塔时请使用“JS代码压缩工具”将所有js代码进行压缩然后将这里的useCompress改为true。
@ -420,15 +420,6 @@ main.statusBar.image.fly.onclick = function () {
return;
}
// 浏览地图时
if (main.core.isPlaying() && (core.status.event||{}).id=='viewMaps') {
if (core.isset(core.status.event.data)) {
core.status.event.data.paint = !core.status.event.data.paint;
core.ui.drawMaps(core.status.event.data);
}
return;
}
if (main.core.isPlaying()) {
if (!main.core.flags.equipboxButton) {
main.core.useFly(true);

View File

@ -68,7 +68,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"firstData": {
"title": "魔塔样板",
"name": "template",
"version": "Ver 2.5",
"version": "Ver 2.5.1",
"floorId": "sample0",
"hero": {
"name": "阳光",
@ -203,6 +203,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"enableMoney": true,
"enableExperience": false,
"enableLevelUp": false,
"levelUpLeftMode": false,
"enableKeys": true,
"enablePZF": false,
"enableDebuff": false,
@ -232,6 +233,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"portalWithoutTrigger": true,
"canGoDeadZone": false,
"enableMoveDirectly": true,
"enableDisabledShop": true
"enableDisabledShop": true,
"disableShopOnDamage": false
}
}

File diff suppressed because it is too large Load Diff

View File

@ -817,7 +817,11 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 进阶
if (core.flags.enableLevelUp && core.status.hero.lv<core.firstData.levelUp.length) {
core.statusBar.up.innerHTML = core.firstData.levelUp[core.status.hero.lv].need || " ";
var need = core.firstData.levelUp[core.status.hero.lv].need;
if (core.flags.levelUpLeftMode)
core.statusBar.up.innerHTML = (need - core.getStatus('experience')) || " ";
else
core.statusBar.up.innerHTML = need || " ";
}
else core.statusBar.up.innerHTML = " ";

View File

@ -1,4 +1,22 @@
HTML5魔塔样板V2.5
HTML5魔塔样板V2.5.1
新增事件type:insert可以插入另一个地点的事件执行公共事件
可以使用\r来控制剧情文本部分文字的颜色
新增事件type:switch多重分歧
绘制前景/背景层时淡化其他图层
追加素材的自动调整(如白底、不规范的素材)
浏览地图时:左上角/V开启显伤右上角/Z查看当前层大地图
允许在受到领域夹击等伤害后禁用快捷商店
升级的扣除模式,即不显示经验值,只显示升级的所需剩余值
装备增加可装备条件判定
选项界面可以使用1-9快速选择
未开启状态的快捷商店用灰色显示
修复不能在背景/前景层绘图的Bug
部分其他细节优化
-----------------------------------------------------------------------
HTML5魔塔样板V2.5
添加绘图模式支持;可以用户手动绘图和保存
内置主动技能:二倍斩的支持,可以仿照制作其他主动技能