Merge pull request #431 from ckcz123/v2.x

V2.x
This commit is contained in:
Zhang Chen 2019-12-31 20:17:18 +08:00 committed by GitHub
commit 5d1d1751f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 4114 additions and 254 deletions

View File

@ -230,9 +230,10 @@ core.onmove(loc)
注册的onmove交互函数需要接受x, y, px, py四个参数代表当前的的位置和像素坐标。
core.onup()
当从屏幕上离开时的操作。请注意此函数是没有参数的
core.onup(loc)
当从屏幕上离开时的操作。loc为当前的坐标信息
请勿直接覆盖或调用此函数,如有需要请注册一个"onup"的交互函数。
注册的onup交互函数需要接受x, y, px, py四个参数代表当前的的位置和像素坐标。
core.onclick(x, y)
@ -253,7 +254,7 @@ core.keyDownCtrl()
core.longClick()
当长按住屏幕时执行的操作。
请勿直接覆盖或调用此函数,如有需要请注册一个"keyDownCtrl"的交互函数。
请勿直接覆盖或调用此函数,如有需要请注册一个"longClick"的交互函数。
注册的交互函数如果某一项返回true则之后仍然会继续触发该长按
如果全部返回false则将停止本次长按行为直到手指离开屏幕并重新进行长按为止。
```

View File

@ -57,6 +57,21 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
## 更新说明
### 2019.12.31 HTML5魔塔样板V2.6.6
* [x] 编辑器增加【最近使用的图块】的区域
* [x] 编辑器拉伸到铺满全屏幕还可以Ctrl+滚轮放缩
* [x] 编辑器支持连续Ctrl+Z的撤销Ctrl+Y的重做
* [x] 新增tileset右键绑定宽高以替代贴图模式
* [x] 多重自动存档可以连续A键读档
* [x] 等待用户操作增设分歧选项
* [x] 增设压缩模式会对图片等进行zip压缩
* [x] 追加素材现在可以同时进行自动注册
* [x] 可以复制和粘贴怪物或道具的属性
* [x] 折叠素材时设置每一列个数
* [x] 标题界面和显示选择项时光标跟随鼠标
* [x] 修复所有已知的bug大量细节优化
### 2019.12.1 HTML5魔塔样板V2.6.5
* [x] 事件:设置怪物属性;穿脱装备

View File

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

View File

@ -1,6 +1,6 @@
# 附录API列表
?> 目前版本**v2.6.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} *
这里将列出所有被转发到core的API没有被转发的函数此处不会列出请自行在代码中查看。
@ -1624,6 +1624,12 @@ core.drawAnimate(name, x, y, callback)
此函数会返回一个动画id可以通过core.stopAnimate()立刻停止该动画的播放。
core.drawHeroAnimate(name, callback)
绘制一个跟随勇士行动的动画。name为动画名callback为绘制完毕的回调函数。
此函数将播放动画音效,并异步开始绘制该动画。
此函数会返回一个动画id可以通过core.stopAnimate()立刻停止该动画的播放。
core.stopAnimate(id, doCallback)
立刻停止某个动画的播放。id为上面core.drawAnimate的返回值。
如果doCallback为真则会执行该动画所对应的回调函数。
@ -2166,7 +2172,16 @@ core.same(a, b)
如果a和b都是数组则会递归依次比较数组中的值如果都是对象亦然。
core.utils.http(type, url, formData, success, error, mimeType, responseType)
core.unzip(blobOrUrl, success, error, convertToText)
解压一个zip文件。
blobOrUrl为传入的二进制zip文件Blob格式或zip文件的地址。
success为成功后的回调接收 文件名-文件内容 形式的对象,即
{"filename1": ..., "filename2": ...}
error为失败的回调接收参数message为错误信息。
convertToText如果为true则会将每个文件内容转成纯文本而不是二进制格式。
core.http(type, url, formData, success, error, mimeType, responseType)
发送一个异步HTTP请求。
type为'GET'或者'POST'url为目标地址formData如果是POST请求则为表单数据。
success为成功后的回调error为失败后的回调。

View File

@ -1,6 +1,6 @@
# 元件说明
?> 目前版本**v2.6.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} *
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。

View File

@ -1,6 +1,6 @@
# 事件
?> 目前版本**v2.6.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} *
本章内将对样板所支持的事件进行介绍。
@ -486,7 +486,8 @@ value是一个表达式将通过这个表达式计算出的结果赋值给nam
![](img/events/13.jpg)
从V2.6.5开始,默认`addValue`不会刷新状态栏、地图显伤和自动事件,除非设置了`"refresh": true`。
从V2.6.5开始,当设置了`"norefresh": true`后可以不刷新状态栏、地图显伤和自动事件,从而加速事件执行。
在刷新的情况下如果hp被设置成了0或以下将触发lose事件直接死亡。
@ -509,7 +510,7 @@ value是一个表达式将通过这个表达式计算出的结果赋值给nam
![](img/events/14.jpg)
从V2.6.5开始,默认`addValue`不会刷新状态栏、地图显伤和自动事件,除非设置了`"refresh": true`
从V2.6.5开始,当设置了`"norefresh": true`后可以不刷新状态栏、地图显伤和自动事件,从而加速事件执行
### setEnemy设置怪物属性
@ -1963,6 +1964,31 @@ yes和no均为必填项即用户点击确认或取消后执行的事件。
![](img/events/52.jpg)
从V2.6.6开始,也允许直接在`type:wait`中增加`data`项判定按键或点击坐标。
```js
[
{"type": "wait", "data": [
{"case": "keyboard", "keycode": 13, "action": [
{"type": "comment", "text": "当按下回车(keycode=13)时执行此事件"},
]},
{"case": "mouse", "px": [0,32], "py": [0,32], "action": [
{"type": "comment", "text": "当点击地图左上角时执行此事件"},
]},
]},
]
```
![](img/events/52.png)
`data`是一个数组每一项中case只能为`keyboard`和`mouse`二选一,分别对应键盘和鼠标(即`type=0`和`type=1`)。
如果是键盘,则可以指定`keycode`为键盘的按键内容;否则指定`px`和`py`为点击的像素区间。
action为如果满足该条件时应该执行的事件列表。
### waitAsync等待所有异步事件执行完毕
上面有很多很多的异步事件(也就是执行时不等待执行完毕)。

BIN
_docs/img/events/52.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

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

View File

@ -1,6 +1,6 @@
# 个性化
?> 目前版本**v2.6.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} *
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。

View File

@ -1,6 +1,6 @@
# 脚本
?> 目前版本**v2.6.5**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} *
在V2.6版本中,基本对整个项目代码进行了重写,更加方便造塔者的使用和复写函数。

View File

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

View File

@ -589,27 +589,27 @@ return code;
*/;
setValue_s
: '数值操作' ':' '名称' idString_e '值' expression '刷新状态栏和显伤' Bool Newline
: '数值操作' ':' '名称' idString_e '值' expression '刷新状态栏' Bool Newline
/* setValue_s
tooltip : setValue设置勇士的某个属性、道具个数, 或某个变量/Flag的值
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=setvalue%EF%BC%9A%E8%AE%BE%E7%BD%AE%E5%8B%87%E5%A3%AB%E7%9A%84%E6%9F%90%E4%B8%AA%E5%B1%9E%E6%80%A7%E3%80%81%E9%81%93%E5%85%B7%E4%B8%AA%E6%95%B0%EF%BC%8C%E6%88%96%E6%9F%90%E4%B8%AA%E5%8F%98%E9%87%8Fflag%E7%9A%84%E5%80%BC
colour : this.dataColor
Bool_0 = Bool_0 ? ', "refresh": true' : '';
Bool_0 = Bool_0 ? ', "norefresh": true' : '';
var code = '{"type": "setValue", "name": "'+idString_e_0+'", "value": "'+expression_0+'"' + Bool_0 + '},\n';
return code;
*/;
addValue_s
: '数值增减' ':' '名称' idString_e '+=' expression '刷新状态栏和显伤' Bool Newline
: '数值增减' ':' '名称' idString_e '+=' expression '刷新状态栏' Bool Newline
/* addValue_s
tooltip : addValue增减勇士的某个属性、道具个数, 或某个变量/Flag的值
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=addValue%ef%bc%9a%e5%a2%9e%e5%87%8f%e5%8b%87%e5%a3%ab%e7%9a%84%e6%9f%90%e4%b8%aa%e5%b1%9e%e6%80%a7%e3%80%81%e9%81%93%e5%85%b7%e4%b8%aa%e6%95%b0%ef%bc%8c%e6%88%96%e6%9f%90%e4%b8%aa%e5%8f%98%e9%87%8f%2fFlag%e7%9a%84%e5%80%bc
colour : this.dataColor
Bool_0 = Bool_0 ? ', "refresh": true' : '';
Bool_0 = Bool_0 ? ', "norefresh": true' : '';
var code = '{"type": "addValue", "name": "'+idString_e_0+'", "value": "'+expression_0+'"' + Bool_0 + '},\n';
return code;
*/;
@ -1988,18 +1988,56 @@ return code;
wait_s
: '等待用户操作并获得按键或点击信息'
: '等待用户操作并获得按键或点击信息' BGNL? Newline waitContext* BEND Newline
/* wait_s
tooltip : wait: 等待用户操作并获得按键或点击信息(具体用法看文档)
tooltip : wait: 等待用户操作并获得按键或点击信息
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=wait%EF%BC%9A%E7%AD%89%E5%BE%85%E7%94%A8%E6%88%B7%E6%93%8D%E4%BD%9C
colour : this.soundColor
var code = '{"type": "wait"},\n';
waitContext_0 = waitContext_0 ? (', "data": [\n' + waitContext_0 + ']') : '';
var code = '{"type": "wait"' + waitContext_0 + '},\n';
return code;
*/;
waitContext
: waitContext_1
| waitContext_2
| waitContext_empty;
waitContext_1
: '按键的场合' '键值' Int BGNL? Newline action+ BEND Newline
/* waitContext_1
tooltip : wait: 等待用户操作并获得按键或点击信息
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=wait%EF%BC%9A%E7%AD%89%E5%BE%85%E7%94%A8%E6%88%B7%E6%93%8D%E4%BD%9C
colour : this.subColor
var code = '{"case": "keyboard", "keycode": ' + Int_0 + ', "action": [\n' + action_0 + ']},\n';
return code;
*/;
waitContext_2
: '点击的场合' '像素x范围' PosString '~' PosString '; y范围' PosString '~' PosString BGNL? Newline action+ BEND Newline
/* waitContext_2
tooltip : wait: 等待用户操作并获得按键或点击信息
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=wait%EF%BC%9A%E7%AD%89%E5%BE%85%E7%94%A8%E6%88%B7%E6%93%8D%E4%BD%9C
default : [0,32,0,32]
colour : this.subColor
var code = '{"case": "mouse", "px": [' + PosString_0 + ',' + PosString_1 + '], "py": [' + PosString_2 + ',' + PosString_3 + '], "action": [\n' + action_0 + ']},\n';
return code;
*/;
waitContext_empty : Newline
/* waitContext_empty
return '';
*/;
waitAsync_s
: '等待所有异步事件执行完毕'
@ -3398,7 +3436,7 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['setValue_s'].xmlText([
this.tryToUseEvFlag_e('idString_e', [data.name]),
MotaActionBlocks['evalString_e'].xmlText([data.value]),
data.refresh || false,
data.norefresh || false,
this.next]);
break;
case "setValue2":
@ -3406,7 +3444,7 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['addValue_s'].xmlText([
this.tryToUseEvFlag_e('idString_e', [data.name]),
MotaActionBlocks['evalString_e'].xmlText([data.value]),
data.refresh || false,
data.norefresh || false,
this.next]);
break;
case "setEnemy":
@ -3547,8 +3585,22 @@ ActionParser.prototype.parseAction = function() {
data.time||0,data.noSkip||false,this.next]);
break;
case "wait": // 等待用户操作
var case_waitList = null;
if (data.data) {
for(var ii=data.data.length-1,caseNow;caseNow=data.data[ii];ii--) {
if (caseNow["case"] == "keyboard") {
case_waitList = MotaActionBlocks['waitContext_1'].xmlText([
caseNow.keycode || 0, this.insertActionList(caseNow.action), case_waitList
]);
} else if (caseNow["case"] == "mouse") {
case_waitList = MotaActionBlocks['waitContext_2'].xmlText([
caseNow.px[0], caseNow.px[1], caseNow.py[0], caseNow.py[1], this.insertActionList(caseNow.action), case_waitList
]);
}
}
}
this.next = MotaActionBlocks['wait_s'].xmlText([
this.next]);
case_waitList, this.next]);
break;
case "waitAsync": // 等待所有异步事件执行完毕
this.next = MotaActionBlocks['waitAsync_s'].xmlText([

View File

@ -40,7 +40,7 @@ body {
width: 104px;
}
#left, #mid, #right {
#left, #mid, #mid2, #right {
border-radius: 2px;
box-sizing: border-box;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
@ -130,6 +130,14 @@ body {
height: 630px;
}
#mid2 {
position: absolute;
left: 448px;
top: 650px;
width: 440px;
bottom: 10px;
}
#mapEdit {
overflow: hidden;
}
@ -142,6 +150,13 @@ body {
height: 416px;
}
#lastUsedDiv {
height: auto;
bottom: 0;
margin-top: 20px;
overflow: hidden;
}
#mid .tools {
position: absolute;
width: 425px;
@ -239,15 +254,15 @@ body {
position: absolute;
left: 900px;
top: 10px;
width: 440px;
height: 630px;
right: 0;
bottom: 0;
/* border: 1px solid rgb(238, 13, 13); */
}
#iconLib {
position: absolute;
width: 435px;
height: 620px;
right: 0;
bottom: 0;
left: 5px;
top: 5px;
overflow: auto;

View File

@ -110,6 +110,10 @@ body {
position: absolute;
}
#mid2 {
display: none;
}
#mapEdit {
overflow: hidden;
}

View File

@ -7,7 +7,7 @@
.leftTab {
overflow: auto;
position: absolute;
height: 630px;
bottom: 0;
}
.leftTab > * {

View File

@ -8,6 +8,7 @@ function editor() {
body:document.body,
eui:document.getElementById('eui'),
euiCtx:document.getElementById('eui').getContext('2d'),
efgCtx:document.getElementById('efg').getContext('2d'),
mid:document.getElementById('mid'),
mapEdit:document.getElementById('mapEdit'),
selectFloor:document.getElementById('selectFloor'),
@ -26,9 +27,13 @@ function editor() {
brushMod2:document.getElementById('brushMod2'),
brushMod3:document.getElementById('brushMod3'),
bgc : document.getElementById('bg'),
bgCtx : document.getElementById('bg').getContext('2d'),
fgc : document.getElementById('fg'),
evc : document.getElementById('event'),
fgCtx : document.getElementById('fg').getContext('2d'),
evc : document.getElementById('event'),
evCtx : document.getElementById('event').getContext('2d'),
ev2c : document.getElementById('event2'),
ev2Ctx : document.getElementById('event2').getContext('2d'),
layerMod:document.getElementById('layerMod'),
layerMod2:document.getElementById('layerMod2'),
layerMod3:document.getElementById('layerMod3'),
@ -46,6 +51,10 @@ function editor() {
changeFloorId :document.getElementById('changeFloorId'),
left1 : document.getElementById('left1'),
editModeSelect :document.getElementById('editModeSelect'),
mid2 : document.getElementById('mid2'),
lastUsedDiv: document.getElementById('lastUsedDiv'),
lastUsed: document.getElementById('lastUsed'),
lastUsedCtx: document.getElementById('lastUsed').getContext('2d'),
};
this.uivalues={
@ -56,12 +65,9 @@ function editor() {
startPos:null,
endPos:null,
// 撤销/恢复
currDrawData : {
pos: [],
info: {}
},
reDo : null,
preMapData : null,
preMapData : [],
preMapMax: 10,
postMapData: [],
//
shortcut:{},
copyedInfo : null,
@ -82,8 +88,19 @@ function editor() {
loc: null,
n: -1,
enemys: []
}
},
// 复制怪物或道具属性
copyEnemyItem : {
type: null,
data: {}
},
// tile
tileSize: [1,1],
// 最近使用的图块
lastUsed: [],
};
window.onerror = function (msg, url, lineNo, columnNo, error) {
@ -155,7 +172,9 @@ editor.prototype.init = function (callback) {
editor_mode = editor_mode(editor);
editor.mode = editor_mode;
core.resetGame(core.firstData.hero, null, core.firstData.floorId, core.clone(core.initStatus.maps));
core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function () {
var lastFloorId = core.getLocalStorage('editorLastFloorId', core.status.floorId);
if (core.floorIds.indexOf(lastFloorId) < 0) lastFloorId = core.status.floorId;
core.changeFloor(lastFloorId, null, core.firstData.hero.loc, null, function () {
afterCoreReset();
}, true);
core.events.setInitData(null);
@ -205,9 +224,9 @@ editor.prototype.init = function (callback) {
}
editor.prototype.mapInit = function () {
var ec = document.getElementById('event').getContext('2d');
var ec = editor.dom.evCtx;
ec.clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32);
document.getElementById('event2').getContext('2d').clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32);
editor.dom.ev2Ctx.clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32);
editor.map = [];
var sy=editor.currentFloorData.map.length,sx=editor.currentFloorData.map[0].length;
for (var y = 0; y < sy; y++) {
@ -240,7 +259,8 @@ editor.prototype.changeFloor = function (floorId, callback) {
});
editor.currentFloorData[name]=mapArray;
}
editor.uivalues.preMapData = null;
editor.uivalues.preMapData = [];
editor.uivalues.postMapData = [];
editor.uifunctions._extraEvent_bindSpecialDoor_doAction(true);
core.changeFloor(floorId, null, {"x": 0, "y": 0, "direction": "up"}, null, function () {
editor.game.fetchMapFromCore();
@ -252,6 +272,7 @@ editor.prototype.changeFloor = function (floorId, callback) {
var loc = editor.viewportLoc[floorId] || [], x = loc[0] || 0, y = loc[1] || 0;
editor.setViewport(x, y);
core.setLocalStorage('editorLastFloorId', floorId);
if (callback) callback();
});
}
@ -259,7 +280,7 @@ editor.prototype.changeFloor = function (floorId, callback) {
/////////// 游戏绘图相关 ///////////
editor.prototype.drawEventBlock = function () {
var fg=document.getElementById('efg').getContext('2d');
var fg=editor.dom.efgCtx;
fg.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
var firstData = editor.game.getFirstData();
@ -310,7 +331,7 @@ editor.prototype.drawEventBlock = function () {
editor.prototype.drawPosSelection = function () {
this.drawEventBlock();
var fg=document.getElementById('efg').getContext('2d');
var fg=editor.dom.efgCtx;
fg.strokeStyle = 'rgba(255,255,255,0.7)';
fg.lineWidth = 4;
fg.strokeRect(32*editor.pos.x - core.bigmap.offsetX + 4, 32*editor.pos.y - core.bigmap.offsetY + 4, 24, 24);
@ -362,20 +383,43 @@ editor.prototype.updateMap = function () {
//ctx.drawImage(core.material.images[tileInfo.images], 0, tileInfo.y*32, 32, 32, x*32, y*32, 32, 32);
}
// 绘制地图 start
var eventCtx = document.getElementById('event').getContext("2d");
var fgCtx = document.getElementById('fg').getContext("2d");
var bgCtx = document.getElementById('bg').getContext("2d");
for (var y = 0; y < editor.map.length; y++)
for (var y = 0; y < editor.map.length; y++) {
for (var x = 0; x < editor.map[0].length; x++) {
var tileInfo = editor.map[y][x];
drawTile(eventCtx, x, y, tileInfo);
drawTile(editor.dom.evCtx, x, y, tileInfo);
tileInfo = editor.fgmap[y][x];
drawTile(fgCtx, x, y, tileInfo);
drawTile(editor.dom.fgCtx, x, y, tileInfo);
tileInfo = editor.bgmap[y][x];
drawTile(bgCtx, x, y, tileInfo);
drawTile(editor.dom.bgCtx, x, y, tileInfo);
}
}
// 绘制地图 end
this.updateLastUsedMap();
}
editor.prototype.updateLastUsedMap = function () {
// 绘制最近使用事件
var ctx = editor.dom.lastUsedCtx;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.strokeStyle = 'rgba(255,128,0,0.85)';
ctx.lineWidth = 4;
for (var i = 0; i < editor.uivalues.lastUsed.length; ++i) {
var x = i % core.__SIZE__, y = parseInt(i / core.__SIZE__);
var info = editor.uivalues.lastUsed[i];
if (!info || !info.images) continue;
if (info.isTile) {
ctx.drawImage(core.material.images.tilesets[info.images], 32 * info.x, 32 * info.y, 32, 32, x*32, y*32, 32, 32);
} else if (info.images == 'autotile') {
ctx.drawImage(core.material.images.autotile[info.id], 0, 0, 32, 32, x * 32, y * 32, 32, 32);
} else {
var per_height = info.images.endsWith('48') ? 48 : 32;
ctx.drawImage(core.material.images[info.images], 0, info.y * per_height, 32, per_height, x * 32, y * 32, 32, 32);
}
if (selectBox.isSelected() && editor.info.id == info.id) {
ctx.strokeRect(32 * x + 2, 32 * y + 2, 28, 28);
}
}
}
editor.prototype.setViewport=function (x, y) {
@ -402,8 +446,9 @@ editor.prototype.drawInitData = function (icons) {
editor.widthsX = {};
editor.uivalues.folded = core.getLocalStorage('folded', false);
// editor.uivalues.folded = true;
editor.uivalues.foldPerCol = 50;
editor.uivalues.foldPerCol = core.getLocalStorage('foldPerCol', 50);
// var imgNames = Object.keys(images); //还是固定顺序吧;
editor.uivalues.lastUsed = core.getLocalStorage("lastUsed", []);
var imgNames = ["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48", "autotile"];
for (var ii = 0; ii < imgNames.length; ii++) {
@ -596,7 +641,10 @@ editor.prototype.setSelectBoxFromInfo=function(thisevent){
editor.dom.dataSelection.style.left = pos.x * 32 + 'px';
editor.dom.dataSelection.style.top = pos.y * ysize + 'px';
editor.dom.dataSelection.style.height = ysize - 6 + 'px';
setTimeout(function(){selectBox.isSelected(true);});
setTimeout(function(){
selectBox.isSelected(true);
editor.updateLastUsedMap();
});
editor.info = JSON.parse(JSON.stringify(thisevent));
tip.infos(JSON.parse(JSON.stringify(thisevent)));
editor.pos=pos;

View File

@ -163,7 +163,10 @@ editor_blockly = function () {
],
'特效/声音':[
MotaActionBlocks['sleep_s'].xmlText(),
MotaActionBlocks['wait_s'].xmlText(),
MotaActionFunctions.actionParser.parseList({"type": "wait", "data": [
{"case": "keyboard", "keycode": 13, "action": [{"type": "comment", "text": "当按下回车(keycode=13)时执行此事件"}]},
{"case": "mouse", "px": [0,32], "py": [0,32], "action": [{"type": "comment", "text": "当点击地图左上角时执行此事件"}]},
]}),
MotaActionBlocks['waitAsync_s'].xmlText(),
MotaActionBlocks['vibrate_s'].xmlText(),
MotaActionBlocks['animate_s'].xmlText(),
@ -219,10 +222,10 @@ editor_blockly = function () {
],
'值块':[
MotaActionBlocks['addValue_s'].xmlText([
MotaActionBlocks['idString_1_e'].xmlText(['status','生命'])
MotaActionBlocks['idString_1_e'].xmlText(['status','生命']), '', false
]),
MotaActionBlocks['setValue_s'].xmlText([
MotaActionBlocks['idString_1_e'].xmlText(['status','生命'])
MotaActionBlocks['idString_1_e'].xmlText(['status','生命']), '', false
]),
MotaActionBlocks['expression_arithmetic_0'].xmlText(),
MotaActionBlocks['evFlag_e'].xmlText(),
@ -689,14 +692,20 @@ function omitedcheckUpdateFunction(event) {
"previewUI_s", "clearMap_s", "clearMap_1_s", "setAttribute_s", "fillText_s",
"fillBoldText_s", "fillRect_s", "strokeRect_s", "drawLine_s",
"drawArrow_s", "fillPolygon_s", "strokePolygon_s", "fillCircle_s", "strokeCircle_s",
"drawImage_s", "drawImage_1_s", "drawIcon_s", "drawBackground_s", "drawSelector_s", "drawSelector_1_s"
"drawImage_s", "drawImage_1_s", "drawIcon_s", "drawBackground_s", "drawSelector_s", "drawSelector_1_s",
"waitContext_2"
];
if (b && types.indexOf(b.type)>=0) {
try {
var code = "[" + Blockly.JavaScript.blockToCode(b).replace(/\\(i|c|d|e)/g, '\\\\$1') + "]";
eval("var obj="+code);
// console.log(obj);
if (obj.length > 0 && b.type.startsWith(obj[0].type)) {
if (obj.length > 0 && b.type == 'waitContext_2') {
var dt = obj[0];
editor.uievent.previewUI([{"type": "fillRect", "x": dt.px[0], "y": dt.py[0],
"width": "(" + dt.px[1] + ")-(" + dt.px[0] + ")", "height": "(" + dt.py[1] + ")-(" + dt.py[0] + ")",
"style": "rgba(255,0,0,0.5)"}])
}
else if (obj.length > 0 && b.type.startsWith(obj[0].type)) {
if (b.type == 'previewUI_s')
editor.uievent.previewUI(obj[0].action);
else editor.uievent.previewUI([obj[0]]);

View File

@ -210,7 +210,57 @@ editor_datapanel_wrapper = function (editor) {
}
}
editor.uifunctions.copyPasteEnemyItem_func = function () {
var copyEnemyItem = document.getElementById('copyEnemyItem');
var pasteEnemyItem = document.getElementById('pasteEnemyItem');
copyEnemyItem.onclick = function () {
var cls = (editor_mode.info || {}).images;
if (editor_mode.mode != 'enemyitem' || (cls != 'enemys' && cls != 'enemy48' && cls != 'items')) return;
editor.uivalues.copyEnemyItem.type = cls;
var id = editor_mode.info.id;
if (cls == 'enemys' || cls == 'enemy48') {
editor.uivalues.copyEnemyItem.data = core.clone(enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80[id]);
printf("怪物属性复制成功");
} else {
editor.uivalues.copyEnemyItem.data = {};
for (var x in items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a) {
if (items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a[x][id] != null) {
editor.uivalues.copyEnemyItem.data[x] = core.clone(items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a[x][id]);
}
}
printf("道具属性复制成功");
}
}
pasteEnemyItem.onclick = function () {
var cls = (editor_mode.info || {}).images;
if (editor_mode.mode != 'enemyitem' || !cls || cls != editor.uivalues.copyEnemyItem.type) return;
var id = editor_mode.info.id;
if (cls == 'enemys' || cls == 'enemy48') {
if (confirm("你确定要覆盖此怪物的全部属性么?这是个不可逆操作!")) {
enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80[id] = core.clone(editor.uivalues.copyEnemyItem.data);
editor.file.saveSetting('enemys', [], function (err) {
if (err) printe(err);
else printf("怪物属性粘贴成功\n请再重新选中该怪物方可查看更新后的表格。");
})
}
} else {
if (confirm("你确定要覆盖此道具的全部属性么?这是个不可逆操作!")) {
for (var x in editor.uivalues.copyEnemyItem.data) {
items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a[x][id] = core.clone(editor.uivalues.copyEnemyItem.data[x]);
}
editor.file.saveSetting('items', [], function (err) {
if (err) printe(err);
else printf("道具属性粘贴成功\n请再重新选中该道具方可查看更新后的表格。");
})
}
}
}
}
@ -490,7 +540,7 @@ editor_datapanel_wrapper = function (editor) {
}
//画灰白相间的格子
var bgc = editor.dom.bg.getContext('2d');
var bgc = editor.dom.bgCtx;
var colorA = ["#f8f8f8", "#cccccc"];
var colorIndex;
var sratio = 4;
@ -586,6 +636,8 @@ editor_datapanel_wrapper = function (editor) {
editor.uifunctions.appendConfirm_func = function () {
var appendRegister = document.getElementById('appendRegister');
var appendConfirm = document.getElementById('appendConfirm');
appendConfirm.onclick = function () {
@ -648,15 +700,29 @@ editor_datapanel_wrapper = function (editor) {
editor.dom.spriteCtx.drawImage(editor.dom.sourceCtx.canvas, v.x * 32, v.y * ysize, 32, ysize, 32 * ii, editor.dom.sprite.height - ysize, 32, ysize);
}
var dt = editor.dom.spriteCtx.getImageData(0, 0, editor.dom.sprite.width, editor.dom.sprite.height);
var imgbase64 = editor.dom.sprite.toDataURL().split(',')[1];
fs.writeFile('./project/images/' + editor_mode.appendPic.imageName + '.png', imgbase64, 'base64', function (err, data) {
var imgbase64 = editor.dom.sprite.toDataURL('image/png');
var imgName = editor_mode.appendPic.imageName;
fs.writeFile('./project/images/' + imgName + '.png', imgbase64.split(',')[1], 'base64', function (err, data) {
if (err) {
printe(err);
throw (err)
}
printf('追加素材成功,你可以继续追加其他素材,最后再刷新以显示在素材区');
editor.dom.sprite.style.height = (editor.dom.sprite.height = (editor.dom.sprite.height + ysize)) + "px";
var currHeight = editor.dom.sprite.height;
editor.dom.sprite.style.height = (editor.dom.sprite.height = (currHeight + ysize)) + "px";
editor.dom.spriteCtx.putImageData(dt, 0, 0);
core.material.images[imgName].src = imgbase64;
editor.widthsX[imgName][3] = currHeight;
if (appendRegister && appendRegister.checked) {
editor.file.autoRegister({images: imgName}, function (e) {
if (e) {
printe(e);
throw e;
}
printf('追加素材并自动注册成功!你可以继续追加其他素材,最后再刷新以使用。');
});
} else {
printf('追加素材成功!你可以继续追加其他素材,最后再刷新以使用。');
}
});
}
@ -679,15 +745,29 @@ editor_datapanel_wrapper = function (editor) {
}
dt = editor.dom.spriteCtx.getImageData(0, 0, editor.dom.sprite.width, editor.dom.sprite.height);
var imgbase64 = editor.dom.sprite.toDataURL().split(',')[1];
fs.writeFile('./project/images/' + editor_mode.appendPic.imageName + '.png', imgbase64, 'base64', function (err, data) {
var imgbase64 = editor.dom.sprite.toDataURL('image/png');
var imgName = editor_mode.appendPic.imageName;
fs.writeFile('./project/images/' + imgName + '.png', imgbase64.split(',')[1], 'base64', function (err, data) {
if (err) {
printe(err);
throw (err)
}
printf('快速追加素材成功,你可以继续追加其他素材,最后再刷新以显示在素材区');
editor.dom.sprite.style.height = (editor.dom.sprite.height = (editor.dom.sprite.height + ysize)) + "px";
var currHeight = editor.dom.sprite.height;
editor.dom.sprite.style.height = (editor.dom.sprite.height = (currHeight + ysize)) + "px";
editor.dom.spriteCtx.putImageData(dt, 0, 0);
core.material.images[imgName].src = imgbase64;
editor.widthsX[imgName][3] = currHeight;
if (appendRegister && appendRegister.checked) {
editor.file.autoRegister({images: imgName}, function (e) {
if (e) {
printe(e);
throw e;
}
printf('快速追加素材并自动注册成功!你可以继续追加其他素材,最后再刷新以使用。');
})
} else {
printf('快速追加素材成功!你可以继续追加其他素材,最后再刷新以使用。');
}
});
}

View File

@ -897,6 +897,8 @@ editor_file = function (editor, callback) {
callback('出错了,要设置的文件名不识别');
}
editor.file.saveSetting = saveSetting;
return editor_file;
}
//editor_file = editor_file(editor);

View File

@ -216,7 +216,7 @@ tip.showHelp = function(value) {
'双击事件编辑器的图块可以进行长文本编辑/脚本编辑/地图选点/UI绘制预览等操作',
'ESC或点击空白处可以自动保存当前修改',
'H键可以打开操作帮助哦',
'tileset贴图模式可以按选中tileset素材在地图上拖动来一次绘制一个区域',
'tileset贴图模式可以在地图上拖动来一次绘制一个区域;右键额外素材也可以绑定宽高',
'可以拖动地图上的图块和事件或按Ctrl+C, Ctrl+X和Ctrl+V进行复制剪切和粘贴Delete删除',
'Alt+数字键保存图块,数字键读取保存的图块',
];

View File

@ -24,6 +24,7 @@ editor_listen_wrapper = function (editor) {
editor.dom.iconExpandBtn.onclick = editor.uifunctions.fold_material_click
editor.dom.iconLib.onmousedown = editor.uifunctions.material_ondown
editor.dom.iconLib.oncontextmenu = function (e) { e.preventDefault() }
editor.dom.extraEvent.onmousedown = editor.uifunctions.extraEvent_click
editor.dom.chooseThis.onmousedown = editor.uifunctions.chooseThis_click
@ -33,6 +34,8 @@ editor_listen_wrapper = function (editor) {
editor.dom.clearEvent.onmousedown = editor.uifunctions.clearEvent_click
editor.dom.clearLoc.onmousedown = editor.uifunctions.clearLoc_click
editor.dom.lastUsed.onmousedown = editor.uifunctions.lastUsed_click;
editor.dom.brushMod.onchange = editor.uifunctions.brushMod_onchange
if (editor.dom.brushMod2) editor.dom.brushMod2.onchange = editor.uifunctions.brushMod2_onchange;
if (editor.dom.brushMod3) editor.dom.brushMod3.onchange = editor.uifunctions.brushMod3_onchange;
@ -133,6 +136,7 @@ editor_listen_wrapper = function (editor) {
editor.uifunctions.newIdIdnum_func()
editor.uifunctions.changeId_func()
editor.uifunctions.copyPasteEnemyItem_func();
editor.uifunctions.selectFloor_func()
editor.uifunctions.saveFloor_func()

View File

@ -206,7 +206,7 @@ editor_mappanel_wrapper = function (editor) {
}
editor.uivalues.holdingPath = 0;
if (editor.uivalues.stepPostfix && editor.uivalues.stepPostfix.length) {
editor.uivalues.preMapData = JSON.parse(JSON.stringify({ map: editor.map, fgmap: editor.fgmap, bgmap: editor.bgmap }));
editor.savePreMap();
if (editor.brushMod !== 'line') {
var x0 = editor.uivalues.stepPostfix[0].x;
var y0 = editor.uivalues.stepPostfix[0].y;
@ -221,11 +221,20 @@ editor_mappanel_wrapper = function (editor) {
}
}
}
editor.uivalues.currDrawData.pos = JSON.parse(JSON.stringify(editor.uivalues.stepPostfix));
editor.uivalues.currDrawData.info = JSON.parse(JSON.stringify(editor.info));
editor.uivalues.reDo = null;
// console.log(editor.uivalues.stepPostfix);
if (editor.brushMod === 'tileset' && core.tilesets.indexOf(editor.info.images) !== -1) {
var useBrushMode = editor.brushMod == 'tileset';
if (editor.uivalues.stepPostfix.length == 1 && (editor.uivalues.tileSize[0] > 1 || editor.uivalues.tileSize[1] > 1)) {
useBrushMode = true;
var x0 = editor.uivalues.stepPostfix[0].x;
var y0 = editor.uivalues.stepPostfix[0].y;
editor.uivalues.stepPostfix = [];
for (var jj = y0; jj < y0 + editor.uivalues.tileSize[1]; ++jj) {
for (var ii = x0; ii < x0 + editor.uivalues.tileSize[0]; ++ii) {
if (jj >= editor[editor.layerMod].length || ii >= editor[editor.layerMod][0].length) continue;
editor.uivalues.stepPostfix.push({ x: ii, y: jj });
}
}
}
if (useBrushMode && core.tilesets.indexOf(editor.info.images) !== -1) {
var imgWidth = ~~(core.material.images.tilesets[editor.info.images].width / 32);
var x0 = editor.uivalues.stepPostfix[0].x;
var y0 = editor.uivalues.stepPostfix[0].y;
@ -242,6 +251,10 @@ editor_mappanel_wrapper = function (editor) {
editor[editor.layerMod][editor.uivalues.stepPostfix[ii].y][editor.uivalues.stepPostfix[ii].x] = editor.info;
}
// console.log(editor.map);
if (editor.info.y != null) {
editor.uivalues.lastUsed = [editor.info].concat(editor.uivalues.lastUsed.filter(function (e) { return e.id != editor.info.id}));
core.setLocalStorage("lastUsed", editor.uivalues.lastUsed);
}
editor.updateMap();
editor.uivalues.holdingPath = 0;
editor.uivalues.stepPostfix = [];
@ -511,8 +524,7 @@ editor_mappanel_wrapper = function (editor) {
editor.uifunctions.copyLoc_click = function (e) {
editor.uifunctions.hideMidMenu();
e.stopPropagation();
editor.uivalues.preMapData = null;
editor.uivalues.reDo = null;
editor.savePreMap();
editor_mode.onmode('');
var now = editor.pos, last = editor.uivalues.lastRightButtonPos[1];
if (now.x == last.x && now.y == last.y) return;
@ -535,8 +547,7 @@ editor_mappanel_wrapper = function (editor) {
editor.uifunctions.moveLoc_click = function (e) {
editor.uifunctions.hideMidMenu();
e.stopPropagation();
editor.uivalues.preMapData = null;
editor.uivalues.reDo = null;
editor.savePreMap();
editor_mode.onmode('');
editor.exchangePos(editor.pos, editor.uivalues.lastRightButtonPos[1]);
}
@ -547,7 +558,6 @@ editor_mappanel_wrapper = function (editor) {
*/
editor.uifunctions.clearEvent_click = function (e) {
e.stopPropagation();
editor.uivalues.reDo = null;
editor.clearPos(false);
}
@ -557,7 +567,6 @@ editor_mappanel_wrapper = function (editor) {
*/
editor.uifunctions.clearLoc_click = function (e) {
e.stopPropagation();
editor.uivalues.reDo = null;
editor.clearPos(true);
}
@ -582,6 +591,7 @@ editor_mappanel_wrapper = function (editor) {
* 切换画笔模式
*/
editor.uifunctions.brushMod3_onchange = function () {
alert("从V2.6.6开始tileset贴图模式已被废弃。\n请右键额外素材并输入所需要绘制的宽高然后单击地图以绘制一个区域。");
// tip.showHelp(5)
tip.isSelectedBlock(false)
tip.msgs[11] = String('tileset贴图模式下可以按选中tileset素材并在地图上拖动来一次绘制一个区域');
@ -705,6 +715,20 @@ editor_mappanel_wrapper = function (editor) {
saveFloor.onclick = editor_mode.saveFloor;
}
editor.uifunctions.lastUsed_click = function (e) {
if (editor.isMobile) return;
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
var px = scrollLeft + e.clientX - editor.dom.mid2.offsetLeft - editor.dom.lastUsedDiv.offsetLeft,
py = scrollTop + e.clientY - editor.dom.mid2.offsetTop - editor.dom.lastUsedDiv.offsetTop;
var x = parseInt(px / 32), y = parseInt(py / 32);
var index = x + core.__SIZE__ * y;
if (index >= editor.uivalues.lastUsed.length) return;
editor.setSelectBoxFromInfo(editor.uivalues.lastUsed[index]);
return;
}
/////////////////////////////////////////////////////////////////////////////
@ -768,6 +792,21 @@ editor_mappanel_wrapper = function (editor) {
if (callback) callback();
});
}
editor.constructor.prototype.savePreMap = function () {
var dt = {
map: editor.map,
fgmap: editor.fgmap,
bgmap: editor.bgmap,
};
if (editor.uivalues.preMapData.length == 0
|| !core.same(editor.uivalues.preMapData[editor.uivalues.preMapData.length - 1], dt)) {
editor.uivalues.preMapData.push(core.clone(dt));
if (editor.uivalues.preMapData.length > editor.uivalues.preMapMax) {
editor.uivalues.preMapData.shift();
}
}
}
editor.constructor.prototype.moveBgFg = function (startPos, endPos, name, callback) {
if (!startPos || !endPos || ["bgmap","fgmap"].indexOf(name)<0) return;
@ -809,7 +848,7 @@ editor_mappanel_wrapper = function (editor) {
var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
pos = pos || editor.pos;
editor.uifunctions.hideMidMenu();
editor.uivalues.preMapData = null;
editor.savePreMap();
editor.info = 0;
editor_mode.onmode('');
if (clearPos)
@ -843,7 +882,4 @@ editor_mappanel_wrapper = function (editor) {
}

View File

@ -29,10 +29,18 @@ editor_materialpanel_wrapper = function (editor) {
* editor.dom.iconExpandBtn.onclick
*/
editor.uifunctions.fold_material_click = function () {
if (confirm(editor.uivalues.folded ? "你想要展开素材吗?\n展开模式下将显示全素材内容。"
: ("你想要折叠素材吗?\n折叠模式下每个素材将仅显示单列并且每" + editor.uivalues.foldPerCol + "个自动换列。"))) {
core.setLocalStorage('folded', !editor.uivalues.folded);
window.location.reload();
if (editor.uivalues.folded) {
if (confirm("你想要展开素材吗?\n展开模式下将显示全素材内容。")) {
core.setLocalStorage('folded', false);
window.location.reload();
}
} else {
var perCol = parseInt(prompt("请输入折叠素材模式下每列的个数:", "50")) || 0;
if (perCol > 0) {
core.setLocalStorage('foldPerCol', perCol);
core.setLocalStorage('folded', true);
window.location.reload();
}
}
}
@ -42,6 +50,7 @@ editor_materialpanel_wrapper = function (editor) {
*/
editor.uifunctions.material_ondown = function (e) {
e.stopPropagation();
e.preventDefault();
if (!editor.isMobile && e.clientY >= editor.dom.iconLib.offsetHeight - editor.uivalues.scrollBarHeight) return;
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
@ -51,6 +60,7 @@ editor_materialpanel_wrapper = function (editor) {
'size': 32
};
editor.loc = loc;
editor.uivalues.tileSize = [1,1];
var pos = editor.uifunctions.locToPos(loc);
for (var spriter in editor.widthsX) {
if (pos.x >= editor.widthsX[spriter][1] && pos.x < editor.widthsX[spriter][2]) {
@ -118,10 +128,26 @@ editor_materialpanel_wrapper = function (editor) {
break;
}
}
if (editor.info.isTile && e.button == 2) {
var v = prompt("请输入该额外素材区域绑定宽高,以逗号分隔", "1,1");
if (v != null && /^\d+,\d+$/.test(v)) {
v = v.split(",");
var x = parseInt(v[0]), y = parseInt(v[1]);
var widthX = editor.widthsX[editor.info.images];
if (x <= 0 || y <= 0 || editor.info.x + x > widthX[2] - widthX[1] || 32*(editor.info.y + y) > widthX[3]) {
alert("不合法的输入范围,已经越界");
} else {
editor.uivalues.tileSize = [x, y];
}
}
}
}
tip.infos(JSON.parse(JSON.stringify(editor.info)));
editor_mode.onmode('nextChange');
editor_mode.onmode('enemyitem');
editor.updateLastUsedMap();
//editor_mode.enemyitem();
}
}

View File

@ -293,6 +293,7 @@ editor_table_wrapper = function (editor) {
var thiseval = null;
if (input.checked != null) input.value = input.checked;
try {
if (input.value == '') input.value = 'null';
thiseval = JSON.parse(input.value);
} catch (ee) {
printe(field + ' : ' + ee);

View File

@ -49,7 +49,7 @@ editor_ui_wrapper = function (editor) {
}
}
if (unselect) {
if (clickpath.indexOf('eui') === -1) {
if (clickpath.indexOf('eui') === -1 && clickpath.indexOf('lastUsed') === -1) {
if (selectBox.isSelected()) {
editor_mode.onmode('');
editor.file.saveFloorFile(function (err) {
@ -81,14 +81,14 @@ editor_ui_wrapper = function (editor) {
editor.uifunctions.body_shortcut = function (e) {
// UI预览 & 地图选点
if (uievent && uievent.isOpen) {
if (editor.uievent && editor.uievent.isOpen) {
e.preventDefault();
if (e.keyCode == 27) uievent.close();
else if (e.keyCode == 13) uievent.confirm();
else if (e.keyCode == 87) uievent.move(0, -1)
else if (e.keyCode == 65) uievent.move(-1, 0)
else if (e.keyCode == 83) uievent.move(0, 1);
else if (e.keyCode == 68) uievent.move(1, 0);
if (e.keyCode == 27) editor.uievent.close();
else if (e.keyCode == 13) editor.uievent.confirm();
else if (e.keyCode == 87) editor.uievent.move(0, -1)
else if (e.keyCode == 65) editor.uievent.move(-1, 0)
else if (e.keyCode == 83) editor.uievent.move(0, 1);
else if (e.keyCode == 68) editor.uievent.move(1, 0);
return;
}
@ -111,29 +111,6 @@ editor_ui_wrapper = function (editor) {
if (editor_multi.id != "" || editor_blockly.id != "")
return;
//Ctrl+z 撤销上一步undo
if (e.keyCode == 90 && e.ctrlKey && editor.uivalues.preMapData && editor.uivalues.currDrawData.pos.length && selectBox.isSelected()) {
editor.map = JSON.parse(JSON.stringify(editor.uivalues.preMapData.map));
editor.fgmap = JSON.parse(JSON.stringify(editor.uivalues.preMapData.fgmap));
editor.bgmap = JSON.parse(JSON.stringify(editor.uivalues.preMapData.bgmap));
editor.updateMap();
editor.uivalues.reDo = JSON.parse(JSON.stringify(editor.uivalues.currDrawData));
editor.uivalues.currDrawData = { pos: [], info: {} };
editor.uivalues.preMapData = null;
return;
}
//Ctrl+y 重做一步redo
if (e.keyCode == 89 && e.ctrlKey && editor.uivalues.reDo && editor.uivalues.reDo.pos.length && selectBox.isSelected()) {
editor.uivalues.preMapData = JSON.parse(JSON.stringify({ map: editor.map, fgmap: editor.fgmap, bgmap: editor.bgmap }));
for (var j = 0; j < editor.uivalues.reDo.pos.length; j++)
editor.map[editor.uivalues.reDo.pos[j].y][editor.uivalues.reDo.pos[j].x] = JSON.parse(JSON.stringify(editor.uivalues.reDo.info));
editor.updateMap();
editor.uivalues.currDrawData = JSON.parse(JSON.stringify(editor.uivalues.reDo));
editor.uivalues.reDo = null;
return;
}
// PGUP和PGDOWN切换楼层
if (e.keyCode == 33 || e.keyCode == 34) {
e.preventDefault();
@ -151,7 +128,37 @@ editor_ui_wrapper = function (editor) {
var focusElement = document.activeElement;
if (!focusElement || focusElement.tagName.toLowerCase() == 'body'
|| focusElement.id == 'selectFloor') {
|| focusElement.id == 'selectFloor') {
//Ctrl+z 撤销上一步undo
if (e.keyCode == 90 && e.ctrlKey) {
e.preventDefault();
if (editor.uivalues.preMapData.length > 0) {
var data = editor.uivalues.preMapData.pop();
editor.map = JSON.parse(JSON.stringify(data.map));
editor.fgmap = JSON.parse(JSON.stringify(data.fgmap));
editor.bgmap = JSON.parse(JSON.stringify(data.bgmap));
editor.updateMap();
editor.uivalues.postMapData.push(data);
printf("已撤销此操作,你可能需要重新保存地图。");
}
return;
}
//Ctrl+y 重做一步redo
if (e.keyCode == 89 && e.ctrlKey) {
e.preventDefault();
if (editor.uivalues.postMapData.length > 0) {
var data = editor.uivalues.postMapData.pop();
editor.map = JSON.parse(JSON.stringify(data.map));
editor.fgmap = JSON.parse(JSON.stringify(data.fgmap));
editor.bgmap = JSON.parse(JSON.stringify(data.bgmap));
editor.updateMap();
editor.uivalues.preMapData.push(data);
printf("已重做此操作,你可能需要重新保存地图。");
}
return;
}
// Ctrl+C, Ctrl+X, Ctrl+V
if (e.ctrlKey && e.keyCode == 67 && !selectBox.isSelected()) {
e.preventDefault();

View File

@ -143,7 +143,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_leaf": true,
"_type": "textarea",
"_range": "thiseval==null || thiseval instanceof Array || (thiseval==~~thiseval && thiseval>=0)",
"_data": "特殊属性\n\n0:无,1:先攻,2:魔攻,3:坚固,4:2连击,\n5:3连击,6:n连击,7:破甲,8:反击,9:净化,\n10:模仿,11:吸血,12:中毒,13:衰弱,14:诅咒,\n15:领域,16:夹击,17:仇恨,18:阻击,19:自爆,\n20:无敌,21:退化,22:固伤,23:重生,24:激光,25:光环\n\n多个属性例如用[1,4,11]表示先攻2连击吸血"
"_data": "特殊属性\n\n0:无,1:先攻,2:魔攻,3:坚固,4:2连击,\n5:3连击,6:n连击,7:破甲,8:反击,9:净化,\n10:模仿,11:吸血,12:中毒,13:衰弱,14:诅咒,\n15:领域,16:夹击,17:仇恨,18:阻击,19:自爆,\n20:无敌,21:退化,22:固伤,23:重生,24:激光,25:光环\n26:支援,27:捕捉\n多个属性例如用[1,4,11]表示先攻2连击吸血"
},
"value": {
"_leaf": true,

View File

@ -77,6 +77,7 @@
<!-- ["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48"] -->
<input id="appendConfirm" type="button" value="追加"/>
<input id="quickAppendConfirm" type="button" value="快速追加"/>
<span style="font-size: 13px">自动注册</span><input id="appendRegister" type="checkbox" checked/>
</p>
<p>
色相:<input id='changeColorInput' type="range" min="0" max="12" step="1" value="0" list="huelists" style="width: 60%;margin-left: 3%;vertical-align: middle">
@ -135,6 +136,10 @@
</tbody>
</table>
</div>
<div style="margin-top: -10px; margin-bottom: 10px">
<button id="copyEnemyItem">复制属性</button>
<button id="pasteEnemyItem">粘贴属性</button>
</div>
</div>
<div id='newIdIdnum'><!-- id and idnum -->
<input placeholder="新id唯一标识符"/>
@ -308,6 +313,12 @@
</div>
</div>
<div id="mid2" style="display: none">
<p style="margin: 10px">最近使用的图块列表:</p>
<div class="map" style="height: 160px; margin-top: 25px" id="lastUsedDiv">
<canvas class='gameCanvas' id='lastUsed' width='416' height='160'></canvas>
</div>
</div>
<div id="right" style="z-index:-1;opacity: 0;">
<div id="iconLib">
<div id="iconImages"></div>
@ -585,6 +596,7 @@
<script src='_server/editor_legacy.js'></script>
<script src='libs/thirdparty/lz-string.min.js'></script>
<script src='libs/thirdparty/localforage.min.js'></script>
<script src='libs/thirdparty/zip.min.js'></script>
<script id='mainScript' src='main.js'></script>
<script src='_server/editor.js'></script>
<script>

View File

@ -73,6 +73,7 @@
<!-- ["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48"] -->
<input id="appendConfirm" type="button" value="追加"/>
<input id="quickAppendConfirm" type="button" value="快速追加"/>
<span style="font-size: 13px">&nbsp;&nbsp;自动注册</span><input id="appendRegister" type="checkbox" checked/>
</p>
<p>
色相:<input id='changeColorInput' type="range" min="0" max="12" step="1" value="0" list="huelists" style="width: 60%;margin-left: 3%;vertical-align: middle">
@ -131,6 +132,10 @@
</tbody>
</table>
</div>
<div style="margin-top: -10px; margin-bottom: 10px">
<button id="copyEnemyItem">复制属性</button>
<button id="pasteEnemyItem">粘贴属性</button>
</div>
</div>
<div id='newIdIdnum'><!-- id and idnum -->
<input placeholder="新id唯一标识符"/>
@ -351,6 +356,12 @@
<input type="button" value="保存地图" id='saveFloor'/>
</div>
</div>
<div id="mid2">
<p style="margin: 10px">最近使用的图块列表:</p>
<div class="map" id="lastUsedDiv">
<canvas id='lastUsed' width='416' height='416' style="overflow: hidden"></canvas>
</div>
</div>
<div id="right">
<div id="iconLib">
<div id="iconImages"></div>
@ -569,6 +580,7 @@
<script src='_server/editor_legacy.js'></script>
<script src='libs/thirdparty/lz-string.min.js'></script>
<script src='libs/thirdparty/localforage.min.js'></script>
<script src='libs/thirdparty/zip.min.js'></script>
<script id='mainScript' src='main.js'></script>
<script src='_server/editor.js'></script>
<script>

View File

@ -188,6 +188,7 @@
<script src='libs/thirdparty/lz-string.min.js'></script>
<script src='libs/thirdparty/priority-queue.min.js'></script>
<script src='libs/thirdparty/localforage.min.js'></script>
<script src='libs/thirdparty/zip.min.js'></script>
<script id='mainScript' src='main.js'></script>
<script>main.init('play');main.listen();</script>
</body>

View File

@ -42,6 +42,7 @@ actions.prototype._init = function () {
// --- onmove注册
this.registerAction('onmove', '_sys_checkReplay', this._sys_checkReplay, 100);
this.registerAction('onmove', '_sys_onmove_paint', this._sys_onmove_paint, 50);
this.registerAction('onmove', '_sys_onmove_choices', this._sys_onmove_choices, 30);
this.registerAction('onmove', '_sys_onmove', this._sys_onmove, 0);
// --- onup注册
this.registerAction('onup', '_sys_checkReplay', this._sys_checkReplay, 100);
@ -439,6 +440,7 @@ actions.prototype._sys_ondown_lockControl = function (x, y, px, py) {
core.setFlag('px', px);
core.setFlag('py', py);
core.status.route.push("input:" + (1000000 + 1000 * px + py));
core.events.__action_wait_afterGet(core.status.event.data.current);
core.doAction();
}
else {
@ -485,6 +487,30 @@ actions.prototype._sys_onmove_paint = function (x, y, px, py) {
}
}
actions.prototype._sys_onmove_choices = function (x, y) {
if (!core.status.lockControl) return false;
switch (core.status.event.id) {
case 'action':
if (core.status.event.data.type != 'choices') break;
case 'shop':
case 'selectShop':
case 'switchs':
case 'settings':
case 'syncSave':
case 'syncSelect':
case 'localSaveSelect':
case 'storageRemove':
case 'replay':
case 'gameInfo':
this._onMoveChoices(x, y);
return true;
default:
break;
}
return false;
}
actions.prototype._sys_onmove = function (x, y) {
if ((core.status.stepPostfix || []).length > 0) {
var pos = {'x': x, 'y': y};
@ -509,8 +535,10 @@ actions.prototype._sys_onmove = function (x, y) {
}
////// 当点击(触摸)事件放开时 //////
actions.prototype.onup = function () {
this.doRegisteredAction('onup');
actions.prototype.onup = function (loc) {
var x = parseInt(loc.x / loc.size), y = parseInt(loc.y / loc.size);
var px = parseInt(loc.x / core.domStyle.scale), py = parseInt(loc.y / core.domStyle.scale);
this.doRegisteredAction('onup', x, y, px, py);
}
actions.prototype._sys_onup_paint = function () {
@ -726,6 +754,7 @@ actions.prototype._sys_onmousewheel = function (direct) {
var keycode = direct == 1 ? 33 : 34;
core.setFlag('keycode', keycode);
core.status.route.push("input:" + keycode);
core.events.__action_wait_afterGet(core.status.event.data.current);
core.doAction();
return;
}
@ -850,6 +879,21 @@ actions.prototype._keyDownChoices = function (keycode) {
}
}
// 移动光标
actions.prototype._onMoveChoices = function (x, y) {
if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return;
var choices = core.status.event.ui.choices;
var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2) + (core.status.event.ui.offset || 0);
if (y >= topIndex && y < topIndex + choices.length) {
var selection = y - topIndex;
if (selection == core.status.event.selection) return;
core.status.event.selection = selection;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
}
////// 点击中心对称飞行器时
actions.prototype._clickCenterFly = function (x, y) {
var posX = core.status.event.data.posX, posY = core.status.event.data.posY;
@ -985,6 +1029,7 @@ actions.prototype._keyUpAction = function (keycode) {
core.setFlag('type', 0);
core.setFlag('keycode', keycode);
core.status.route.push("input:" + keycode);
core.events.__action_wait_afterGet(core.status.event.data.current);
core.doAction();
return;
}

View File

@ -169,7 +169,11 @@ control.prototype._animationFrame_animate = function (timestamp) {
return obj.index < obj.animate.frames.length;
});
core.status.animateObjs.forEach(function (obj) {
core.maps._drawAnimateFrame(obj.animate, obj.centerX, obj.centerY, obj.index++);
if (obj.hero) {
core.maps._drawAnimateFrame(obj.animate, core.status.heroCenter.px, core.status.heroCenter.py, obj.index++);
} else {
core.maps._drawAnimateFrame(obj.animate, obj.centerX, obj.centerY, obj.index++);
}
});
core.animateFrame.animateTime = timestamp;
}
@ -806,6 +810,8 @@ control.prototype.drawHero = function (status, offset) {
core.bigmap.offsetY = core.clamp((y - core.__HALF_SIZE__) * 32 + offsetY, 0, 32*core.bigmap.height-core.__PIXELS__);
core.clearAutomaticRouteNode(x+dx, y+dy);
core.clearMap('hero');
core.status.heroCenter.px = 32 * x + offsetX + 16;
core.status.heroCenter.py = 32 * y + offsetY + 32 - core.material.icons.hero.height / 2;
if (!core.hasFlag('hideHero')) {
this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function (block) {
@ -996,7 +1002,7 @@ control.prototype.checkBlock = function () {
if (damage) {
core.status.hero.hp -= damage;
core.drawTip("受到"+(core.status.checkBlock.type[loc]||"伤害")+damage+"点");
core.drawAnimate("zone", x, y);
core.drawHeroAnimate("zone");
this._checkBlock_disableQuickShop();
core.status.hero.statistics.extraDamage += damage;
if (core.status.hero.hp <= 0) {
@ -1595,7 +1601,13 @@ control.prototype.autosave = function (removeLast) {
}
if (core.status.event.id == 'action') // 事件中的自动存档
core.setFlag("__events__", core.clone(core.status.event.data));
core.saves.autosave.data = core.saveData();
if (core.saves.autosave.data == null) {
core.saves.autosave.data = [];
}
core.saves.autosave.data.push(core.saveData());
if (core.saves.autosave.data.length > core.saves.autosave.max) {
core.saves.autosave.data.shift();
}
core.saves.autosave.updated = true;
core.saves.ids[0] = true;
core.removeFlag("__events__");
@ -1609,9 +1621,12 @@ 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;
core.saves.autosave.updated = false;
core.setLocalForage("autoSave", core.saves.autosave.data);
var autosave = core.saves.autosave;
if (autosave.data == null || !autosave.updated || !autosave.storage) return;
autosave.updated = false;
if (autosave.data.length >= 1) {
core.setLocalForage("autoSave", autosave.data[autosave.data.length - 1]);
}
}
////// 实际进行存读档事件 //////
@ -1651,11 +1666,21 @@ control.prototype._doSL_save = function (id) {
control.prototype._doSL_load = function (id, callback) {
if (id == 'autoSave' && core.saves.autosave.data != null) {
callback(id, core.clone(core.saves.autosave.data))
var data = core.saves.autosave.data.pop();
if (core.saves.autosave.data.length == 0) {
core.saves.autosave.data.push(core.clone(data));
}
callback(id, data);
}
else {
core.getLocalForage(id=='autoSave'?id:"save"+id, null, function(data) {
if (id == 'autoSave') core.saves.autosave.data = core.clone(data);
if (id == 'autoSave' && data != null) {
core.saves.autosave.data = data;
if (!(core.saves.autosave.data instanceof Array)) {
core.saves.autosave.data = [core.saves.autosave.data];
}
return core.control._doSL_load(id, callback);
}
callback(id, data);
}, function(err) {
main.log(err);
@ -1835,10 +1860,16 @@ control.prototype.getSave = function (index, callback) {
if (index == 0) {
// --- 自动存档先从缓存中获取
if (core.saves.autosave.data != null)
callback(core.clone(core.saves.autosave.data));
callback(core.saves.autosave.data);
else {
core.getLocalForage("autoSave", null, function(data) {
callback(data);
if (data != null) {
core.saves.autosave.data = data;
if (!(core.saves.autosave.data instanceof Array)) {
core.saves.autosave.data = [core.saves.autosave.data];
}
}
callback(core.saves.autosave.data);
}, function(err) {
main.log(err);
callback(null);
@ -2452,7 +2483,7 @@ control.prototype.updateHeroIcon = function (name) {
// 全身图
var w = core.material.icons.hero.width || 32;
var h = core.material.icons.hero.height || 48;
var ratio = Math.max(w / h, 1), width = 32 * ratio, left = 16 - width/2;
var ratio = Math.min(w / h, 1), width = 32 * ratio, left = 16 - width/2;
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");

View File

@ -106,6 +106,8 @@ function core() {
"data": null,
"time": 0,
"updated": false,
"storage": true, // 是否把自动存档写入文件a
"max": 10, // 自动存档最大回退数
},
"favorite": [],
"favoriteName": {}
@ -116,6 +118,7 @@ function core() {
// 勇士属性
'hero': {},
'heroCenter': {'px': null, 'py': null},
// 当前地图
'floorId': null,

View File

@ -842,8 +842,15 @@ events.prototype.doEvent = function (data, x, y, prefix) {
events.prototype.setEvents = function (list, x, y, callback) {
var data = core.status.event.data || {};
if (list)
if (list) {
data.list = [{todo: core.clone(list), total: core.clone(list), condition: "false"}];
// 结束所有正在执行的自动事件
if (list.length == 0) {
core.status.autoEvents.forEach(function (autoEvent) {
core.autoEventExecuting(autoEvent.symbol, false);
});
}
}
if (x != null) data.x = x;
if (y != null) data.y = y;
if (callback) data.callback = callback;
@ -976,13 +983,13 @@ events.prototype.recoverEvents = function (data) {
////// 检测自动事件 //////
events.prototype.checkAutoEvents = function () {
// 只有在无操作或事件流中才能执行自动事件!
if (!core.isPlaying() || core.status.lockControl && core.status.event.id != 'action') return;
if (!core.isPlaying() || (core.status.lockControl && core.status.event.id != 'action')) return;
var todo = [], delay = [];
core.status.autoEvents.forEach(function (autoEvent) {
var symbol = autoEvent.symbol, x = autoEvent.x, y = autoEvent.y, floorId = autoEvent.floorId;
// 不在当前楼层 or 已经执行过 or 正在执行中
if (autoEvent.currentFloor && floorId != core.status.floorId) return;
if (!autoEvent.multiExecute && autoEvent.executed) return;
if (!autoEvent.multiExecute && core.autoEventExecuted(symbol)) return;
if (core.autoEventExecuting(symbol)) return;
var prefix = floorId + "@" + x + "@" + y;
try {
@ -992,7 +999,7 @@ events.prototype.checkAutoEvents = function () {
}
core.autoEventExecuting(symbol, true);
autoEvent.executed = true;
core.autoEventExecuted(symbol, true);
var event = [
{"type": "function", "function":
@ -1015,14 +1022,23 @@ events.prototype.checkAutoEvents = function () {
core.insertAction(todo);
core.push(core.status.event.data.appendingEvents, delay);
} else {
core.insertAction(delay);
core.insertAction(delay[0]);
if (delay.length > 0) {
core.insertAction(delay.slice(1));
}
}
}
events.prototype.autoEventExecuting = function (symbol, value) {
var name = '_executing_autoEvent_' + symbol;
if (value == null) return core.getFlag(name, false);
if (value == null) return core.hasFlag(name);
else core.setFlag(name, value || null);
}
events.prototype.autoEventExecuted = function (symbol, value) {
var name = '_executed_autoEvent_' + symbol;
if (value == null) return core.hasFlag(name);
else core.setFlag(name, value || null);
}
@ -1122,6 +1138,7 @@ events.prototype.__precompile_getArray = function () {
}
events.prototype.__precompile_text = function (text) {
if (typeof text != 'string') return text;
return text.replace(/\${(.*?)}/g, function (word, value) {
return "${" + core.replaceValue(value) + "}";
});
@ -1297,9 +1314,12 @@ events.prototype._action_unfollow = function (data, x, y, prefix) {
}
events.prototype._action_animate = function (data, x, y, prefix) {
if (data.loc == 'hero') data.loc = [core.getHeroLoc('x'), core.getHeroLoc('y')];
else data.loc = this.__action_getLoc(data.loc, x, y, prefix);
this.__action_doAsyncFunc(data.async, core.drawAnimate, data.name, data.loc[0], data.loc[1]);
if (data.loc == 'hero') {
this.__action_doAsyncFunc(data.async, core.drawHeroAnimate, data.name);
} else {
data.loc = this.__action_getLoc(data.loc, x, y, prefix);
this.__action_doAsyncFunc(data.async, core.drawAnimate, data.name, data.loc[0], data.loc[1]);
}
}
events.prototype._action_setViewport = function (data, x, y, prefix) {
@ -1581,7 +1601,7 @@ events.prototype._action_setVolume = function (data, x, y, prefix) {
events.prototype._action_setValue = function (data, x, y, prefix) {
this.setValue(data.name, data.value, prefix);
if (data.refresh) {
if (!data.norefresh) {
if (core.status.hero.hp <= 0) {
core.status.hero.hp = 0;
core.updateStatusBar();
@ -1599,7 +1619,7 @@ events.prototype._action_setValue2 = function (data, x, y, prefix) {
events.prototype._action_addValue = function (data, x, y, prefix) {
this.addValue(data.name, data.value, prefix);
if (data.refresh) {
if (!data.norefresh) {
if (core.status.hero.hp <= 0) {
core.status.hero.hp = 0;
core.updateStatusBar();
@ -1900,6 +1920,7 @@ events.prototype._action_wait = function (data, x, y, prefix) {
var value = parseInt(code.substring(6));
core.status.route.push("input:" + value);
this.__action_wait_getValue(value);
this.__action_wait_afterGet(data);
}
else {
main.log("录像文件出错!当前需要一个 input: 项,实际为 " + code);
@ -1934,6 +1955,42 @@ events.prototype.__action_wait_getValue = function (value) {
}
}
events.prototype.__action_wait_afterGet = function (data) {
if (!data.data) return;
var todo = [];
data.data.forEach(function (one) {
if (one["case"] == "keyboard" && core.getFlag("type") == 0) {
if (one["keycode"] == core.getFlag("keycode", 0)) {
core.push(todo, one.action);
}
}
if (one["case"] == "mouse" && one.px instanceof Array
&& one.py instanceof Array && core.getFlag("type") == 1) {
var pxmin = core.calValue(one.px[0]);
var pxmax = core.calValue(one.px[1]);
var pymin = core.calValue(one.py[0]);
var pymax = core.calValue(one.py[1]);
var px = core.getFlag("px", 0), py = core.getFlag("py", 0);
if (px >= pxmin && px <= pxmax && py >= pymin && py <= pymax) {
core.push(todo, one.action);
}
}
})
if (todo.length > 0)
core.insertAction(todo);
}
events.prototype._precompile_wait = function (data) {
if (data.data) {
data.data.forEach(function (v) {
if (v.px) v.px = this.__precompile_array(v.px);
if (v.py) v.py = this.__precompile_array(v.py);
v.action = this.precompile(v.action);
}, this);
}
return data;
}
events.prototype._action_waitAsync = function (data, x, y, prefix) {
var test = window.setInterval(function () {
if (!core.hasAsync()) {
@ -2690,6 +2747,8 @@ events.prototype._jumpHero_jumping = function (jumpInfo) {
core.control.updateViewport();
core.drawImage('hero', core.material.images.hero, jumpInfo.icon.stop, jumpInfo.icon.loc * height, width, height,
nowx + (32 - width) / 2 - core.bigmap.offsetX, nowy + 32-height - core.bigmap.offsetY, width, height);
core.status.heroCenter.px = nowx + 16;
core.status.heroCenter.py = nowy + 32 - height / 2;
}
events.prototype._jumpHero_finished = function (animate, ex, ey, callback) {

View File

@ -50,7 +50,11 @@ loader.prototype._loadIcons = function () {
}
loader.prototype._loadMaterialImages = function (callback) {
this.loadImages(core.materials, core.material.images, callback);
if (main.useCompress) {
this.loadImagesFromZip('project/images/materials.zip', core.materials, core.material.images, callback);
} else {
this.loadImages(core.materials, core.material.images, callback);
}
}
loader.prototype._loadExtraImages = function (callback) {
@ -60,14 +64,18 @@ loader.prototype._loadExtraImages = function (callback) {
if (images.indexOf("hero.png") < 0)
images.push("hero.png");
this.loadImages(images, core.material.images.images, callback);
if (main.useCompress) {
this.loadImagesFromZip('project/images/images.zip', images, core.material.images.images, callback);
} else {
this.loadImages(images, core.material.images.images, callback);
}
}
loader.prototype._loadAutotiles = function (callback) {
core.material.images.autotile = {};
var keys = Object.keys(core.material.icons.autotile);
var autotiles = {};
this.loadImages(keys, autotiles, function () {
var _callback = function () {
keys.forEach(function (v) {
core.material.images.autotile[v] = autotiles[v];
});
@ -77,13 +85,18 @@ loader.prototype._loadAutotiles = function (callback) {
});
callback();
});
}
if (main.useCompress) {
this.loadImagesFromZip('project/images/autotiles.zip', keys, autotiles, _callback);
} else {
this.loadImages(keys, autotiles, _callback);
}
}
loader.prototype._loadTilesets = function (callback) {
core.material.images.tilesets = {};
core.tilesets = core.tilesets || [];
core.loader.loadImages(core.clone(core.tilesets), core.material.images.tilesets, function () {
var _callback = function () {
// 检查宽高是32倍数如果出错在控制台报错
for (var imgName in core.material.images.tilesets) {
var img = core.material.images.tilesets[imgName];
@ -95,7 +108,12 @@ loader.prototype._loadTilesets = function (callback) {
}
}
callback();
});
}
if (main.useCompress) {
this.loadImagesFromZip('project/images/tilesets.zip', core.tilesets, core.material.images.tilesets, _callback);
} else {
this.loadImages(core.tilesets, core.material.images.tilesets, _callback);
}
}
loader.prototype.loadImages = function (names, toSave, callback) {
@ -122,6 +140,35 @@ loader.prototype.loadImages = function (names, toSave, callback) {
}
}
loader.prototype.loadImagesFromZip = function (url, names, toSave, callback) {
if (!names || names.length == 0) {
if (callback) callback();
return;
}
core.unzip(url + "?v=" + main.version, function (data) {
var cnt = 1;
names.forEach(function (name) {
var imgName = name;
if (imgName.indexOf('.') < 0) imgName += '.png';
if (imgName in data) {
var img = new Image();
var url = URL.createObjectURL(data[imgName]);
cnt++;
img.onload = function () {
cnt--;
URL.revokeObjectURL(url);
if (cnt == 0 && callback) callback();
}
img.src = url;
toSave[name] = img;
}
});
cnt--;
if (cnt == 0 && callback) callback();
});
}
loader.prototype.loadImage = function (imgName, callback) {
try {
var name = imgName;
@ -144,58 +191,74 @@ loader.prototype.loadImage = function (imgName, callback) {
}
loader.prototype._loadAnimates = function () {
core.animates.forEach(function (t) {
core.http('GET', 'project/animates/' + t + ".animate", null, function (content) {
try {
content = JSON.parse(content);
var data = {};
data.ratio = content.ratio;
data.se = content.se;
data.images = [];
data.images_rev = [];
content.bitmaps.forEach(function (t2) {
if (!t2) {
data.images.push(null);
}
else {
try {
var image = new Image();
image.src = t2;
data.images.push(image);
} catch (e) {
main.log(e);
data.images.push(null);
}
}
})
data.frame = content.frame_max;
data.frames = [];
content.frames.forEach(function (t2) {
var info = [];
t2.forEach(function (t3) {
info.push({
'index': t3[0],
'x': t3[1],
'y': t3[2],
'zoom': t3[3],
'opacity': t3[4],
'mirror': t3[5] || 0,
'angle': t3[6] || 0,
})
})
data.frames.push(info);
})
core.material.animates[t] = data;
if (main.useCompress) {
core.unzip('project/animates/animates.zip?v=' + main.version, function (animates) {
for (var name in animates) {
if (name.endsWith(".animate")) {
var t = name.substring(0, name.length - 8);
if (core.animates.indexOf(t) >= 0)
core.loader._loadAnimate(t, animates[name]);
}
}
catch (e) {
}, null, true);
} else {
core.animates.forEach(function (t) {
core.http('GET', 'project/animates/' + t + ".animate?v=" + main.version, null, function (content) {
core.loader._loadAnimate(t, content);
}, function (e) {
main.log(e);
core.material.animates[t] = null;
}, "text/plain; charset=x-user-defined")
})
}
}
loader.prototype._loadAnimate = function (name, content) {
try {
content = JSON.parse(content);
var data = {};
data.ratio = content.ratio;
data.se = content.se;
data.images = [];
data.images_rev = [];
content.bitmaps.forEach(function (t2) {
if (!t2) {
data.images.push(null);
}
}, function (e) {
main.log(e);
core.material.animates[t] = null;
}, "text/plain; charset=x-user-defined")
})
else {
try {
var image = new Image();
image.src = t2;
data.images.push(image);
} catch (e) {
main.log(e);
data.images.push(null);
}
}
})
data.frame = content.frame_max;
data.frames = [];
content.frames.forEach(function (t2) {
var info = [];
t2.forEach(function (t3) {
info.push({
'index': t3[0],
'x': t3[1],
'y': t3[2],
'zoom': t3[3],
'opacity': t3[4],
'mirror': t3[5] || 0,
'angle': t3[6] || 0,
})
})
data.frames.push(info);
})
core.material.animates[name] = data;
}
catch (e) {
main.log(e);
core.material.animates[name] = null;
}
}
////// 加载音频 //////
@ -204,9 +267,19 @@ loader.prototype._loadMusic = function () {
core.loader.loadOneMusic(t);
});
core.sounds.forEach(function (t) {
core.loader.loadOneSound(t);
});
if (main.useCompress && core.musicStatus.audioContext) {
core.unzip('project/sounds/sounds.zip?v=' + main.version, function (data) {
for (var name in data) {
if (core.sounds.indexOf(name) >= 0) {
core.loader._loadOneSound_decodeData(name, data[name]);
}
}
});
} else {
core.sounds.forEach(function (t) {
core.loader.loadOneSound(t);
});
}
// 直接开始播放
core.playBgm(main.startBgm);
}
@ -222,19 +295,8 @@ loader.prototype.loadOneMusic = function (name) {
loader.prototype.loadOneSound = function (name) {
if (core.musicStatus.audioContext != null) {
core.http('GET', 'project/sounds/' + name, null, function (data) {
try {
core.musicStatus.audioContext.decodeAudioData(data, function (buffer) {
core.material.sounds[name] = buffer;
}, function (e) {
main.log(e);
core.material.sounds[name] = null;
})
}
catch (e) {
main.log(e);
core.material.sounds[name] = null;
}
core.http('GET', 'project/sounds/' + name + "?v=" + main.version, null, function (data) {
core.loader._loadOneSound_decodeData(name, data);
}, function (e) {
main.log(e);
core.material.sounds[name] = null;
@ -247,6 +309,30 @@ loader.prototype.loadOneSound = function (name) {
}
}
loader.prototype._loadOneSound_decodeData = function (name, data) {
if (data instanceof Blob) {
var blobReader = new zip.BlobReader(data);
blobReader.init(function () {
blobReader.readUint8Array(0, blobReader.size, function (uint8) {
core.loader._loadOneSound_decodeData(name, uint8.buffer);
})
});
return;
}
try {
core.musicStatus.audioContext.decodeAudioData(data, function (buffer) {
core.material.sounds[name] = buffer;
}, function (e) {
main.log(e);
core.material.sounds[name] = null;
})
}
catch (e) {
main.log(e);
core.material.sounds[name] = null;
}
}
loader.prototype.loadBgm = function (name) {
name = core.getMappedName(name);
if (!core.material.bgms[name]) return;

View File

@ -98,7 +98,7 @@ maps.prototype.initBlock = function (x, y, id, addInfo, eventFloor) {
var block = {'x': x, 'y': y, 'id': id};
if (disable != null) block.disable = disable;
if (id == 17) block.event = {"cls": "terrains", "id": "airwall", "noPass": true};
if (id == 17) block.event = {"cls": "terrains", "id": "airwall", "noPass": true, "cannotIn":["up", "down", "left", "right"]};
else if (id in this.blocksInfo) block.event = JSON.parse(JSON.stringify(this.blocksInfo[id]));
else if (core.icons.getTilesetOffset(id)) block.event = {"cls": "tileset", "id": "X" + id, "noPass": true};
else block.event = {'cls': 'terrains', 'id': 'none', 'noPass': false};
@ -369,7 +369,7 @@ maps.prototype._getBgFgMapArray = function (name, floorId, noCache) {
return core.status[name + "maps"][floorId];
var arr = core.clone(core.floors[floorId][name + "map"] || []);
if (main.mode == 'editor' && !(uievent && uievent.isOpen))
if (main.mode == 'editor' && !(window.editor && editor.uievent && editor.uievent.isOpen))
arr = core.clone(editor[name + "map"]) || arr;
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
@ -2030,13 +2030,7 @@ maps.prototype.drawAnimate = function (name, x, y, callback) {
name = core.getMappedName(name);
// 正在播放录像:不显示动画
if (core.isReplaying()) {
if (callback) callback();
return -1;
}
// 检测动画是否存在
if (!core.material.animates[name] || x == null || y == null) {
if (core.isReplaying() || !core.material.animates[name] || x == null || y == null) {
if (callback) callback();
return -1;
}
@ -2059,6 +2053,33 @@ maps.prototype.drawAnimate = function (name, x, y, callback) {
return id;
}
////// 绘制一个跟随勇士的动画 //////
maps.prototype.drawHeroAnimate = function (name, callback) {
name = core.getMappedName(name);
// 正在播放录像或动画不存在:不显示动画
if (core.isReplaying() || !core.material.animates[name]) {
if (callback) callback();
return -1;
}
// 开始绘制
var animate = core.material.animates[name];
// 播放音效
core.playSound(animate.se);
var id = setTimeout(null);
core.status.animateObjs.push({
"id": id,
"animate": animate,
"hero": true,
"index": 0,
"callback": callback
});
return id;
}
////// 绘制动画的某一帧 //////
maps.prototype._drawAnimateFrame = function (animate, centerX, centerY, index) {
var frame = animate.frames[index];

View File

@ -1,3 +1,238 @@
lzstring
============
MIT License
Copyright (c) 2013 pieroxy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
localforage
============
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2014 Mozilla
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
mid
============
Copyright (c) 2010, Matt Westcott & Ben Firshman
All rights reserved.
@ -21,4 +256,28 @@ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
zip
============
Copyright (c) 2013 Gildas Lormeau. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

2895
libs/thirdparty/zip.js vendored Normal file

File diff suppressed because it is too large Load Diff

1
libs/thirdparty/zip.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -587,7 +587,7 @@ ui.prototype._getTitleAndIcon = function (content) {
////// 正则处理 \b[up,xxx] 问题
ui.prototype._getPosition = function (content) {
var pos = null, px = null, py = null;
var pos = null, px = null, py = null, noPeak = false;
if (core.status.event.id=='action') {
px = core.status.event.data.x;
py = core.status.event.data.y;
@ -614,6 +614,7 @@ ui.prototype._getPosition = function (content) {
} else{
px = parseInt(str[0]);
py = parseInt(str[1]);
noPeak = core.getBlockId(px, py) == null;
}
}
if(pos=='hero' || pos=='null'){
@ -621,7 +622,7 @@ ui.prototype._getPosition = function (content) {
}
return "";
});
return {content: content, position: pos, px: px, py: py};
return {content: content, position: pos, px: px, py: py, noPeak: noPeak};
}
////// 绘制选择光标
@ -719,8 +720,8 @@ ui.prototype.drawWindowSkin = function(background, ctx, x, y, w, h, direction, p
////// 绘制一个背景图,可绘制 winskin 或纯色背景;支持小箭头绘制
ui.prototype.drawBackground = function (left, top, right, bottom, posInfo) {
posInfo = posInfo || {};
var px = posInfo.px == null ? null : posInfo.px * 32 - core.bigmap.offsetX;
var py = posInfo.py == null ? null : posInfo.py * 32 - core.bigmap.offsetY;
var px = posInfo.px == null || posInfo.noPeak ? null : posInfo.px * 32 - core.bigmap.offsetX;
var py = posInfo.py == null || posInfo.noPeak ? null : posInfo.py * 32 - core.bigmap.offsetY;
var xoffset = posInfo.xoffset || 0, yoffset = posInfo.yoffset || 0;
var background = core.status.textAttribute.background;
@ -1114,7 +1115,7 @@ ui.prototype.drawTextBox = function(content, showAll) {
main.dom.next.style.borderRightColor = main.dom.next.style.borderBottomColor = core.arrayToRGB(textAttribute.text);
main.dom.next.style.top = (vPos.bottom - 20) * core.domStyle.scale + "px";
var left = (hPos.left + hPos.right) / 2;
if (pInfo.position == 'up' && pInfo.px != null && Math.abs(pInfo.px * 32 + 16 - left) < 50)
if (pInfo.position == 'up' && !pInfo.noPeak && pInfo.px != null && Math.abs(pInfo.px * 32 + 16 - left) < 50)
left = hPos.right - 64;
main.dom.next.style.left = left * core.domStyle.scale + "px";
return config;
@ -2501,9 +2502,9 @@ ui.prototype._drawSLPanel_loadSave = function(page, callback) {
ids.push(id);
}
core.getSaves(ids, function (data) {
for (var i = 0; i < ids.length; ++i)
for (var i = 1; i < ids.length; ++i)
core.status.event.ui[i] = data[i];
core.saves.autosave.data = data[0];
core.status.event.ui[0] = data[0] == null ? null : data[0][data[0].length-1];
callback();
});
}
@ -2522,6 +2523,10 @@ ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, hi
}, {
ctx: 'ui', x: x-size/2, y: y+15, size: size, centerX: data.hero.loc.x, centerY: data.hero.loc.y
});
if (core.isPlaying() && core.getFlag("hard") != data.hero.flags.hard) {
core.fillRect('ui', x-size/2, y+15, size, size, [0, 0, 0, 0.4], 2);
core.fillText('ui', data.hard, x, parseInt(y+22+size/2), core.dom.hard.style.color, this._buildFont(30,true));
}
var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true);
var v2 = "/"+core.formatBigNumber(data.hero.mdef,true);
if (core.calWidth('ui', v + v2, this._buildFont(10, false)) <= size) v += v2;

View File

@ -1166,6 +1166,54 @@ utils.prototype._export = function (floorIds) {
console.log(content);
}
utils.prototype.unzip = function (blobOrUrl, success, error, convertToText) {
var _error = function (msg) {
main.log(msg);
if (error) error(msg);
}
if (!window.zip) {
return _error("zip.js not exists!");
}
if (typeof blobOrUrl == 'string') {
return core.http('GET', blobOrUrl, null, function (data) {
core.unzip(data, success, error, convertToText);
}, _error, 'application/zip', 'blob');
}
if (!(blobOrUrl instanceof Blob)) {
return _error("Should use Blob or URL as input");
}
zip.createReader(new zip.BlobReader(blobOrUrl), function (reader) {
reader.getEntries(function (entries) {
core.utils._unzip_readEntries(entries, function (data) {
reader.close(function () {
if (success) success(data);
});
}, convertToText);
});
}, _error);
}
utils.prototype._unzip_readEntries = function (entries, success, convertToText) {
var results = {};
if (entries == null) {
return success(results);
}
var length = entries.length;
entries.forEach(function (entry) {
entry.getData(convertToText ? new zip.TextWriter('utf8') : new zip.BlobWriter(), function (data) {
results[entry.filename] = data;
length--;
if (length == 0) {
success(results);
}
});
});
}
utils.prototype.http = function (type, url, formData, success, error, mimeType, responseType) {
var xhr = new XMLHttpRequest();
xhr.open(type, url, true);
@ -1193,6 +1241,12 @@ utils.prototype.http = function (type, url, formData, success, error, mimeType,
else xhr.send();
}
utils.prototype.httpAndZip = function (url, success, error) {
this.http('GET', url, null, function (data) {
}, error, null, 'blob');
}
// LZW-compress
// https://gist.github.com/revolunet/843889
function lzw_encode(s) {

32
main.js
View File

@ -2,7 +2,7 @@ function main() {
//------------------------ 用户修改内容 ------------------------//
this.version = "2.6.5"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.version = "2.6.6"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.useCompress = false; // 是否使用压缩文件
// 当你即将发布你的塔时请使用“JS代码压缩工具”将所有js代码进行压缩然后将这里的useCompress改为true。
@ -189,8 +189,8 @@ function main() {
this.floors = {}
this.canvas = {};
this.__VERSION__ = "2.6.5";
this.__VERSION_CODE__ = 87;
this.__VERSION__ = "2.6.6";
this.__VERSION_CODE__ = 99;
}
main.prototype.init = function (mode, callback) {
@ -426,7 +426,17 @@ main.dom.body.onkeyup = function(e) {
(main.core.isPlaying() || main.core.status.lockControl))
main.core.onkeyUp(e);
} catch (ee) { main.log(ee); }
}
};
[main.dom.startButtons, main.dom.levelChooseButtons].forEach(function (dom) {
dom.onmousemove = function (e) {
for (var i = 0; i < dom.children.length; ++i) {
if (dom.children[i] == e.target && i != (main.selectedButton || 0)) {
main.selectButton(i);
}
}
}
});
////// 开始选择时 //////
main.dom.body.onselectstart = function () {
@ -454,9 +464,12 @@ main.dom.data.onmousemove = function (e) {
}
////// 鼠标放开时 //////
main.dom.data.onmouseup = function () {
main.dom.data.onmouseup = function (e) {
try {
main.core.onup();
e.stopPropagation();
var loc = main.core.actions._getClickLoc(e.clientX, e.clientY);
if (loc == null) return;
main.core.onup(loc);
}catch (e) { main.log(e); }
}
@ -476,6 +489,7 @@ main.dom.data.ontouchstart = function (e) {
e.preventDefault();
var loc = main.core.actions._getClickLoc(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
if (loc == null) return;
main.lastTouchLoc = loc;
main.core.ondown(loc);
}catch (ee) { main.log(ee); }
}
@ -486,6 +500,7 @@ main.dom.data.ontouchmove = function (e) {
e.preventDefault();
var loc = main.core.actions._getClickLoc(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
if (loc == null) return;
main.lastTouchLoc = loc;
main.core.onmove(loc);
}catch (ee) { main.log(ee); }
}
@ -494,7 +509,10 @@ main.dom.data.ontouchmove = function (e) {
main.dom.data.ontouchend = function (e) {
try {
e.preventDefault();
main.core.onup();
if (main.lastTouchLoc == null) return;
var loc = main.lastTouchLoc;
delete main.lastTouchLoc;
main.core.onup(loc);
} catch (e) {
main.log(e);
}

View File

@ -63,8 +63,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"武器",
"盾牌"
],
"startBgm": "bgm.mp3",
"statusLeftBackground": "url(project/images/ground.png) repeat",
"startBgm": null,
"statusLeftBackground": null,
"statusTopBackground": "url(project/images/ground.png) repeat",
"toolsBackground": "url(project/images/ground.png) repeat",
"borderColor": "#CCCCCC",
@ -78,7 +78,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"firstData": {
"title": "魔塔样板",
"name": "template",
"version": "Ver 2.6.5",
"version": "Ver 2.6.6",
"floorId": "sample0",
"hero": {
"name": "阳光",
@ -387,7 +387,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"snowFourDirections": false,
"bigKeyIsBox": false,
"steelDoorWithoutKey": false,
"itemFirstText": true,
"itemFirstText": false,
"equipment": false,
"equipboxButton": false,
"iconInEquipbox": false,

View File

@ -266,7 +266,10 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
if (!(core.material.animates[equipAnimate] || {}).se)
core.playSound('attack.mp3');
// 强制战斗的战斗动画
core.drawAnimate(equipAnimate, x != null ? x : core.getHeroLoc('x'), y != null ? y : core.getHeroLoc('y'));
if (x != null && y != null)
core.drawAnimate(equipAnimate, x, y);
else
core.drawHeroAnimate(equipAnimate);
var damage = core.enemys.getDamage(enemyId, x, y);
if (damage == null) damage = core.status.hero.hp + 1;
@ -1290,8 +1293,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
}
// 如需强行终止行走可以在这里条件判定:
// core.stopAutomaticRoute();
core.updateStatusBar();
},
"moveDirectly": function (x, y, ignoreSteps) {
// 瞬间移动x,y为要瞬间移动的点ignoreSteps为减少的步数可能之前已经被计算过

View File

@ -39,22 +39,22 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"redPotion": {
"cls": "items",
"name": "红血瓶",
"text": "',生命+'+core.values.redPotion"
"text": "',生命+${core.values.redPotion}'"
},
"bluePotion": {
"cls": "items",
"name": "蓝血瓶",
"text": "',生命+'+core.values.bluePotion"
"text": "',生命+${core.values.bluePotion}'"
},
"yellowPotion": {
"cls": "items",
"name": "黄血瓶",
"text": "'生命+'+core.values.yellowPotion"
"text": "',生命+${core.values.yellowPotion'}"
},
"greenPotion": {
"cls": "items",
"name": "绿血瓶",
"text": "',生命+'+core.values.greenPotion"
"text": "',生命+${core.values.greenPotion}'"
},
"sword0": {
"cls": "items",

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,21 @@
HTML5魔塔样板V2.6.5
HTML5魔塔样板V2.6.6
编辑器增加【最近使用的图块】的区域
编辑器拉伸到铺满全屏幕还可以Ctrl+滚轮放缩
编辑器支持连续Ctrl+Z的撤销Ctrl+Y的重做
新增tileset右键绑定宽高以替代贴图模式
多重自动存档可以连续A键读档
等待用户操作增设分歧选项
增设压缩模式会对图片等进行zip压缩
追加素材现在可以同时进行自动注册
可以复制和粘贴怪物或道具的属性
折叠素材时设置每一列个数
标题界面和显示选择项时光标跟随鼠标
修复所有已知的bug大量细节优化
-----------------------------------------------------------------------
HTML5魔塔样板V2.6.5
事件:设置怪物属性;穿脱装备
新值块enemy:xxx:atk可获得怪物数据
@ -13,7 +30,6 @@ NPC48自动注册可以自动绑定faceIds
可以对flags.进行自动补全
部分Bug修复大量细节优化
-----------------------------------------------------------------------
HTML5魔塔样板V2.6.4