commit
889f10d498
14
README.md
14
README.md
@ -53,6 +53,20 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
|
||||
## 更新说明
|
||||
|
||||
### 2018.11.30 V2.5.2
|
||||
|
||||
* [x] 怪物和NPC的行走图和朝向问题
|
||||
* [x] 可以引入WindowSkin作为对话框的背景素材
|
||||
* [x] \r可以动态调整剧情文本的颜色
|
||||
* [x] 升级事件改用事件编辑器完成
|
||||
* [x] 每层楼都增添该层的并行事件处理
|
||||
* [x] 新增快捷键:N返回标题;P查看评论;O打开工程
|
||||
* [x] 道具可以设置是否在回放时绘制道具栏或直接使用
|
||||
* [x] 追加素材一次可以追加多个
|
||||
* [x] 可以同时异步移动两张或以上的图片了
|
||||
* [x] 菜单栏中新增虚拟键盘的弹出
|
||||
* [x] 修复所有已知Bug;部分细节优化
|
||||
|
||||
### 2018.11.21 V2.5.1
|
||||
|
||||
* [x] 新增事件type:insert,可以插入另一个地点的事件执行(公共事件)
|
||||
|
||||
@ -331,7 +331,7 @@ autoText_s
|
||||
/* autoText_s
|
||||
tooltip : autoText:自动剧情文本,用户无法跳过自动剧情文本,大段剧情文本请添加“是否跳过剧情”的提示
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=autotext%EF%BC%9A%E8%87%AA%E5%8A%A8%E5%89%A7%E6%83%85%E6%96%87%E6%9C%AC
|
||||
default : ["小妖精","fairy","",3000,"双击方块进入多行编辑\\n自动剧情文本\\n自动剧情文本\\n自动剧情文本"]
|
||||
default : ["小妖精","fairy","",3000,"用户无法跳过自动剧情文本,大段剧情文本请添加“是否跳过剧情”的提示"]
|
||||
var title='';
|
||||
if (EvalString_0==''){
|
||||
if (IdString_0=='')title='';
|
||||
@ -371,8 +371,15 @@ if (EvalString_2) {
|
||||
EvalString_2 = ', "text": ['+EvalString_2+']';
|
||||
}
|
||||
if (EvalString_3) {
|
||||
if (!colorRe.test(EvalString_3))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1');
|
||||
EvalString_3 = ', "background": ['+EvalString_3+']';
|
||||
if (colorRe.test(EvalString_3)) {
|
||||
EvalString_3 = ', "background": ['+EvalString_3+']';
|
||||
}
|
||||
else if (/^\w+\.png$/.test(EvalString_3)) {
|
||||
EvalString_3 = ', "background": "'+EvalString_3+'"';
|
||||
}
|
||||
else {
|
||||
throw new Error('背景格式错误,必须是形如0~255,0~255,0~255,0~1的颜色,或一个WindowSkin的png图片名称');
|
||||
}
|
||||
}
|
||||
if (EvalString_4) {
|
||||
if (!/^\d+$/.test(EvalString_4))throw new Error('字体大小必须是整数或不填');
|
||||
@ -1805,7 +1812,8 @@ ActionParser.prototype.parseAction = function() {
|
||||
var setTextfunc = function(a){return a?JSON.stringify(a).slice(1,-1):null;}
|
||||
data.title=setTextfunc(data.title);
|
||||
data.text=setTextfunc(data.text);
|
||||
data.background=setTextfunc(data.background);
|
||||
if (!/^\w+\.png$/.test(data.background))
|
||||
data.background=setTextfunc(data.background);
|
||||
this.next = MotaActionBlocks['setText_s'].xmlText([
|
||||
data.position,data.offset,data.title,data.text,data.background,data.bold,data.titlefont,data.textfont,data.time,this.next]);
|
||||
break;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
var comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
"_leaf": false,
|
||||
"_type": "object",
|
||||
@ -41,7 +41,13 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "装备属性设置,仅对cls为equips有效。\n如果此项不为null,需要是一个对象,里面可含\"type\",\"atk\",\"def\",\"mdef\",\"animate\"五项,分别对应装备部位、攻防魔防和动画。\n具体详见文档(元件说明-装备)和已有的几个装备的写法。"
|
||||
},
|
||||
},
|
||||
"hideInReplay": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否回放时绘制道具栏。\n如果此项为true,则在回放录像时使用本道具将不会绘制道具栏页面,而是直接使用。\n此项建议在会频繁连续多次使用的道具开启(如开启技能,或者《镜子》那样的镜像切换等等)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"itemEffect": {
|
||||
@ -92,6 +98,12 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
"_string": true,
|
||||
"_data": "名称"
|
||||
},
|
||||
"displayIdInBook": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "在怪物手册中映射到的怪物ID。如果此项不为null,则在怪物手册中,将用目标ID来替换该怪物原本的ID。\n此项应被运用在同一个怪物的多朝向上。\n例如,如果想定义同一个怪物的向下和向左的行走图,则需要建立两个属性完全相同的怪物。\n但是这样会导致在怪物手册中同时存在向下和向左的两种怪物的显示。\n可以将朝向左的怪物的displayIdInBook项指定为朝向下的怪物ID,这样在怪物手册中则会归一化,只显示一个。"
|
||||
},
|
||||
"hp": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
@ -250,6 +262,11 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||(thiseval instanceof Array)",
|
||||
"_data": "该图块的不可入方向\n可以在这里定义不能从哪个方向访问该图块,可以达到悬崖之类的效果\n例如 [\"down\", \"right\"] 代表不能从下或右访问此图块\n此值对背景层、事件层、前景层上的图块均有效"
|
||||
},
|
||||
"faceIds": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "行走图朝向,仅对NPC有效。可以在这里定义同一个NPC的多个朝向行走图。\n比如 {\"up\":\"N333\",\"down\":\"N334\",\"left\":\"N335\",\"right\":\"N336\"} 就将该素材的上下左右朝向分别绑定到N333,N334,N335和N336四个图块。\n在勇士撞上NPC时,或NPC在移动时,会自动选择最合适的朝向图块(如果存在定义)来进行绘制。"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -330,7 +347,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||((thiseval instanceof Array) && thiseval.length==2)",
|
||||
"_data": "该层上楼点,如[2,3]。\n如果此项不为null,则楼层转换时的stair:downFloor,以及楼传器的落点会被替换成该点而不是该层的下楼梯。"
|
||||
"_data": "该层下楼点,如[2,3]。\n如果此项不为null,则楼层转换时的stair:downFloor,以及楼传器的落点会被替换成该点而不是该层的下楼梯。"
|
||||
},
|
||||
"defaultGround": {
|
||||
"_leaf": true,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
"_leaf": false,
|
||||
"_type": "object",
|
||||
@ -225,8 +225,16 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
"_data": {
|
||||
"direction": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "勇士初始方向"
|
||||
"_type": "select",
|
||||
"_data": "勇士初始方向",
|
||||
"_select": {
|
||||
"values": [
|
||||
"up",
|
||||
"down",
|
||||
"left",
|
||||
"right"
|
||||
]
|
||||
},
|
||||
},
|
||||
"x": {
|
||||
"_leaf": true,
|
||||
|
||||
@ -58,13 +58,7 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['text_0_s'].xmlText(),
|
||||
MotaActionBlocks['text_1_s'].xmlText(),
|
||||
MotaActionBlocks['comment_s'].xmlText(),
|
||||
MotaActionFunctions.actionParser.parseList({"type": "choices", "text": "是否跳过剧情", "choices": [
|
||||
{"text": "是", "action": []},
|
||||
{"text": "否", "action": [
|
||||
{"type": "autoText", "text": "\\t[小妖精,fairy]双击方块进入多行编辑\\n用户无法跳过自动剧情文本,大段剧情文本请添加“是否跳过剧情”的提示\\n自动剧情文本\\n自动剧情文本\\n自动剧情文本", "time" :3000},
|
||||
{"type": "autoText", "text": "(可以右键方块后点复制)", "time" :3000},
|
||||
]},
|
||||
]}),
|
||||
MotaActionBlocks['autoText_s'].xmlText(),
|
||||
MotaActionBlocks['setText_s'].xmlText(),
|
||||
MotaActionBlocks['showImage_0_s'].xmlText(),
|
||||
MotaActionBlocks['animateImage_0_s'].xmlText(),
|
||||
|
||||
@ -805,7 +805,7 @@ editor_file = function (editor, callback) {
|
||||
actionList.forEach(function (value) {
|
||||
eval("icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr = 'icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = \n';
|
||||
var datastr = 'var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = \n';
|
||||
datastr += JSON.stringify(icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1, null, '\t');
|
||||
fs.writeFile('project/icons.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
@ -816,7 +816,7 @@ editor_file = function (editor, callback) {
|
||||
actionList.forEach(function (value) {
|
||||
eval("maps_90f36752_8815_4be8_b32b_d7fad1d0542e" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr = 'maps_90f36752_8815_4be8_b32b_d7fad1d0542e = \n';
|
||||
var datastr = 'var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = \n';
|
||||
//datastr+=JSON.stringify(maps_90f36752_8815_4be8_b32b_d7fad1d0542e,null,4);
|
||||
|
||||
var emap = {};
|
||||
@ -841,7 +841,7 @@ editor_file = function (editor, callback) {
|
||||
actionList.forEach(function (value) {
|
||||
eval("items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr = 'items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = \n';
|
||||
var datastr = 'var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = \n';
|
||||
datastr += JSON.stringify(items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a, null, '\t');
|
||||
fs.writeFile('project/items.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
@ -852,7 +852,7 @@ editor_file = function (editor, callback) {
|
||||
actionList.forEach(function (value) {
|
||||
eval("enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr = 'enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 = \n';
|
||||
var datastr = 'var enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 = \n';
|
||||
var emap = {};
|
||||
var estr = JSON.stringify(enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80, function (k, v) {
|
||||
if (v.hp != null) {
|
||||
@ -876,7 +876,7 @@ editor_file = function (editor, callback) {
|
||||
});
|
||||
if (data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds.indexOf(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.floorId) < 0)
|
||||
data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.floorId = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds[0];
|
||||
var datastr = 'data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = \n';
|
||||
var datastr = 'var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = \n';
|
||||
datastr += JSON.stringify(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d, null, '\t');
|
||||
fs.writeFile('project/data.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
@ -891,7 +891,7 @@ editor_file = function (editor, callback) {
|
||||
for (var id_ in fmap) {
|
||||
fraw = fraw.replace('"' + id_ + '"', fmap[id_])
|
||||
}
|
||||
var datastr = 'functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = \n';
|
||||
var datastr = 'var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = \n';
|
||||
datastr += fraw;
|
||||
fs.writeFile('project/functions.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
"_leaf": false,
|
||||
"_type": "object",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
maps_comment_90f36752_8815_4be8_b32b_d7fad1d0542e =
|
||||
var maps_comment_90f36752_8815_4be8_b32b_d7fad1d0542e =
|
||||
{
|
||||
////////////////////////// 地形部分 //////////////////////////
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# V2.0版本介绍
|
||||
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。
|
||||
|
||||
|
||||
10
docs/api.md
10
docs/api.md
@ -1,6 +1,6 @@
|
||||
# 附录: API列表
|
||||
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
**这里只列出所有可能会被造塔者用到的常用API,更多的有关内容请在代码内进行查询。**
|
||||
|
||||
@ -439,6 +439,10 @@ loader.js将主要用来进行资源的加载,比如加载音乐、图片、
|
||||
maps.js主要用来进行地图相关的的操作。包括绘制地图,获取地图上的点等等。
|
||||
|
||||
|
||||
core.maps.getNumberById(id)
|
||||
根据ID来获得对应的数字。如果该ID不存在对应的数字则返回0。
|
||||
|
||||
|
||||
core.maps.canMoveHero(x,y,direction,floorId)
|
||||
判断能否前往某个方向。x,y为坐标,可忽略为当前点;direction为方向,可忽略为当前方向。
|
||||
floorId为楼层ID,可忽略为当前楼层。
|
||||
@ -504,6 +508,10 @@ core.utils.arrayToRGB(color)
|
||||
将形如[255,0,0]之类的数组转成#FF0000这样的RGB形式。
|
||||
|
||||
|
||||
core.utils.arrayToRGBA(color)
|
||||
将形如[255,0,0,1]之类的数组转成rgba(255,0,0,1)这样的RGBA形式。
|
||||
|
||||
|
||||
core.utils.encodeRoute(list)
|
||||
压缩加密路线。可以使用core.encodeRoute(core.status.route)来压缩当前路线。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 元件说明
|
||||
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
|
||||
|
||||
@ -236,6 +236,49 @@ N连击怪物的special是6,且我们可以为它定义n代表实际连击数
|
||||
|
||||
如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。
|
||||
|
||||
## 怪物和NPC的朝向问题
|
||||
|
||||
从V2.5.2开始,对于人形怪物和NPC的朝向问题已经有着比较好的解决方式。
|
||||
|
||||
首先明确一点的是,和RM不同,H5中即使是对同一个怪物/NPC的不同朝向,也需要分别将其各个朝向素材追加对应的图片上,并进行注册。
|
||||
|
||||
### 怪物的朝向问题
|
||||
|
||||
对于同一个怪物的不同朝向,需要对每个朝向创建一个怪物(属性完全相同),这样就可以在地图上绘制不同朝向的怪物。
|
||||
|
||||
但是这样会存在一个问题,就是怪物手册中怪物的每个朝向都会显示成一个单独的怪物。
|
||||
|
||||
为了避免这种情况的发生,在怪物的属性中存在一个`displayIdInBook`项,**我们可以指定该项来控制每个怪物在怪物手册中中显示成的怪物。**
|
||||
|
||||
举个例子,假设我现在有个怪物,其向下的行走图ID是`E300`,其向左的行走图ID是`E301`,向右的行走图ID是`E302`。分别对这几个怪物填写完全相同的怪物属性。
|
||||
|
||||
如果我在地图上同时绘制向下、向左和向右的该怪物,则确实能在地图上显示出来不同的朝向,但是在怪物手册中会同时显示这三种类型的怪物,观感较差。
|
||||
|
||||
我们可以给`E301`和`E302`怪物属性中的`displayIdInBook`项填写为`"E300"`。
|
||||
|
||||
这样的话,在怪物手册中,所有的E301和E302均会被视为E300并进行合并。即使只有一只朝向左的怪物(E301),怪物手册仍然会按E300进行显示。
|
||||
|
||||
从而完美解决了同种怪物不同朝向在怪物手册的显示问题。
|
||||
|
||||
### NPC的朝向问题
|
||||
|
||||
和怪物不同的是,NPC朝向问题更复杂一点。
|
||||
|
||||
在NPC的图块属性中,存在一个`faceIds`的项目,可以用其来绑定一个图块所对应的其他朝向的图块ID。
|
||||
|
||||
举个例子,假设我存在一个NPC,其向上的图块ID是N333,向下的图块ID是N334,向左的图块ID是N335,不存在向右的图块ID。
|
||||
|
||||
则可以在这几个图块属性中的`faceIds`中写:`{"up": "N333", "down": "N334", "left": "N335"}`。
|
||||
|
||||
当勇士从左边撞上此怪物后,将从该图块的图块属性中的faceIds中寻求`left`所对应的ID。
|
||||
如果存在定义(如N335),则会在触发对话事件前改变当前图块为N335,看起来就是在对话前进行了转向,面向勇士。
|
||||
|
||||
!> 请注意,在对话结束后朝向不会切换回来,因此如果有必要切换朝向请在事件结束前调用转变图块事件。
|
||||
|
||||
同理,使用移动事件让NPC在行走时,不同朝向的行走会自动调用`faceIds`中不同朝向的ID所对应的行走图,看起来就是在行走时也可以不断转向了。
|
||||
|
||||
从而,完美解决了NPC的朝向问题(碰触时面向勇士、行走时改变朝向)。
|
||||
|
||||
## 路障,楼梯,传送门
|
||||
|
||||
血网的伤害数值、中毒后每步伤害数值、衰弱时暂时攻防下降的数值,都在 `data.js` 的values内定义。
|
||||
@ -262,7 +305,7 @@ floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
|
||||
**从2.1.1开始,楼层属性中提供了`upFloor`和`downFloor`两项。如果设置此项(比如`"upFloor": [2,3]`),则写stair:upFloor或者楼传器的落点将用此点来替换楼梯位置(即类似于RM中的上箭头)。**
|
||||
|
||||
## 剧情文本控制
|
||||
## 剧情文本控制与界面皮肤
|
||||
|
||||
在写剧情文本时,可以:
|
||||
|
||||
@ -273,6 +316,14 @@ floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
|
||||
详细信息请参见[剧情文本控制](event#text:显示一段文字(剧情))中的说明。
|
||||
|
||||
从V2.5.2开始,可以用一张WindowSkin图片作为对话框的背景皮肤。
|
||||
|
||||
使用时,需要将图片放在images目录下,并在全塔属性中予以注册。
|
||||
|
||||
可以使用[设置剧情文本的属性](setText:设置剧情文本的属性)事件将对话框背景设置为需要的皮肤。
|
||||
|
||||
!> 关于对话框效果请注意,现在是采用WindowSkin的右下角两个32x32的图片作为对话框尖角进行绘制。因此请尽量使用群文件或网盘的常用素材中给出的WindowSkin素材(均已进行对话框适配)。如需使用来自第三方的WindowSkin素材,请自行注意对话框的尖角问题,或弃用`\b`效果。
|
||||
|
||||
## 大地图
|
||||
|
||||
从V2.4开始,H5魔塔开始支持大地图。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 事件
|
||||
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
本章内将对样板所支持的事件进行介绍。
|
||||
|
||||
@ -304,7 +304,8 @@ time为可选项,代表该自动文本的时间。可以不指定,不指定
|
||||
"x,y": [ // 实际执行的事件列表
|
||||
{"type": "setText", "title": [255,0,0], "text": [255,255,0], "background": [0,0,255,0.3]},
|
||||
{"type": "setText", "position": "up", "bold": true, "titlefont": 26, "textfont": 17, "time": 70},
|
||||
"这段话将显示在上方,标题为红色,正文为黄色粗体,背景为透明度0.3的蓝色,标题26px,正文17px,70毫秒速度打字机效果"
|
||||
"这段话将显示在上方,标题为红色,正文为黄色粗体,背景为透明度0.3的蓝色,标题26px,正文17px,70毫秒速度打字机效果",
|
||||
{"type": "setText", "background": "winskin.png"} // 还可以一张使用WindowSkin作为皮肤。
|
||||
]
|
||||
```
|
||||
|
||||
@ -312,7 +313,9 @@ title为可选项,如果设置则为一个RGB三元组或RGBA四元组,表
|
||||
|
||||
text为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示正文颜色。 默认值:`[255,255,255,1]`
|
||||
|
||||
background为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示背景色。 默认值:`[0,0,0,0.85]`
|
||||
background为可选项,如果设置可为一个RGB三元组或RGBA四元组,表示背景色。 默认值:`[0,0,0,0.85]`
|
||||
|
||||
V2.5.2以后,background也可以为一个WindowSkin的文件名。详见[剧情文本控制与界面皮肤](element#剧情文本控制与界面皮肤)。
|
||||
|
||||
position为可选项,表示设置文字显示位置。只能为up(上),center(中)和down(下)三者。 默认值: `center`
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# HTML5 魔塔样板说明文档
|
||||
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 个性化
|
||||
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
|
||||
|
||||
@ -818,8 +818,6 @@ if (core.flags.enableSkill) {
|
||||
3. 在脚本编辑 - setInitData中加上`core.plugin.initHeros()`来初始化新勇士。(写在`core.events.afterLoadData()`后,反大括号之前。)
|
||||
4. 如果需要切换角色(包括事件、道具或者快捷键等),可以直接调用自定义JS脚本:`core.plugin.changeHero();`进行切换。也可以指定参数调用`core.plugin.changeHero(1)`来切换到某个具体的勇士上。
|
||||
|
||||
!> 如果道具不共用,需要在初始定义那里写 `'items': {"keys": {"yellowKey": 0, "blueKey": 0, "redKey": 0}, "tools": {}, "constants": {}}`
|
||||
|
||||
## 根据难度分歧来自定义地图
|
||||
|
||||
遗憾的是,所有地图数据必须在剧本的map中指定,换句话说,我们无法在游戏进行中动态修改地图,比如为简单难度增加一个血瓶。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 快速上手
|
||||
|
||||
?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
|
||||
|
||||
|
||||
@ -1823,8 +1823,9 @@ actions.prototype.clickSwitchs = function (x,y) {
|
||||
case 8:
|
||||
if (core.platform.isPC)
|
||||
window.open("editor.html", "_blank");
|
||||
else
|
||||
else if (confirm("即将离开本塔,跳转至本塔工程页面,确认?")) {
|
||||
window.location.href = "editor-mobile.html";
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (core.platform.isPC)
|
||||
@ -1889,8 +1890,7 @@ actions.prototype.clickSettings = function (x,y) {
|
||||
core.ui.drawSwitchs();
|
||||
break;
|
||||
case 1:
|
||||
core.status.event.selection=0;
|
||||
core.ui.drawQuickShop();
|
||||
core.ui.drawKeyBoard();
|
||||
break;
|
||||
case 2:
|
||||
core.ui.drawMaps();
|
||||
@ -1903,6 +1903,25 @@ actions.prototype.clickSettings = function (x,y) {
|
||||
core.ui.drawSyncSave();
|
||||
break;
|
||||
case 5:
|
||||
core.ui.drawStatistics();
|
||||
break;
|
||||
case 6:
|
||||
if (core.platform.isPC) {
|
||||
window.open("/score.php?name="+core.firstData.name+"&num=10", "_blank");
|
||||
}
|
||||
else {
|
||||
if (confirm("即将离开本塔,跳转至本塔评论页面,确认?")) {
|
||||
window.location.href = "/score.php?name="+core.firstData.name+"&num=10";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
core.ui.drawHelp();
|
||||
break;
|
||||
case 8:
|
||||
core.ui.drawAbout();
|
||||
break;
|
||||
case 9:
|
||||
core.status.event.selection=1;
|
||||
core.ui.drawConfirmBox("你确定要返回标题页面吗?", function () {
|
||||
core.ui.closePanel();
|
||||
@ -1912,16 +1931,7 @@ actions.prototype.clickSettings = function (x,y) {
|
||||
core.ui.drawSettings();
|
||||
});
|
||||
break;
|
||||
case 6:
|
||||
core.ui.drawStatistics();
|
||||
break;
|
||||
case 7:
|
||||
core.ui.drawHelp();
|
||||
break;
|
||||
case 8:
|
||||
core.ui.drawAbout();
|
||||
break;
|
||||
case 9:
|
||||
case 10:
|
||||
core.ui.closePanel();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -45,7 +45,6 @@ control.prototype.setRequestAnimationFrame = function () {
|
||||
}());
|
||||
|
||||
core.animateFrame.speed = core.values.animateSpeed;
|
||||
core.animateFrame.background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||
|
||||
var scan = {
|
||||
'up': {'x': 0, 'y': -1},
|
||||
@ -865,14 +864,14 @@ control.prototype.eventMoveHero = function(steps, time, callback) {
|
||||
'right': {'x': 1, 'y': 0}
|
||||
};
|
||||
|
||||
core.status.replay.animate=true;
|
||||
// core.status.replay.animate=true;
|
||||
|
||||
var animate=window.setInterval(function() {
|
||||
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
|
||||
if (moveSteps.length==0) {
|
||||
clearInterval(animate);
|
||||
core.drawHero(null, x, y);
|
||||
core.status.replay.animate=false;
|
||||
// core.status.replay.animate=false;
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
else {
|
||||
@ -905,7 +904,7 @@ control.prototype.jumpHero = function (ex, ey, time, callback) {
|
||||
time = time || 500;
|
||||
core.clearMap('ui');
|
||||
core.setAlpha('ui', 1.0);
|
||||
core.status.replay.animate=true;
|
||||
// core.status.replay.animate=true;
|
||||
|
||||
core.playSound('jump.mp3');
|
||||
|
||||
@ -955,7 +954,7 @@ control.prototype.jumpHero = function (ex, ey, time, callback) {
|
||||
core.setHeroLoc('x', ex);
|
||||
core.setHeroLoc('y', ey);
|
||||
core.drawHero();
|
||||
core.status.replay.animate=false;
|
||||
// core.status.replay.animate=false;
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
|
||||
@ -1483,30 +1482,28 @@ control.prototype.setFg = function(color, time, callback) {
|
||||
if (time==0) {
|
||||
// 直接变色
|
||||
core.clearMap('curtain');
|
||||
core.setAlpha('curtain', color[3]);
|
||||
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGB(color));
|
||||
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGBA(color));
|
||||
core.status.curtainColor = color;
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
|
||||
var step=0;
|
||||
core.status.replay.animate=true;
|
||||
// core.status.replay.animate=true;
|
||||
var changeAnimate = setInterval(function() {
|
||||
step++;
|
||||
|
||||
var nowAlpha = fromColor[3]+(color[3]-fromColor[3])*step/25;
|
||||
var nowA = fromColor[3]+(color[3]-fromColor[3])*step/25;
|
||||
var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/25);
|
||||
var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/25);
|
||||
var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/25);
|
||||
core.clearMap('curtain');
|
||||
core.setAlpha('curtain', nowAlpha);
|
||||
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGB([nowR,nowG,nowB]));
|
||||
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGBA([nowR,nowG,nowB,nowA]));
|
||||
|
||||
if (step>=25) {
|
||||
clearInterval(changeAnimate);
|
||||
core.status.curtainColor = color;
|
||||
core.status.replay.animate=false;
|
||||
// core.status.replay.animate=false;
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
}, time/25/core.status.replay.speed);
|
||||
@ -1912,27 +1909,36 @@ control.prototype.replay = function () {
|
||||
else if (action.indexOf("item:")==0) {
|
||||
var itemId = action.substring(5);
|
||||
if (core.canUseItem(itemId)) {
|
||||
var tools = Object.keys(core.status.hero.items.tools).sort();
|
||||
var constants = Object.keys(core.status.hero.items.constants).sort();
|
||||
var index=-1;
|
||||
if ((index=tools.indexOf(itemId))>=0) {
|
||||
core.status.event.data = {"toolsPage":Math.floor(index/12)+1, "constantsPage":1, "selectId":null};
|
||||
index = index%12;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (index>=0) {
|
||||
core.ui.drawToolbox(index);
|
||||
setTimeout(function () {
|
||||
core.ui.closePanel();
|
||||
core.useItem(itemId, function () {
|
||||
core.replay();
|
||||
});
|
||||
}, 750 / Math.max(1, core.status.replay.speed));
|
||||
// 是否绘制道具栏
|
||||
if (core.material.items[itemId].hideInReplay) {
|
||||
core.useItem(itemId, function () {
|
||||
core.replay();
|
||||
});
|
||||
return;
|
||||
}
|
||||
else {
|
||||
var tools = Object.keys(core.status.hero.items.tools).sort();
|
||||
var constants = Object.keys(core.status.hero.items.constants).sort();
|
||||
var index=-1;
|
||||
if ((index=tools.indexOf(itemId))>=0) {
|
||||
core.status.event.data = {"toolsPage":Math.floor(index/12)+1, "constantsPage":1, "selectId":null};
|
||||
index = index%12;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (index>=0) {
|
||||
core.ui.drawToolbox(index);
|
||||
setTimeout(function () {
|
||||
core.ui.closePanel();
|
||||
core.useItem(itemId, function () {
|
||||
core.replay();
|
||||
});
|
||||
}, 750 / Math.max(1, core.status.replay.speed));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (action.indexOf("unEquip:")==0) {
|
||||
|
||||
10
libs/core.js
10
libs/core.js
@ -29,7 +29,6 @@ function core() {
|
||||
'onDownInterval': null,
|
||||
}
|
||||
this.animateFrame = {
|
||||
'background': null,
|
||||
'globalAnimate': false,
|
||||
'globalTime': null,
|
||||
'boxTime': null,
|
||||
@ -309,6 +308,9 @@ core.prototype.init = function (coreData, callback) {
|
||||
core.flags.displayExtraDamage = core.getLocalStorage('extraDamage', core.flags.displayExtraDamage);
|
||||
|
||||
core.material.ground = new Image();
|
||||
core.material.ground.onload = function () {
|
||||
core.material.groundPattern = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||
}
|
||||
core.material.ground.src = "project/images/ground.png";
|
||||
|
||||
core.bigmap.tempCanvas = document.createElement('canvas').getContext('2d');
|
||||
@ -1024,6 +1026,12 @@ core.prototype.arrayToRGB = function (color) {
|
||||
return core.utils.arrayToRGB(color);
|
||||
}
|
||||
|
||||
////// 数组转RGBA //////
|
||||
core.prototype.arrayToRGBA = function (color) {
|
||||
return core.utils.arrayToRGBA(color);
|
||||
}
|
||||
|
||||
|
||||
////// 作弊 //////
|
||||
core.prototype.debug = function() {
|
||||
core.control.debug();
|
||||
|
||||
@ -242,9 +242,18 @@ enemys.prototype.getCurrentEnemys = function (floorId) {
|
||||
if (core.isset(mapBlocks[b].event) && !mapBlocks[b].disable
|
||||
&& mapBlocks[b].event.cls.indexOf('enemy')==0) {
|
||||
var enemyId = mapBlocks[b].event.id;
|
||||
if (core.isset(used[enemyId])) continue;
|
||||
|
||||
var enemy = core.material.enemys[enemyId];
|
||||
if (!core.isset(enemy)) continue;
|
||||
|
||||
// 检查displayIdInBook
|
||||
var tmpId = enemy.displayIdInBook;
|
||||
if (core.isset(core.material.enemys[tmpId])) {
|
||||
enemyId = tmpId;
|
||||
enemy = core.material.enemys[tmpId];
|
||||
}
|
||||
if (core.isset(used[enemyId])) continue;
|
||||
|
||||
var mon_hp = enemy.hp, mon_atk = enemy.atk, mon_def = enemy.def;
|
||||
var hero_atk = core.status.hero.atk, hero_def = core.status.hero.def, hero_mdef = core.status.hero.mdef;
|
||||
|
||||
|
||||
@ -60,7 +60,18 @@ events.prototype.init = function () {
|
||||
callback();
|
||||
},
|
||||
'action': function (data, core, callback) {
|
||||
core.events.insertAction(data.event.data, data.x, data.y, callback);
|
||||
var ev = core.clone(data.event.data), ex = data.x, ey = data.y;
|
||||
// 检查是否需要改变朝向
|
||||
if (ex == core.nextX() && ey == core.nextY()) {
|
||||
var dir = {"up":"down","down":"up","left":"right","right":"left"}[core.getHeroLoc('direction')];
|
||||
var id = data.event.id, toId = (data.event.faceIds||{})[dir];
|
||||
if (core.isset(toId) && id!=toId) {
|
||||
var number = core.maps.getNumberById(toId);
|
||||
if (number>0)
|
||||
core.setBlock(number, ex, ey);
|
||||
}
|
||||
}
|
||||
core.events.insertAction(ev, ex, ey, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -406,6 +417,12 @@ events.prototype.doAction = function() {
|
||||
if (data[t].length==3) data[t].push(1);
|
||||
core.status.textAttribute[t]=data[t];
|
||||
}
|
||||
if (t=='background' && core.isset(data[t])) {
|
||||
var img = core.material.images.images[data[t]];
|
||||
if (core.isset(img) && img.width==192 && img.height==128) {
|
||||
core.status.textAttribute[t]=data[t];
|
||||
}
|
||||
}
|
||||
});
|
||||
core.setFlag('textAttribute', core.status.textAttribute);
|
||||
core.events.doAction();
|
||||
@ -1354,11 +1371,7 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback
|
||||
if (core.isset(color)) {
|
||||
// 直接变色
|
||||
core.clearMap('curtain');
|
||||
if (core.isset(color[3]))
|
||||
core.setAlpha('curtain', color[3]);
|
||||
else
|
||||
core.setAlpha('curtain', 1);
|
||||
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGB(color));
|
||||
core.fillRect('curtain',0,0,416,core.arrayToRGBA(color));
|
||||
core.status.curtainColor = color;
|
||||
}
|
||||
else {
|
||||
@ -1456,7 +1469,7 @@ events.prototype.animateImage = function (type, image, loc, time, keep, callback
|
||||
core.setOpacity('data', opacityVal);
|
||||
var x = core.calValue(loc[0]), y = core.calValue(loc[1]);
|
||||
core.canvas.data.drawImage(image, x, y);
|
||||
core.status.replay.animate=true;
|
||||
// core.status.replay.animate=true;
|
||||
var animate = setInterval(function () {
|
||||
if (type=='show') opacityVal += 0.1;
|
||||
else opacityVal -= 0.1;
|
||||
@ -1467,7 +1480,7 @@ events.prototype.animateImage = function (type, image, loc, time, keep, callback
|
||||
core.canvas.image.drawImage(image, x, y);
|
||||
core.clearMap('data');
|
||||
core.setOpacity('data', 1);
|
||||
core.status.replay.animate=false;
|
||||
// core.status.replay.animate=false;
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
}, time / 10);
|
||||
@ -1480,29 +1493,33 @@ events.prototype.moveImage = function (image, from, to, time, keep, callback) {
|
||||
core.setAlpha('data', 1);
|
||||
core.setOpacity('data', 1);
|
||||
|
||||
if (keep) core.clearMap('image');
|
||||
var width = image.width, height = image.height;
|
||||
|
||||
core.status.replay.animate=true;
|
||||
// core.status.replay.animate=true;
|
||||
var fromX = core.calValue(from[0]), fromY = core.calValue(from[1]),
|
||||
toX = core.calValue(to[0]), toY = core.calValue(to[1]);
|
||||
var step = 0;
|
||||
|
||||
if (keep) core.clearMap('image', fromX, fromY, width, height);
|
||||
|
||||
var step = 0, preX = fromX, preY = fromY;
|
||||
var per_time = 10, steps = parseInt(time / per_time);
|
||||
var drawImage = function () {
|
||||
core.clearMap('data');
|
||||
var nowX = parseInt(fromX + (toX-fromX)*step/steps);
|
||||
var nowY = parseInt(fromY + (toY-fromY)*step/steps);
|
||||
core.canvas.data.drawImage(image, nowX, nowY);
|
||||
preX = parseInt(fromX + (toX-fromX)*step/steps);
|
||||
preY = parseInt(fromY + (toY-fromY)*step/steps);
|
||||
core.canvas.data.drawImage(image, preX, preY);
|
||||
}
|
||||
|
||||
drawImage();
|
||||
var animate = setInterval(function () {
|
||||
core.clearMap('data', preX, preY, width, height);
|
||||
step++;
|
||||
drawImage();
|
||||
if (step>=steps) {
|
||||
if (step <= steps)
|
||||
drawImage();
|
||||
else {
|
||||
clearInterval(animate);
|
||||
core.clearMap('data');
|
||||
core.status.replay.animate=false;
|
||||
if (keep) core.canvas.data.drawImage(image, toX, toY);
|
||||
// score.clearMap('data');
|
||||
// core.status.replay.animate=false;
|
||||
if (keep) core.canvas.image.drawImage(image, toX, toY);
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
}, per_time);
|
||||
@ -1524,7 +1541,7 @@ events.prototype.setVolume = function (value, time, callback) {
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
core.status.replay.animate=true;
|
||||
// core.status.replay.animate=true;
|
||||
var currVolume = core.musicStatus.volume;
|
||||
var step = 0;
|
||||
var fade = setInterval(function () {
|
||||
@ -1533,7 +1550,7 @@ events.prototype.setVolume = function (value, time, callback) {
|
||||
set(nowVolume);
|
||||
if (step>=32) {
|
||||
clearInterval(fade);
|
||||
core.status.replay.animate=false;
|
||||
// core.status.replay.animate=false;
|
||||
if (core.isset(callback))
|
||||
callback();
|
||||
}
|
||||
@ -1548,7 +1565,7 @@ events.prototype.vibrate = function(time, callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
core.status.replay.animate=true;
|
||||
// core.status.replay.animate=true;
|
||||
|
||||
var addGameCanvasTranslate=function(x,y){
|
||||
for(var ii=0,canvas;canvas=core.dom.gameCanvas[ii];ii++){
|
||||
@ -1596,7 +1613,7 @@ events.prototype.vibrate = function(time, callback) {
|
||||
addGameCanvasTranslate(shake, 0);
|
||||
if(shake_duration===0) {
|
||||
clearInterval(animate);
|
||||
core.status.replay.animate=false;
|
||||
// core.status.replay.animate=false;
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
}, 50/3);
|
||||
|
||||
48
libs/maps.js
48
libs/maps.js
@ -49,6 +49,23 @@ maps.prototype.loadFloor = function (floorId, map) {
|
||||
return content;
|
||||
}
|
||||
|
||||
////// 从ID获得数字 //////
|
||||
maps.prototype.getNumberById = function (id) {
|
||||
for (var number in this.blocksInfo) {
|
||||
if ((this.blocksInfo[number]||{}).id == id)
|
||||
return parseInt(number)||0;
|
||||
}
|
||||
// tilesets
|
||||
if (/^X\d+$/.test(id)) {
|
||||
var info = core.icons.getTilesetOffset(id);
|
||||
if (info!=null) return parseInt(id.substring(1));
|
||||
}
|
||||
// 特殊ID
|
||||
if (id == 'none') return 0;
|
||||
if (id == 'airwall') return 17;
|
||||
return 0;
|
||||
}
|
||||
|
||||
////// 数字和ID的对应关系 //////
|
||||
maps.prototype.initBlock = function (x, y, id) {
|
||||
var disable=null;
|
||||
@ -730,7 +747,7 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
|
||||
}
|
||||
var id = block.block.id;
|
||||
|
||||
core.status.replay.animate=true;
|
||||
// core.status.replay.animate=true;
|
||||
|
||||
// 需要删除该块
|
||||
core.removeBlock(x,y);
|
||||
@ -741,6 +758,7 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
|
||||
block=block.block;
|
||||
|
||||
var image, bx, by, height = block.event.height || 32;
|
||||
var faceIds = {};
|
||||
if (block.event.cls == 'tileset') {
|
||||
var offset = core.icons.getTilesetOffset(block.event.id);
|
||||
if (offset==null) {
|
||||
@ -765,6 +783,7 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
|
||||
image = core.material.images[block.event.cls];
|
||||
bx = 0;
|
||||
by = core.material.icons[block.event.cls][block.event.id];
|
||||
faceIds = block.event.faceIds||{};
|
||||
}
|
||||
|
||||
var opacityVal = 1;
|
||||
@ -829,15 +848,26 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
|
||||
core.setBlock(id, nowX/32, nowY/32);
|
||||
core.showBlock(nowX/32, nowY/32);
|
||||
}
|
||||
core.status.replay.animate=false;
|
||||
// core.status.replay.animate=false;
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 移动中
|
||||
var direction = moveSteps[0];
|
||||
if (step == 0) {
|
||||
// 根据faceIds修改朝向
|
||||
var currid = faceIds[direction];
|
||||
if (core.isset(currid)) {
|
||||
var tby = core.material.icons[block.event.cls][currid];
|
||||
if (core.isset(tby))
|
||||
by = tby;
|
||||
}
|
||||
}
|
||||
|
||||
step++;
|
||||
nowX+=scan[moveSteps[0]].x*2;
|
||||
nowY+=scan[moveSteps[0]].y*2;
|
||||
nowX+=scan[direction].x*2;
|
||||
nowY+=scan[direction].y*2;
|
||||
core.clearMap('route', nowX-32, nowY-32, 96, 96);
|
||||
// 绘制
|
||||
core.canvas.route.drawImage(image, animateCurrent * 32, by * height, 32, height, nowX, nowY-height+32, 32, height);
|
||||
@ -861,7 +891,7 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) {
|
||||
}
|
||||
var id = block.block.id;
|
||||
|
||||
core.status.replay.animate=true;
|
||||
// core.status.replay.animate=true;
|
||||
|
||||
// 需要删除该块
|
||||
core.removeBlock(sx,sy);
|
||||
@ -960,7 +990,7 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) {
|
||||
core.setBlock(id, ex, ey);
|
||||
core.showBlock(ex, ey);
|
||||
}
|
||||
core.status.replay.animate=false;
|
||||
// core.status.replay.animate=false;
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
}
|
||||
@ -1015,7 +1045,7 @@ maps.prototype.animateBlock = function (loc,type,time,callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
core.status.replay.animate=true;
|
||||
// core.status.replay.animate=true;
|
||||
var draw = function () {
|
||||
list.forEach(function (t) {
|
||||
core.canvas.route.drawImage(t.image, t.bx*32, t.by*t.height, 32, t.height, t.x*32, t.y*32+32-t.height, 32, t.height);
|
||||
@ -1036,7 +1066,7 @@ maps.prototype.animateBlock = function (loc,type,time,callback) {
|
||||
clearInterval(animate);
|
||||
core.clearMap('route');
|
||||
core.setOpacity('route', 1);
|
||||
core.status.replay.animate=false;
|
||||
// core.status.replay.animate=false;
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
}, time / 10 / core.status.replay.speed);
|
||||
@ -1233,7 +1263,7 @@ maps.prototype.drawBoxAnimate = function () {
|
||||
var obj = core.status.boxAnimateObjs[a];
|
||||
obj.status = ((obj.status||0)+1)%obj.animate;
|
||||
core.clearMap('ui', obj.bgx, obj.bgy, obj.bgWidth, obj.bgHeight);
|
||||
core.fillRect('ui', obj.bgx, obj.bgy, obj.bgWidth, obj.bgHeight, core.animateFrame.background);
|
||||
core.fillRect('ui', obj.bgx, obj.bgy, obj.bgWidth, obj.bgHeight, core.material.groundPattern);
|
||||
core.canvas.ui.drawImage(obj.image, obj.status * 32, obj.pos,
|
||||
32, obj.height, obj.x, obj.y, 32, obj.height);
|
||||
}
|
||||
|
||||
260
libs/ui.js
260
libs/ui.js
@ -344,6 +344,57 @@ ui.prototype.getTitleAndIcon = function (content) {
|
||||
};
|
||||
}
|
||||
|
||||
// 绘制选择光标
|
||||
ui.prototype.drawWindowSelector = function(background,canvas,x,y,w,h) {
|
||||
var dstImage = core.canvas[canvas];
|
||||
|
||||
// back
|
||||
dstImage.drawImage(background,130,66,28,28,x+2,y+2,w-4,h-4);
|
||||
// corner
|
||||
dstImage.drawImage(background,128,64,2,2,x,y,2,2);
|
||||
dstImage.drawImage(background,158,64,2,2,x+w-2,y,2,2);
|
||||
dstImage.drawImage(background,128,94,2,2,x,y+h-2,2,2);
|
||||
dstImage.drawImage(background,158,94,2,2,x+w-2,y+h-2,2,2);
|
||||
// border
|
||||
dstImage.drawImage(background,130,64,28,2,x+2,y,w-4,2);
|
||||
dstImage.drawImage(background,130,94,28,2,x+2,y+h-2,w-4,2);
|
||||
dstImage.drawImage(background,128,66,2,28,x,y+2,2,h-4);
|
||||
dstImage.drawImage(background,158,66,2,28,x+w-2,y+2,2,h-4);
|
||||
}
|
||||
|
||||
// 绘制皮肤
|
||||
ui.prototype.drawWindowSkin = function(background,canvas,x,y,w,h,direction,px,py) {
|
||||
// 仿RM窗口皮肤 ↓
|
||||
var dstImage = core.canvas[canvas];
|
||||
|
||||
// back
|
||||
dstImage.drawImage(background,0,0,128,128,x+1,y+1,w-2,h-2);
|
||||
// corner
|
||||
dstImage.drawImage(background,128,0,16,16,x,y,16,16);
|
||||
dstImage.drawImage(background,176,0,16,16,x+w-16,y,16,16);
|
||||
dstImage.drawImage(background,128,48,16,16,x,y+h-16,16,16);
|
||||
dstImage.drawImage(background,176,48,16,16,x+w-16,y+h-16,16,16);
|
||||
// border
|
||||
dstImage.drawImage(background,144,0,32,16,x+16,y,w-32,16);
|
||||
dstImage.drawImage(background,144,48,32,16,x+16,y+h-16,w-32,16);
|
||||
dstImage.drawImage(background,128,16,16,32,x,y+16,16,h-32);
|
||||
dstImage.drawImage(background,176,16,16,32,x+w-16,y+16,16,h-32);
|
||||
// arrow
|
||||
if(core.isset(px) && core.isset(py)){
|
||||
if(direction == 'up'){
|
||||
dstImage.drawImage(background,128,96,32,32,px,y+h-3,32,32);
|
||||
}else if(direction == 'down') {
|
||||
dstImage.drawImage(background,160,96,32,32,px,y-29,32,32);
|
||||
}
|
||||
}
|
||||
// 仿RM窗口皮肤 ↑
|
||||
}
|
||||
|
||||
// 绘制纯色的背景框
|
||||
ui.prototype.drawPureBackground = function (background,canvas,borderColor,x,y,w,h,direction,px,py) {
|
||||
|
||||
}
|
||||
|
||||
////// 绘制一个对话框 //////
|
||||
ui.prototype.drawTextBox = function(content, showAll) {
|
||||
|
||||
@ -359,14 +410,25 @@ ui.prototype.drawTextBox = function(content, showAll) {
|
||||
content = info.content;
|
||||
var id=info.id, name=info.name, image=info.image, icon=info.icon, iconHeight=info.iconHeight, animate=info.animate;
|
||||
|
||||
// 获得位置信息
|
||||
|
||||
// 获得颜色的盒子等信息
|
||||
var textAttribute = core.status.textAttribute || core.initStatus.textAttribute;
|
||||
|
||||
var titlefont = textAttribute.titlefont || 22;
|
||||
var textfont = textAttribute.textfont || 16;
|
||||
var offset = textAttribute.offset || 0;
|
||||
var background = core.status.textAttribute.background;
|
||||
var isWindowSkin = false;
|
||||
if (typeof background == 'string') {
|
||||
background = core.material.images.images[background];
|
||||
if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true;
|
||||
else background = core.initStatus.textAttribute.background;
|
||||
}
|
||||
|
||||
var titleColor = core.arrayToRGBA(textAttribute.title);
|
||||
var textColor = core.arrayToRGBA(textAttribute.text);
|
||||
var borderColor = main.borderColor||"#FFFFFF";
|
||||
var alpha = isWindowSkin?0.85:background[3];
|
||||
|
||||
// 获得位置信息
|
||||
var position = textAttribute.position, px=null, py=null, ydelta=iconHeight-32;
|
||||
if (content.indexOf("\b[")==0 || content.indexOf("\\b[")==0) {
|
||||
var index = content.indexOf("]");
|
||||
@ -383,6 +445,9 @@ ui.prototype.drawTextBox = function(content, showAll) {
|
||||
px = core.status.event.data.x;
|
||||
py = core.status.event.data.y;
|
||||
}
|
||||
else {
|
||||
px = null; py=null;
|
||||
}
|
||||
|
||||
if (ss.length>=2) {
|
||||
if (ss[1]=='hero') {
|
||||
@ -401,17 +466,14 @@ ui.prototype.drawTextBox = function(content, showAll) {
|
||||
|
||||
content = core.replaceText(content);
|
||||
|
||||
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||
core.status.boxAnimateObjs = [];
|
||||
core.clearMap('ui');
|
||||
|
||||
// var contents = content.split('\n');
|
||||
// var contents = core.splitLines('ui', content, );
|
||||
var left=7, right=416-2*left;
|
||||
var left=7, right=416-left, width = right-left;
|
||||
var content_left = left + 25;
|
||||
if (id=='hero' || core.isset(icon)) content_left=left+63;
|
||||
|
||||
var validWidth = right-(content_left-left)-13;
|
||||
var validWidth = right-content_left - 10;
|
||||
var font = textfont + 'px Verdana';
|
||||
if (textAttribute.bold) font = "bold "+font;
|
||||
var realContent = content.replace(/(\r|\\r)(\[.*?])?/g, "");
|
||||
@ -419,8 +481,7 @@ ui.prototype.drawTextBox = function(content, showAll) {
|
||||
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;
|
||||
var xoffset = 11, yoffset = 16;
|
||||
|
||||
var top;
|
||||
if (position=='center') {
|
||||
@ -438,52 +499,43 @@ ui.prototype.drawTextBox = function(content, showAll) {
|
||||
else
|
||||
top = 32 * py + 32 + yoffset;
|
||||
}
|
||||
var bottom = top + height;
|
||||
|
||||
// var left = 97, top = 64, right = 416 - 2 * left, bottom = 416 - 2 * top;
|
||||
//core.setAlpha('ui', 0.85);
|
||||
|
||||
var borderColor = main.borderColor||"#FFFFFF";
|
||||
|
||||
core.setAlpha('ui', textAttribute.background[3]);
|
||||
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 = 10;
|
||||
|
||||
// draw triangle
|
||||
if (position=='up' && core.isset(px) && core.isset(py)) {
|
||||
core.canvas.ui.clearRect(32*px+xoffset, top+height-1, 32-2*xoffset, 2);
|
||||
core.canvas.ui.beginPath();
|
||||
core.canvas.ui.moveTo(32*px+xoffset-1, top+height-1);
|
||||
core.canvas.ui.lineTo(32*px+16, top+height+yoffset-2);
|
||||
core.canvas.ui.lineTo(32*px+32-xoffset+1, top+height-1);
|
||||
core.canvas.ui.moveTo(32*px+xoffset-1, top+height-1);
|
||||
core.canvas.ui.closePath();
|
||||
core.canvas.ui.fill();
|
||||
// core.canvas.ui.stroke();
|
||||
// core.drawLine('ui', 32*px+4+1, top+height+1, 32*px + 28-1, top+height+1, core.arrayToRGB(textAttribute.background), 3);
|
||||
core.drawLine('ui', 32*px+xoffset, top+height, 32*px+16, top+height+yoffset-2);
|
||||
core.drawLine('ui', 32*px+32-xoffset, top+height, 32*px+16, top+height+yoffset-2);
|
||||
if (isWindowSkin) {
|
||||
core.setAlpha('ui', alpha);
|
||||
this.drawWindowSkin(background,'ui',left,top,width,height,position,px==null?null:px*32,py==null?null:py*32);
|
||||
core.setAlpha('ui', 1);
|
||||
}
|
||||
if (position=='down' && core.isset(px) && core.isset(py)) {
|
||||
core.canvas.ui.clearRect(32*px+xoffset, top-2, 32-2*xoffset, 3);
|
||||
core.canvas.ui.beginPath();
|
||||
core.canvas.ui.moveTo(32*px+xoffset-1, top+1);
|
||||
core.canvas.ui.lineTo(32*px+16-1, top-yoffset+2);
|
||||
core.canvas.ui.lineTo(32*px+32-xoffset-1, top+1);
|
||||
core.canvas.ui.moveTo(32*px+xoffset-1, top+1);
|
||||
core.canvas.ui.closePath();
|
||||
core.canvas.ui.fill();
|
||||
// core.canvas.ui.stroke();
|
||||
// core.drawLine('ui', 32*px+4+1, top+height+1, 32*px + 28-1, top+height+1, core.arrayToRGB(textAttribute.background), 3);
|
||||
core.drawLine('ui', 32*px+xoffset, top, 32*px+16, top-yoffset+2);
|
||||
core.drawLine('ui', 32*px+32-xoffset, top, 32*px+16, top-yoffset+2);
|
||||
else {
|
||||
yoffset -= 4;
|
||||
core.setAlpha('ui', alpha);
|
||||
core.setStrokeStyle('ui', borderColor);
|
||||
core.setFillStyle('ui', core.arrayToRGB(background));
|
||||
core.setLineWidth('ui', 2);
|
||||
// 绘制
|
||||
var canvas = core.canvas.ui;
|
||||
canvas.beginPath();
|
||||
canvas.moveTo(left,top);
|
||||
// 上边缘
|
||||
if (position=='down' && core.isset(px) && core.isset(py)) {
|
||||
canvas.lineTo(32*px+xoffset, top);
|
||||
canvas.lineTo(32*px+16, top-yoffset);
|
||||
canvas.lineTo(32*(px+1)-xoffset, top);
|
||||
}
|
||||
canvas.lineTo(right, top);
|
||||
canvas.lineTo(right, bottom);
|
||||
// 下边缘
|
||||
if (position=='up' && core.isset(px) && core.isset(py)) {
|
||||
canvas.lineTo(32*(px+1)-xoffset, bottom);
|
||||
canvas.lineTo(32*px+16, bottom+yoffset);
|
||||
canvas.lineTo(32*px+xoffset, bottom);
|
||||
}
|
||||
canvas.lineTo(left, bottom);
|
||||
canvas.closePath();
|
||||
canvas.fill();
|
||||
canvas.stroke();
|
||||
core.setAlpha('ui', 1);
|
||||
}
|
||||
|
||||
|
||||
// 名称
|
||||
core.canvas.ui.textAlign = "left";
|
||||
|
||||
@ -491,24 +543,26 @@ ui.prototype.drawTextBox = function(content, showAll) {
|
||||
if (core.isset(id)) {
|
||||
|
||||
content_top = top+57;
|
||||
core.setAlpha('ui', textAttribute.title[3]);
|
||||
core.setFillStyle('ui', core.arrayToRGB(textAttribute.title));
|
||||
core.setStrokeStyle('ui', core.arrayToRGB(textAttribute.title));
|
||||
core.setFillStyle('ui', titleColor);
|
||||
core.setStrokeStyle('ui', titleColor);
|
||||
|
||||
if (id == 'hero') {
|
||||
var heroHeight=core.material.icons.hero.height;
|
||||
core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, heroHeight+2, borderColor, 2);
|
||||
core.setAlpha('ui', alpha);
|
||||
core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, heroHeight+2, null, 2);
|
||||
core.setAlpha('ui', 1);
|
||||
core.fillText('ui', name, content_left, top + 30, null, 'bold '+titlefont+'px Verdana');
|
||||
core.clearMap('ui', left + 15, top + 40, 32, heroHeight);
|
||||
core.fillRect('ui', left + 15, top + 40, 32, heroHeight, background);
|
||||
core.fillRect('ui', left + 15, top + 40, 32, heroHeight, core.material.groundPattern);
|
||||
var heroIcon = core.material.icons.hero['down'];
|
||||
core.canvas.ui.drawImage(core.material.images.hero, heroIcon.stop * 32, heroIcon.loc * heroHeight, 32, heroHeight, left+15, top+40, 32, heroHeight);
|
||||
}
|
||||
else {
|
||||
core.fillText('ui', name, content_left, top + 30, null, 'bold '+titlefont+'px Verdana');
|
||||
if (core.isset(icon)) {
|
||||
|
||||
core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, iconHeight + 2, borderColor, 2);
|
||||
core.setAlpha('ui', alpha);
|
||||
core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, iconHeight + 2, null, 2);
|
||||
core.setAlpha('ui', 1);
|
||||
core.status.boxAnimateObjs = [];
|
||||
core.status.boxAnimateObjs.push({
|
||||
'bgx': left + 15, 'bgy': top + 40, 'bgWidth': 32, 'bgHeight': iconHeight,
|
||||
@ -522,12 +576,10 @@ 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;
|
||||
core.setFillStyle('ui', textColor);
|
||||
var index = 0, currcolor = textColor, changed = false;
|
||||
|
||||
var drawNext = function () {
|
||||
if (index >= content.length) return false;
|
||||
@ -554,11 +606,11 @@ ui.prototype.drawTextBox = function(content, showAll) {
|
||||
if (content.charAt(index) == '[' && ((index2=content.indexOf(']', index))>=0)) {
|
||||
// 变色
|
||||
var str = content.substring(index+1, index2);
|
||||
if (str=="") currcolor = defaultColor;
|
||||
if (str=="") currcolor = textColor;
|
||||
else currcolor = str;
|
||||
index = index2+1;
|
||||
}
|
||||
else currcolor = defaultColor;
|
||||
else currcolor = textColor;
|
||||
return drawNext();
|
||||
}
|
||||
// 检查是不是自动换行
|
||||
@ -595,11 +647,17 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
|
||||
choices = choices || [];
|
||||
|
||||
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||
|
||||
core.clearMap('ui');
|
||||
core.setAlpha('ui', 1);
|
||||
core.setFillStyle('ui', background);
|
||||
var background = core.status.textAttribute.background;
|
||||
var isWindowSkin = false;
|
||||
if (typeof background == 'string') {
|
||||
background = core.material.images.images[background];
|
||||
if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true;
|
||||
else background = core.initStatus.textAttribute.background;
|
||||
}
|
||||
if (!isWindowSkin) background = core.arrayToRGBA(background);
|
||||
var borderColor = main.borderColor || "#FFFFFF";
|
||||
var textColor = core.arrayToRGBA(core.status.textAttribute.text);
|
||||
var titleColor = core.arrayToRGBA(core.status.textAttribute.title);
|
||||
|
||||
core.status.event.ui = {"text": content, "choices": choices};
|
||||
|
||||
@ -644,10 +702,16 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
}
|
||||
var top = bottom-height;
|
||||
|
||||
var borderColor = main.borderColor||"#FFFFFF";
|
||||
|
||||
core.fillRect('ui', left, top, width, height, background);
|
||||
core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, borderColor, 2);
|
||||
core.clearMap('ui');
|
||||
if (isWindowSkin) {
|
||||
core.setAlpha('ui', 0.85);
|
||||
this.drawWindowSkin(background,'ui',left,top,width,height);
|
||||
}
|
||||
else {
|
||||
core.fillRect('ui', left, top, width, height, background);
|
||||
core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, borderColor, 2);
|
||||
}
|
||||
core.setAlpha('ui', 1);
|
||||
|
||||
// 如果有内容
|
||||
if (core.isset(contents)) {
|
||||
@ -667,14 +731,14 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
if (id == 'hero') {
|
||||
var heroHeight = core.material.icons.hero.height;
|
||||
core.strokeRect('ui', left + 15 - 1, top + 30 - 1, 34, heroHeight+2, '#DDDDDD', 2);
|
||||
core.fillText('ui', name, title_offset, top + 27, '#FFD700', 'bold 19px Verdana');
|
||||
core.fillText('ui', name, title_offset, top + 27, titleColor, 'bold 19px Verdana');
|
||||
core.clearMap('ui', left + 15, top + 30, 32, heroHeight);
|
||||
core.fillRect('ui', left + 15, top + 30, 32, heroHeight, background);
|
||||
core.fillRect('ui', left + 15, top + 30, 32, heroHeight, core.material.groundPattern);
|
||||
var heroIcon = core.material.icons.hero['down'];
|
||||
core.canvas.ui.drawImage(core.material.images.hero, heroIcon.stop * 32, heroIcon.loc *heroHeight, 32, heroHeight, left+15, top+30, 32, heroHeight);
|
||||
}
|
||||
else {
|
||||
core.fillText('ui', name, title_offset, top + 27, '#FFD700', 'bold 19px Verdana');
|
||||
core.fillText('ui', name, title_offset, top + 27, titleColor, 'bold 19px Verdana');
|
||||
if (core.isset(icon)) {
|
||||
core.strokeRect('ui', left + 15 - 1, top + 30 - 1, 34, iconHeight + 2, '#DDDDDD', 2);
|
||||
core.status.boxAnimateObjs = [];
|
||||
@ -691,7 +755,7 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
|
||||
core.canvas.ui.textAlign = "left";
|
||||
for (var i=0;i<contents.length;i++) {
|
||||
core.fillText('ui', contents[i], content_left, content_top, '#FFFFFF', 'bold 15px Verdana');
|
||||
core.fillText('ui', contents[i], content_left, content_top, textColor, 'bold 15px Verdana');
|
||||
content_top+=20;
|
||||
}
|
||||
}
|
||||
@ -699,7 +763,7 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
// 选项
|
||||
core.canvas.ui.textAlign = "center";
|
||||
for (var i = 0; i < choices.length; i++) {
|
||||
core.setFillStyle('ui', choices[i].color || "#FFFFFF");
|
||||
core.setFillStyle('ui', choices[i].color || textColor);
|
||||
core.fillText('ui', core.replaceText(choices[i].text || choices[i]), 208, choice_top + 32 * i, null, "bold 17px Verdana");
|
||||
}
|
||||
|
||||
@ -708,7 +772,10 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
while (core.status.event.selection<0) core.status.event.selection+=choices.length;
|
||||
while (core.status.event.selection>=choices.length) core.status.event.selection-=choices.length;
|
||||
var len = core.canvas.ui.measureText(core.replaceText(choices[core.status.event.selection].text || choices[core.status.event.selection])).width;
|
||||
core.strokeRect('ui', 208-len/2-5, choice_top + 32 * core.status.event.selection - 20, len+10, 28, "#FFD700", 2);
|
||||
if (isWindowSkin)
|
||||
this.drawWindowSelector(background, 'ui' ,208-len/2-5, choice_top + 32 * core.status.event.selection - 20, len+10, 28);
|
||||
else
|
||||
core.strokeRect('ui', 208-len/2-5, choice_top + 32 * core.status.event.selection - 20, len+10, 28, "#FFD700", 2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -724,10 +791,9 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
|
||||
if (!core.isset(core.status.event.selection) || core.status.event.selection>1) core.status.event.selection=1;
|
||||
if (core.status.event.selection<0) core.status.event.selection=0;
|
||||
|
||||
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||
core.clearMap('ui');
|
||||
core.setAlpha('ui', 1);
|
||||
core.setFillStyle('ui', background);
|
||||
core.setFillStyle('ui', core.material.groundPattern);
|
||||
core.setFont('ui', "bold 19px Verdana");
|
||||
|
||||
var contents = text.split('\n');
|
||||
@ -744,7 +810,7 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
|
||||
var borderColor = main.borderColor||"#FFFFFF";
|
||||
|
||||
if (core.isPlaying())
|
||||
core.fillRect('ui', left, top, right, bottom, background);
|
||||
core.fillRect('ui', left, top, right, bottom, core.material.groundPattern);
|
||||
if (core.isPlaying())
|
||||
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, borderColor, 2);
|
||||
core.canvas.ui.textAlign = "center";
|
||||
@ -790,7 +856,7 @@ ui.prototype.drawSettings = function () {
|
||||
core.status.event.id = 'settings';
|
||||
|
||||
this.drawChoices(null, [
|
||||
"系统设置", "快捷商店", "浏览地图", "绘图模式", "同步存档", "返回标题", "数据统计", "操作帮助", "关于本塔", "返回游戏"
|
||||
"系统设置", "虚拟键盘", "浏览地图", "绘图模式", "同步存档", "数据统计", "查看评论", "操作帮助", "关于本塔", "返回标题", "返回游戏"
|
||||
]);
|
||||
}
|
||||
|
||||
@ -877,13 +943,9 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
||||
|
||||
var specialTexts = core.enemys.getSpecialText(monsterId);
|
||||
|
||||
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||
|
||||
core.clearMap('ui');
|
||||
var left=10, right=416-2*left;
|
||||
|
||||
|
||||
// var lines = core.flags.enableExperience?5:4;
|
||||
var lines = 3;
|
||||
if (core.flags.enableMDef || core.flags.enableMoney || core.flags.enableExperience) lines=4;
|
||||
if (core.flags.enableMoney && core.flags.enableExperience) lines=5;
|
||||
@ -934,7 +996,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
||||
|
||||
// 图标
|
||||
core.clearMap('ui', left + margin, top + margin, boxWidth, heroHeight+boxWidth-32);
|
||||
core.fillRect('ui', left + margin, top + margin, boxWidth, heroHeight+boxWidth-32, background);
|
||||
core.fillRect('ui', left + margin, top + margin, boxWidth, heroHeight+boxWidth-32, core.material.groundPattern);
|
||||
var heroIcon = core.material.icons.hero['down'];
|
||||
core.canvas.ui.drawImage(core.material.images.hero, heroIcon.stop * 32, heroIcon.loc *heroHeight, 32, heroHeight, left+margin+(boxWidth-32)/2, top+margin+(boxWidth-32)/2, 32, heroHeight);
|
||||
// 怪物的
|
||||
@ -1127,10 +1189,9 @@ ui.prototype.drawWaiting = function(text) {
|
||||
core.lockControl();
|
||||
core.status.event.id = 'waiting';
|
||||
|
||||
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||
core.clearMap('ui');
|
||||
core.setAlpha('ui', 1);
|
||||
core.setFillStyle('ui', background);
|
||||
core.setFillStyle('ui', core.material.groundPattern);
|
||||
|
||||
core.setFont('ui', 'bold 17px Verdana');
|
||||
var text_length = core.canvas.ui.measureText(text).width;
|
||||
@ -1138,7 +1199,7 @@ ui.prototype.drawWaiting = function(text) {
|
||||
var right = Math.max(text_length+50, 220);
|
||||
var left = 208-parseInt(right/2), top = 208 - 32 - 16, bottom = 416 - 2 * top;
|
||||
|
||||
core.fillRect('ui', left, top, right, bottom, background);
|
||||
core.fillRect('ui', left, top, right, bottom);
|
||||
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
|
||||
|
||||
core.canvas.ui.textAlign = "center";
|
||||
@ -1237,7 +1298,6 @@ ui.prototype.drawCursor = function () {
|
||||
////// 绘制怪物手册 //////
|
||||
ui.prototype.drawBook = function (index) {
|
||||
var enemys = core.enemys.getCurrentEnemys(core.floorIds[(core.status.event.selection||{}).index]);
|
||||
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||
|
||||
clearInterval(core.interval.tipAnimate);
|
||||
core.clearMap('data');
|
||||
@ -1245,7 +1305,7 @@ ui.prototype.drawBook = function (index) {
|
||||
|
||||
core.clearMap('ui');
|
||||
core.setAlpha('ui', 1);
|
||||
core.setFillStyle('ui', background);
|
||||
core.setFillStyle('ui', core.material.groundPattern);
|
||||
core.fillRect('ui', 0, 0, 416, 416);
|
||||
|
||||
core.setAlpha('ui', 0.6);
|
||||
@ -2206,8 +2266,7 @@ ui.prototype.drawKeyBoard = function () {
|
||||
core.clearMap('ui');
|
||||
|
||||
var left = 16, top = 48, right = 416 - 2 * left, bottom = 416 - 2 * top;
|
||||
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||
core.fillRect('ui', left, top, right, bottom, background);
|
||||
core.fillRect('ui', left, top, right, bottom, core.material.groundPattern);
|
||||
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
|
||||
|
||||
core.canvas.ui.textAlign = "center";
|
||||
@ -2481,12 +2540,13 @@ ui.prototype.drawHelp = function () {
|
||||
"[CTRL] 跳过对话 [Z] 转向\n" +
|
||||
"[X] 怪物手册 [G] 楼层传送\n" +
|
||||
"[A] 读取自动存档 [S/D] 存读档页面\n" +
|
||||
"[S/D] 打开/关闭存/读档页面\n" +
|
||||
"[K/V] 快捷商店 [ESC] 系统菜单\n" +
|
||||
"[T] 道具页面 [Q] 装备页面\n" +
|
||||
"[B] 数据统计 [H] 帮助页面\n" +
|
||||
"[R] 回放录像 [E] 显示光标\n" +
|
||||
"[B] 数据统计 [H] 帮助页面\n" +
|
||||
"[R] 回放录像 [E] 显示光标\n" +
|
||||
"[SPACE] 轻按 [M] 绘图模式\n" +
|
||||
"[N] 返回标题页面 [P] 查看评论区\n" +
|
||||
"[O] 查看工程 [F7] 打开debug穿墙模式\n" +
|
||||
"[PgUp/PgDn] 浏览地图\n"+
|
||||
"[1~4] 快捷使用破炸飞和其他道具\n"+
|
||||
"[Alt+0~9] 快捷换装",
|
||||
|
||||
@ -327,12 +327,18 @@ utils.prototype.formatBigNumber = function (x) {
|
||||
|
||||
////// 数组转RGB //////
|
||||
utils.prototype.arrayToRGB = function (color) {
|
||||
var nowR = parseInt(color[0])||0, nowG = parseInt(color[1])||0, nowB = parseInt(color[2])||0;
|
||||
if (nowR<0) nowR=0; if (nowB<0) nowB=0;if (nowG<0) nowG=0;
|
||||
if (nowR>255) nowR=255; if (nowB>255) nowB=255; if (nowG>255) nowG=255;
|
||||
var nowR = this.clamp(parseInt(color[0]),0,255), nowG = this.clamp(parseInt(color[1]),0,255),
|
||||
nowB = this.clamp(parseInt(color[2]),0,255);
|
||||
return "#"+((1<<24)+(nowR<<16)+(nowG<<8)+nowB).toString(16).slice(1);
|
||||
}
|
||||
|
||||
utils.prototype.arrayToRGBA = function (color) {
|
||||
if (!this.isset(color[3])) color[3]=1;
|
||||
var nowR = this.clamp(parseInt(color[0]),0,255), nowG = this.clamp(parseInt(color[1]),0,255),
|
||||
nowB = this.clamp(parseInt(color[2]),0,255), nowA = this.clamp(parseFloat(color[3]),0,1);
|
||||
return "rgba("+nowR+","+nowG+","+nowB+","+nowA+")";
|
||||
}
|
||||
|
||||
////// 加密路线 //////
|
||||
utils.prototype.encodeRoute = function (route) {
|
||||
var ans="";
|
||||
|
||||
6
main.js
6
main.js
@ -2,7 +2,7 @@ function main() {
|
||||
|
||||
//------------------------ 用户修改内容 ------------------------//
|
||||
|
||||
this.version = "2.5.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。
|
||||
this.version = "2.5.2"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。
|
||||
|
||||
this.useCompress = false; // 是否使用压缩文件
|
||||
// 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。
|
||||
@ -323,10 +323,6 @@ main.dom.body.onselectstart = function () {
|
||||
main.dom.data.onmousedown = function (e) {
|
||||
try {
|
||||
e.stopPropagation();
|
||||
if(e.button==1){// 把鼠标中键绑定为ESC
|
||||
core.keyUp(27);
|
||||
return;
|
||||
}
|
||||
var loc = main.core.getClickLoc(e.clientX, e.clientY);
|
||||
if (loc == null) return;
|
||||
main.core.ondown(loc);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
{
|
||||
"main": {
|
||||
"floorIds": [
|
||||
@ -9,7 +9,8 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"MT0"
|
||||
],
|
||||
"images": [
|
||||
"bg.jpg"
|
||||
"bg.jpg",
|
||||
"winskin.png"
|
||||
],
|
||||
"tilesets": [],
|
||||
"animates": [
|
||||
@ -68,7 +69,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"firstData": {
|
||||
"title": "魔塔样板",
|
||||
"name": "template",
|
||||
"version": "Ver 2.5.1",
|
||||
"version": "Ver 2.5.2",
|
||||
"floorId": "sample0",
|
||||
"hero": {
|
||||
"name": "阳光",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 =
|
||||
var enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 =
|
||||
{
|
||||
"greenSlime": {"name":"绿头怪","hp":100,"atk":120,"def":0,"money":1,"experience":1,"point":0,"special":[1,5,7,8]},
|
||||
"redSlime": {"name":"红头怪","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":[16,18],"value":10},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
{
|
||||
"events": {
|
||||
"initGame": function() {
|
||||
@ -660,6 +660,21 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
case 72: // H:打开帮助页面
|
||||
core.ui.drawHelp();
|
||||
break;
|
||||
case 78: // N:重新开始
|
||||
core.status.event.selection=1;
|
||||
core.ui.drawConfirmBox("你确定要返回标题页面吗?", function () {
|
||||
core.ui.closePanel();
|
||||
core.restart();
|
||||
}, function () {
|
||||
core.ui.closePanel();
|
||||
});
|
||||
break;
|
||||
case 79: // O:查看工程
|
||||
window.open(core.platform.isPC?"editor.html":"editor-mobile.html", "_blank");
|
||||
break;
|
||||
case 80: // P:查看评论
|
||||
window.open("/score.php?name="+core.firstData.name+"&num=10", "_blank");
|
||||
break;
|
||||
case 49: // 快捷键1: 破
|
||||
if (core.hasItem('pickaxe')) {
|
||||
if (core.canUseItem('pickaxe')) {
|
||||
@ -1110,8 +1125,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
// 绘制色调层,默认不透明度
|
||||
if (!core.isset(color)) color = 0.9;
|
||||
if (typeof color == "number") color = [0,0,0,color];
|
||||
core.fillRect('curtain', 0, 0, 416, 416,
|
||||
'rgba('+color[0]+','+color[1]+','+color[2]+','+core.clamp(color[3],0,1)+')');
|
||||
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGBA(color));
|
||||
|
||||
// 绘制每个灯光效果
|
||||
if (!core.isset(lights) || lights.length==0) return;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 =
|
||||
var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 =
|
||||
{
|
||||
'hero': {
|
||||
'down': {'loc': 0, 'stop': 0, 'leftFoot': 1, 'rightFoot': 3},
|
||||
|
||||
BIN
project/images/winskin.png
Normal file
BIN
project/images/winskin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
@ -1,4 +1,4 @@
|
||||
items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
|
||||
var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
|
||||
{
|
||||
"items": {
|
||||
"yellowKey": {
|
||||
@ -184,7 +184,8 @@ items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
|
||||
"fly": {
|
||||
"cls": "constants",
|
||||
"name": "楼层传送器",
|
||||
"text": "可以自由往来去过的楼层"
|
||||
"text": "可以自由往来去过的楼层",
|
||||
"hideInReplay": true
|
||||
},
|
||||
"coin": {
|
||||
"cls": "constants",
|
||||
@ -299,7 +300,8 @@ items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
|
||||
"skill1": {
|
||||
"cls": "constants",
|
||||
"name": "技能:二倍斩",
|
||||
"text": "可以打开或关闭主动技能二倍斩"
|
||||
"text": "可以打开或关闭主动技能二倍斩",
|
||||
"hideInReplay": true
|
||||
}
|
||||
},
|
||||
"itemEffect": {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
|
||||
var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
|
||||
{
|
||||
////////////////////////// 地形部分 //////////////////////////
|
||||
|
||||
|
||||
16
更新说明.txt
16
更新说明.txt
@ -1,4 +1,18 @@
|
||||
HTML5魔塔样板V2.5.1
|
||||
HTML5魔塔样板V2.5.2
|
||||
|
||||
怪物和NPC的行走图和朝向问题(详见文档)
|
||||
可以引入WindowSkin作为对话框的背景素材
|
||||
\r可以动态调整剧情文本的颜色
|
||||
升级事件改用事件编辑器完成
|
||||
每层楼都增添该层的并行事件处理
|
||||
新增快捷键:N返回标题;P查看评论;O打开工程
|
||||
道具可以设置是否在回放时绘制道具栏或直接使用
|
||||
追加素材一次可以追加多个
|
||||
可以同时异步移动两张或以上的图片了
|
||||
菜单栏中新增虚拟键盘的弹出
|
||||
修复所有已知Bug;部分细节优化
|
||||
|
||||
HTML5魔塔样板V2.5.1
|
||||
|
||||
新增事件type:insert,可以插入另一个地点的事件执行(公共事件)
|
||||
可以使用\r来控制剧情文本部分文字的颜色
|
||||
|
||||
Loading…
Reference in New Issue
Block a user