commit
9e02f57cb8
@ -59,9 +59,11 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
* [x] 存档方式优化,大幅降低单个存档的占用空间
|
||||
* [x] 脚本编辑器增加代码格式化的选项
|
||||
* [x] 事件和脚本编辑器中Ctrl+S可以进行保存
|
||||
* [x] 显示选择项提供颜色控制
|
||||
* [x] 事件的移动勇士增加前进和后退两个操作
|
||||
* [x] 事件编辑器的下拉框增加滚动条
|
||||
* [x] 通关后将询问是否进行评分
|
||||
* [x] 录像播放失败后可以回退到上个节点
|
||||
* [x] 修复已知的所有Bug,大量细节优化
|
||||
|
||||
### 2019.2.4 V2.5.4
|
||||
|
||||
@ -176,6 +176,7 @@ core.openDoor(id, x, y, needKey, callback) [异步]
|
||||
尝试开门操作。id为目标点的ID,x和y为坐标,needKey表示是否需要使用钥匙,callback为开门完毕后的回调函数。
|
||||
id可为null代表使用地图上的值。
|
||||
例如:core.openDoor('yellowDoor', 10, 3, false, function() {console.log("1")})
|
||||
此函数返回true代表成功开门,并将执行callback回调;返回false代表无法开门,且不会执行回调函数。
|
||||
|
||||
|
||||
core.battle(id, x, y, force, callback) [异步]
|
||||
|
||||
@ -1528,7 +1528,8 @@ choices是一个很麻烦的事件,它将弹出一个列表供用户进行选
|
||||
|
||||
``` js
|
||||
"x,y": [ // 实际执行的事件列表
|
||||
{"type": "choices", "text": "...", // 提示文字
|
||||
{"type": "choices", "text": "...", // 提示文字
|
||||
"color": [255,0,0,1], // 颜色
|
||||
"choices": [
|
||||
{"text": "选项1文字", "action": [
|
||||
// 选项1执行的事件
|
||||
@ -1544,11 +1545,15 @@ choices是一个很麻烦的事件,它将弹出一个列表供用户进行选
|
||||
]
|
||||
```
|
||||
|
||||
其中最外面的"text"为提示文本。同上面的`"type":"text"`一样,支持`${}`表达式的计算,和\t显示名称、图标。text可省略,如果省略将不显示任何提示文字。
|
||||
其中最外面的"text"为提示文本。同上面的`"type":"text"`一样,支持`${}`表达式的计算,和\t显示名称、图标,\r更改颜色。text可省略,如果省略将不显示任何提示文字。
|
||||
|
||||
choices为一个数组,其中每一项都是一个选项列表。
|
||||
|
||||
每一项的text为显示在屏幕上的选项名,也支持${}的表达式计算,但不支持`\t[]`的显示。action为当用户选择了该选项时将执行的事件。
|
||||
每一项的text为显示在屏幕上的选项名,也支持${}的表达式计算,但不支持`\t[]`的显示。
|
||||
|
||||
action为当用户选择了该选项时将执行的事件。
|
||||
|
||||
color为可选的,可以是一个字符串(#FF0000),或者一个RGBA数组([255,0,0,1])。
|
||||
|
||||
选项可以有任意多个,但一般不要超过6个,否则屏幕可能塞不下。
|
||||
|
||||
@ -1577,7 +1582,7 @@ choices为一个数组,其中每一项都是一个选项列表。
|
||||
"false": [ // 否则,显示选择页面
|
||||
{"type": "choices", "text": "\t[老人,woman]少年,你需要钥匙吗?\n我这里有大把的!", // 显示一个卖钥匙的选择页面
|
||||
"choices": [ // 提供四个选项:黄钥匙、蓝钥匙、红钥匙、离开。前三个选项显示需要的金额
|
||||
{"text": "黄钥匙(${9+flag:woman_times}金币)", "action": [ // 第一个选项,黄钥匙
|
||||
{"text": "黄钥匙(${9+flag:woman_times}金币)", "color": [255,255,0,1], "action": [ // 第一个选项,黄钥匙
|
||||
// 选择该选项的执行内容
|
||||
{"type": "if", "condition": "status:money>=9+flag:woman_times", // 条件判断:钱够不够
|
||||
"true": [
|
||||
@ -1591,10 +1596,10 @@ choices为一个数组,其中每一项都是一个选项列表。
|
||||
]
|
||||
}
|
||||
]},
|
||||
{"text": "蓝钥匙(${18+2*flag:woman_times}金币)", "action": [ // 第二个选项:蓝钥匙
|
||||
{"text": "蓝钥匙(${18+2*flag:woman_times}金币)", "color": [0,0,255,1], "action": [ // 第二个选项:蓝钥匙
|
||||
// 逻辑和上面黄钥匙完全相同,略
|
||||
]},
|
||||
{"text": "红钥匙(${36+4*flag:woman_times}金币)", "action": [ // 第三个选项:红钥匙
|
||||
{"text": "红钥匙(${36+4*flag:woman_times}金币)", "color": [255,0,0,1], "action": [ // 第三个选项:红钥匙
|
||||
// 逻辑和上面黄钥匙完全相同,略
|
||||
]},
|
||||
{"text": "离开", "action": [ // 第四个选项:离开
|
||||
|
||||
@ -1528,15 +1528,22 @@ return code;
|
||||
*/;
|
||||
|
||||
choicesContext
|
||||
: '子选项' EvalString BGNL? Newline action+
|
||||
: '子选项' EvalString '颜色' EvalString? Colour BGNL? Newline action+
|
||||
|
||||
|
||||
/* choicesContext
|
||||
tooltip : 选项的选择
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=choices%EF%BC%9A%E7%BB%99%E7%94%A8%E6%88%B7%E6%8F%90%E4%BE%9B%E9%80%89%E9%A1%B9
|
||||
default : ["提示文字:红钥匙"]
|
||||
default : ["提示文字:红钥匙",""]
|
||||
colour : this.subColor
|
||||
var code = '{"text": "'+EvalString_0+'", "action": [\n'+action_0+']},\n';
|
||||
if (EvalString_1) {
|
||||
var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
|
||||
if (colorRe.test(EvalString_1))
|
||||
EvalString_1 = ', "color": ['+EvalString_1+']';
|
||||
else
|
||||
EvalString_1 = ', "color": "'+EvalString_1+'"';
|
||||
}
|
||||
var code = '{"text": "'+EvalString_0+'"'+EvalString_1+', "action": [\n'+action_0+']},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
@ -2095,7 +2102,9 @@ ActionParser.prototype.parseAction = function() {
|
||||
if (!/^\w+\.png$/.test(data.background))
|
||||
data.background=setTextfunc(data.background);
|
||||
this.next = MotaActionBlocks['setText_s'].xmlText([
|
||||
data.position,data.offset,data.title,`rgba(${data.title})`,data.text,`rgba(${data.text})`,data.background,`rgba(${data.background})`,data.bold,data.titlefont,data.textfont,data.time,this.next]);
|
||||
data.position,data.offset,data.title,'rgba('+data.title+')',
|
||||
data.text,'rgba('+data.text+')',data.background,'rgba('+data.background+')',
|
||||
data.bold,data.titlefont,data.textfont,data.time,this.next]);
|
||||
break;
|
||||
case "tip":
|
||||
this.next = MotaActionBlocks['tip_s'].xmlText([
|
||||
@ -2267,7 +2276,7 @@ ActionParser.prototype.parseAction = function() {
|
||||
case "setFg": // 颜色渐变
|
||||
if(this.isset(data.color)){
|
||||
this.next = MotaActionBlocks['setFg_0_s'].xmlText([
|
||||
data.color,`rgba(${data.color})`,data.time||0,data.async||false,this.next]);
|
||||
data.color,'rgba('+data.color+')',data.time||0,data.async||false,this.next]);
|
||||
} else {
|
||||
this.next = MotaActionBlocks['setFg_1_s'].xmlText([
|
||||
data.time||0,data.async||false,this.next]);
|
||||
@ -2275,7 +2284,7 @@ ActionParser.prototype.parseAction = function() {
|
||||
break;
|
||||
case "screenFlash": // 画面闪烁
|
||||
this.next = MotaActionBlocks['screenFlash_s'].xmlText([
|
||||
data.color,`rgba(${data.color})`,data.time||500,data.times||1,data.async||false,this.next]);
|
||||
data.color,'rgba('+data.color+')',data.time||500,data.times||1,data.async||false,this.next]);
|
||||
break;
|
||||
case "setWeather": // 更改天气
|
||||
this.next = MotaActionBlocks['setWeather_s'].xmlText([
|
||||
@ -2402,7 +2411,7 @@ ActionParser.prototype.parseAction = function() {
|
||||
var text_choices = null;
|
||||
for(var ii=data.choices.length-1,choice;choice=data.choices[ii];ii--) {
|
||||
text_choices=MotaActionBlocks['choicesContext'].xmlText([
|
||||
choice.text,this.insertActionList(choice.action),text_choices]);
|
||||
choice.text,choice.color,'rgba('+choice.color+')',this.insertActionList(choice.action),text_choices]);
|
||||
}
|
||||
this.next = MotaActionBlocks['choices_s'].xmlText([
|
||||
this.isset(data.text)?this.EvalString(data.text):null,'','',text_choices,this.next]);
|
||||
|
||||
@ -153,8 +153,8 @@ editor.prototype.idsInit = function (maps, icons) {
|
||||
if(img.width%32 || img.height%32){
|
||||
alert(imgName+'的长或宽不是32的整数倍, 请修改后刷新页面');
|
||||
}
|
||||
if(img.width*img.height > 32*32*1000){
|
||||
alert(imgName+'上的图块数量超过了1000,请修改后刷新页面');
|
||||
if(img.width*img.height > 32*32*3000){
|
||||
alert(imgName+'上的图块数量超过了3000,请修改后刷新页面');
|
||||
}
|
||||
for (var id=startOffset; id<startOffset+width*height;id++) {
|
||||
var x = (id-startOffset)%width, y = parseInt((id-startOffset)/width);
|
||||
@ -645,12 +645,6 @@ editor.prototype.listen = function () {
|
||||
if(clickpath.length>=2 && clickpath[0].indexOf('id_')===0){editor.lastClickId=clickpath[0]}
|
||||
}
|
||||
|
||||
var iconLib=document.getElementById('iconLib');
|
||||
iconLib.onmousedown = function (e) {
|
||||
console.log("iconLib: ("+e.clientX+","+e.clientY+")");
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
var eui=document.getElementById('eui');
|
||||
var uc = eui.getContext('2d');
|
||||
|
||||
@ -797,25 +791,21 @@ editor.prototype.listen = function () {
|
||||
currDrawData.info = JSON.parse(JSON.stringify(editor.info));
|
||||
reDo = null;
|
||||
// console.log(stepPostfix);
|
||||
if (editor.layerMod!='map' && editor.info.images && editor.info.images.indexOf('48')!==-1){
|
||||
printe('前景/背景不支持48的图块');
|
||||
} else {
|
||||
if(editor.brushMod==='tileset' && core.tilesets.indexOf(editor.info.images)!==-1){
|
||||
var imgWidth=~~(core.material.images.tilesets[editor.info.images].width/32);
|
||||
var x0=stepPostfix[0].x;
|
||||
var y0=stepPostfix[0].y;
|
||||
var idnum=editor.info.idnum;
|
||||
for (var ii = 0; ii < stepPostfix.length; ii++){
|
||||
if(stepPostfix[ii].y!=y0){
|
||||
y0++;
|
||||
idnum+=imgWidth;
|
||||
}
|
||||
editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.ids[editor.indexs[idnum+stepPostfix[ii].x-x0]];
|
||||
if(editor.brushMod==='tileset' && core.tilesets.indexOf(editor.info.images)!==-1){
|
||||
var imgWidth=~~(core.material.images.tilesets[editor.info.images].width/32);
|
||||
var x0=stepPostfix[0].x;
|
||||
var y0=stepPostfix[0].y;
|
||||
var idnum=editor.info.idnum;
|
||||
for (var ii = 0; ii < stepPostfix.length; ii++){
|
||||
if(stepPostfix[ii].y!=y0){
|
||||
y0++;
|
||||
idnum+=imgWidth;
|
||||
}
|
||||
} else {
|
||||
for (var ii = 0; ii < stepPostfix.length; ii++)
|
||||
editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.info;
|
||||
editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.ids[editor.indexs[idnum+stepPostfix[ii].x-x0]];
|
||||
}
|
||||
} else {
|
||||
for (var ii = 0; ii < stepPostfix.length; ii++)
|
||||
editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.info;
|
||||
}
|
||||
// console.log(editor.map);
|
||||
editor.updateMap();
|
||||
@ -975,9 +965,38 @@ editor.prototype.listen = function () {
|
||||
}
|
||||
}
|
||||
|
||||
var getScrollBarHeight = function () {
|
||||
var outer = document.createElement("div");
|
||||
outer.style.visibility = "hidden";
|
||||
outer.style.width = "100px";
|
||||
outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
|
||||
|
||||
document.body.appendChild(outer);
|
||||
|
||||
var widthNoScroll = outer.offsetWidth;
|
||||
// force scrollbars
|
||||
outer.style.overflow = "scroll";
|
||||
|
||||
// add innerdiv
|
||||
var inner = document.createElement("div");
|
||||
inner.style.width = "100%";
|
||||
outer.appendChild(inner);
|
||||
|
||||
var widthWithScroll = inner.offsetWidth;
|
||||
|
||||
// remove divs
|
||||
outer.parentNode.removeChild(outer);
|
||||
|
||||
return widthNoScroll - widthWithScroll;
|
||||
}
|
||||
var scrollBarHeight = getScrollBarHeight();
|
||||
console.log(scrollBarHeight);
|
||||
|
||||
var dataSelection = document.getElementById('dataSelection');
|
||||
var iconLib=document.getElementById('iconLib');
|
||||
iconLib.onmousedown = function (e) {
|
||||
e.stopPropagation();
|
||||
if (!editor.isMobile && e.clientY>=(635 - 5 - scrollBarHeight)) return;
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
var loc = {
|
||||
|
||||
@ -64,9 +64,9 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['lose_s'].xmlText(),
|
||||
MotaActionBlocks['choices_s'].xmlText([
|
||||
'选择剑或者盾','流浪者','man',MotaActionBlocks['choicesContext'].xmlText([
|
||||
'剑',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]),
|
||||
'剑','',null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]),
|
||||
MotaActionBlocks['choicesContext'].xmlText([
|
||||
'盾',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]),
|
||||
'盾','',null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]),
|
||||
])
|
||||
])
|
||||
]),
|
||||
@ -137,7 +137,7 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['setWeather_s'].xmlText(),
|
||||
MotaActionBlocks['playBgm_s'].xmlText(),
|
||||
MotaActionBlocks['pauseBgm_s'].xmlText(),
|
||||
// MotaActionBlocks['resumeBgm_s'].xmlText(),
|
||||
MotaActionBlocks['resumeBgm_s'].xmlText(),
|
||||
MotaActionBlocks['loadBgm_s'].xmlText(),
|
||||
MotaActionBlocks['freeBgm_s'].xmlText(),
|
||||
MotaActionBlocks['playSound_s'].xmlText(),
|
||||
@ -175,7 +175,7 @@ editor_blockly = function () {
|
||||
MotaActionFunctions.actionParser.parse([
|
||||
{"type": "choices", "text": "\t[老人,man]少年,你需要钥匙吗?\n我这里有大把的!",
|
||||
"choices": [
|
||||
{"text": "黄钥匙(\${9+flag:shop_times}金币)", "action": [
|
||||
{"text": "黄钥匙(\${9+flag:shop_times}金币)", "color": [255,255,0,1], "action": [
|
||||
{"type": "if", "condition": "status:money>=9+flag:shop_times",
|
||||
"true": [
|
||||
{"type": "setValue", "name": "status:money", "value": "status:money-(9+flag:shop_times)"},
|
||||
@ -187,7 +187,7 @@ editor_blockly = function () {
|
||||
]
|
||||
}
|
||||
]},
|
||||
{"text": "蓝钥匙(\${18+2*flag:shop_times}金币)", "action": [
|
||||
{"text": "蓝钥匙(\${18+2*flag:shop_times}金币)", "color": [0,0,255,1], "action": [
|
||||
]},
|
||||
{"text": "离开", "action": [
|
||||
{"type": "exit"}
|
||||
|
||||
@ -734,7 +734,9 @@ actions.prototype.keyDownCtrl = function () {
|
||||
|
||||
//////
|
||||
actions.prototype.clickCenterFly = function(x, y) {
|
||||
if (x==core.status.event.data.poxX && y==core.status.event.data.posY) {
|
||||
var posX = core.status.event.data.posX, posY = core.status.event.data.posY;
|
||||
core.ui.closePanel();
|
||||
if (x==posX&& y==posY) {
|
||||
if (core.canUseItem('centerFly')) {
|
||||
core.useItem('centerFly');
|
||||
}
|
||||
@ -742,10 +744,10 @@ actions.prototype.clickCenterFly = function(x, y) {
|
||||
core.drawTip('当前不能使用中心对称飞行器');
|
||||
}
|
||||
}
|
||||
core.ui.closePanel();
|
||||
}
|
||||
|
||||
actions.prototype.keyUpCenterFly = function (keycode) {
|
||||
core.ui.closePanel();
|
||||
if (keycode==51 || keycode==13 || keycode==32 || keycode==67) {
|
||||
if (core.canUseItem('centerFly')) {
|
||||
core.useItem('centerFly');
|
||||
@ -754,7 +756,6 @@ actions.prototype.keyUpCenterFly = function (keycode) {
|
||||
core.drawTip('当前不能使用中心对称飞行器');
|
||||
}
|
||||
}
|
||||
core.ui.closePanel();
|
||||
}
|
||||
|
||||
|
||||
@ -2062,6 +2063,7 @@ actions.prototype.clickSyncSave = function (x,y) {
|
||||
core.removeLocalForage("save"+i);
|
||||
}
|
||||
}
|
||||
core.ui.closePanel();
|
||||
core.drawText("读取成功!\n你的本地所有存档均已被覆盖。");
|
||||
}, function () {
|
||||
core.status.event.selection=0;
|
||||
|
||||
@ -1654,7 +1654,7 @@ control.prototype.setReplaySpeed = function (speed) {
|
||||
control.prototype.stopReplay = function () {
|
||||
if (!core.isPlaying()) return;
|
||||
if (core.status.event.id=='save' || (core.status.event.id||"").indexOf('book')==0 || core.status.event.id=='viewMaps') return;
|
||||
if (!core.isReplaying()) return;
|
||||
// if (!core.isReplaying()) return;
|
||||
core.status.replay.toReplay = [];
|
||||
core.status.replay.totalList = [];
|
||||
core.status.replay.replaying=false;
|
||||
@ -1962,8 +1962,27 @@ control.prototype.replay = function () {
|
||||
return;
|
||||
}
|
||||
|
||||
core.stopReplay();
|
||||
core.insertAction("录像文件出错");
|
||||
// core.stopReplay();
|
||||
// core.insertAction("录像文件出错");
|
||||
|
||||
core.status.replay.replaying = false;
|
||||
main.log("录像文件出错,当前操作:"+action+
|
||||
"\n接下来10个操作是:"+core.status.replay.toReplay.slice(0, 10).toString());
|
||||
core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () {
|
||||
core.ui.closePanel();
|
||||
if (core.status.replay.save.length > 0) {
|
||||
core.status.replay.replaying = true;
|
||||
core.status.replay.pausing = true;
|
||||
core.rewindReplay();
|
||||
}
|
||||
else {
|
||||
core.drawTip("无法回到上一个节点");
|
||||
core.stopReplay();
|
||||
}
|
||||
}, function () {
|
||||
core.ui.closePanel();
|
||||
core.stopReplay();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -2151,6 +2170,9 @@ control.prototype.autosave = function (removeLast) {
|
||||
|
||||
/////// 实际进行自动存档 //////
|
||||
control.prototype.checkAutosave = function () {
|
||||
|
||||
if (!core.animateFrame || !core.saves || !core.saves.autosave) return;
|
||||
|
||||
core.setLocalStorage('totalTime', core.animateFrame.totalTime);
|
||||
|
||||
if (core.saves.autosave.data == null || !core.saves.autosave.updated) return;
|
||||
@ -2347,6 +2369,7 @@ control.prototype.syncLoad = function () {
|
||||
core.removeLocalForage("save"+i);
|
||||
}
|
||||
}
|
||||
core.ui.closePanel();
|
||||
core.drawText("同步成功!\n你的本地所有存档均已被覆盖。");
|
||||
}, function () {
|
||||
core.status.event.selection=0;
|
||||
@ -2581,6 +2604,7 @@ control.prototype.playBgm = function (bgm) {
|
||||
if (!core.musicStatus.bgmStatus) {
|
||||
try {
|
||||
core.musicStatus.playingBgm = bgm;
|
||||
core.musicStatus.lastBgm = bgm;
|
||||
core.material.bgms[bgm].pause();
|
||||
}
|
||||
catch (e) {
|
||||
@ -2614,6 +2638,7 @@ control.prototype.playBgm = function (bgm) {
|
||||
core.material.bgms[bgm].currentTime = 0;
|
||||
core.material.bgms[bgm].play();
|
||||
core.musicStatus.playingBgm = bgm;
|
||||
core.musicStatus.lastBgm = bgm;
|
||||
}
|
||||
catch (e) {
|
||||
console.log("无法播放BGM "+bgm);
|
||||
@ -2644,7 +2669,7 @@ control.prototype.resumeBgm = function () {
|
||||
|
||||
// 恢复BGM
|
||||
try {
|
||||
core.playBgm(core.musicStatus.playingBgm);
|
||||
core.playBgm(core.musicStatus.playingBgm || core.musicStatus.lastBgm);
|
||||
}
|
||||
catch (e) {
|
||||
console.log("无法恢复BGM");
|
||||
@ -2765,7 +2790,8 @@ control.prototype.updateStatusBar = function () {
|
||||
core.statusBar.image.toolbox.src = core.statusBar.icons.rewind.src;
|
||||
|
||||
core.statusBar.image.keyboard.src = core.statusBar.icons.book.src;
|
||||
core.statusBar.image.shop.style.opacity = 0;
|
||||
|
||||
core.statusBar.image.shop.src = core.statusBar.icons.floor.src;
|
||||
|
||||
core.statusBar.image.save.src = core.statusBar.icons.speedDown.src;
|
||||
|
||||
@ -2790,7 +2816,8 @@ control.prototype.updateStatusBar = function () {
|
||||
core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src;
|
||||
|
||||
core.statusBar.image.keyboard.src = core.statusBar.icons.keyboard.src;
|
||||
core.statusBar.image.shop.style.opacity = 1;
|
||||
|
||||
core.statusBar.image.shop.src = core.statusBar.icons.shop.src;
|
||||
|
||||
core.statusBar.image.save.src = core.statusBar.icons.save.src;
|
||||
|
||||
|
||||
@ -53,6 +53,7 @@ function core() {
|
||||
'bgmStatus': false, // 是否播放BGM
|
||||
'soundStatus': true, // 是否播放SE
|
||||
'playingBgm': null, // 正在播放的BGM
|
||||
'lastBgm': null, // 上次播放的bgm
|
||||
'gainNode': null,
|
||||
'playingSounds': {}, // 正在播放的SE
|
||||
'volume': 1.0, // 音量
|
||||
@ -622,7 +623,7 @@ core.prototype.nearHero = function (x, y) {
|
||||
|
||||
////// 开门 //////
|
||||
core.prototype.openDoor = function (id, x, y, needKey, callback) {
|
||||
core.events.openDoor(id, x, y, needKey, callback);
|
||||
return core.events.openDoor(id, x, y, needKey, callback);
|
||||
}
|
||||
|
||||
////// 战斗 //////
|
||||
|
||||
@ -184,8 +184,9 @@ enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) {
|
||||
var info = this.getDamageInfo(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
|
||||
|
||||
if (info == null) {
|
||||
if (core.status.hero.atk<=enemy.def) {
|
||||
return [[enemy.def+1-core.status.hero.atk,'?']];
|
||||
info = this.getEnemyInfo(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
|
||||
if (core.status.hero.atk<=info.def) {
|
||||
return [[info.def+1-core.status.hero.atk,'?']];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
@ -109,6 +109,7 @@ events.prototype.startGame = function (hard, seed, route, callback) {
|
||||
core.clearStatusBar();
|
||||
|
||||
var post_start = function () {
|
||||
core.ui.closePanel();
|
||||
|
||||
core.control.triggerStatusBar('show');
|
||||
core.dom.musicBtn.style.display = 'none';
|
||||
@ -277,7 +278,7 @@ events.prototype.gameOver = function (ending, fromReplay, norank) {
|
||||
var doUpload = function(username) {
|
||||
var hp = core.status.hero.hp;
|
||||
if (username==undefined) hp = 1;
|
||||
|
||||
core.ui.closePanel();
|
||||
// upload
|
||||
var formData = new FormData();
|
||||
formData.append('type', 'score');
|
||||
@ -863,11 +864,15 @@ events.prototype.doAction = function() {
|
||||
y = core.calValue(data.loc[1], prefix);
|
||||
}
|
||||
var floorId=data.floorId || core.status.floorId;
|
||||
if (floorId==core.status.floorId)
|
||||
core.openDoor(null, x, y, data.needKey, function() {
|
||||
if (floorId==core.status.floorId) {
|
||||
var _callback = function () {
|
||||
core.lockControl();
|
||||
core.events.doAction();
|
||||
})
|
||||
}
|
||||
if (!core.openDoor(null, x, y, data.needKey, _callback)) {
|
||||
_callback();
|
||||
}
|
||||
}
|
||||
else {
|
||||
core.removeBlock(x, y, floorId);
|
||||
this.doAction();
|
||||
@ -966,12 +971,10 @@ events.prototype.doAction = function() {
|
||||
core.pauseBgm();
|
||||
this.doAction();
|
||||
break
|
||||
/*
|
||||
case "resumeBgm":
|
||||
core.resumeBgm();
|
||||
this.doAction();
|
||||
break
|
||||
*/
|
||||
case "loadBgm":
|
||||
if (core.platform.isPC)
|
||||
core.loadBgm(data.name);
|
||||
@ -1424,8 +1427,7 @@ events.prototype.openDoor = function (id, x, y, needKey, callback) {
|
||||
// 是否存在门
|
||||
if (!core.terrainExists(x, y, id) || !(id.endsWith("Door") || id.endsWith("Wall"))
|
||||
|| !core.isset(core.material.icons.animates[id])) {
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (core.status.automaticRoute.moveStepBeforeStop.length==0) {
|
||||
core.status.automaticRoute.moveStepBeforeStop=core.status.automaticRoute.autoStepRoutes.slice(core.status.automaticRoute.autoStep-1,core.status.automaticRoute.autoStepRoutes.length);
|
||||
@ -1441,8 +1443,7 @@ events.prototype.openDoor = function (id, x, y, needKey, callback) {
|
||||
core.drawTip("你没有" + ((core.material.items[key]||{}).name||"钥匙"));
|
||||
else core.drawTip("无法开启此门");
|
||||
core.clearContinueAutomaticRoute();
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
core.autosave(true);
|
||||
core.removeItem(key);
|
||||
@ -1470,7 +1471,9 @@ events.prototype.openDoor = function (id, x, y, needKey, callback) {
|
||||
}
|
||||
core.clearMap('event', 32 * x, 32 * y, 32, 32);
|
||||
core.drawImage('event', core.material.images.animates, 32 * state, 32 * door, 32, 32, 32 * x, 32 * y, 32, 32);
|
||||
}, speed / core.status.replay.speed)
|
||||
}, speed / core.status.replay.speed);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////// 战斗 //////
|
||||
@ -1811,7 +1814,7 @@ events.prototype.moveImage = function (code, to, opacityVal, time, callback) {
|
||||
var animate = setInterval(function () {
|
||||
step++;
|
||||
moveStep();
|
||||
if (step > steps) {
|
||||
if (step == steps) {
|
||||
if (core.isset(opacityVal))
|
||||
core.setOpacity(name, opacityVal);
|
||||
delete core.animateFrame.asyncId[animate];
|
||||
@ -2047,7 +2050,7 @@ events.prototype.useItem = function(itemId) {
|
||||
core.ui.drawThumbnail(core.status.floorId, 'ui', core.status.thisMap.blocks, 0, 0, 416, toX, toY, core.status.hero.loc, core.getFlag('heroIcon', "hero.png"));
|
||||
var offsetX = core.clamp(toX-6, 0, core.bigmap.width-13), offsetY = core.clamp(toY-6, 0, core.bigmap.height-13);
|
||||
core.fillRect('ui',(toX-offsetX)*32,(toY-offsetY)*32,32,32,fillstyle);
|
||||
core.status.event.data = {"x": toX, "y": toY, "poxX": toX-offsetX, "posY": toY-offsetY};
|
||||
core.status.event.data = {"x": toX, "y": toY, "posX": toX-offsetX, "posY": toY-offsetY};
|
||||
core.drawTip("请确认当前中心对称飞行器的位置");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -62,8 +62,8 @@ loader.prototype.load = function (callback) {
|
||||
if (img.width%32!=0 || img.height%32!=0) {
|
||||
console.warn("警告!"+imgName+"的宽或高不是32的倍数!");
|
||||
}
|
||||
if (img.width * img.height > 32*32*1000) {
|
||||
console.warn("警告!"+imgName+"上的图块素材个数大于1000!");
|
||||
if (img.width * img.height > 32*32*3000) {
|
||||
console.warn("警告!"+imgName+"上的图块素材个数大于3000!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
44
libs/maps.js
44
libs/maps.js
@ -178,20 +178,42 @@ maps.prototype.initMaps = function (floorIds) {
|
||||
return maps;
|
||||
}
|
||||
|
||||
maps.prototype.__initFloorMap = function (floorId) {
|
||||
var map = core.clone(core.floors[floorId].map);
|
||||
|
||||
var mw = core.floors[floorId].width || 13;
|
||||
var mh = core.floors[floorId].height || 13;
|
||||
|
||||
for (var x=0;x<mh;x++) {
|
||||
if (!core.isset(map[x])) map[x] = [];
|
||||
for (var y=0;y<mw;y++) {
|
||||
if (!core.isset(map[x][y])) map[x][y]=0;
|
||||
// check "disable"
|
||||
var event = core.floors[floorId].events[y+","+x];
|
||||
if (core.isset(event) && event.enable === false && main.mode == 'play') {
|
||||
map[x][y] += ":f";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
////// 压缩地图
|
||||
maps.prototype.compressMap = function (mapArr, floorId) {
|
||||
if (core.utils.same(mapArr, core.floors[floorId].map)) return null;
|
||||
var floorMap = this.__initFloorMap(floorId);
|
||||
if (core.utils.same(mapArr, floorMap)) return null;
|
||||
|
||||
var mw = core.floors[floorId].width || 13;
|
||||
var mh = core.floors[floorId].height || 13;
|
||||
for (var x=0;x<mh;x++) {
|
||||
if (core.utils.same(mapArr[x], core.floors[floorId].map[x]||[])) {
|
||||
if (core.utils.same(mapArr[x], floorMap[x])) {
|
||||
// 没有改变的行直接删掉记成0
|
||||
mapArr[x] = 0;
|
||||
}
|
||||
else {
|
||||
for (var y=0;y<mw;y++) {
|
||||
if (mapArr[x][y] === (core.floors[floorId].map[x]||[])[y]) {
|
||||
if (mapArr[x][y] === floorMap[x][y]) {
|
||||
// 没有改变的数据记成-1
|
||||
mapArr[x][y] = -1;
|
||||
}
|
||||
@ -203,18 +225,19 @@ maps.prototype.compressMap = function (mapArr, floorId) {
|
||||
|
||||
////// 解压缩地图
|
||||
maps.prototype.decompressMap = function (mapArr, floorId) {
|
||||
if (!core.isset(mapArr)) return core.clone(core.floors[floorId].map);
|
||||
var floorMap = this.__initFloorMap(floorId);
|
||||
if (!core.isset(mapArr)) return floorMap;
|
||||
|
||||
var mw = core.floors[floorId].width || 13;
|
||||
var mh = core.floors[floorId].height || 13;
|
||||
for (var x=0;x<mh;x++) {
|
||||
if (mapArr[x] === 0) {
|
||||
mapArr[x] = core.clone(core.floors[floorId].map[x]);
|
||||
mapArr[x] = floorMap[x];
|
||||
}
|
||||
else {
|
||||
for (var y=0;y<mw;y++) {
|
||||
if (mapArr[x][y] === -1) {
|
||||
mapArr[x][y] = core.floors[floorId].map[x][y];
|
||||
mapArr[x][y] = floorMap[x][y];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -432,11 +455,16 @@ maps.prototype.drawBlock = function (block, animate, dx, dy) {
|
||||
if (!blockInfo.isTileset) x = (animate||0)%(block.event.animate||1);
|
||||
|
||||
if (core.isset(block.name)) {
|
||||
core.clearMap(block.name, block.x * 32, block.y * 32, 32, 32);
|
||||
core.clearMap(block.name, block.x * 32, block.y * 32 + 32 - height, 32, height);
|
||||
if (block.name == 'bg') {
|
||||
if (height>32) {
|
||||
core.clearMap(block.name, block.x * 32, block.y * 32 - 32, 32, 32);
|
||||
core.drawImage('bg', core.material.groundCanvas.canvas, block.x * 32, block.y * 32 - 32);
|
||||
}
|
||||
core.drawImage('bg', core.material.groundCanvas.canvas, block.x * 32, block.y * 32);
|
||||
}
|
||||
core.drawImage(block.name, image, x * 32, y * 32, 32, 32, block.x * 32, block.y * 32, 32, 32);
|
||||
core.drawImage(block.name, image, x * 32, y * height, 32, height,
|
||||
block.x * 32, block.y * 32 + 32 - height, 32, height);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
158
libs/ui.js
158
libs/ui.js
@ -503,6 +503,72 @@ ui.prototype.calTextBoxWidth = function (canvas, content, min_width, max_width)
|
||||
}
|
||||
}
|
||||
|
||||
ui.prototype.__drawText = function (canvas, content, content_left, content_top, valid_width,
|
||||
color, per_height, time) {
|
||||
core.setTextAlign(canvas, 'left');
|
||||
|
||||
var offsetx = content_left, offsety = content_top;
|
||||
core.setFillStyle(canvas, color);
|
||||
var index = 0, currcolor = color, changed = false;
|
||||
|
||||
var drawNext = function () {
|
||||
if (index >= content.length) return false;
|
||||
if (changed) {
|
||||
core.setFillStyle(canvas, currcolor);
|
||||
changed = false;
|
||||
}
|
||||
|
||||
// get next character
|
||||
var ch = content.charAt(index++);
|
||||
// \n, \\n
|
||||
if (ch == '\n' || (ch=='\\' && content.charAt(index)=='n')) {
|
||||
offsetx = content_left;
|
||||
offsety += per_height;
|
||||
if (ch=='\\') index++;
|
||||
return drawNext();
|
||||
}
|
||||
// \r, \\r
|
||||
if (ch == '\r' || (ch=='\\' && content.charAt(index)=='r')) {
|
||||
if (ch == '\\') index++;
|
||||
changed = true;
|
||||
// 检查是不是 []
|
||||
var index2;
|
||||
if (content.charAt(index) == '[' && ((index2=content.indexOf(']', index))>=0)) {
|
||||
// 变色
|
||||
var str = content.substring(index+1, index2);
|
||||
if (str=="") currcolor = color;
|
||||
else currcolor = str;
|
||||
index = index2+1;
|
||||
}
|
||||
else currcolor = color;
|
||||
return drawNext();
|
||||
}
|
||||
// 检查是不是自动换行
|
||||
var charwidth = core.calWidth(canvas, ch);
|
||||
if (core.isset(valid_width) && offsetx + charwidth > content_left + valid_width) {
|
||||
index--;
|
||||
offsetx = content_left;
|
||||
offsety += per_height;
|
||||
return drawNext();
|
||||
}
|
||||
// 输出
|
||||
core.fillText(canvas, ch, offsetx, offsety);
|
||||
offsetx += charwidth;
|
||||
return true;
|
||||
};
|
||||
|
||||
if (!core.isset(time) || time<=0) while (drawNext());
|
||||
else {
|
||||
core.status.event.interval = setInterval(function () {
|
||||
changed = true;
|
||||
if (!drawNext()) {
|
||||
clearInterval(core.status.event.interval);
|
||||
core.status.event.interval = null;
|
||||
}
|
||||
}, time);
|
||||
}
|
||||
}
|
||||
|
||||
////// 绘制一个对话框 //////
|
||||
ui.prototype.drawTextBox = function(content, showAll) {
|
||||
|
||||
@ -729,69 +795,10 @@ ui.prototype.drawTextBox = function(content, showAll) {
|
||||
core.drawImage('ui', image, 0, 0, image.width, image.height, left+10, top+10, 70, 70);
|
||||
}
|
||||
|
||||
var offsetx = content_left, offsety = content_top;
|
||||
core.setFont('ui', font);
|
||||
core.setFillStyle('ui', textColor);
|
||||
var index = 0, currcolor = textColor, changed = false;
|
||||
|
||||
var drawNext = function () {
|
||||
if (index >= content.length) return false;
|
||||
if (changed) {
|
||||
core.setFillStyle('ui', currcolor);
|
||||
changed = false;
|
||||
}
|
||||
|
||||
// get next character
|
||||
var ch = content.charAt(index++);
|
||||
// \n, \\n
|
||||
if (ch == '\n' || (ch=='\\' && content.charAt(index)=='n')) {
|
||||
offsetx = content_left;
|
||||
offsety += textfont+5;
|
||||
if (ch=='\\') index++;
|
||||
return drawNext();
|
||||
}
|
||||
// \r, \\r
|
||||
if (ch == '\r' || (ch=='\\' && content.charAt(index)=='r')) {
|
||||
if (ch == '\\') index++;
|
||||
changed = true;
|
||||
// 检查是不是 []
|
||||
var index2;
|
||||
if (content.charAt(index) == '[' && ((index2=content.indexOf(']', index))>=0)) {
|
||||
// 变色
|
||||
var str = content.substring(index+1, index2);
|
||||
if (str=="") currcolor = textColor;
|
||||
else currcolor = str;
|
||||
index = index2+1;
|
||||
}
|
||||
else currcolor = textColor;
|
||||
return drawNext();
|
||||
}
|
||||
// 检查是不是自动换行
|
||||
var charwidth = core.calWidth('ui', ch);
|
||||
if (offsetx + charwidth > content_left + validWidth) {
|
||||
index--;
|
||||
offsetx = content_left;
|
||||
offsety += textfont+5;
|
||||
return drawNext();
|
||||
}
|
||||
// 输出
|
||||
core.fillText('ui', ch, offsetx, offsety);
|
||||
offsetx += charwidth;
|
||||
return true;
|
||||
};
|
||||
|
||||
if (showAll || textAttribute.time<=0 || core.status.event.id!='action') {
|
||||
while (drawNext());
|
||||
}
|
||||
else {
|
||||
core.status.event.interval = setInterval(function () {
|
||||
changed = true;
|
||||
if (!drawNext()) {
|
||||
clearInterval(core.status.event.interval);
|
||||
core.status.event.interval = null;
|
||||
}
|
||||
}, textAttribute.time);
|
||||
}
|
||||
this.__drawText('ui', content, content_left, content_top, validWidth, textColor, textfont + 5,
|
||||
(showAll || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time);
|
||||
|
||||
}
|
||||
|
||||
@ -812,7 +819,8 @@ ui.prototype.drawScrollText = function (content, time, callback) {
|
||||
|
||||
var font = textfont+"px "+core.status.globalAttribute.font;
|
||||
if (textAttribute.bold) font = "bold "+font;
|
||||
var contents = core.splitLines('ui', content), lines = contents.length;
|
||||
var realContent = content.replace(/(\r|\\r)(\[.*?])?/g, "");
|
||||
var contents = core.splitLines('ui', realContent), lines = contents.length;
|
||||
|
||||
// 计算总高度,按1.4倍行距计算
|
||||
var width = 416, height = textfont * 1.4 * lines;
|
||||
@ -821,15 +829,8 @@ ui.prototype.drawScrollText = function (content, time, callback) {
|
||||
tempCanvas.canvas.height = height;
|
||||
tempCanvas.clearRect(0, 0, width, height);
|
||||
tempCanvas.font = font;
|
||||
tempCanvas.fillStyle = textColor;
|
||||
|
||||
// 全部绘制
|
||||
var currH = textfont;
|
||||
for (var i = 0; i < lines; ++i) {
|
||||
var text = contents[i];
|
||||
tempCanvas.fillText(text, offset, currH);
|
||||
currH += 1.4 * textfont;
|
||||
}
|
||||
this.__drawText(tempCanvas, content, offset, textfont, null, textColor, 1.4*textfont, 0);
|
||||
|
||||
// 开始绘制到UI上
|
||||
core.clearMap('ui');
|
||||
@ -891,17 +892,19 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
|
||||
var contents = null;
|
||||
var content_left = left + 15;
|
||||
var validWidth = width-(content_left-left)-10;
|
||||
|
||||
if (core.isset(content)) {
|
||||
// 获得name, image, icon
|
||||
// 获得name, image, icon
|
||||
var info = this.getTitleAndIcon(content);
|
||||
content = core.replaceText(info.content);
|
||||
var realContent = content.replace(/(\r|\\r)(\[.*?])?/g, "");
|
||||
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 '+globalFont);
|
||||
validWidth = width-(content_left-left)-10
|
||||
contents = core.splitLines('ui', realContent, validWidth, 'bold 15px '+globalFont);
|
||||
|
||||
// content部分高度
|
||||
var cheight=0;
|
||||
@ -963,17 +966,16 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
}
|
||||
}
|
||||
|
||||
core.setTextAlign('ui', 'left');
|
||||
for (var i=0;i<contents.length;i++) {
|
||||
core.fillText('ui', contents[i], content_left, content_top, textColor, 'bold 15px '+globalFont);
|
||||
content_top+=20;
|
||||
}
|
||||
core.setFont('ui', 'bold 15px '+globalFont);
|
||||
this.__drawText('ui', content, content_left, content_top, validWidth, textColor, 20, 0);
|
||||
}
|
||||
|
||||
// 选项
|
||||
core.setTextAlign('ui', 'center');
|
||||
for (var i = 0; i < choices.length; i++) {
|
||||
core.setFillStyle('ui', choices[i].color || textColor);
|
||||
var color = choices[i].color || textColor;
|
||||
if (color instanceof Array) color = core.arrayToRGBA(color);
|
||||
core.setFillStyle('ui', color);
|
||||
core.fillText('ui', core.replaceText(choices[i].text || choices[i]), 208, choice_top + 32 * i, null, "bold 17px "+globalFont);
|
||||
}
|
||||
|
||||
|
||||
@ -462,7 +462,9 @@ utils.prototype.encodeRoute = function (route) {
|
||||
ans+=lastMove.substring(0,1).toUpperCase();
|
||||
if (cnt>1) ans+=cnt;
|
||||
}
|
||||
return ans;
|
||||
// return ans;
|
||||
// 压缩
|
||||
return LZString.compressToBase64(ans);
|
||||
}
|
||||
|
||||
////// 解密路线 //////
|
||||
@ -470,6 +472,14 @@ utils.prototype.decodeRoute = function (route) {
|
||||
|
||||
if (!core.isset(route)) return route;
|
||||
|
||||
// 解压缩
|
||||
try {
|
||||
var v = LZString.decompressFromBase64(route);
|
||||
if (core.isset(v) && /^[a-zA-Z0-9+\/=:]+$/.test(v)) {
|
||||
route = v;
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
var ans=[], index=0;
|
||||
|
||||
var getNumber = function (noparse) {
|
||||
|
||||
12
main.js
12
main.js
@ -316,7 +316,7 @@ main.prototype.setMainTipsText = function (text) {
|
||||
main.prototype.log = function (e) {
|
||||
if (e) {
|
||||
if (main.core && main.core.platform && !main.core.platform.isPC) {
|
||||
console.log((e.stack || e.toString()).replace("\n", " --- "));
|
||||
console.log((e.stack || e.toString()));
|
||||
}
|
||||
else {
|
||||
console.log(e);
|
||||
@ -490,7 +490,6 @@ main.statusBar.image.toolbox.ondblclick = function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
if (core.isReplaying()) {
|
||||
core.rewindReplay();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -516,6 +515,11 @@ main.statusBar.image.keyboard.onclick = function (e) {
|
||||
main.statusBar.image.shop.onclick = function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
if (core.isReplaying()) {
|
||||
core.viewMapReplay();
|
||||
return;
|
||||
}
|
||||
|
||||
if (main.core.isPlaying())
|
||||
main.core.openQuickShop(true);
|
||||
}
|
||||
@ -664,7 +668,9 @@ main.dom.musicBtn.onclick = function () {
|
||||
|
||||
window.onblur = function () {
|
||||
if (main.core && main.core.control) {
|
||||
main.core.control.checkAutosave();
|
||||
try {
|
||||
main.core.control.checkAutosave();
|
||||
} catch (e) {main.log(e);}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user