commit
6542c4e845
16
README.md
16
README.md
@ -53,6 +53,22 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
|
||||
## 更新说明
|
||||
|
||||
### 2018.11.21 V2.5.1
|
||||
|
||||
* [x] 新增事件type:insert,可以插入另一个地点的事件执行(公共事件)
|
||||
* [x] 可以使用\v来控制剧情文本部分文字的颜色
|
||||
* [x] 新增事件type:switch,多重分歧
|
||||
* [x] 绘制前景/背景层时淡化其他图层
|
||||
* [x] 追加素材的自动调整(如白底、不规范的素材)
|
||||
* [x] 浏览地图时:左上角/V开启显伤;右上角/Z查看当前层大地图
|
||||
* [x] 允许在受到领域夹击等伤害后禁用快捷商店
|
||||
* [x] 升级的扣除模式,即不显示经验值,只显示升级的所需剩余值
|
||||
* [x] 装备增加可装备条件判定
|
||||
* [x] 选项界面可以使用1-9快速选择
|
||||
* [x] 未开启状态的快捷商店用灰色显示
|
||||
* [x] 修复不能在背景/前景层绘图的Bug
|
||||
* [x] 部分其他细节优化
|
||||
|
||||
### 2018.10.31 V2.5
|
||||
|
||||
* [x] 添加绘图模式支持;可以用户手动绘图和保存
|
||||
|
||||
@ -192,6 +192,7 @@ action
|
||||
| show_s
|
||||
| hide_s
|
||||
| trigger_s
|
||||
| insert_s
|
||||
| revisit_s
|
||||
| exit_s
|
||||
| setBlock_s
|
||||
@ -481,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
|
||||
|
||||
@ -1966,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]);
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -1079,19 +1079,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');
|
||||
|
||||
@ -108,10 +108,10 @@ editor_blockly = function () {
|
||||
],
|
||||
'事件控制':[
|
||||
MotaActionBlocks['if_s'].xmlText(),
|
||||
MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别量", "caseList": [
|
||||
MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [
|
||||
{"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]},
|
||||
{"action": []},
|
||||
{"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行此事件"}]},
|
||||
{"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行default事件"}]},
|
||||
]}),
|
||||
MotaActionBlocks['while_s'].xmlText(),
|
||||
MotaActionBlocks['break_s'].xmlText(),
|
||||
@ -126,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(),
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# V2.0版本介绍
|
||||
|
||||
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 附录: API列表
|
||||
|
||||
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
**这里只列出所有可能会被造塔者用到的常用API,更多的有关内容请在代码内进行查询。**
|
||||
|
||||
|
||||
@ -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]`。
|
||||
- 使用`\v[...]`来动态修改局部文本的颜色,如`\v[red]`。
|
||||
- 使用`${}`来计算一个表达式的值,如`${status:atk+status:def}`。
|
||||
|
||||
详细信息请参见[剧情文本控制](event#text:显示一段文字(剧情))中的说明。
|
||||
|
||||
## 大地图
|
||||
|
||||
从V2.4开始,H5魔塔开始支持大地图。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 事件
|
||||
|
||||
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
本章内将对样板所支持的事件进行介绍。
|
||||
|
||||
@ -237,6 +237,15 @@
|
||||
|
||||
!> `\t[...]`必须在`\b[...]`前面!不然两者都无法正常显示。
|
||||
|
||||
还可以使用`\v[...]`来调整剧情文本的颜色。
|
||||
|
||||
``` js
|
||||
"x,y": [ // 实际执行的事件列表
|
||||
"这句话是默认颜色,\v[red]将颜色变成红色,\v[blue]将颜色变成蓝色",
|
||||
"\v[#FF00FF]还可以使用RGB值来控制颜色,\v如果不加中括号则回到默认颜色",
|
||||
"\t[hero]\b[up,hero]啊啊啊,别过来,\v[red]别过来!!!\n\v你到底是什么东西!"
|
||||
]
|
||||
```
|
||||
|
||||
另外值得一提的是,我们是可以在文字中计算一个表达式的值的。只需要将表达式用 `${ }`整个括起来就可以。
|
||||
|
||||
@ -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完全相同,只不过是立刻触发的还是本地点的事件
|
||||
@ -1215,11 +1250,11 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以
|
||||
]
|
||||
```
|
||||
|
||||
我们可以在condition中给出一个表达式(能将`status:xxx, item:xxx, flag:xxx`来作为参数),并计算它的值
|
||||
我们可以在condition中给出一个表达式(能将`status:xxx`, `item:xxx`, `flag:xxx`来作为参数),并计算它的值
|
||||
|
||||
如果某条件中的值与其相等,则将执行其对应的列表事件内容。
|
||||
|
||||
如果没有符合的值,则将执行`"default"`中的列表事件内容。
|
||||
如果没有符合的值,则将执行`default`中的列表事件内容。
|
||||
|
||||
例如下面这个例子,将检查当前游戏难度并赠送不同属性。
|
||||
|
||||
@ -1248,7 +1283,7 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以
|
||||
需要额外注意的几点:
|
||||
|
||||
- 各个条件分支的判断是顺序执行的,因此若多个分支的条件都满足,将只执行最靠前的分支,同理,请不要在`"default"`分支后添加分支,这些分支将不可能被执行。
|
||||
-`"default"`分支并不是必要的,如果删除,则在没有满足条件的分支时将不执行任何事件。
|
||||
- `default`分支并不是必要的,如果删除,则在没有满足条件的分支时将不执行任何事件。
|
||||
- 即使某个场合不执行事件,对应的action数组也需要存在,不过简单的留空就好。
|
||||
- switch可以不断进行嵌套,一层套一层;如某条件成立的场合再进行另一个switch判断等。
|
||||
- switch语句内的内容执行完毕后将接着其后面的语句继续执行。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# HTML5 魔塔样板说明文档
|
||||
|
||||
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。
|
||||
|
||||
|
||||
@ -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,7 +556,7 @@ this.myfunc = function(x) {
|
||||
然后比如我们在某个道具的使用效果 `useItemEffect` 中写 `core.plugin.myfunc(2)` 即可调用此公共事件(插件)。也可以在战后事件或自定义脚本等位置来写。
|
||||
|
||||
通过这种,将脚本和自定义事件混用的方式,可以达到和RM中公共事件类似的效果,即一个调用触发一系列事件。
|
||||
|
||||
-->
|
||||
## 自定义状态栏(新增显示项)
|
||||
|
||||
在V2.2以后,我们可以自定义状态栏背景图(全塔属性 - statusLeftBackground)等等。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 快速上手
|
||||
|
||||
?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
|
||||
|
||||
|
||||
107
libs/actions.js
107
libs/actions.js
@ -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;
|
||||
}
|
||||
|
||||
@ -1811,6 +1856,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 +1944,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 +2030,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 +2072,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 +2129,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 +2210,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 +2304,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 +2327,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 +2351,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 +2386,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////// “虚拟键盘”界面时的点击操作 //////
|
||||
|
||||
@ -1519,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;
|
||||
// 没有怪物手册
|
||||
@ -1598,7 +1600,7 @@ control.prototype.updateDamage = function (floorId, canvas) {
|
||||
}
|
||||
}
|
||||
// 如果是领域&夹击
|
||||
if (core.flags.displayExtraDamage) {
|
||||
if (core.flags.displayExtraDamage && core.isset((core.status.checkBlock||{}).damage)) {
|
||||
canvas.textAlign = 'center';
|
||||
|
||||
// 临时改变
|
||||
@ -2254,7 +2256,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;
|
||||
}
|
||||
@ -2293,7 +2295,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;
|
||||
}
|
||||
@ -2794,6 +2796,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;
|
||||
|
||||
@ -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],
|
||||
@ -203,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();
|
||||
|
||||
|
||||
@ -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);
|
||||
@ -910,7 +919,7 @@ events.prototype.doAction = function() {
|
||||
case "switch": // 条件选择
|
||||
var key = core.calValue(data.condition)
|
||||
for (var i = 0; i < data.caseList.length; i++) {
|
||||
if (core.calValue(data.caseList[i].case) == key || core.calValue(data.caseList[i].case) == "default") {
|
||||
if (data.caseList[i].case=="default" || core.calValue(data.caseList[i].case) == key) {
|
||||
core.events.insertAction(data.caseList[i].action);
|
||||
break;
|
||||
}
|
||||
@ -1336,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;
|
||||
}
|
||||
@ -1356,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;
|
||||
}
|
||||
@ -1641,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);
|
||||
@ -1912,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');
|
||||
|
||||
@ -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 = [];
|
||||
|
||||
25
libs/maps.js
25
libs/maps.js
@ -386,7 +386,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 +409,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 +448,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 +467,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 +498,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'){
|
||||
|
||||
369
libs/ui.js
369
libs/ui.js
@ -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(/(\v|\\v)(\[.*?])?/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();
|
||||
}
|
||||
// \v, \\v
|
||||
if (char == '\v' || (char=='\\' && content.charAt(index)=='v')) {
|
||||
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);
|
||||
@ -1618,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);
|
||||
@ -1635,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;
|
||||
}
|
||||
|
||||
@ -1642,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;
|
||||
@ -1661,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');
|
||||
@ -1683,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);
|
||||
@ -2112,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 = [];
|
||||
@ -2124,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) &&
|
||||
@ -2136,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) {
|
||||
@ -2171,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) {
|
||||
@ -2189,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);
|
||||
@ -2198,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 () {
|
||||
|
||||
@ -13,7 +13,7 @@ utils.prototype.init = function () {
|
||||
|
||||
////// 将文字中的${和}(表达式)进行替换 //////
|
||||
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 +486,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 +497,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);
|
||||
|
||||
11
main.js
11
main.js
@ -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);
|
||||
|
||||
@ -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": "阳光",
|
||||
|
||||
@ -594,7 +594,7 @@ main.floors.sample1=
|
||||
]
|
||||
},
|
||||
{
|
||||
"case": "'default'",
|
||||
"case": "default",
|
||||
"action": [
|
||||
{
|
||||
"type": "comment",
|
||||
|
||||
20
更新说明.txt
20
更新说明.txt
@ -1,4 +1,22 @@
|
||||
HTML5魔塔样板V2.5
|
||||
HTML5魔塔样板V2.5.1
|
||||
|
||||
新增事件type:insert,可以插入另一个地点的事件执行(公共事件)
|
||||
可以使用\v来控制剧情文本部分文字的颜色
|
||||
新增事件type:switch,多重分歧
|
||||
绘制前景/背景层时淡化其他图层
|
||||
追加素材的自动调整(如白底、不规范的素材)
|
||||
浏览地图时:左上角/V开启显伤;右上角/Z查看当前层大地图
|
||||
允许在受到领域夹击等伤害后禁用快捷商店
|
||||
升级的扣除模式,即不显示经验值,只显示升级的所需剩余值
|
||||
装备增加可装备条件判定
|
||||
选项界面可以使用1-9快速选择
|
||||
未开启状态的快捷商店用灰色显示
|
||||
修复不能在背景/前景层绘图的Bug
|
||||
部分其他细节优化
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
HTML5魔塔样板V2.5
|
||||
|
||||
添加绘图模式支持;可以用户手动绘图和保存
|
||||
内置主动技能:二倍斩的支持,可以仿照制作其他主动技能
|
||||
|
||||
Loading…
Reference in New Issue
Block a user