Merge branch 'v2.x' of github.com:ckcz123/mota-js into v2.x

This commit is contained in:
ckcz123 2021-09-25 09:45:15 +08:00
commit cd746fd6d9
60 changed files with 2794 additions and 1946 deletions

2
.gitignore vendored
View File

@ -56,3 +56,5 @@ fabric.properties
node_modules node_modules
package-lock.json package-lock.json
_saves

View File

@ -65,6 +65,22 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
## 更新说明 ## 更新说明
### 2021.9.1 HTML5魔塔样板V2.8.2
* [x] 在游戏中,可以在大地图长按后拖动预览。(超大地图福音!)
* [x] 编辑器支持快速选层操作,还可以搜索楼层。
* [x] 离线游戏存档本地化将直接存入本地的_saves目录。
* [x] 支持播放存档剩余录像(接续播放录像的简化版本)。
* [x] 编辑器中自绘状态栏支持直接预览。
* [x] 可以以当前素材为模板追加新素材并修改色调。
* [x] 对话框支持不等待用户操作,从而可做多对话框。
* [x] 事件:设置勇士不透明度;同时移除显示和隐藏勇士事件。
* [x] 在sample2层新增了大怪物使用样例。
* [x] 大幅提升了高层塔加载的加载速度。
* [x] 增加了高清显伤。
* [x] 修复素材区折叠对齐的问题。
* [x] 修复所有已知问题,大量细节优化。
### 2021.8.14 HTML5魔塔样板V2.8.1 ### 2021.8.14 HTML5魔塔样板V2.8.1
* [x] 支持任意尺寸和任意朝向的怪物和NPC素材。 * [x] 支持任意尺寸和任意朝向的怪物和NPC素材。

View File

@ -56,7 +56,6 @@ core.platform
core.platform.isPC (是否是电脑端) core.platform.isPC (是否是电脑端)
core.platform.isAndroid (是否是安卓端) core.platform.isAndroid (是否是安卓端)
core.platform.isIOS 是否是iOS端 core.platform.isIOS 是否是iOS端
core.platform.useLocalForage (是否开启了新版存档)
core.domStyle core.domStyle
@ -318,9 +317,6 @@ status: 只能为 stop, leftFoot 和 rightFoot不填用stop。
offset: 相对主角逻辑位置的偏移量,不填视为无偏移。 offset: 相对主角逻辑位置的偏移量,不填视为无偏移。
frame: 绘制的第几帧 frame: 绘制的第几帧
fillPosWithPoint: fn(pos?: ?)
显示离散的寻路点
gatherFollowers: fn() gatherFollowers: fn()
立刻聚集所有的跟随者 立刻聚集所有的跟随者
@ -611,6 +607,9 @@ noGather: 是否聚集跟随者
setHeroMoveInterval: fn(callback?: fn()) setHeroMoveInterval: fn(callback?: fn())
设置行走的效果动画 设置行走的效果动画
setHeroOpacity: fn(opacity?: number, moveMode?: string, time?: number, callback?: fn())
改变勇士的不透明度
setMusicBtn: fn() setMusicBtn: fn()
设置音乐图标的显隐状态 设置音乐图标的显隐状态
@ -683,9 +682,6 @@ triggerDebuff: fn(action: string, type: string|[string])
action: 要获得还是移除,'get'为获得,'remove'为移除 action: 要获得还是移除,'get'为获得,'remove'为移除
type: 获得或移除的内容poison/weak/curse可以为字符串或数组 type: 获得或移除的内容poison/weak/curse可以为字符串或数组
triggerHero: fn(type?: string, time?: number, callback?: fn())
改变勇士的显隐状态
triggerReplay: fn() triggerReplay: fn()
播放或暂停录像回放 播放或暂停录像回放
@ -1213,6 +1209,9 @@ seed: 随机种子,相同的种子保证了录像的可重复性
route: 经由base64压缩后的录像用于从头开始的录像回放 route: 经由base64压缩后的录像用于从头开始的录像回放
callback: 回调函数,可选 callback: 回调函数,可选
stopAsync: fn()
立刻停止所有正在进行的异步事件
trigger: fn(x?: number, y?: number, callback?: fn()) trigger: fn(x?: number, y?: number, callback?: fn())
触发(x,y)点的系统事件会执行该点图块的script属性同时支持战斗会触发战后、道具会触发道具后、楼层切换等等 触发(x,y)点的系统事件会执行该点图块的script属性同时支持战斗会触发战后、道具会触发道具后、楼层切换等等
callback: 执行完毕的回调函数 callback: 执行完毕的回调函数
@ -1810,9 +1809,9 @@ showFloorImage: fn(loc?: [number]|[[number]], floorId?: string, callback?: fn())
stairExists: fn(x: number, y: number, floorId?: string) -> bool stairExists: fn(x: number, y: number, floorId?: string) -> bool
某个点是否存在楼梯 某个点是否存在楼梯
stopAnimate: fn(id: number, doCallback?: bool) stopAnimate: fn(id?: number, doCallback?: bool)
立刻停止一个动画播放 立刻停止一个动画播放
id: 播放动画的编号即drawAnimate或drawHeroAnimate的返回值 id: 播放动画的编号即drawAnimate或drawHeroAnimate的返回值;不填视为停止所有动画
doCallback: 是否执行该动画的回调函数 doCallback: 是否执行该动画的回调函数
terrainExists: fn(x: number, y: number, id?: string, floorId?: string) -> bool terrainExists: fn(x: number, y: number, id?: string, floorId?: string) -> bool
@ -1999,7 +1998,7 @@ getToolboxItems: fn(cls: string) -> [string]
loadCanvas: fn(name: string|CanvasRenderingContext2D) loadCanvas: fn(name: string|CanvasRenderingContext2D)
加载某个canvas状态 加载某个canvas状态
relocateCanvas: fn(name: string, x: number, y: number) relocateCanvas: fn(name: string, x: number, y: number, useDelta: bool)
重新定位一个自定义画布 重新定位一个自定义画布
resizeCanvas: fn(name: string, x: number, y: number) resizeCanvas: fn(name: string, x: number, y: number)

View File

@ -308,7 +308,7 @@ V2.8.1新增了怪物的大贴图绑定编辑器1:1模式下大贴图会被
4. **额外素材:**`project/tilesets`中的文件名需要后缀只支持png 4. **额外素材:**`project/tilesets`中的文件名需要后缀只支持png
* 注册方法同上,最大的区别在于这个数组的顺序必须保持好。如果随意调换其中的顺序,或注销不在数组末尾的图片,就会导致地图上最终呈现的素材发生错位。因此,新勾选的图片总会被自动追加到数组的末尾。 * 注册方法同上,最大的区别在于这个数组的顺序必须保持好。如果随意调换其中的顺序,或注销不在数组末尾的图片,就会导致地图上最终呈现的素材发生错位。因此,新勾选的图片总会被自动追加到数组的末尾。
* 比起常规素材,额外素材最大的好处有几点: * 比起常规素材,额外素材最大的好处有几点:
1. 图片没有数量限制。常规素材的总数量最多只允许不到一万个,而额外素材每张图片上的图块数量最多允许一千个。 1. 图片没有数量限制。常规素材的总数量最多只允许不到10000个而额外素材每张图片上的图块数量最多允许3000个。
2. 查看和绘制更为方便。常规素材每个图块独占一行,每列为一帧,导致不方便观察,且用多个图块拼图必须逐图块绘制。额外素材都是静止的,所以每个图块只占一格,多个图块可以在准备素材时就直接以相邻的样子绘制在同一张图片上,绘制地图时直接从素材区拖动来批量框选,再在地图区单击成片绘制或拖动平铺。 2. 查看和绘制更为方便。常规素材每个图块独占一行,每列为一帧,导致不方便观察,且用多个图块拼图必须逐图块绘制。额外素材都是静止的,所以每个图块只占一格,多个图块可以在准备素材时就直接以相邻的样子绘制在同一张图片上,绘制地图时直接从素材区拖动来批量框选,再在地图区单击成片绘制或拖动平铺。
3. 批量替换也更为方便。譬如您如果想制作形如“一场大战/天灾过后/多年以后,村庄/城镇化为了一片废墟”的效果,可以预先准备两张甚至更多张相同规格的额外素材图片,然后在适当的时候遍历某个/某些楼层的图块ID将以“X1”开头的图块统一替换为“X2”开头等。发布单机版游戏时您也可以提供多张相同规格的额外素材图片供玩家直接替换皮肤风格。 3. 批量替换也更为方便。譬如您如果想制作形如“一场大战/天灾过后/多年以后,村庄/城镇化为了一片废墟”的效果,可以预先准备两张甚至更多张相同规格的额外素材图片,然后在适当的时候遍历某个/某些楼层的图块ID将以“X1”开头的图块统一替换为“X2”开头等。发布单机版游戏时您也可以提供多张相同规格的额外素材图片供玩家直接替换皮肤风格。
5. **使用动画:**`project/animates`文件夹中的文件名(不含后缀,请注意与`animates.png`相区分)。 5. **使用动画:**`project/animates`文件夹中的文件名(不含后缀,请注意与`animates.png`相区分)。

View File

@ -581,8 +581,8 @@ core.insertAction({"type": "changeFloor", "floorId": "MT" + core.rand2(20)})
* V2.8.1起,支持暂时锁定视角,视角锁定期间,只有上下楼后才会将视角重置到勇士身上(但依然保持锁定)。 * V2.8.1起,支持暂时锁定视角,视角锁定期间,只有上下楼后才会将视角重置到勇士身上(但依然保持锁定)。
4. **显隐状态栏:**如题,如果隐藏状态栏期间勇士需要恢复行动,则建议不隐藏竖屏工具栏以方便手机玩家。 4. **显隐状态栏:**如题,如果隐藏状态栏期间勇士需要恢复行动,则建议不隐藏竖屏工具栏以方便手机玩家。
* 实际调用`core.showStatusBar()`和`core.hideStatusBar(showToolbox)` * 实际调用`core.showStatusBar()`和`core.hideStatusBar(showToolbox)`
5. **显隐勇士**如题,动画时间为淡入淡出时间,异步勾选框用法如前。 5. **设置勇士不透明度**如题,动画时间为淡入淡出时间,异步勾选框用法如前。
* 实际调用`core.triggerHero(type, time, callback)` * 实际调用`core.setHeroOpacity(opacity, moveMode, time, callback)`
6. **更改画面色调:**色调可以用调色器调配,“动画时间”为渐变的总时间。 6. **更改画面色调:**色调可以用调色器调配,“动画时间”为渐变的总时间。
* 请注意渐变是在RGBA颜色空间中直线运动V2.8.1支持加速度),因此效果可能不好,画面闪烁同理。 * 请注意渐变是在RGBA颜色空间中直线运动V2.8.1支持加速度),因此效果可能不好,画面闪烁同理。
* 如需在勇士自由行动时反复执行,请使用并行脚本或自我回调。 * 如需在勇士自由行动时反复执行,请使用并行脚本或自我回调。

View File

@ -215,7 +215,7 @@ function () {
``` ```
registerAction: fn(action: string, name: string, func: string|fn(params: ?), priority?: number) registerAction: fn(action: string, name: string, func: string|fn(params: ?), priority?: number)
此函数将注册一个用户交互行为。 此函数将注册一个用户交互行为。
action: 要注册的交互类型,如 ondown, onclick, keyDown 等等。 action: 要注册的交互类型,如 ondown, onup, keyDown 等等。
name: 你的自定义名称,可被注销使用;同名重复注册将后者覆盖前者。 name: 你的自定义名称,可被注销使用;同名重复注册将后者覆盖前者。
func: 执行函数。 func: 执行函数。
如果func返回true则不会再继续执行其他的交互函数否则会继续执行其他的交互函数。 如果func返回true则不会再继续执行其他的交互函数否则会继续执行其他的交互函数。
@ -228,8 +228,8 @@ priority: 优先级;优先级高的将会被执行。此项可不填,默认
```js ```js
// 当flag:abc是true时点击屏幕左上角可以使用道具破墙镐 // 当flag:abc是true时点击屏幕左上角可以使用道具破墙镐
// 注入一个 onclick 事件,名称为 my_pickaxe // 注入一个 ondown 事件,名称为 my_pickaxe
core.registerAction('onclick', 'my_pickaxe', function (x, y, px, py) { core.registerAction('ondown', 'my_pickaxe', function (x, y, px, py) {
// 如果当前正在执行某个事件,则忽略之。 // 如果当前正在执行某个事件,则忽略之。
if (core.status.lockControl) return false; if (core.status.lockControl) return false;
// 如果勇士正在行走中,则忽略之。 // 如果勇士正在行走中,则忽略之。
@ -251,7 +251,7 @@ core.registerAction('onclick', 'my_pickaxe', function (x, y, px, py) {
}, 100); }, 100);
// 当你不再需要上述监听时,可以通过下面这一句取消注入。 // 当你不再需要上述监听时,可以通过下面这一句取消注入。
// core.unregisterActon('onclick', 'my_pickaxe'); // core.unregisterActon('ondown', 'my_pickaxe');
``` ```
下面是另一个例子: 下面是另一个例子:
@ -339,12 +339,8 @@ core.registerAction('longClick', 'my_shop', '_my_shop_longClick', 100);
- 如果是触摸屏,则只有手指按下滑动时才会触发`onmove`(并不存在什么悬浮的说法)。 - 如果是触摸屏,则只有手指按下滑动时才会触发`onmove`(并不存在什么悬浮的说法)。
- `onup`: 当屏幕被鼠标或手指放开时 - `onup`: 当屏幕被鼠标或手指放开时
- 对应的函数参数:`function (x, y, px, py)`,为此时放开时的格子坐标和像素坐标。 - 对应的函数参数:`function (x, y, px, py)`,为此时放开时的格子坐标和像素坐标。
- `onclick`: 当屏幕被鼠标或手机点击时 - `onclick` 【已废弃】
- 对应的函数参数:`function (x, y, px, py, stepPostfix)`,为此时点击的格子坐标、像素坐标,和拖动路径 - 从V2.8.2起,此交互已被废弃,注册一个`onclick`会被直接转发至`ondown`。
- 此函数会在两种情况下被调用:
- 在锁定状态下(即角色不可以自由移动),会在`ondown`时直接触发`onclick`,此时`stepPostfix`为空数组。
- 在自由状态下(即角色可以自由移动),会在`onup`时触发`onclick`;此时`stepPostfix`为拖动寻路的路径数组。
- 推荐自定义的点击监听都使用`ondown`处理。
- `onmousewheel`: 当鼠标滚轮滚动时 - `onmousewheel`: 当鼠标滚轮滚动时
- 对应的函数参数:`function (direct)`,为此时滚轮方向。向下滚动是-1向上滚动是1。 - 对应的函数参数:`function (direct)`,为此时滚轮方向。向下滚动是-1向上滚动是1。
- 目前在楼传、怪物手册、存读档、浏览地图等多个地方绑定了鼠标滚轮事件。 - 目前在楼传、怪物手册、存读档、浏览地图等多个地方绑定了鼠标滚轮事件。

View File

@ -1824,7 +1824,6 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"isPC": "bool", "isPC": "bool",
"isAndroid": "bool", "isAndroid": "bool",
"isIOS": "bool", "isIOS": "bool",
"useLocalForage": "bool"
}, },
"domStyle": { "domStyle": {
"!doc": "界面样式", "!doc": "界面样式",
@ -2240,9 +2239,9 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!doc": "半自动寻路,用于鼠标或手指拖动<br/>例如core.setAutomaticRoute(0, 0, [{direction: \"right\", x: 4, y: 9}, {direction: \"right\", x: 5, y: 9}]);<br/>destX: 鼠标或手指的起拖点横坐标<br/>destY: 鼠标或手指的起拖点纵坐标<br/>stepPostfix: 拖动轨迹的数组表示,每项为一步的方向和目标点。", "!doc": "半自动寻路,用于鼠标或手指拖动<br/>例如core.setAutomaticRoute(0, 0, [{direction: \"right\", x: 4, y: 9}, {direction: \"right\", x: 5, y: 9}]);<br/>destX: 鼠标或手指的起拖点横坐标<br/>destY: 鼠标或手指的起拖点纵坐标<br/>stepPostfix: 拖动轨迹的数组表示,每项为一步的方向和目标点。",
"!type": "fn(destX: number, destY: number, stepPostfix: [{x: number, y: number, direction: string}])" "!type": "fn(destX: number, destY: number, stepPostfix: [{x: number, y: number, direction: string}])"
}, },
"triggerHero": { "setHeroOpacity": {
"!doc": "改变勇士的显隐状态", "!doc": "改变勇士的不透明度",
"!type": "fn(type?: string, time?: number, callback?: fn())" "!type": "fn(opacity?: number, moveMode?: string, time?: number, callback?: fn())"
}, },
"gatherFollowers": { "gatherFollowers": {
"!doc": "立刻聚集所有的跟随者", "!doc": "立刻聚集所有的跟随者",
@ -2344,10 +2343,6 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!doc": "连续行走<br/>例如core.setAutoHeroMove([{direction: \"up\", step: 1}, {direction: \"left\", step: 3}]); // 上左左左<br/>steps: 压缩的步伐数组,每项表示朝某方向走多少步", "!doc": "连续行走<br/>例如core.setAutoHeroMove([{direction: \"up\", step: 1}, {direction: \"left\", step: 3}]); // 上左左左<br/>steps: 压缩的步伐数组,每项表示朝某方向走多少步",
"!type": "fn(steps: [?])" "!type": "fn(steps: [?])"
}, },
"fillPosWithPoint": {
"!doc": "显示离散的寻路点",
"!type": "fn(pos?: ?)"
},
"unregisterResize": { "unregisterResize": {
"!doc": "注销一个resize函数", "!doc": "注销一个resize函数",
"!type": "fn(name: string)" "!type": "fn(name: string)"
@ -3086,8 +3081,8 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!type": "fn(name: string, callback?: fn()) -> number" "!type": "fn(name: string, callback?: fn()) -> number"
}, },
"stopAnimate": { "stopAnimate": {
"!doc": "立刻停止一个动画播放<br/>id: 播放动画的编号即drawAnimate或drawHeroAnimate的返回值<br/>doCallback: 是否执行该动画的回调函数", "!doc": "立刻停止一个动画播放<br/>id: 播放动画的编号即drawAnimate或drawHeroAnimate的返回值;不填视为所有动画br/>doCallback: 是否执行该动画的回调函数",
"!type": "fn(id: number, doCallback?: bool)" "!type": "fn(id?: number, doCallback?: bool)"
}, },
"getPlayingAnimates": { "getPlayingAnimates": {
"!doc": "获得当前正在播放的所有指定动画的id列表<br/>name: 动画名;不填代表返回全部正在播放的动画<br/>返回值: 一个数组每一项为一个正在播放的动画可用core.stopAnimate停止播放。", "!doc": "获得当前正在播放的所有指定动画的id列表<br/>name: 动画名;不填代表返回全部正在播放的动画<br/>返回值: 一个数组每一项为一个正在播放的动画可用core.stopAnimate停止播放。",
@ -3525,7 +3520,7 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
}, },
"relocateCanvas": { "relocateCanvas": {
"!doc": "重新定位一个自定义画布", "!doc": "重新定位一个自定义画布",
"!type": "fn(name: string, x: number, y: number)" "!type": "fn(name: string, x: number, y: number, useDelta: bool)"
}, },
"rotateCanvas": { "rotateCanvas": {
"!doc": "设置一个自定义画布的旋转角度<br/>centerX, centerY: 旋转中心(以屏幕像素为基准);不填视为图片正中心。", "!doc": "设置一个自定义画布的旋转角度<br/>centerX, centerY: 旋转中心(以屏幕像素为基准);不填视为图片正中心。",
@ -3840,6 +3835,10 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!doc": "当前是否有未处理完毕的异步事件(不包含动画和音效)", "!doc": "当前是否有未处理完毕的异步事件(不包含动画和音效)",
"!type": "fn() -> bool" "!type": "fn() -> bool"
}, },
"stopAsync": {
"!doc": "立刻停止所有正在进行的异步事件",
"!type": "fn()"
},
"openEquipbox": { "openEquipbox": {
"!doc": "点击装备栏时的打开操作", "!doc": "点击装备栏时的打开操作",
"!type": "fn(fromUserAction?: bool)" "!type": "fn(fromUserAction?: bool)"

View File

@ -636,8 +636,8 @@ return '{' + [
mainStyle_m mainStyle_m
: '主要样式设置:' '标题界面背景图554x422' EvalString BGNL? Newline : '主要样式设置:' '标题界面背景图:' EvalString BGNL? Newline
'竖屏标题界面背景图422x580' EvalString BGNL? Newline '竖屏标题界面背景图' EvalString BGNL? Newline
'标题样式;可写 display: none 隐藏标题' EvalString BGNL? Newline '标题样式;可写 display: none 隐藏标题' EvalString BGNL? Newline
'标题按钮样式:' EvalString BGNL? Newline '标题按钮样式:' EvalString BGNL? Newline
'横屏状态栏背景url(...) 0 0/100% 100% no-repeat 可将图片拉伸自适配' BGNL? Newline EvalString BGNL? Newline '横屏状态栏背景url(...) 0 0/100% 100% no-repeat 可将图片拉伸自适配' BGNL? Newline EvalString BGNL? Newline
@ -847,11 +847,11 @@ action
| update_s | update_s
| showStatusBar_s | showStatusBar_s
| hideStatusBar_s | hideStatusBar_s
| showHero_s | setHeroOpacity_s
| hideHero_s
| sleep_s | sleep_s
| wait_s | wait_s
| waitAsync_s | waitAsync_s
| stopAsync_s
| battle_s | battle_s
| battle_1_s | battle_1_s
| openDoor_s | openDoor_s
@ -870,6 +870,7 @@ action
| unfollow_s | unfollow_s
| animate_s | animate_s
| animate_1_s | animate_1_s
| stopAnimate_s
| vibrate_s | vibrate_s
| showImage_s | showImage_s
| showImage_1_s | showImage_1_s
@ -969,7 +970,7 @@ return code+',\n';
*/; */;
text_1_s text_1_s
: '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '起点像素 px' PosString? 'py' PosString? '宽' PosString? '对话框编号' Int BGNL? Newline EvalString_Multi Newline : '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '起点 px' PosString? 'py' PosString? '宽' PosString? '编号' Int '不等待操作' Bool BGNL? Newline EvalString_Multi Newline
/* text_1_s /* text_1_s
@ -977,7 +978,7 @@ tooltip : text显示一段文字剧情,选项较多请右键点击帮
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
previewBlock : true previewBlock : true
allIds : ['EvalString_1'] allIds : ['EvalString_1']
default : ["小妖精","fairy","","","","",0,"欢迎使用事件编辑器(双击方块可直接预览)"] default : ["小妖精","fairy","","","","",0,false,"欢迎使用事件编辑器(双击方块可直接预览)"]
var title=''; var title='';
if (EvalString_0==''){ if (EvalString_0==''){
if (EvalString_1=='' )title=''; if (EvalString_1=='' )title='';
@ -998,10 +999,11 @@ if(EvalString_2 && !(/^(up|center|down|hero|this)(,(hero|null|\d+,\d+|\d+))?$/.t
} }
EvalString_2 = EvalString_2 && ('\\b['+EvalString_2+']'); EvalString_2 = EvalString_2 && ('\\b['+EvalString_2+']');
var code = '"'+title+EvalString_2+EvalString_Multi_0+'"'; var code = '"'+title+EvalString_2+EvalString_Multi_0+'"';
if (block.isCollapsed() || !block.isEnabled() || pos || Int_0) { if (block.isCollapsed() || !block.isEnabled() || pos || Int_0 || Bool_0) {
code = '{"type": "text", "text": '+code; code = '{"type": "text", "text": '+code;
if (pos) code += ', "pos": ' + pos; if (pos) code += ', "pos": ' + pos;
if (Int_0) code += ', "code": ' + Int_0; if (Int_0) code += ', "code": ' + Int_0;
if (Bool_0) code += ', "async": true';
if (block.isCollapsed()) code += ', "_collapsed": true'; if (block.isCollapsed()) code += ', "_collapsed": true';
if (!block.isEnabled()) code += ', "_disabled": true'; if (!block.isEnabled()) code += ', "_disabled": true';
code += '}'; code += '}';
@ -1010,7 +1012,7 @@ return code+',\n';
*/; */;
text_2_s text_2_s
: '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '起点像素 px' PosString? 'py' PosString? '宽' PosString? '对话框编号' Int BGNL? Newline EvalString_Multi BGNL? Newline textDrawingList* Newline : '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '起点 px' PosString? 'py' PosString? '宽' PosString? '编号' Int '不等待操作' Bool BGNL? Newline EvalString_Multi BGNL? Newline textDrawingList* Newline
/* text_2_s /* text_2_s
@ -1039,10 +1041,11 @@ if(EvalString_2 && !(/^(up|center|down|hero|this)(,(hero|null|\d+,\d+|\d+))?$/.t
} }
EvalString_2 = EvalString_2 && ('\\b['+EvalString_2+']'); EvalString_2 = EvalString_2 && ('\\b['+EvalString_2+']');
var code = '"'+title+EvalString_2+textDrawingList_0.replace(/\s/g, '')+EvalString_Multi_0+'"'; var code = '"'+title+EvalString_2+textDrawingList_0.replace(/\s/g, '')+EvalString_Multi_0+'"';
if (block.isCollapsed() || !block.isEnabled() || pos || Int_0) { if (block.isCollapsed() || !block.isEnabled() || pos || Int_0 || Bool_0) {
code = '{"type": "text", "text": '+code; code = '{"type": "text", "text": '+code;
if (pos) code += ', "pos": ' + pos; if (pos) code += ', "pos": ' + pos;
if (Int_0) code += ', "code": ' + Int_0; if (Int_0) code += ', "code": ' + Int_0;
if (Bool_0) code += ', "async": true';
if (block.isCollapsed()) code += ', "_collapsed": true'; if (block.isCollapsed()) code += ', "_collapsed": true';
if (!block.isEnabled()) code += ', "_disabled": true'; if (!block.isEnabled()) code += ', "_disabled": true';
code += '}'; code += '}';
@ -1255,19 +1258,20 @@ return code;
setEnemy_s setEnemy_s
: '设置怪物属性' ':' '怪物ID' IdString '的' EnemyId_List AssignOperator_List expression Newline : '设置怪物属性' ':' '怪物ID' IdString '的' EnemyId_List AssignOperator_List expression '不刷新显伤' Bool Newline
/* setEnemy_s /* setEnemy_s
tooltip : setEnemy设置某个怪物的属性 tooltip : setEnemy设置某个怪物的属性
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
default : ["greenSlime", "atk", "="] default : ["greenSlime", "atk", "=", "", false]
allEnemys : ['IdString_0'] allEnemys : ['IdString_0']
colour : this.dataColor colour : this.dataColor
if (AssignOperator_List_0 && AssignOperator_List_0 != '=') { if (AssignOperator_List_0 && AssignOperator_List_0 != '=') {
AssignOperator_List_0 = ', "operator": "' + AssignOperator_List_0 + '"'; AssignOperator_List_0 = ', "operator": "' + AssignOperator_List_0 + '"';
} else AssignOperator_List_0 = ''; } else AssignOperator_List_0 = '';
var code = '{"type": "setEnemy", "id": "'+IdString_0+'", "name": "'+EnemyId_List_0+'"'+AssignOperator_List_0+', "value": "'+expression_0+'"},\n'; Bool_0 = Bool_0 ? ', "norefresh": true' : '';
var code = '{"type": "setEnemy", "id": "'+IdString_0+'", "name": "'+EnemyId_List_0+'"'+AssignOperator_List_0+', "value": "'+expression_0+'"'+Bool_0+'},\n';
return code; return code;
*/; */;
@ -1292,13 +1296,13 @@ return code;
setEnemyOnPoint_s setEnemyOnPoint_s
: '设置某点怪物属性' ':' 'x' EvalString? ',' 'y' EvalString? '楼层' IdString? '的' EnemyPoint_List AssignOperator_List expression Newline : '设置某点怪物属性' ':' 'x' EvalString? ',' 'y' EvalString? '楼层' IdString? '的' EnemyPoint_List AssignOperator_List expression '不刷新显伤' Bool Newline
/* setEnemyOnPoint_s /* setEnemyOnPoint_s
tooltip : setEnemyOnPoint设置某个点上怪物的属性 tooltip : setEnemyOnPoint设置某个点上怪物的属性
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
default : ["", "", "", "atk", "="] default : ["", "", "", "atk", "=", "", false]
selectPoint : ["EvalString_0", "EvalString_1", "IdString_0"] selectPoint : ["EvalString_0", "EvalString_1", "IdString_0"]
allFloorIds : ['IdString_0'] allFloorIds : ['IdString_0']
colour : this.dataColor colour : this.dataColor
@ -1307,35 +1311,37 @@ if (AssignOperator_List_0 && AssignOperator_List_0 != '=') {
AssignOperator_List_0 = ', "operator": "' + AssignOperator_List_0 + '"'; AssignOperator_List_0 = ', "operator": "' + AssignOperator_List_0 + '"';
} else AssignOperator_List_0 = ''; } else AssignOperator_List_0 = '';
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"'); IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
var code = '{"type": "setEnemyOnPoint"'+floorstr+IdString_0+', "name": "'+EnemyPoint_List_0+'"'+AssignOperator_List_0+', "value": "'+expression_0+'"},\n'; Bool_0 = Bool_0 ? ', "norefresh": true' : '';
var code = '{"type": "setEnemyOnPoint"'+floorstr+IdString_0+', "name": "'+EnemyPoint_List_0+'"'+AssignOperator_List_0+', "value": "'+expression_0+'"'+Bool_0+'},\n';
return code; return code;
*/; */;
resetEnemyOnPoint_s resetEnemyOnPoint_s
: '重置某点怪物属性' ':' 'x' EvalString? ',' 'y' EvalString? '楼层' IdString? Newline : '重置某点怪物属性' ':' 'x' EvalString? ',' 'y' EvalString? '楼层' IdString? '不刷新显伤' Bool Newline
/* resetEnemyOnPoint_s /* resetEnemyOnPoint_s
tooltip : resetEnemyOnPoint重置某个点上怪物的属性 tooltip : resetEnemyOnPoint重置某个点上怪物的属性
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
default : ["", "", ""] default : ["", "", "", false]
selectPoint : ["EvalString_0", "EvalString_1", "IdString_0"] selectPoint : ["EvalString_0", "EvalString_1", "IdString_0"]
allFloorIds : ['IdString_0'] allFloorIds : ['IdString_0']
colour : this.dataColor colour : this.dataColor
var floorstr = MotaActionFunctions.processMultiLoc(EvalString_0, EvalString_1); var floorstr = MotaActionFunctions.processMultiLoc(EvalString_0, EvalString_1);
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"'); IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
var code = '{"type": "resetEnemyOnPoint"'+floorstr+IdString_0+'},\n'; Bool_0 = Bool_0 ? ', "norefresh": true' : '';
var code = '{"type": "resetEnemyOnPoint"'+floorstr+IdString_0+Bool_0+'},\n';
return code; return code;
*/; */;
moveEnemyOnPoint_s moveEnemyOnPoint_s
: '移动某点怪物属性' ':' '起点' 'x' PosString? ',' 'y' PosString? '终点' 'x' PosString? 'y' PosString? '楼层' IdString? Newline : '移动某点怪物属性' ':' '起点' 'x' PosString? ',' 'y' PosString? '终点' 'x' PosString? 'y' PosString? '楼层' IdString? '不刷新显伤' Bool Newline
/* moveEnemyOnPoint_s /* moveEnemyOnPoint_s
tooltip : moveEnemyOnPoint移动某个点上怪物的属性到其他点 tooltip : moveEnemyOnPoint移动某个点上怪物的属性到其他点
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
default : ["", "", "", "", ""] default : ["", "", "", "", "", false]
allFloorIds : ['IdString_0'] allFloorIds : ['IdString_0']
selectPoint : ["PosString_2", "PosString_3"] selectPoint : ["PosString_2", "PosString_3"]
menu : [['选择起点位置','editor_blockly.selectPoint(block,["PosString_0", "PosString_1"])']] menu : [['选择起点位置','editor_blockly.selectPoint(block,["PosString_0", "PosString_1"])']]
@ -1343,25 +1349,27 @@ colour : this.dataColor
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"'); IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
var floorstr = PosString_0 && PosString_1 ? ', "from": ['+PosString_0+','+PosString_1+']' : ''; var floorstr = PosString_0 && PosString_1 ? ', "from": ['+PosString_0+','+PosString_1+']' : '';
if (PosString_2 && PosString_3) floorstr += ', "to": ['+PosString_2+','+PosString_3+']' if (PosString_2 && PosString_3) floorstr += ', "to": ['+PosString_2+','+PosString_3+']'
var code = '{"type": "moveEnemyOnPoint"'+floorstr+IdString_0+'},\n'; Bool_0 = Bool_0 ? ', "norefresh": true' : '';
var code = '{"type": "moveEnemyOnPoint"'+floorstr+IdString_0+Bool_0+'},\n';
return code; return code;
*/; */;
moveEnemyOnPoint_1_s moveEnemyOnPoint_1_s
: '移动某点怪物属性' ':' '起点' 'x' PosString? ',' 'y' PosString? '增量' 'dx' PosString? 'dy' PosString? '楼层' IdString? Newline : '移动某点怪物属性' ':' '起点' 'x' PosString? ',' 'y' PosString? '增量' 'dx' PosString? 'dy' PosString? '楼层' IdString? '不刷新显伤' Bool Newline
/* moveEnemyOnPoint_1_s /* moveEnemyOnPoint_1_s
tooltip : moveEnemyOnPoint移动某个点上怪物的属性到其他点 tooltip : moveEnemyOnPoint移动某个点上怪物的属性到其他点
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
default : ["", "", "", "", ""] default : ["", "", "", "", "", false]
allFloorIds : ['IdString_0'] allFloorIds : ['IdString_0']
selectPoint : ["PosString_0", "PosString_1"] selectPoint : ["PosString_0", "PosString_1"]
colour : this.dataColor colour : this.dataColor
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"'); IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
var floorstr = PosString_0 && PosString_1 ? ', "from": ['+PosString_0+','+PosString_1+']' : ''; var floorstr = PosString_0 && PosString_1 ? ', "from": ['+PosString_0+','+PosString_1+']' : '';
if (PosString_2 && PosString_3) floorstr += ', "dxy": ['+PosString_2+','+PosString_3+']' if (PosString_2 && PosString_3) floorstr += ', "dxy": ['+PosString_2+','+PosString_3+']'
var code = '{"type": "moveEnemyOnPoint"'+floorstr+IdString_0+'},\n'; Bool_0 = Bool_0 ? ', "norefresh": true' : '';
var code = '{"type": "moveEnemyOnPoint"'+floorstr+IdString_0+Bool_0+'},\n';
return code; return code;
*/; */;
@ -1775,33 +1783,19 @@ var code = '{"type": "hideStatusBar"'+Bool_0+'},\n';
return code; return code;
*/; */;
showHero_s setHeroOpacity_s
: '显示勇士' '动画时间' IntString? '不等待执行完毕' Bool Newline : '设置勇士不透明度' Number '渐变方式' MoveMode_List '动画时间' IntString? '不等待执行完毕' Bool Newline
/* setHeroOpacity_s
/* showHero_s tooltip : setHeroOpacity: 设置勇士不透明度
tooltip : showHero: 显示勇士
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
default : ['',false] default : [1,'','',false]
colour : this.soundColor colour : this.soundColor
if (Number_0 < 0 || Number_0 > 1) throw new Error('不透明度需要在0~1之间');
MoveMode_List_0 = (MoveMode_List_0!=='') ? (', "moveMode": "'+MoveMode_List_0+'"'):'';
IntString_0 = IntString_0 && (', "time": ' + IntString_0); IntString_0 = IntString_0 && (', "time": ' + IntString_0);
Bool_0 = Bool_0 ? (', "async": true') : ''; Bool_0 = Bool_0 ? (', "async": true') : '';
var code = '{"type": "showHero"'+IntString_0+Bool_0+'},\n'; var code = '{"type": "setHeroOpacity", "opacity": '+Number_0+MoveMode_List_0+IntString_0+Bool_0+'},\n';
return code;
*/;
hideHero_s
: '隐藏勇士' '动画时间' IntString? '不等待执行完毕' Bool Newline
/* hideHero_s
tooltip : hideHero: 隐藏勇士
helpUrl : /_docs/#/instruction
default : ['',false]
colour : this.soundColor
IntString_0 = IntString_0 && (', "time": ' + IntString_0);
Bool_0 = Bool_0 ? (', "async": true') : '';
var code = '{"type": "hideHero"'+IntString_0+Bool_0+'},\n';
return code; return code;
*/; */;
@ -2055,37 +2049,50 @@ return code;
*/; */;
animate_s animate_s
: '显示动画' IdString '位置' 'x' PosString? 'y' PosString? '相对窗口坐标' Bool '不等待执行完毕' Bool Newline : '显示动画' EvalString '位置' 'x' PosString? 'y' PosString? '相对窗口坐标' Bool '不等待执行完毕' Bool Newline
/* animate_s /* animate_s
tooltip : animate显示动画,位置填hero或者1,2形式的位置,或者不填代表当前事件点 tooltip : animate显示动画,位置填hero或者1,2形式的位置,或者不填代表当前事件点
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
default : ["zone","","",false,false] default : ["zone","","",false,false]
allAnimates : ['IdString_0'] allAnimates : ['EvalString_0']
material : ["./project/animates/", "IdString_0"] material : ["./project/animates/", "EvalString_0"]
menu : [['选择位置', 'editor_blockly.selectPoint(block, ["PosString_0", "PosString_1"])']] menu : [['选择位置', 'editor_blockly.selectPoint(block, ["PosString_0", "PosString_1"])']]
colour : this.soundColor colour : this.soundColor
var loc = PosString_0&&PosString_1?(', "loc": ['+PosString_0+','+PosString_1+']'):''; var loc = PosString_0&&PosString_1?(', "loc": ['+PosString_0+','+PosString_1+']'):'';
Bool_0 = Bool_0?', "alignWindow": true':''; Bool_0 = Bool_0?', "alignWindow": true':'';
Bool_1 = Bool_1?', "async": true':''; Bool_1 = Bool_1?', "async": true':'';
var code = '{"type": "animate", "name": "'+IdString_0+'"'+loc+Bool_0+Bool_1+'},\n'; var code = '{"type": "animate", "name": "'+EvalString_0+'"'+loc+Bool_0+Bool_1+'},\n';
return code; return code;
*/; */;
animate_1_s animate_1_s
: '显示动画并跟随角色' IdString '不等待执行完毕' Bool Newline : '显示动画并跟随角色' EvalString '不等待执行完毕' Bool Newline
/* animate_1_s /* animate_1_s
tooltip : animate显示动画并跟随角色 tooltip : animate显示动画并跟随角色
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
default : ["zone",false] default : ["zone",false]
allAnimates : ['IdString_0'] allAnimates : ['EvalString_0']
material : ["./project/animates/", "IdString_0"] material : ["./project/animates/", "EvalString_0"]
colour : this.soundColor colour : this.soundColor
Bool_0 = Bool_0?', "async": true':''; Bool_0 = Bool_0?', "async": true':'';
var code = '{"type": "animate", "name": "'+IdString_0+'", "loc": "hero"'+Bool_0+'},\n'; var code = '{"type": "animate", "name": "'+EvalString_0+'", "loc": "hero"'+Bool_0+'},\n';
return code;
*/;
stopAnimate_s
: '停止所有动画' '执行动画回调' Bool Newline
/* stopAnimate_s
tooltip : stopAnimate停止所有动画
helpUrl : /_docs/#/instruction
default : [false]
colour : this.soundColor
Bool_0 = Bool_0?', "doCallback": true':'';
var code = '{"type": "stopAnimate"'+Bool_0+'},\n';
return code; return code;
*/; */;
@ -2804,7 +2811,7 @@ choices_s
tooltip : choices: 给用户提供选项 tooltip : choices: 给用户提供选项
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
previewBlock : true previewBlock : true
default : ["","流浪者","trader",0,0,''] default : ["","流浪者","trader",0,'']
allIds : ['IdString_0'] allIds : ['IdString_0']
var title=''; var title='';
if (EvalString_0==''){ if (EvalString_0==''){
@ -3072,6 +3079,19 @@ return code;
*/; */;
stopAsync_s
: '立刻结束所有异步事件' BGNL Newline
/* stopAsync_s
tooltip : stopAsync: 立刻结束所有异步事件
helpUrl : /_docs/#/instruction
colour : this.soundColor
var code = '{"type": "stopAsync"},\n';
return code;
*/;
callBook_s callBook_s
: '呼出怪物手册' : '呼出怪物手册'
@ -4034,8 +4054,8 @@ EquipValueType_List
/*EquipValueType_List ['value','percentage']*/; /*EquipValueType_List ['value','percentage']*/;
Vibrate_List Vibrate_List
: '左右'|'上下'|'左上-右下'|'左下-右上' : '左右'|'上下'|'左上-右下'|'左下-右上'|'随机'
/*Vibrate_List ['horizontal','vertical','diagonal1','diagonal2']*/; /*Vibrate_List ['horizontal','vertical','diagonal1','diagonal2','random']*/;
Colour Colour
: 'sdeirughvuiyasdeb'+ //为了被识别为复杂词法规则 : 'sdeirughvuiyasdeb'+ //为了被识别为复杂词法规则
@ -4070,8 +4090,8 @@ Direction_List
/*Direction_List ['up','down','left','right']*/; /*Direction_List ['up','down','left','right']*/;
DirectionEx_List DirectionEx_List
: '不变'|'朝上'|'朝下'|'朝左'|'朝右'|'左转'|'右转'|'背对' : '不变'|'朝上'|'朝下'|'朝左'|'朝右'|'左转'|'右转'|'背对'|'角色同向'|'角色反向'
/*DirectionEx_List ['null','up','down','left','right',':left',':right',':back']*/; /*DirectionEx_List ['null','up','down','left','right',':left',':right',':back',':hero',':backhero']*/;
StepString StepString
: (Direction_List Int?)+ : (Direction_List Int?)+
@ -4110,12 +4130,12 @@ Move_List
/*Move_List ['up','down','left','right','forward','backward','leftup','leftdown','rightup','rightdown','speed']*/; /*Move_List ['up','down','left','right','forward','backward','leftup','leftdown','rightup','rightdown','speed']*/;
MoveMode_List MoveMode_List
: '匀速移动'|'缓入快出'|'快入缓出'|'缓入缓出' : '匀速移动'|'缓入快出'|'快入缓出'|'缓入缓出'|'随机'
/*MoveMode_List ['', 'easeIn', 'easeOut', 'easeInOut']*/; /*MoveMode_List ['', 'easeIn', 'easeOut', 'easeInOut', 'random']*/;
NameMap_List NameMap_List
: '确定'|'取消'|'操作失败'|'光标移动'|'打开界面'|'读档'|'存档'|'获得道具'|'回血'|'宝石'|'炸弹'|'飞行器'|'开关门'|'上下楼'|'跳跃'|'破墙镐'|'破冰镐'|'阻激夹域'|'穿脱装备'|'商店' : '确定'|'取消'|'操作失败'|'光标移动'|'打开界面'|'读档'|'存档'|'获得道具'|'回血'|'宝石'|'炸弹'|'飞行器'|'开关门'|'上下楼'|'跳跃'|'破墙镐'|'破冰镐'|'阻激夹域'|'穿脱装备'|'商店'
/*NameMap_List ['确定','取消','操作失败','光标移动','打开界面','读档','存档','获得道具','回血','宝石','炸弹','飞行器','开关门','上下楼','跳跃','破墙镐','破冰稿','阻激夹域','穿脱装备','商店']*/; /*NameMap_List ['确定','取消','操作失败','光标移动','打开界面','读档','存档','获得道具','回血','宝石','炸弹','飞行器','开关门','上下楼','跳跃','破墙镐','破冰','阻激夹域','穿脱装备','商店']*/;
//转blockly后不保留需要加" //转blockly后不保留需要加"
EvalString EvalString

View File

@ -292,12 +292,12 @@ ActionParser.prototype.parseAction = function() {
} }
data.pos = data.pos || []; data.pos = data.pos || [];
this.next = MotaActionFunctions.xmlText('text_2_s', [ this.next = MotaActionFunctions.xmlText('text_2_s', [
info[0], info[1], info[2], data.pos[0], data.pos[1], data.pos[2], data.code||0, info[3], buildTextDrawing(textDrawing), this.next info[0], info[1], info[2], data.pos[0], data.pos[1], data.pos[2], data.code||0, data.async||false, info[3], buildTextDrawing(textDrawing), this.next
], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled); ], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled);
} else if (info[0] || info[1] || info[2] || data.pos || data.code) { } else if (info[0] || info[1] || info[2] || data.pos || data.code) {
data.pos = data.pos || []; data.pos = data.pos || [];
this.next = MotaActionFunctions.xmlText('text_1_s',[ this.next = MotaActionFunctions.xmlText('text_1_s',[
info[0], info[1], info[2], data.pos[0], data.pos[1], data.pos[2], data.code||0, info[3], this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled); info[0], info[1], info[2], data.pos[0], data.pos[1], data.pos[2], data.code||0, data.async||false, info[3], this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled);
} }
else { else {
this.next = MotaActionFunctions.xmlText('text_0_s', [info[3],this.next], this.next = MotaActionFunctions.xmlText('text_0_s', [info[3],this.next],
@ -322,7 +322,7 @@ ActionParser.prototype.parseAction = function() {
data.time, data.lineHeight||1.4, data.async||false, this.EvalString_Multi(data.text), this.next]); data.time, data.lineHeight||1.4, data.async||false, this.EvalString_Multi(data.text), this.next]);
break; break;
case "comment": // 注释 case "comment": // 注释
this.next = MotaActionBlocks['comment_s'].xmlText([this.EvalString_Multi(data.text),this.next],null,data.text); this.next = MotaActionBlocks['comment_s'].xmlText([this.EvalString_Multi(data.text),this.next]);
break; break;
case "setText": // 设置剧情文本的属性 case "setText": // 设置剧情文本的属性
data.title=this.Colour(data.title); data.title=this.Colour(data.title);
@ -559,6 +559,9 @@ ActionParser.prototype.parseAction = function() {
data.name,data.loc[0],data.loc[1],data.alignWindow||false,data.async||false,this.next]); data.name,data.loc[0],data.loc[1],data.alignWindow||false,data.async||false,this.next]);
} }
break; break;
case "stopAnimate": // 停止所有动画
this.next = MotaActionBlocks['stopAnimate_s'].xmlText([data.doCallback||false,this.next]);
break;
case "setViewport": // 设置视角 case "setViewport": // 设置视角
if (data.dxy) { if (data.dxy) {
this.next = MotaActionBlocks['setViewport_1_s'].xmlText([ this.next = MotaActionBlocks['setViewport_1_s'].xmlText([
@ -750,7 +753,8 @@ ActionParser.prototype.parseAction = function() {
break; break;
case "setEnemy": case "setEnemy":
this.next = MotaActionBlocks['setEnemy_s'].xmlText([ this.next = MotaActionBlocks['setEnemy_s'].xmlText([
MotaActionFunctions.replaceToName_token(data.id), data.name, data["operator"]||'=', this.expandEvalBlock([data.value]), this.next]); MotaActionFunctions.replaceToName_token(data.id), data.name, data["operator"]||'=', this.expandEvalBlock([data.value]),
data.norefresh||false, this.next]);
break; break;
case "setEnemyOnPoint": case "setEnemyOnPoint":
data.loc=data.loc||[]; data.loc=data.loc||[];
@ -762,7 +766,8 @@ ActionParser.prototype.parseAction = function() {
y_str.push(t[1]); y_str.push(t[1]);
}) })
this.next = MotaActionBlocks['setEnemyOnPoint_s'].xmlText([ this.next = MotaActionBlocks['setEnemyOnPoint_s'].xmlText([
x_str.join(','),y_str.join(','),data.floorId||'',data.name, data["operator"]||'=', this.expandEvalBlock([data.value]), this.next]); x_str.join(','),y_str.join(','),data.floorId||'',data.name, data["operator"]||'=', this.expandEvalBlock([data.value]),
data.norefresh||false, this.next]);
break; break;
case "resetEnemyOnPoint": case "resetEnemyOnPoint":
data.loc=data.loc||[]; data.loc=data.loc||[];
@ -774,17 +779,17 @@ ActionParser.prototype.parseAction = function() {
y_str.push(t[1]); y_str.push(t[1]);
}) })
this.next = MotaActionBlocks['resetEnemyOnPoint_s'].xmlText([ this.next = MotaActionBlocks['resetEnemyOnPoint_s'].xmlText([
x_str.join(','),y_str.join(','), data.floorId||'',this.next]); x_str.join(','),y_str.join(','), data.floorId||'',data.norefresh||false,this.next]);
break; break;
case "moveEnemyOnPoint": case "moveEnemyOnPoint":
data.from=data.from||['',''] data.from=data.from||['','']
if (data.dxy) { if (data.dxy) {
this.next = MotaActionBlocks['moveEnemyOnPoint_1_s'].xmlText([ this.next = MotaActionBlocks['moveEnemyOnPoint_1_s'].xmlText([
data.from[0], data.from[1], data.dxy[0], data.dxy[1], data.floorId||'',this.next]); data.from[0], data.from[1], data.dxy[0], data.dxy[1], data.floorId||'',data.norefresh||false,this.next]);
} else { } else {
data.to=data.to||['',''] data.to=data.to||['','']
this.next = MotaActionBlocks['moveEnemyOnPoint_s'].xmlText([ this.next = MotaActionBlocks['moveEnemyOnPoint_s'].xmlText([
data.from[0], data.from[1], data.to[0], data.to[1], data.floorId||'',this.next]); data.from[0], data.from[1], data.to[0], data.to[1], data.floorId||'',data.norefresh||false,this.next]);
} }
break; break;
case "setEquip": case "setEquip":
@ -929,13 +934,9 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['hideStatusBar_s'].xmlText([ this.next = MotaActionBlocks['hideStatusBar_s'].xmlText([
data.toolbox||false,this.next]); data.toolbox||false,this.next]);
break; break;
case "showHero": case "setHeroOpacity":
this.next = MotaActionBlocks['showHero_s'].xmlText([ this.next = MotaActionBlocks['setHeroOpacity_s'].xmlText([
data.time, data.async||false, this.next]); data.opacity, data.moveMode, data.time, data.async||false, this.next]);
break;
case "hideHero":
this.next = MotaActionBlocks['hideHero_s'].xmlText([
data.time, data.async||false, this.next]);
break; break;
case "sleep": // 等待多少毫秒 case "sleep": // 等待多少毫秒
this.next = MotaActionBlocks['sleep_s'].xmlText([ this.next = MotaActionBlocks['sleep_s'].xmlText([
@ -971,6 +972,10 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['waitAsync_s'].xmlText([ this.next = MotaActionBlocks['waitAsync_s'].xmlText([
data.excludeAnimates||false, data.includeSounds||false, this.next]); data.excludeAnimates||false, data.includeSounds||false, this.next]);
break; break;
case "stopAsync": // 立刻停止所有异步事件
this.next = MotaActionBlocks['stopAsync_s'].xmlText([
this.next]);
break;
case "callBook": // 呼出怪物手册 case "callBook": // 呼出怪物手册
this.next = MotaActionBlocks['callBook_s'].xmlText([ this.next = MotaActionBlocks['callBook_s'].xmlText([
this.next]); this.next]);
@ -1464,7 +1469,7 @@ MotaActionFunctions.PosString_pre = function(PosString){
if (!PosString || /^-?\d+$/.test(PosString)) return PosString; if (!PosString || /^-?\d+$/.test(PosString)) return PosString;
//if (!(MotaActionFunctions.pattern.id.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ 和中文之外的字符,或者是没有以flag: 开头'); //if (!(MotaActionFunctions.pattern.id.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ 和中文之外的字符,或者是没有以flag: 开头');
var comma = PosString.indexOf(','); var comma = PosString.indexOf(',');
if (comma >= 0 && PosString.substring(0, comma).ifndexOf('(') < 0) throw '此处不可写多点坐标'; if (comma >= 0 && PosString.substring(0, comma).indexOf('(') < 0) throw '此处不可写多点坐标';
return '"'+MotaActionFunctions.replaceFromName(PosString)+'"'; return '"'+MotaActionFunctions.replaceFromName(PosString)+'"';
} }

View File

@ -1,5 +1,9 @@
/** editor **/ /** editor **/
:root {
--pixel: 416px;
}
html, body, div, img { html, body, div, img {
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -128,15 +132,15 @@ body {
position: absolute; position: absolute;
left: 448px; left: 448px;
top: 10px; top: 10px;
width: 440px; width: calc(24px + var(--pixel));
height: 630px; height: calc(422px + var(--pixel) / 2);
} }
#mid2 { #mid2 {
position: absolute; position: absolute;
left: 448px; left: 448px;
top: 650px; top: calc(442px + var(--pixel) / 2);
width: 440px; width: calc(24px + var(--pixel));
bottom: 10px; bottom: 10px;
} }
@ -148,8 +152,8 @@ body {
position: absolute; position: absolute;
left: 20px; left: 20px;
top: 21px; top: 21px;
width: 416px; width: var(--pixel);
height: 416px; height: var(--pixel);
} }
#lastUsedDiv { #lastUsedDiv {
@ -162,8 +166,8 @@ body {
#mid .tools { #mid .tools {
position: absolute; position: absolute;
width: 425px; width: calc(var(--pixel) + 9px);
height: 180px; height: calc(388px - var(--pixel) / 2);
left: 0; left: 0;
bottom: 0; bottom: 0;
padding: 10px 5px; padding: 10px 5px;
@ -214,7 +218,7 @@ body {
#right { #right {
position: absolute; position: absolute;
left: 900px; left: calc(484px + var(--pixel));
top: 10px; top: 10px;
right: 0; right: 0;
bottom: 0; bottom: 0;
@ -300,7 +304,7 @@ table.col {
#mapColMark { #mapColMark {
top: 2px; top: 2px;
left: 19px; left: 19px;
width: 418px; width: var(--pixel);
height: 16px; height: 16px;
font-size: 13px; font-size: 13px;
} }
@ -312,7 +316,7 @@ table.col {
#mapColMark td:hover .colBlock { #mapColMark td:hover .colBlock {
position: absolute; position: absolute;
top: 19px; top: 19px;
height: 416px; height: var(--pixel);
width: 32px; width: 32px;
z-index: 100; z-index: 100;
} }
@ -336,7 +340,7 @@ table.row {
top: 1px; top: 1px;
left: 2px; left: 2px;
width: 16px; width: 16px;
height: 416px; height: var(--pixel);
font-size: 12px; font-size: 12px;
} }
@ -348,7 +352,7 @@ table.row {
position: absolute; position: absolute;
left: 18px; left: 18px;
height: 32px; height: 32px;
width: 416px; width: var(--pixel);
z-index: 100; z-index: 100;
} }
@ -421,8 +425,8 @@ table.row {
position: fixed; position: fixed;
top: 50%; top: 50%;
left: 50%; left: 50%;
transform: translate(-50%, -60%); transform: translate(-50%, -55%);
width: 436px; width: 560px;
} }
#uieventHead { #uieventHead {
@ -444,8 +448,8 @@ table.row {
} }
#uieventBody { #uieventBody {
width: 416px; width: 540px;
height: 416px; height: 540px;
position: relative; position: relative;
margin-left: 10px; margin-left: 10px;
margin-bottom: 5px; margin-bottom: 5px;

View File

@ -1,5 +1,9 @@
/** editor **/ /** editor **/
:root {
--size: 13;
}
html{ html{
font-size: 4vw; font-size: 4vw;
} }
@ -276,14 +280,14 @@ table.col, div.col {
#mapColMark .coltd, #mapColMark .coltd,
#mapColMark .coltd .coltext { #mapColMark .coltd .coltext {
position: absolute; position: absolute;
width: 7.15vw; width: calc(93vw / var(--size));
height: 4vw; height: 4vw;
line-height: 4vw; line-height: 4vw;
padding: 0; padding: 0;
border-bottom-width: 0px; border-bottom-width: 0px;
border-top-width: 0px; border-top-width: 0px;
border-left-width: 0.117307vw; border-left-width: calc(1.5vw / var(--size));
border-right-width: 0.117307vw; border-right-width: calc(1.5vw / var(--size));
} }
#mapColMark .coltd:hover .colBlock { #mapColMark .coltd:hover .colBlock {
@ -291,7 +295,7 @@ table.col, div.col {
top: 4vw; top: 4vw;
left:0; left:0;
height: 96vw; height: 96vw;
width: 7.384615vw; width: calc(96vw / var(--size));
z-index: 100; z-index: 100;
} }
@ -328,20 +332,20 @@ table.row,div.row .rowtext {
#mapRowMark .rowtd, #mapRowMark .rowtd,
#mapRowMark .rowtd .rowtext{ #mapRowMark .rowtd .rowtext{
height: 7.15vw; height: calc(93vw / var(--size));
line-height: 7.15vw; line-height: calc(93vw / var(--size));
padding: 0; padding: 0;
border-left-width: 0px; border-left-width: 0px;
border-right-width: 0px; border-right-width: 0px;
border-top-width: 0.117307vw; border-top-width: calc(1.5vw / var(--size));
border-bottom-width: 0.117397vw; border-bottom-width: calc(1.5vw / var(--size));
} }
#mapRowMark .rowtd:hover .rowBlock { #mapRowMark .rowtd:hover .rowBlock {
position: absolute; position: absolute;
left: 4vw; left: 4vw;
top: 0; top: 0;
height: 7.384615vw; height: calc(96vw / var(--size));
width: 96vw; width: 96vw;
z-index: 100; z-index: 100;
} }

View File

@ -57,6 +57,7 @@ function editor() {
showMovable: document.getElementById('showMovable'), showMovable: document.getElementById('showMovable'),
gameInject: document.getElementById('gameInject'), gameInject: document.getElementById('gameInject'),
undoFloor: document.getElementById('undoFloor'), undoFloor: document.getElementById('undoFloor'),
selectFloorBtn: document.getElementById('selectFloorBtn'),
editorTheme: document.getElementById('editorTheme'), editorTheme: document.getElementById('editorTheme'),
bigmapBtn : document.getElementById('bigmapBtn'), bigmapBtn : document.getElementById('bigmapBtn'),
mapRowMark: document.getElementById('mapRowMark'), mapRowMark: document.getElementById('mapRowMark'),
@ -206,6 +207,7 @@ editor.prototype.init = function (callback) {
editor_file_wrapper(editor); editor_file_wrapper(editor);
editor_table_wrapper(editor); editor_table_wrapper(editor);
editor_ui_wrapper(editor); editor_ui_wrapper(editor);
editor_uievent_wrapper(editor);
editor_mappanel_wrapper(editor); editor_mappanel_wrapper(editor);
editor_datapanel_wrapper(editor); editor_datapanel_wrapper(editor);
editor_materialpanel_wrapper(editor); editor_materialpanel_wrapper(editor);
@ -396,20 +398,40 @@ editor.prototype.drawEventBlock = function () {
var directions = (movableArray[x]||{})[y]; var directions = (movableArray[x]||{})[y];
if (directions == null) continue; if (directions == null) continue;
if (!directions.includes('left') && x != 0) { if (!directions.includes('left') && x != 0) {
core.drawLine(fg, 32 * i + 1, 32 * j + 10, 32 * i + 1, 32 * j + 22, '#FF0000', 2); var ndirections = (movableArray[x-1]||{})[y];
core.fillPolygon(fg, [[32 * i + 9, 32 * j + 12], [32 * i + 1, 32 * j + 16], [32 * i + 9, 32 * j + 20]], '#FF0000'); if (ndirections != null && !ndirections.includes('right')) {
core.drawLine(fg, 32 * i + 1, 32 * j + 6, 32 * i + 1, 32 * j + 26, '#FF0000', 2);
} else {
core.drawLine(fg, 32 * i + 1, 32 * j + 10, 32 * i + 1, 32 * j + 22, '#FF0000', 2);
core.fillPolygon(fg, [[32 * i + 9, 32 * j + 12], [32 * i + 1, 32 * j + 16], [32 * i + 9, 32 * j + 20]], '#FF0000');
}
} }
if (!directions.includes('right') && x != editor.currentFloorData.width - 1) { if (!directions.includes('right') && x != editor.currentFloorData.width - 1) {
core.drawLine(fg, 32 * i + 31, 32 * j + 10, 32 * i + 31, 32 * j + 22, '#FF0000', 2); var ndirections = (movableArray[x+1]||{})[y];
core.fillPolygon(fg, [[32 * i + 23, 32 * j + 12], [32 * i + 31, 32 * j + 16], [32 * i + 23, 32 * j + 20]], '#FF0000'); if (ndirections != null && !ndirections.includes('left')) {
core.drawLine(fg, 32 * i + 31, 32 * j + 6, 32 * i + 31, 32 * j + 26, '#FF0000', 2);
} else {
core.drawLine(fg, 32 * i + 31, 32 * j + 10, 32 * i + 31, 32 * j + 22, '#FF0000', 2);
core.fillPolygon(fg, [[32 * i + 23, 32 * j + 12], [32 * i + 31, 32 * j + 16], [32 * i + 23, 32 * j + 20]], '#FF0000');
}
} }
if (!directions.includes('up') && y != 0) { if (!directions.includes('up') && y != 0) {
core.drawLine(fg, 32 * i + 10, 32 * j + 1, 32 * i + 22, 32 * j + 1, '#FF0000', 2); var ndirections = movableArray[x][y-1];
core.fillPolygon(fg, [[32 * i + 12, 32 * j + 9], [32 * i + 16, 32 * j + 1], [32 * i + 20, 32 * j + 9]], '#FF0000'); if (ndirections != null && !ndirections.includes('down')) {
core.drawLine(fg, 32 * i + 6, 32 * j + 1, 32 * i + 26, 32 * j + 1, '#FF0000', 2);
} else {
core.drawLine(fg, 32 * i + 10, 32 * j + 1, 32 * i + 22, 32 * j + 1, '#FF0000', 2);
core.fillPolygon(fg, [[32 * i + 12, 32 * j + 9], [32 * i + 16, 32 * j + 1], [32 * i + 20, 32 * j + 9]], '#FF0000');
}
} }
if (!directions.includes('down') && y != editor.currentFloorData.height - 1) { if (!directions.includes('down') && y != editor.currentFloorData.height - 1) {
core.drawLine(fg, 32 * i + 10, 32 * j + 31, 32 * i + 22, 32 * j + 31, '#FF0000', 2); var ndirections = movableArray[x][y+1];
core.fillPolygon(fg, [[32 * i + 12, 32 * j + 23], [32 * i + 16, 32 * j + 31], [32 * i + 20, 32 * j + 23]], '#FF0000'); if (ndirections != null && !ndirections.includes('up')) {
core.drawLine(fg, 32 * i + 6, 32 * j + 31, 32 * i + 26, 32 * j + 31, '#FF0000', 2);
} else {
core.drawLine(fg, 32 * i + 10, 32 * j + 31, 32 * i + 22, 32 * j + 31, '#FF0000', 2);
core.fillPolygon(fg, [[32 * i + 12, 32 * j + 23], [32 * i + 16, 32 * j + 31], [32 * i + 20, 32 * j + 23]], '#FF0000');
}
} }
} }
} }
@ -471,28 +493,48 @@ editor.prototype._drawEventBlock_bigmap = function () {
var directions = (movableArray[i]||{})[j]; var directions = (movableArray[i]||{})[j];
if (directions == null) continue; if (directions == null) continue;
if (!directions.includes('left') && i != 0) { if (!directions.includes('left') && i != 0) {
core.drawLine(fg, info.left + size * i, info.top + size * j + size / 3, info.left + size * i + 1, info.top + size * j + size * 2 / 3, '#FF0000', 2); var ndirections = (movableArray[i-1]||{})[j];
core.fillPolygon(fg, [[info.left + size * i + size / 4, info.top + size * j + size * 3 / 8], if (ndirections != null && !ndirections.includes('right')) {
[info.left + size * i, info.top + size * j + size / 2], core.drawLine(fg, info.left + size * i, info.top + size * j + size / 4, info.left + size * i, info.top + size * j + size * 3 / 4, '#FF0000', 2);
[info.left + size * i + size / 4, info.top + size * j + size * 5 / 8]], '#FF0000'); } else {
core.drawLine(fg, info.left + size * i, info.top + size * j + size / 3, info.left + size * i, info.top + size * j + size * 2 / 3, '#FF0000', 2);
core.fillPolygon(fg, [[info.left + size * i + size / 4, info.top + size * j + size * 3 / 8],
[info.left + size * i, info.top + size * j + size / 2],
[info.left + size * i + size / 4, info.top + size * j + size * 5 / 8]], '#FF0000');
}
} }
if (!directions.includes('right') && i != editor.currentFloorData.width - 1) { if (!directions.includes('right') && i != editor.currentFloorData.width - 1) {
core.drawLine(fg, info.left + size * i + size, info.top + size * j + size / 3, info.left + size * i + size, info.top + size * j + size * 2 / 3, '#FF0000', 2); var ndirections = (movableArray[i+1]||{})[j];
core.fillPolygon(fg, [[info.left + size * i + size * 3 / 4, info.top + size * j + size * 3 / 8], if (ndirections != null && !ndirections.includes('left')) {
[info.left + size * i + size, info.top + size * j + size / 2], core.drawLine(fg, info.left + size * i + size, info.top + size * j + size / 4, info.left + size * i + size, info.top + size * j + size * 3 / 4, '#FF0000', 2);
[info.left + size * i + size * 3 / 4, info.top + size * j + size * 5 / 8]], '#FF0000'); } else {
core.drawLine(fg, info.left + size * i + size, info.top + size * j + size / 3, info.left + size * i + size, info.top + size * j + size * 2 / 3, '#FF0000', 2);
core.fillPolygon(fg, [[info.left + size * i + size * 3 / 4, info.top + size * j + size * 3 / 8],
[info.left + size * i + size, info.top + size * j + size / 2],
[info.left + size * i + size * 3 / 4, info.top + size * j + size * 5 / 8]], '#FF0000');
}
} }
if (!directions.includes('up') && j != 0) { if (!directions.includes('up') && j != 0) {
core.drawLine(fg, info.left + size * i + size / 3, info.top + size * j, info.left + size * i + size * 2 / 3, info.top + size * j, '#FF0000', 2); var ndirections = movableArray[i][j-1];
core.fillPolygon(fg, [[info.left + size * i + size * 3 / 8, info.top + size * j + size / 4], if (ndirections != null && !ndirections.includes('down')) {
[info.left + size * i + size / 2, info.top + size * j], core.drawLine(fg, info.left + size * i + size / 4, info.top + size * j, info.left + size * i + size * 3 / 4, info.top + size * j, '#FF0000', 2);
[info.left + size * i + size * 5 / 8, info.top + size * j + size / 4]], '#FF0000'); } else {
core.drawLine(fg, info.left + size * i + size / 3, info.top + size * j, info.left + size * i + size * 2 / 3, info.top + size * j, '#FF0000', 2);
core.fillPolygon(fg, [[info.left + size * i + size * 3 / 8, info.top + size * j + size / 4],
[info.left + size * i + size / 2, info.top + size * j],
[info.left + size * i + size * 5 / 8, info.top + size * j + size / 4]], '#FF0000');
}
} }
if (!directions.includes('down') && j != editor.currentFloorData.height - 1) { if (!directions.includes('down') && j != editor.currentFloorData.height - 1) {
core.drawLine(fg, info.left + size * i + size / 3, info.top + size * j + size - 1, info.left + size * i + size * 2 / 3, info.top + size * j + size - 1, '#FF0000', 2); var ndirections = movableArray[i][j+1];
core.fillPolygon(fg, [[info.left + size * i + size * 3 / 8, info.top + size * j + size * 3 / 4], if (ndirections != null && !ndirections.includes('up')) {
[info.left + size * i + size / 2, info.top + size * j + size], core.drawLine(fg, info.left + size * i + size / 4, info.top + size * j + size, info.left + size * i + size * 3 / 4, info.top + size * j + size, '#FF0000', 2);
[info.left + size * i + size * 5 / 8, info.top + size * j + size * 3 / 4]], '#FF0000'); } else {
core.drawLine(fg, info.left + size * i + size / 3, info.top + size * j + size, info.left + size * i + size * 2 / 3, info.top + size * j + size, '#FF0000', 2);
core.fillPolygon(fg, [[info.left + size * i + size * 3 / 8, info.top + size * j + size * 3 / 4],
[info.left + size * i + size / 2, info.top + size * j + size],
[info.left + size * i + size * 5 / 8, info.top + size * j + size * 3 / 4]], '#FF0000');
}
} }
} }
} }
@ -714,6 +756,27 @@ editor.prototype.drawInitData = function (icons) {
}); });
var imgNames = ["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48", "autotile"]; var imgNames = ["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48", "autotile"];
var splitCanvas = document.createElement('canvas');
var splitCtx = splitCanvas.getContext('2d');
splitCtx.imageSmoothingEnabled = false;
var splitImage = function (image, width, height) {
if (image.width == width && image.height == height) {
return [image];
}
var ans = [];
for (var j = 0; j < image.height; j += h) {
var h = Math.min(height, image.height - j);
splitCanvas.width = width;
splitCanvas.height = h;
core.drawImage(splitCtx, image, 0, j, width, h, 0, 0, width, h);
var data = new Image();
data.src = splitCanvas.toDataURL("image/png");
ans.push(data);
}
return ans;
}
for (var ii = 0; ii < imgNames.length; ii++) { for (var ii = 0; ii < imgNames.length; ii++) {
var img = imgNames[ii], tempy = 0; var img = imgNames[ii], tempy = 0;
if (img == 'autotile') { if (img == 'autotile') {
@ -729,9 +792,14 @@ editor.prototype.drawInitData = function (icons) {
} }
var width = images[img].width, height = images[img].height, mh = height; var width = images[img].width, height = images[img].height, mh = height;
if (editor.uivalues.folded) { if (editor.uivalues.folded) {
var per_height = (img == 'enemy48' || img == 'npc48' ? 48 : 32); if (img == 'terrains') {
width = Math.ceil(height / per_height / editor.uivalues.foldPerCol) * 32; width = Math.ceil((height / 32 + 2) / editor.uivalues.foldPerCol) * 32;
if (width > 32) mh = per_height * editor.uivalues.foldPerCol; if (width > 32) mh = 32 * editor.uivalues.foldPerCol;
} else {
var per_height = (img == 'enemy48' || img == 'npc48' ? 48 : 32);
width = Math.ceil(height / per_height / editor.uivalues.foldPerCol) * 32;
if (width > 32) mh = per_height * editor.uivalues.foldPerCol;
}
} }
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + width) / 32, height]; editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + width) / 32, height];
sumWidth += width; sumWidth += width;
@ -812,10 +880,13 @@ editor.prototype.drawInitData = function (icons) {
})(editor.airwallImg,nowx); })(editor.airwallImg,nowx);
if (editor.uivalues.folded) { if (editor.uivalues.folded) {
// --- 单列 & 折行 // --- 单列 & 折行
var subimgs = core.splitImage(images[img], 32, editor.uivalues.foldPerCol * 32); var canvas = document.createElement("canvas");
var frames = images[img].width / 32; canvas.width = 32;
for (var i = 0; i < subimgs.length; i+=frames) { canvas.height = images[img].height + 64;
drawImage(subimgs[i], nowx, i==0?2*32:0, img); canvas.getContext('2d').drawImage(images[img], 0, 64);
var subimgs = splitImage(canvas, 32, editor.uivalues.foldPerCol * 32);
for (var i = 0; i < subimgs.length; i++) {
drawImage(subimgs[i], nowx, 0, img);
nowx += 32; nowx += 32;
} }
} }
@ -830,7 +901,7 @@ editor.prototype.drawInitData = function (icons) {
var tempx = editor.uivalues.folded ? 32 : 96; var tempx = editor.uivalues.folded ? 32 : 96;
for (var im in autotiles) { for (var im in autotiles) {
var tempy = editor.uivalues.folded ? 32 : autotiles[im].height; var tempy = editor.uivalues.folded ? 32 : autotiles[im].height;
var subimgs = core.splitImage(autotiles[im], tempx, tempy); var subimgs = splitImage(autotiles[im], tempx, tempy);
drawImage(subimgs[0], nowx, nowy, img); drawImage(subimgs[0], nowx, nowy, img);
nowy += tempy; nowy += tempy;
} }
@ -840,9 +911,8 @@ editor.prototype.drawInitData = function (icons) {
if (editor.uivalues.folded) { if (editor.uivalues.folded) {
// --- 单列 & 折行 // --- 单列 & 折行
var per_height = img.endsWith('48') ? 48 : 32; var per_height = img.endsWith('48') ? 48 : 32;
var subimgs = core.splitImage(images[img], 32, editor.uivalues.foldPerCol * per_height); var subimgs = splitImage(images[img], 32, editor.uivalues.foldPerCol * per_height);
var frames = images[img].width / 32; for (var i = 0; i < subimgs.length; i++) {
for (var i = 0; i < subimgs.length; i+=frames) {
drawImage(subimgs[i], nowx, 0, img); drawImage(subimgs[i], nowx, 0, img);
nowx += 32; nowx += 32;
} }

View File

@ -163,7 +163,7 @@ editor_blockly = function () {
editor_blockly.hide(); editor_blockly.hide();
} }
editor_blockly.confirm = function () { editor_blockly.confirm = function (keep) {
if (!editor_blockly.id) { if (!editor_blockly.id) {
editor_blockly.id = ''; editor_blockly.id = '';
return; return;
@ -186,10 +186,13 @@ editor_blockly = function () {
} }
var setvalue = function (value) { var setvalue = function (value) {
var thisTr = document.getElementById(editor_blockly.id); var thisTr = document.getElementById(editor_blockly.id);
editor_blockly.id = '';
var input = thisTr.children[2].children[0].children[0]; var input = thisTr.children[2].children[0].children[0];
input.value = value; input.value = value;
editor_blockly.hide(); if (!keep) {
editor_blockly.id = '';
editor_blockly.hide();
}
else alert('保存成功!');
input.onchange(); input.onchange();
} }
if (codeAreaHL.getValue() === '') { if (codeAreaHL.getValue() === '') {
@ -244,8 +247,8 @@ editor_blockly = function () {
} }
} }
if (one.type == 'previewUI' && this.checkAsync(one.action)) return true; if (one.type == 'previewUI' && this.checkAsync(one.action)) return true;
if (one.async && one.type != 'animate' && one.type != 'function') hasAsync = true; if (one.async && one.type != 'animate' && one.type != 'function' && one.type != 'text') hasAsync = true;
if (one.type == 'waitAsync') hasAsync = false; if (one.type == 'waitAsync' || one.type == 'stopAsync') hasAsync = false;
} }
return hasAsync; return hasAsync;
} }
@ -1189,3 +1192,16 @@ Blockly.FieldDropdown.prototype.doValueUpdate_ = function (newValue) {
this.selectedOption_ = options[options.length - 1]; this.selectedOption_ = options[options.length - 1];
} }
}; };
Blockly.FieldMultilineInput.prototype.getDisplayText_ = function() {
var value = this.value_;
if (!value) return Blockly.Field.NBSP;
var curr = '', text = '';
for (var i = 0; i < value.length; ++i) {
if (value[i] == '\n' || curr.length == this.maxDisplayLength) {
text += curr.replace(/\s/g, Blockly.Field.NBSP) + '\n';
curr = value[i] == '\n' ? '' : value[i];
} else curr += value[i];
}
return text + curr;
};

View File

@ -108,7 +108,7 @@ editor_blocklyconfig=(function(){
MotaActionBlocks['tip_s'].xmlText(), MotaActionBlocks['tip_s'].xmlText(),
MotaActionBlocks['confirm_s'].xmlText(), MotaActionBlocks['confirm_s'].xmlText(),
MotaActionBlocks['choices_s'].xmlText([ MotaActionBlocks['choices_s'].xmlText([
'选择剑或者盾','流浪者','man',0,0,'',MotaActionBlocks['choicesContext'].xmlText([ '选择剑或者盾','流浪者','man',0,'',MotaActionBlocks['choicesContext'].xmlText([
'剑','','',null,'','',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]), '剑','','',null,'','',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]),
]) ])
]), ]),
@ -196,16 +196,17 @@ editor_blocklyconfig=(function(){
{"case": "timeout", "action": [{"type": "comment", "text": "当超时未操作时执行此事件"}]}, {"case": "timeout", "action": [{"type": "comment", "text": "当超时未操作时执行此事件"}]},
]}), ]}),
MotaActionBlocks['waitAsync_s'].xmlText(), MotaActionBlocks['waitAsync_s'].xmlText(),
MotaActionBlocks['stopAsync_s'].xmlText(),
MotaActionBlocks['vibrate_s'].xmlText(), MotaActionBlocks['vibrate_s'].xmlText(),
MotaActionBlocks['animate_s'].xmlText(), MotaActionBlocks['animate_s'].xmlText(),
MotaActionBlocks['animate_1_s'].xmlText(), MotaActionBlocks['animate_1_s'].xmlText(),
MotaActionBlocks['stopAnimate_s'].xmlText(),
MotaActionBlocks['setViewport_s'].xmlText(), MotaActionBlocks['setViewport_s'].xmlText(),
MotaActionBlocks['setViewport_1_s'].xmlText(), MotaActionBlocks['setViewport_1_s'].xmlText(),
MotaActionBlocks['lockViewport_s'].xmlText(), MotaActionBlocks['lockViewport_s'].xmlText(),
MotaActionBlocks['showStatusBar_s'].xmlText(), MotaActionBlocks['showStatusBar_s'].xmlText(),
MotaActionBlocks['hideStatusBar_s'].xmlText(), MotaActionBlocks['hideStatusBar_s'].xmlText(),
MotaActionBlocks['showHero_s'].xmlText(), MotaActionBlocks['setHeroOpacity_s'].xmlText(),
MotaActionBlocks['hideHero_s'].xmlText(),
MotaActionBlocks['setCurtain_0_s'].xmlText(), MotaActionBlocks['setCurtain_0_s'].xmlText(),
MotaActionBlocks['setCurtain_1_s'].xmlText(), MotaActionBlocks['setCurtain_1_s'].xmlText(),
MotaActionBlocks['screenFlash_s'].xmlText(), MotaActionBlocks['screenFlash_s'].xmlText(),
@ -363,22 +364,6 @@ editor_blocklyconfig=(function(){
] ]
} }
], 'event'), ], 'event'),
'<label text="战前剧情"></label>',
MotaActionFunctions.actionParser.parse({
"trigger": "action",
"displayDamage": true,
"data": [
' ... 战前剧情',
{"type": "battle", "id": "greenSlime"},
' ... 战后剧情;请注意上面的强制战斗不会使怪物消失',
'需要下一句来调用{"type": "hide"}来隐藏事件',
{"type": "hide"},
]
},'event'),
'<label text="杀死魔龙后隐藏其余图块"></label>',
MotaActionFunctions.actionParser.parse([
{"type": "function", "function": "function(){var x=core.status.event.data.x,y=core.status.event.data.y;if(core.isset(x)&&core.isset(y)){core.insertAction([{type:'hide',loc:[[x-1,y-2],[x,y-2],[x+1,y-2],[x-1,y-1],[x,y-1],[x+1,y-1],[x-1,y],[x+1,y]]}]);}}"},
],'afterBattle'),
'<label text="全地图选中一个点"></label>', '<label text="全地图选中一个点"></label>',
MotaActionFunctions.actionParser.parse([ MotaActionFunctions.actionParser.parse([
{ {

View File

@ -180,6 +180,12 @@ editor_datapanel_wrapper = function (editor) {
editor.uifunctions.createNewMaps_func = function () { editor.uifunctions.createNewMaps_func = function () {
document.getElementById('newMapWidth').value = core.__SIZE__;
document.getElementById('newMapHeight').value = core.__SIZE__;
document.getElementById('newMapsWidth').value = core.__SIZE__;
document.getElementById('newMapsHeight').value = core.__SIZE__;
var newMaps = document.getElementById('newMaps'); var newMaps = document.getElementById('newMaps');
var newFloors = document.getElementById('newFloors'); var newFloors = document.getElementById('newFloors');
newMaps.onclick = function () { newMaps.onclick = function () {
@ -301,6 +307,13 @@ editor_datapanel_wrapper = function (editor) {
printe('不合法的id请使用字母、数字或下划线且不能以数字开头'); printe('不合法的id请使用字母、数字或下划线且不能以数字开头');
return; return;
} }
if (id == 'hero' || id == 'this' || id == 'none' || id == 'airwall') {
printe('不得使用保留关键字作为id');
return;
}
if (core.statusBar.icons[id] != null) {
alert('警告此ID在状态栏图标中被注册仍然允许使用但是\\i[]等绘制可能出现冲突。');
}
editor.file.changeIdAndIdnum(id, idnum, editor_mode.info, function (err) { editor.file.changeIdAndIdnum(id, idnum, editor_mode.info, function (err) {
if (err) { if (err) {
printe(err); printe(err);
@ -332,6 +345,9 @@ editor_datapanel_wrapper = function (editor) {
window.location.reload(); window.location.reload();
}); });
} }
newIdIdnum.children[6].onclick = function () {
editor.uifunctions.appendMaterialByInfo(editor_mode.info);
}
} }
editor.uifunctions.changeId_func = function () { editor.uifunctions.changeId_func = function () {
@ -355,6 +371,9 @@ editor_datapanel_wrapper = function (editor) {
printe('额外素材不可修改id'); printe('额外素材不可修改id');
return; return;
} }
if (core.statusBar.icons[id] != null) {
alert('警告此ID在状态栏图标中被注册仍然允许使用但是\\i[]等绘制可能出现冲突。');
}
editor.file.changeIdAndIdnum(id, null, editor_mode.info, function (err) { editor.file.changeIdAndIdnum(id, null, editor_mode.info, function (err) {
if (err) { if (err) {
printe(err); printe(err);
@ -381,6 +400,9 @@ editor_datapanel_wrapper = function (editor) {
window.location.reload(); window.location.reload();
}); });
} }
changeId.children[3].onclick = function () {
editor.uifunctions.appendMaterialByInfo(editor_mode.info);
}
} }
editor.uifunctions.copyPasteEnemyItem_func = function () { editor.uifunctions.copyPasteEnemyItem_func = function () {
@ -811,6 +833,10 @@ editor_datapanel_wrapper = function (editor) {
} }
var loadImage = function (content, callback) { var loadImage = function (content, callback) {
if (content instanceof Image || content.getContext != null) {
callback(content);
return;
}
var image = new Image(); var image = new Image();
try { try {
image.onload = function () { image.onload = function () {
@ -1124,6 +1150,46 @@ editor_datapanel_wrapper = function (editor) {
} }
reader.readAsDataURL(file); reader.readAsDataURL(file);
} }
editor.uifunctions.appendMaterialByInfo = function (info) {
if (info.isTile) {
printe('额外素材不支持此功能!');
return;
}
var img = null;
var cls = info.images;
var height = cls == 'enemy48' || cls == 'npc48' ? 48 : 32;
if (cls == 'autotile') {
img = core.material.images.autotile[info.id];
} else {
var image = core.material.images[cls];
var width = image.width;
img = document.createElement('canvas');
img.width = width;
img.height = height;
img.getContext('2d').drawImage(image, 0, info.y * height, width, height, 0, 0, width, height);
}
editor.mode.change('appendpic');
editor.dom.selectAppend.value = cls;
editor.dom.selectAppend.onchange();
afterReadFile(img, function () {
changeColorInput.value = 0;
if (cls == 'autotile') return;
editor_mode.appendPic.index = 0;
for (var ii = 0; ii < editor_mode.appendPic.num; ++ii) {
editor_mode.appendPic.selectPos[ii] = {x: ii, y: 0, ysize: height};
editor.dom.appendPicSelection.children[ii].style = [
'left:', ii * 32, 'px;',
'top:', 0, 'px;',
'height:', height - 6, 'px;'
].join('');
}
});
}
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////

View File

@ -219,6 +219,14 @@ editor_file = function (editor, callback) {
color: currData.color, color: currData.color,
weather: currData.weather, weather: currData.weather,
}:{}); }:{});
// 继承配置表格新增的基本楼层属性
if (saveStatus) {
for (var x in currData) {
if (editor.currentFloorData[x] == null && (typeof currData[x] == 'number' || typeof currData[x] == 'string')) {
editor.currentFloorData[x] = currData[x];
}
}
}
Object.keys(editor.currentFloorData).forEach(function (t) { Object.keys(editor.currentFloorData).forEach(function (t) {
if (editor.currentFloorData[t] == null) if (editor.currentFloorData[t] == null)
@ -577,7 +585,7 @@ editor_file = function (editor, callback) {
(function () { (function () {
var locObj = Object.assign({}, editor.core.items.items[id]); var locObj = Object.assign({}, editor.core.items.items[id]);
Object.keys(editor.file.comment._data.items._data).forEach(function (v) { Object.keys(editor.file.comment._data.items._data).forEach(function (v) {
if (!isset(editor.core.items.items[id][v])) if (!isset((editor.core.items.items[id]||{})[v]))
locObj[v] = null; locObj[v] = null;
}); });
return locObj; return locObj;
@ -609,7 +617,7 @@ editor_file = function (editor, callback) {
(function () { (function () {
var locObj = Object.assign({}, editor.core.enemys.enemys[id]); var locObj = Object.assign({}, editor.core.enemys.enemys[id]);
Object.keys(editor.file.comment._data.enemys._data).forEach(function (v) { Object.keys(editor.file.comment._data.enemys._data).forEach(function (v) {
if (!isset(editor.core.enemys.enemys[id][v])) if (!isset((editor.core.enemys.enemys[id]||{})[v]))
/* locObj[v]=editor.core.enemys.enemys[id][v]; /* locObj[v]=editor.core.enemys.enemys[id][v];
else */ else */
locObj[v] = null; locObj[v] = null;

View File

@ -37,6 +37,7 @@ editor_listen_wrapper = function (editor) {
editor.dom.clearEvent.onmouseup = editor.uifunctions.clearEvent_click editor.dom.clearEvent.onmouseup = editor.uifunctions.clearEvent_click
editor.dom.clearLoc.onmouseup = editor.uifunctions.clearLoc_click editor.dom.clearLoc.onmouseup = editor.uifunctions.clearLoc_click
editor.dom.undoFloor.onclick = editor.uifunctions.undoFloor_click editor.dom.undoFloor.onclick = editor.uifunctions.undoFloor_click
editor.dom.selectFloorBtn.onclick = editor.uifunctions.selectFloorBtn_click
editor.dom.editorTheme.onchange = editor.uifunctions.editorTheme_onchange editor.dom.editorTheme.onchange = editor.uifunctions.editorTheme_onchange
editor.dom.lastUsed.onmouseup = editor.uifunctions.lastUsed_click; editor.dom.lastUsed.onmouseup = editor.uifunctions.lastUsed_click;

View File

@ -452,6 +452,23 @@ editor_mappanel_wrapper = function (editor) {
editor.changeFloor(toId); editor.changeFloor(toId);
} }
editor.uifunctions.selectFloorBtn_click = function () {
editor.uievent.selectFloor(null, '选择楼层', function (floorId) {
if (!floorId || floorId == editor.currentFloorId) return;
var saveFloor = document.getElementById('saveFloor');
if (saveFloor && saveFloor.classList.contains('highlight')) {
printe('请先保存地图!');
return;
}
editor_mode.onmode('nextChange');
editor_mode.onmode('floor');
editor.dom.selectFloor.value = floorId;
editor.changeFloor(floorId);
})
}
editor.uifunctions.editorTheme_onchange = function () { editor.uifunctions.editorTheme_onchange = function () {
var theme = editor.dom.editorTheme.value; var theme = editor.dom.editorTheme.value;
editor.config.set('theme', theme); editor.config.set('theme', theme);

View File

@ -150,10 +150,10 @@ editor_materialpanel_wrapper = function (editor) {
} }
else { else {
var height = editor.widthsX[spriter][3], col = height / ysize; var height = editor.widthsX[spriter][3], col = height / ysize;
if (spriter == 'terrains') col += 2;
if (editor.uivalues.folded && core.tilesets.indexOf(pos.images) == -1) { if (editor.uivalues.folded && core.tilesets.indexOf(pos.images) == -1) {
col = (pos.x == editor.widthsX[spriter][2] - 1) ? ((col - 1) % editor.uivalues.foldPerCol + 1) : editor.uivalues.foldPerCol; col = (pos.x == editor.widthsX[spriter][2] - 1) ? ((col - 1) % editor.uivalues.foldPerCol + 1) : editor.uivalues.foldPerCol;
} }
if (spriter == 'terrains' && pos.x == editor.widthsX[spriter][1]) col += 2;
pos.y = Math.min(pos.y, col - 1); pos.y = Math.min(pos.y, col - 1);
} }
@ -177,7 +177,7 @@ editor_materialpanel_wrapper = function (editor) {
if (editor.uivalues.folded) { if (editor.uivalues.folded) {
y += editor.uivalues.foldPerCol * (pos.x - editor.widthsX[spriter][1]); y += editor.uivalues.foldPerCol * (pos.x - editor.widthsX[spriter][1]);
} }
if (pos.images == 'terrains' && pos.x == 0) y -= 2; if (pos.images == 'terrains') y -= 2;
editor.info = { 'images': pos.images, 'y': y } editor.info = { 'images': pos.images, 'y': y }
} }

View File

@ -282,6 +282,18 @@ editor_multi = function () {
}).length > 0; }).length > 0;
} }
var _previewButton = document.getElementById('editor_multi_preview');
_previewButton.onclick = function () {
if (!editor_multi.preview) return;
_format();
if (editor_multi.hasError()) {
alert("当前好像存在严重的语法错误,请处理后再预览。");
return;
}
editor.uievent.previewEditorMulti(editor_multi.preview, codeEditor.getValue());
}
editor_multi.import = function (id_, args) { editor_multi.import = function (id_, args) {
var thisTr = document.getElementById(id_); var thisTr = document.getElementById(id_);
if (!thisTr) return false; if (!thisTr) return false;
@ -292,6 +304,8 @@ editor_multi = function () {
editor_multi.id = id_; editor_multi.id = id_;
editor_multi.isString = false; editor_multi.isString = false;
editor_multi.lintAutocomplete = false; editor_multi.lintAutocomplete = false;
editor_multi.preview = args.preview;
_previewButton.style.display = editor_multi.preview ? 'inline' : 'none';
if (args.lint === true) editor_multi.lintAutocomplete = true; if (args.lint === true) editor_multi.lintAutocomplete = true;
if ((!input.value || input.value == 'null') && args.template) if ((!input.value || input.value == 'null') && args.template)
input.value = '"' + args.template + '"'; input.value = '"' + args.template + '"';
@ -318,7 +332,7 @@ editor_multi = function () {
_setValue(tstr || ''); _setValue(tstr || '');
} }
editor_multi.show(); editor_multi.show();
codeEditor.scrollTo(0, lastOffset[id_] || 0); codeEditor.scrollTo(0, lastOffset[editor_multi.id] || 0);
return true; return true;
} }
@ -331,7 +345,7 @@ editor_multi = function () {
multiLineArgs = [null, null, null]; multiLineArgs = [null, null, null];
} }
editor_multi.confirm = function () { editor_multi.confirm = function (keep) {
if (editor_multi.hasError()) { if (editor_multi.hasError()) {
alert("当前好像存在严重的语法错误,请处理后再保存。\n严重的语法错误可能会导致整个编辑器的崩溃。"); alert("当前好像存在严重的语法错误,请处理后再保存。\n严重的语法错误可能会导致整个编辑器的崩溃。");
return; return;
@ -345,21 +359,18 @@ editor_multi = function () {
if (editor_multi.id === 'callFromBlockly') { if (editor_multi.id === 'callFromBlockly') {
// ----- 自动格式化 // ----- 自动格式化
_format(); _format();
editor_multi.id = ''; editor_multi.multiLineDone(keep);
editor_multi.multiLineDone();
return; return;
} }
if (editor_multi.id === 'importFile') { if (editor_multi.id === 'importFile') {
_format(); _format();
editor_multi.id = ''; editor_multi.writeFileDone(keep);
editor_multi.writeFileDone();
return; return;
} }
var setvalue = function (value) { var setvalue = function (value) {
var thisTr = document.getElementById(editor_multi.id); var thisTr = document.getElementById(editor_multi.id);
editor_multi.id = '';
var input = thisTr.children[2].children[0].children[0]; var input = thisTr.children[2].children[0].children[0];
if (editor_multi.isString) { if (editor_multi.isString) {
input.value = JSON.stringify(value); input.value = JSON.stringify(value);
@ -378,7 +389,12 @@ editor_multi = function () {
} }
input.value = tstr; input.value = tstr;
} }
editor_multi.hide(); if (!keep) {
editor_multi.id = '';
editor_multi.hide();
} else {
alert('写入成功!');
}
input.onchange(); input.onchange();
} }
lastOffset[editor_multi.id] = (codeEditor.getScrollInfo() || {}).top; lastOffset[editor_multi.id] = (codeEditor.getScrollInfo() || {}).top;
@ -410,11 +426,16 @@ editor_multi = function () {
editor_multi.lintAutocomplete = Boolean(args.lint); editor_multi.lintAutocomplete = Boolean(args.lint);
editor_multi.show(); editor_multi.show();
} }
editor_multi.multiLineDone = function () { editor_multi.multiLineDone = function (keep) {
editor_multi.hide();
if (!multiLineArgs[0] || !multiLineArgs[1] || !multiLineArgs[2]) return; if (!multiLineArgs[0] || !multiLineArgs[1] || !multiLineArgs[2]) return;
var newvalue = codeEditor.getValue() || ''; var newvalue = codeEditor.getValue() || '';
multiLineArgs[2](newvalue, multiLineArgs[0], multiLineArgs[1]) multiLineArgs[2](newvalue, multiLineArgs[0], multiLineArgs[1])
if (!keep) {
editor_multi.id = '';
editor_multi.hide();
} else {
alert('写入成功!');
}
} }
var _fileValues = [''] var _fileValues = ['']
@ -435,11 +456,16 @@ editor_multi = function () {
}) })
} }
editor_multi.writeFileDone = function () { editor_multi.writeFileDone = function (keep) {
fs.writeFile(_fileValues[0], editor.util.encode64(codeEditor.getValue() || ''), 'base64', function (err, data) { fs.writeFile(_fileValues[0], editor.util.encode64(codeEditor.getValue() || ''), 'base64', function (err, data) {
if (err) printe('文件写入失败,请手动粘贴至' + _fileValues[0] + '\n' + err); if (err) printe('文件写入失败,请手动粘贴至' + _fileValues[0] + '\n' + err);
else { else {
editor_multi.hide(); if (!keep) {
editor_multi.id = '';
editor_multi.hide();
} else {
alert('写入成功!');
}
printf(_fileValues[0] + " 写入成功F5刷新后生效"); printf(_fileValues[0] + " 写入成功F5刷新后生效");
} }
}); });

View File

@ -419,7 +419,7 @@ editor_table_wrapper = function (editor) {
var cobj = JSON.parse(tr.children[1].getAttribute('cobj')); var cobj = JSON.parse(tr.children[1].getAttribute('cobj'));
var input = tr.children[2].children[0].children[0]; var input = tr.children[2].children[0].children[0];
if (cobj._type === 'event') editor_blockly.import(guid, { type: cobj._event }); if (cobj._type === 'event') editor_blockly.import(guid, { type: cobj._event });
if (cobj._type === 'textarea') editor_multi.import(guid, { lint: cobj._lint, string: cobj._string, template: cobj._template }); if (cobj._type === 'textarea') editor_multi.import(guid, { lint: cobj._lint, string: cobj._string, template: cobj._template, preview: cobj._preview });
if (cobj._type === 'material') editor.table.selectMaterial(input, cobj); if (cobj._type === 'material') editor.table.selectMaterial(input, cobj);
if (cobj._type === 'color') editor.table.selectColor(input); if (cobj._type === 'color') editor.table.selectColor(input);
if (cobj._type === 'point') editor.table.selectPoint(input); if (cobj._type === 'point') editor.table.selectPoint(input);
@ -451,7 +451,7 @@ editor_table_wrapper = function (editor) {
editor_table.prototype.dblclickfunc = function (guid, obj, commentObj, thisTr, input, field, cobj, modeNode) { editor_table.prototype.dblclickfunc = function (guid, obj, commentObj, thisTr, input, field, cobj, modeNode) {
if (editor_mode.doubleClickMode === 'change') { if (editor_mode.doubleClickMode === 'change') {
if (cobj._type === 'event') editor_blockly.import(guid, { type: cobj._event }); if (cobj._type === 'event') editor_blockly.import(guid, { type: cobj._event });
if (cobj._type === 'textarea') editor_multi.import(guid, { lint: cobj._lint, string: cobj._string, template: cobj._template }); if (cobj._type === 'textarea') editor_multi.import(guid, { lint: cobj._lint, string: cobj._string, template: cobj._template, preview: cobj._preview });
if (cobj._type === 'material') editor.table.selectMaterial(input, cobj); if (cobj._type === 'material') editor.table.selectMaterial(input, cobj);
if (cobj._type === 'color') editor.table.selectColor(input); if (cobj._type === 'color') editor.table.selectColor(input);
if (cobj._type === 'point') editor.table.selectPoint(input); if (cobj._type === 'point') editor.table.selectPoint(input);

View File

@ -336,856 +336,4 @@ editor_ui_wrapper = function (editor) {
"双击事件编辑器:长文本编辑/脚本编辑/地图选点/UI绘制预览" "双击事件编辑器:长文本编辑/脚本编辑/地图选点/UI绘制预览"
); );
} }
// ------ UI预览 & 地图选点相关 ------ //
var uievent = {
elements: {},
values: {},
isOpen: false,
mode: ""
};
uievent.elements.div = document.getElementById('uieventDiv');
uievent.elements.title = document.getElementById('uieventTitle');
uievent.elements.yes = document.getElementById('uieventYes');
uievent.elements.no = document.getElementById('uieventNo');
uievent.elements.selectBackground = document.getElementById('uieventBackground');
uievent.elements.selectPoint = document.getElementById('selectPoint');
uievent.elements.selectFloor = document.getElementById('selectPointFloor');
uievent.elements.selectPointBox = document.getElementById('selectPointBox');
uievent.elements.body = document.getElementById('uieventBody');
uievent.elements.selectPointButtons = document.getElementById('selectPointButtons');
uievent.elements.canvas = document.getElementById('uievent');
uievent.elements.usedFlags = document.getElementById('uieventUsedFlags');
uievent.elements.extraBody = document.getElementById('uieventExtraBody');
uievent.close = function () {
uievent.isOpen = false;
uievent.elements.div.style.display = 'none';
if (uievent.values.interval) {
clearTimeout(uievent.values.interval);
clearInterval(uievent.values.interval);
}
uievent.values = {};
}
uievent.elements.no.onclick = uievent.close;
uievent.elements.selectBackground.onchange = function () {
uievent.drawPreviewUI();
}
uievent.drawPreviewUI = function () {
core.setAlpha('uievent', 1);
core.clearMap('uievent');
core.setFilter('uievent', null);
// 绘制UI
var background = uievent.elements.selectBackground.value;
if (background == 'thumbnail') {
core.drawThumbnail(editor.currentFloorId, null, {ctx: 'uievent'});
}
else {
core.fillRect('uievent', 0, 0, core.__PIXELS__, core.__PIXELS__, background);
}
if (uievent.values.list instanceof Array) {
uievent.values.list.forEach(function (data) {
if (typeof data == 'string') data = { "type": "text", "text": data };
var type = data.type;
if (type == "text") {
data.ctx = 'uievent';
core.saveCanvas('uievent');
core.drawTextBox(data.text, data);
core.loadCanvas('uievent');
return;
}
else if (type == "choices") {
for (var i = 0; i < data.choices.length; i++) {
if (typeof data.choices[i] === 'string')
data.choices[i] = {"text": data.choices[i]};
data.choices[i].text = core.replaceText(data.choices[i].text);
}
core.saveCanvas('uievent');
core.status.event.selection = data.selected || 0;
core.drawChoices(core.replaceText(data.text), data.choices, data.width, 'uievent');
core.status.event.selection = null;
core.loadCanvas('uievent');
return;
} else if (type == "confirm") {
core.saveCanvas('uievent');
core.drawConfirmBox(data.text, null, null, 'uievent');
core.loadCanvas('uievent');
} else if (core.ui["_uievent_" + type])
core.ui["_uievent_" + type](data);
})
}
}
uievent.previewUI = function (list) {
uievent.isOpen = true;
uievent.elements.div.style.display = 'block';
uievent.mode = 'previewUI';
uievent.elements.selectPoint.style.display = 'none';
uievent.elements.yes.style.display = 'none';
uievent.elements.title.innerText = 'UI绘制预览';
uievent.elements.selectBackground.style.display = 'inline';
uievent.elements.selectBackground.value = 'thumbnail';
uievent.elements.selectFloor.style.display = 'none';
uievent.elements.selectPointBox.style.display = 'none';
uievent.elements.canvas.style.display = 'block';
uievent.elements.usedFlags.style.display = 'none';
uievent.elements.extraBody.style.display = 'none';
uievent.elements.body.style.overflow = "hidden";
uievent.values.list = list;
uievent.drawPreviewUI();
}
uievent.selectPoint = function (floorId, x, y, bigmap, callback) {
uievent.values.bigmap = bigmap;
uievent.values.size = editor.isMobile ? window.innerWidth / core.__SIZE__ : 32;
uievent.isOpen = true;
uievent.elements.div.style.display = 'block';
uievent.mode = 'selectPoint';
uievent.elements.selectPoint.style.display = 'block';
uievent.elements.yes.style.display = 'inline';
uievent.elements.selectBackground.style.display = 'none';
uievent.elements.selectFloor.style.display = 'inline';
uievent.elements.selectPointBox.style.display = 'block';
uievent.elements.canvas.style.display = 'block';
uievent.elements.usedFlags.style.display = 'none';
uievent.elements.extraBody.style.display = 'none';
uievent.elements.body.style.overflow = "hidden";
uievent.elements.yes.onclick = function () {
var floorId = uievent.values.floorId, x = uievent.values.x, y = uievent.values.y;
var multipoints = uievent.values.multipoints || [];
uievent.close();
if (callback) {
if (multipoints.length > 0) {
callback(floorId, multipoints.map(function (one) { return one.split(',')[0]}).join(','),
multipoints.map(function (one) { return one.split(',')[1]}).join(','));
} else {
callback(floorId, x, y);
}
}
}
// Append children
var floors = "";
core.floorIds.forEach(function (f) {
floors += "<option value=" + f + ">" + f + "</option>";
})
uievent.elements.selectFloor.innerHTML = floors;
// 检查多选点
if (/^\d+(,\d+)+$/.test(x) && /^\d+(,\d+)+$/.test(y)) {
var xx = x.split(','), yy = y.split(',');
uievent.values.multipoints = [];
for (var i = 0; i < xx.length; ++i) {
uievent.values.multipoints.push(xx[i] + "," + yy[i]);
}
x = xx[xx.length - 1];
y = yy[yy.length - 1];
}
this.setPoint(floorId || editor.currentFloorId, core.calValue(x) || 0, core.calValue(y) || 0);
}
uievent.updateSelectPoint = function (redraw) {
uievent.elements.title.innerText = '地图选点【右键多选】 (' + uievent.values.x + "," + uievent.values.y + ')';
// 计算size
uievent.values.boxSize = uievent.values.size *
(uievent.values.bigmap ? (core.__SIZE__ / Math.max(uievent.values.width, uievent.values.height)) : 1);
uievent.values.boxLeft = uievent.values.bigmap ?
(core.__PIXELS__ * Math.max(0, (1 - uievent.values.width / uievent.values.height) / 2)) : 0;
uievent.values.boxTop = uievent.values.bigmap ?
(core.__PIXELS__ * Math.max(0, (1 - uievent.values.height / uievent.values.width) / 2)) : 0;
if (uievent.values.bigmap) {
uievent.elements.selectPointBox.style.left = uievent.values.boxSize * uievent.values.x + uievent.values.boxLeft + "px";
uievent.elements.selectPointBox.style.top = uievent.values.boxSize * uievent.values.y + uievent.values.boxTop + "px";
} else {
uievent.elements.selectPointBox.style.left = uievent.values.boxSize * (uievent.values.x - uievent.values.left) + "px";
uievent.elements.selectPointBox.style.top = uievent.values.boxSize * (uievent.values.y - uievent.values.top) + "px";
}
uievent.elements.selectPointBox.style.width = uievent.values.boxSize - 6 + "px";
uievent.elements.selectPointBox.style.height = uievent.values.boxSize - 6 + "px";
if (redraw) {
core.setAlpha('uievent', 1);
core.clearMap('uievent');
core.drawThumbnail(uievent.values.floorId, null, {
ctx: 'uievent', centerX: uievent.values.left + core.__HALF_SIZE__,
centerY: uievent.values.top + core.__HALF_SIZE__, all: uievent.values.bigmap
});
uievent.values.multipoints = uievent.values.multipoints || [];
core.setTextAlign('uievent', 'right');
for (var i = 0; i < uievent.values.multipoints.length; ++i) {
var xy = uievent.values.multipoints[i].split(","), x = parseInt(xy[0]), y = parseInt(xy[1]);
core.fillBoldText('uievent', i + 1,
32 * (x - uievent.values.left) + 28 , 32 * (y - uievent.values.top) + 26, '#FF7F00', null, '14px Verdana');
}
core.setTextAlign('uievent', 'left');
}
}
uievent.setPoint = function (floorId, x, y) {
if (core.floorIds.indexOf(floorId) == -1) floorId = editor.currentFloorId;
uievent.values.floorId = floorId;
uievent.elements.selectFloor.value = floorId;
uievent.values.x = x != null ? x : (uievent.values.x || 0);
uievent.values.y = y != null ? y : (uievent.values.y || 0);
uievent.values.width = core.floors[uievent.values.floorId].width || core.__SIZE__;
uievent.values.height = core.floors[uievent.values.floorId].height || core.__SIZE__;
uievent.values.left = core.clamp(uievent.values.x - core.__HALF_SIZE__, 0, uievent.values.width - core.__SIZE__);
uievent.values.top = core.clamp(uievent.values.y - core.__HALF_SIZE__, 0, uievent.values.height - core.__SIZE__);
uievent.updateSelectPoint(true);
}
uievent.elements.selectFloor.onchange = function () {
uievent.values.multipoints = [];
uievent.setPoint(uievent.elements.selectFloor.value);
}
uievent.elements.selectPointBox.onclick = function (e) {
e.preventDefault();
e.stopPropagation();
return false;
}
uievent.elements.body.onclick = function (e) {
if (uievent.mode != 'selectPoint') return;
if (uievent.values.bigmap) {
uievent.values.x = core.clamp(Math.floor((e.offsetX - uievent.values.boxLeft) / uievent.values.boxSize), 0, uievent.values.width - 1);
uievent.values.y = core.clamp(Math.floor((e.offsetY - uievent.values.boxTop) / uievent.values.boxSize), 0, uievent.values.height - 1);
} else {
uievent.values.x = uievent.values.left + Math.floor(e.offsetX / uievent.values.size);
uievent.values.y = uievent.values.top + Math.floor(e.offsetY / uievent.values.size);
}
uievent.updateSelectPoint(false);
}
uievent.elements.body.oncontextmenu = function (e) {
e.preventDefault();
e.stopPropagation();
if (uievent.mode != 'selectPoint' || uievent.values.bigmap) return;
var x = uievent.values.left + Math.floor(e.offsetX / uievent.values.size);
var y = uievent.values.top + Math.floor(e.offsetY / uievent.values.size);
uievent.values.multipoints = uievent.values.multipoints || [];
if (uievent.values.multipoints.indexOf(x+","+y) >= 0) {
uievent.values.multipoints = uievent.values.multipoints.filter(function (o) { return o != x+","+y;})
} else {
uievent.values.multipoints.push(x+","+y);
}
uievent.values.x = x;
uievent.values.y = y;
uievent.updateSelectPoint(true);
return false;
}
uievent.move = function (dx, dy) {
if (uievent.mode != 'selectPoint') return;
if (uievent.values.bigmap) return;
uievent.values.left = core.clamp(uievent.values.left + dx, 0, uievent.values.width - core.__SIZE__);
uievent.values.top = core.clamp(uievent.values.top + dy, 0, uievent.values.height - core.__SIZE__);
this.updateSelectPoint(true);
};
uievent.triggerBigmap = function () {
if (uievent.mode != 'selectPoint') return;
uievent.values.bigmap = !uievent.values.bigmap;
uievent.values.multipoints = [];
uievent.setPoint(uievent.values.floorId);
};
(function () {
var viewportButtons = uievent.elements.selectPointButtons;
var pressTimer = null;
for (var ii = 0, node; node = viewportButtons.children[ii]; ii++) {
if (ii == 4) {
node.onclick = uievent.triggerBigmap;
continue;
}
if (ii == 5) {
node.onclick = function () {
alert(core.copy(uievent.values.floorId) ? ('楼层ID '+uievent.values.floorId+' 已成功复制到剪切板') : '无法复制楼层ID');
}
}
(function (x, y) {
var move = function () {
uievent.move(x, y);
}
node.onmousedown = function () {
clearTimeout(pressTimer);
pressTimer = setTimeout(function () {
pressTimer = -1;
var f = function () {
if (pressTimer != null) {
move();
setTimeout(f, 150);
}
}
f();
}, 500);
};
node.onmouseup = function () {
if (pressTimer > 0) {
clearTimeout(pressTimer);
move();
}
pressTimer = null;
}
})([-1, 0, 0, 1][ii], [0, -1, 1, 0][ii]);
}
})();
uievent.elements.div.onmousewheel = function (e) {
if (uievent.mode != 'selectPoint') return;
var index = core.floorIds.indexOf(uievent.values.floorId);
try {
if (e.wheelDelta)
index += Math.sign(e.wheelDelta);
else if (e.detail)
index += Math.sign(e.detail);
} catch (ee) { main.log(ee); }
index = core.clamp(index, 0, core.floorIds.length - 1);
uievent.values.multipoints = [];
uievent.setPoint(core.floorIds[index]);
}
uievent.onKeyDown = function (e) {
if (e.keyCode == 27) editor.uievent.close();
if (uievent.mode == 'selectPoint') {
if (e.keyCode == 87) editor.uievent.move(0, -1)
if (e.keyCode == 65) editor.uievent.move(-1, 0)
if (e.keyCode == 83) editor.uievent.move(0, 1);
if (e.keyCode == 68) editor.uievent.move(1, 0);
}
}
// ------ 搜索变量出现的位置也放在uievent好了 ------ //
uievent.searchUsedFlags = function () {
uievent.isOpen = true;
uievent.elements.div.style.display = 'block';
uievent.mode = 'searchUsedFlags';
uievent.elements.selectPoint.style.display = 'none';
uievent.elements.yes.style.display = 'none';
uievent.elements.title.innerText = '搜索变量';
uievent.elements.selectBackground.style.display = 'none';
uievent.elements.selectFloor.style.display = 'none';
uievent.elements.selectPointBox.style.display = 'none';
uievent.elements.canvas.style.display = 'none';
uievent.elements.usedFlags.style.display = 'inline';
uievent.elements.extraBody.style.display = 'block';
uievent.elements.body.style.overflow = "auto";
// build flags
var html = "";
Object.keys(editor.used_flags).sort().forEach(function (v) {
v = "flag:" + v;
html += "<option value='" + v + "'>" + v + "</option>";
});
uievent.elements.usedFlags.innerHTML = html;
uievent.doSearchUsedFlags();
}
uievent.doSearchUsedFlags = function () {
var flag = uievent.elements.usedFlags.value;
var html = "<p style='margin-left: 10px'>该变量出现的所有位置如下:</p><ul>";
var list = uievent._searchUsedFlags(flag);
list.forEach(function (x) {
html += "<li>" + x + "</li>";
});
html += "</ul>";
uievent.elements.extraBody.innerHTML = html;
}
var hasUsedFlags = function (obj, flag) {
if (obj == null) return false;
if (typeof obj != 'string') return hasUsedFlags(JSON.stringify(obj), flag);
var index = -1, length = flag.length;
while (true) {
index = obj.indexOf(flag, index + 1);
if (index < 0) return false;
if (!/^[a-zA-Z0-9_\u4E00-\u9FCC\u3040-\u30FF\u2160-\u216B\u0391-\u03C9]$/.test(obj.charAt(index + length))) return true;
}
}
uievent._searchUsedFlags = function (flag) {
var list = [];
// 每个点的事件
var events = ["events", "autoEvent", "changeFloor", "beforeBattle", "afterBattle", "afterGetItem", "afterOpenDoor"]
for (var floorId in core.floors) {
var floor = core.floors[floorId];
if (hasUsedFlags(floor.firstArrive, flag)) list.push([floorId, "firstArrive"]);
if (hasUsedFlags(floor.eachArrive, flag)) list.push([floorId, "eachArrive"]);
events.forEach(function (e) {
if (floor[e]) {
for (var loc in floor[e]) {
if (hasUsedFlags(floor[e][loc], flag)) {
list.push(floorId + " 层 " + e + " 的 (" + loc + ") 点");
}
}
}
});
}
// 公共事件
for (var name in events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent) {
if (hasUsedFlags(events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent[name], flag))
list.push("公共事件 " + name);
}
// 道具 & 装备属性
for (var id in items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a) {
var item = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a[id];
// 装备属性
if (hasUsedFlags(item.equip, flag)) {
list.push("道具 " + (item.name || id) + " 的装备属性");
}
// 使用事件
if (hasUsedFlags(item.useItemEvent, flag)) {
list.push("道具 " + (item.name || id) + " 的使用事件");
}
}
// 怪物战前 & 战后
for (var id in enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80) {
var enemy = enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80[id];
if (hasUsedFlags(enemy.beforeBattle, flag)) {
list.push("怪物 " + (enemy.name || id) + " 的战前事件");
}
if (hasUsedFlags(enemy.afterBattle, flag)) {
list.push("怪物 " + (enemy.name || id) + " 的战后事件");
}
}
// 图块的碰触 & 门信息
for (var id in maps_90f36752_8815_4be8_b32b_d7fad1d0542e) {
var mapInfo = maps_90f36752_8815_4be8_b32b_d7fad1d0542e[id];
if (hasUsedFlags(mapInfo.doorInfo, flag))
list.push("图块 " + (mapInfo.name || mapInfo.id) + " 的门信息");
if (hasUsedFlags(mapInfo.event, flag))
list.push("图块 " + (mapInfo.name || mapInfo.id) + " 碰触事件");
}
// 难度 & 标题事件 & 开场剧情 & 等级提升
if (hasUsedFlags(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.levelChoose, flag))
list.push("难度分歧");
if (hasUsedFlags(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.startCanvas, flag))
list.push("标题事件");
if (hasUsedFlags(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.startText, flag))
list.push("开场剧情");
if (hasUsedFlags(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.levelUp, flag))
list.push("等级提升");
// 全局商店
(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.shops || []).forEach(function (shop) {
if (hasUsedFlags(shop, flag)) list.push("商店 " + shop.id);
});
return list;
}
// ------ 素材选择框 ------ //
uievent.selectMaterial = function (value, title, directory, transform, callback) {
var one = directory.split(':');
if (one.length > 1) directory = one[0];
var appendedImages = one[1] == 'images' ? core.material.images.images : {};
fs.readdir(directory, function (err, data) {
if (err) {
printe(directory + '不存在!');
throw (directory + '不存在!');
}
if (!(data instanceof Array)) {
printe('没有可显示的内容')
return;
}
value = value || [];
data = (transform ? data.map(transform) : data).filter(function (one) {return one;}).sort();
var data2 = Object.keys(appendedImages);
data2 = (transform ? data2.map(transform) : data2).filter(function (one) {
return one && data.indexOf(one) < 0;
}).sort();
uievent.isOpen = true;
uievent.elements.div.style.display = 'block';
uievent.mode = 'selectMaterial';
uievent.elements.selectPoint.style.display = 'none';
uievent.elements.yes.style.display = 'block';
uievent.elements.title.innerText = title;
uievent.elements.selectBackground.style.display = 'none';
uievent.elements.selectFloor.style.display = 'none';
uievent.elements.selectPointBox.style.display = 'none';
uievent.elements.canvas.style.display = 'none';
uievent.elements.usedFlags.style.display = 'none';
uievent.elements.extraBody.style.display = 'block';
uievent.elements.body.style.overflow = "auto";
uievent.elements.yes.onclick = function () {
var list = Array.from(document.getElementsByClassName('materialCheckbox')).filter(function (one) {
return one.checked;
}).map(function (one) {return one.getAttribute('key'); });
uievent.close();
if (callback) callback(list);
}
var _isTileset = directory.indexOf('project/tilesets') >= 0;
// 显示每一项内容
var html = "<p style='margin-left: 10px; line-height: 25px'>";
html += "<button onclick='editor.uievent._selectAllMaterial(true)'>全选</button>"+
"<button style='margin-left: 10px' onclick='editor.uievent._selectAllMaterial(false)'>全不选</button><br/>";
if (_isTileset) {
html += "<b style='margin-top: 5px;'>警告!额外素材一旦注册成功将不可删除,否则可能会导致素材错位风险!如果你不再想用某个额外素材,"
+"但又不想让它出现在素材区,可以考虑使用空气墙同名替换该额外素材文件。</b><br/>"
}
data.forEach(function (one) {
var checked = value.indexOf(one) >= 0? 'checked' : '';
var disabled = _isTileset && value.indexOf(one) >= 0 ? 'disabled' : ''
html += `<input type="checkbox" key="${one}" class="materialCheckbox" ${checked} ${disabled}/> ${one}`;
// 预览图片
if (one.endsWith('.png') || one.endsWith('.jpg') || one.endsWith('.jpeg') || one.endsWith('.gif')) {
html += "<button onclick='editor.uievent._previewMaterialImage(this)' style='margin-left: 10px'>预览</button>";
html += '<br style="display:none"/><img key="'+directory+one+'" style="display:none; max-width: 100%"/>';
}
// 试听音频
if (one.endsWith('.mp3') || one.endsWith('.ogg') || one.endsWith('.wav') || one.endsWith('.m4a') || one.endsWith('.flac')) {
html += "<button onclick='editor.uievent._previewMaterialAudio(this)' style='margin-left: 10px'>播放</button>"
html += "<small> 音调:<input value='100' style='width:28px' onchange='editor.uievent._previewMaterialAudio_onPitchChange(this)'></small>";
html += `<small style='display:none; margin-left: 15px'>0:00 / 0:00</small><br style="display:none"/>
<audio preload="none" src="${directory+one}" ontimeupdate="editor.uievent._previewMaterialAudio_onTimeUpdate(this)"></audio>
<progress value="0" max="1" style="display:none; width:100%" onclick="editor.uievent._previewMaterialAudio_seek(this, event)"></progress>`;
}
// 预览动画
if (directory.indexOf('animates') >= 0) {
html += "<button onclick='editor.uievent._previewMaterialAnimate(this)' style='margin-left: 10px'>预览</button>";
html += "<span style='display:none; margin-left: 10px' key='"+directory+one+".animate'></span>";
}
html += '<br/>';
});
data2.forEach(function (one) {
var checked = value.indexOf(one) >= 0? 'checked' : '';
var disabled = _isTileset && value.indexOf(one) >= 0 ? 'disabled' : '';
html += `<input type="checkbox" key="${one}" class="materialCheckbox" ${checked} ${disabled}/> ${one}`;
// 预览图片
if (one.endsWith('.png') || one.endsWith('.jpg') || one.endsWith('.jpeg') || one.endsWith('.gif')) {
html += "<button onclick='editor.uievent._previewMaterialImage2(this)' style='margin-left: 10px'>预览</button>";
html += '<br style="display:none" key="'+one+'"/><br/>';
}
})
html += "</p>";
html += "<p style='margin-left: 10px'><small>如果文件未在此列表显示,请检查文件名是否合法(只能由数字字母下划线横线和点组成),后缀名是否正确。</small></p>";
uievent.elements.extraBody.innerHTML = html;
});
}
uievent._selectAllMaterial = function (checked) {
Array.from(document.getElementsByClassName('materialCheckbox')).forEach(function (one) {
if (!one.disabled) one.checked = checked;
})
}
uievent._previewMaterialImage = function (button) {
var br = button.nextElementSibling;
var img = br.nextElementSibling;
if (br.style.display == 'none') {
button.innerText = '折叠';
br.style.display = 'block';
img.style.display = 'block';
img.src = img.getAttribute('key');
} else {
button.innerText = '预览';
br.style.display = 'none';
img.style.display = 'none';
}
}
uievent._previewMaterialImage2 = function (button) {
var br = button.nextElementSibling;
if (br.style.display == 'none') {
button.innerText = '折叠';
br.style.display = 'block';
br.parentElement.insertBefore(core.material.images.images[br.getAttribute('key')], br.nextElementSibling);
} else {
button.innerText = '预览';
br.style.display = 'none';
br.parentElement.removeChild(core.material.images.images[br.getAttribute('key')]);
}
}
uievent._previewMaterialAudio = function (button) {
var span = button.nextElementSibling.nextElementSibling;
var br = span.nextElementSibling;
var audio = br.nextElementSibling;
var progress = audio.nextElementSibling;
if (br.style.display == 'none') {
button.innerText = '暂停';
br.style.display = 'block';
progress.style.display = 'block';
span.style.display = 'inline';
audio.play();
} else {
button.innerText = '播放';
br.style.display = 'none';
progress.style.display='none';
span.style.display = 'none';
audio.pause();
}
}
uievent._previewMaterialAudio_onPitchChange = function (input) {
var audio = input.parentElement.nextElementSibling.nextElementSibling.nextElementSibling;
audio.preservesPitch = false;
audio.playbackRate = core.clamp((parseInt(input.value) || 100) / 100, 0.3, 3.0);
}
uievent._previewMaterialAudio_onTimeUpdate = function (audio) {
var _format = function (time) { return parseInt(time/60) + ":" + core.setTwoDigits(parseInt(time) % 60); }
if (audio.duration > 0) {
audio.previousElementSibling.previousElementSibling.innerText = _format(audio.currentTime) + " / " + _format(audio.duration);
audio.nextElementSibling.setAttribute('value', audio.currentTime / audio.duration);
}
}
uievent._previewMaterialAudio_seek = function (element, event) {
var audio = element.previousElementSibling;
var value = event.offsetX * element.max / element.offsetWidth;
element.setAttribute("value", value);
audio.currentTime = audio.duration * value;
if (audio.paused) audio.play();
}
var _previewMaterialAnimate = function (span, content) {
_previewMaterialAnimate_buildSounds(span, content);
// 创建dom
if (!uievent.values.dom) {
var dom = document.createElement('span');
dom.style.position = "relative";
dom.style.marginLeft = "-10px";
var canvas = document.createElement('canvas');
canvas.width = canvas.height = core.__PIXELS__;
canvas.style.position = 'absolute';
core.drawThumbnail(editor.currentFloorId, null, {ctx: canvas.getContext('2d')});
dom.appendChild(canvas);
var canvas2 = document.createElement('canvas');
canvas2.style.position = 'absolute';
canvas2.width = canvas2.height = core.__PIXELS__;
uievent.values.ctx = canvas2.getContext('2d');
dom.appendChild(canvas2);
var canvas3 = document.createElement('canvas');
canvas3.width = canvas3.height = core.__PIXELS__;
dom.appendChild(canvas3);
uievent.values.dom = dom;
}
span.appendChild(uievent.values.dom);
clearInterval(uievent.values.interval);
var frame = 0;
uievent.values.interval = setInterval(function () {
if (span.style.display == 'none') {
clearInterval(uievent.values.interval);
uievent.values.interval = null;
return;
}
core.clearMap(uievent.values.ctx);
core.maps._drawAnimateFrame(uievent.values.ctx, content, core.__PIXELS__ / 2, core.__PIXELS__ / 2, frame++);
}, 50);
}
var _previewMaterialAnimate_buildSounds = function (span, content) {
var sounds = content.se || {};
if (typeof sounds == 'string') sounds = {1: sounds};
var pitch = content.pitch || {};
span.appendChild(document.createElement('br'));
var dom = document.createElement('span');
dom.setAttribute('frames', content.frame);
var html = "";
Object.keys(sounds).forEach(function (frame) {
html += "<span>" + _previewMaterialAnimate_buildSoundRow(frame, sounds[frame], content.frame, pitch[frame]) + "</span>";
});
html += '<button onclick="editor.uievent._previewMaterialAnimate_addSound(this)">添加音效</button>';
html += '<button onclick="editor.uievent._previewMaterialAnimate_saveSound(this)" style="margin-left:10px">保存</button>';
html += "<br/><br/>";
dom.innerHTML = html;
span.appendChild(dom);
_previewMaterialAnimate_awesomplete(span);
}
var _previewMaterialAnimate_buildSoundRow = function (index, se, frames, pitch) {
var audios = Object.keys(core.material.sounds).sort().join(",");
var html = "";
html += "第 <select>";
for (var i = 1; i <= frames; ++i) {
html += "<option value="+i;
if (index == i) html += " selected";
html += ">"+i+"</option>";
}
html += "</select> 帧:";
html += '<input type="text" class="_audio" data-list="'+audios+'" data-minchars="1" data-autofirst="true" style="width: 110px" value="'+se+'"/>';
html += '<button onclick="editor.uievent._previewMaterialAnimate_previewSound(this)" style="margin-left: 10px">试听</button>';
html += "<small> 音调:<input value='"+(pitch||100)+"' style='width:28px'></small>";
html += '<button onclick="editor.uievent._previewMaterialAnimate_deleteSound(this)" style="margin-left: 10px">删除</button>';
html += '<br/>';
return html;
}
var _previewMaterialAnimate_awesomplete = function (span) {
var inputs = span.getElementsByClassName("_audio");
for (var i = 0; i < inputs.length; ++i) {
var input = inputs[i];
if (!input.hasAttribute('awesomplete')) {
input.setAttribute('awesomplete', '1');
new Awesomplete(input);
}
}
}
uievent._previewMaterialAnimate = function (button) {
var span = button.nextElementSibling;
while (span.firstChild) span.removeChild(span.lastChild);
var filename = span.getAttribute("key");
uievent.values.animates = uievent.values.animates || {};
if (span.style.display == 'none') {
button.innerText = '收起';
span.style.display = 'inline';
if (uievent.values.animates[filename]) {
_previewMaterialAnimate(span, uievent.values.animates[filename]);
} else {
fs.readFile(filename, 'utf-8', function (e, d) {
if (e) {
alert('无法打开动画文件!'+e); return;
}
uievent.values.animates[filename] = core.loader._loadAnimate(d);
if (uievent.values.animates[filename]) {
uievent.values.animates[filename + ':raw'] = JSON.parse(d);
_previewMaterialAnimate(span, uievent.values.animates[filename]);
}
})
}
} else {
button.innerText = '预览';
span.style.display = 'none';
}
}
uievent._previewMaterialAnimate_previewSound = function (button) {
var input = button.previousElementSibling;
if (input.tagName == 'DIV') input = input.firstChild;
if (!input.value) return;
if (!uievent.values.audio)
uievent.values.audio = new Audio();
uievent.values.audio.src = './project/sounds/' + input.value;
uievent.values.audio.preservesPitch = false;
uievent.values.audio.playbackRate = core.clamp((parseInt(button.nextElementSibling.children[0].value) || 100) / 100, 0.3, 3.0);
uievent.values.audio.play();
}
uievent._previewMaterialAnimate_addSound = function (button) {
var parent = button.parentElement;
var span = document.createElement("span");
span.innerHTML = _previewMaterialAnimate_buildSoundRow(1, "", parseInt(parent.getAttribute("frames")));
parent.insertBefore(span, button);
_previewMaterialAnimate_awesomplete(parent);
}
uievent._previewMaterialAnimate_deleteSound = function (button) {
var element = button.parentElement;
element.parentElement.removeChild(element);
}
uievent._previewMaterialAnimate_saveSound = function (button) {
var span = button.parentElement;
var filename = span.parentElement.getAttribute("key");
if (!filename || !uievent.values.animates[filename]) return;
var se = {};
var pitch = {};
var audios = span.getElementsByClassName("_audio");
for (var i = 0; i < audios.length; ++i) {
var audio = audios[i];
var select = audio.parentElement.previousElementSibling;
if (audio.value && select.tagName == 'SELECT') {
se[select.value] = audio.value;
var p = audio.parentElement.nextElementSibling.nextElementSibling.children[0];
pitch[select.value] = core.clamp(parseInt(p.value) || 100, 30, 300);
}
}
uievent.values.animates[filename].se = se;
uievent.values.animates[filename+':raw'].se = se;
uievent.values.animates[filename].pitch = pitch;
uievent.values.animates[filename+':raw'].pitch = pitch;
fs.writeFile(filename, JSON.stringify(uievent.values.animates[filename+':raw']), 'utf-8', function (e, d) {
if (e) alert('无法修改音效文件!'+e);
else {
alert('动画音效修改成功!别忘了在全塔属性中注册音效哦!');
}
})
}
// ------ 多选框 ------ //
uievent.popCheckboxSet = function (value, comments, title, callback) {
if (value == null) value = [];
if (!(value instanceof Array)) {
if (value == 0) value = [];
else value = [value];
}
uievent.isOpen = true;
uievent.elements.div.style.display = 'block';
uievent.mode = 'popCheckboxSet';
uievent.elements.selectPoint.style.display = 'none';
uievent.elements.yes.style.display = 'block';
uievent.elements.title.innerText = title;
uievent.elements.selectBackground.style.display = 'none';
uievent.elements.selectFloor.style.display = 'none';
uievent.elements.selectPointBox.style.display = 'none';
uievent.elements.canvas.style.display = 'none';
uievent.elements.usedFlags.style.display = 'none';
uievent.elements.extraBody.style.display = 'block';
uievent.elements.body.style.overflow = "auto";
uievent.elements.yes.onclick = function () {
var list = Array.from(document.getElementsByClassName('uieventCheckboxSet')).filter(function (one) {
return one.checked;
}).map(function (one) {
var value = one.getAttribute('key');
if (one.getAttribute('_type') == 'number') value = parseFloat(value);
return value;
});
uievent.close();
if (callback) callback(list);
}
var keys=Array.from(comments.key)
var prefixStrings=Array.from(comments.prefix)
for (var index = 0; index < value.length; index++) {
if (keys.indexOf(value[index])==-1) {
prefixStrings.push(value[index]+': ')
keys.push(value[index])
}
}
var table = '<table style="width: 100%">';
for (var index = 0; index < keys.length; index++) {
var one = keys[index];
if (index % 3 == 0) {
table += '<tr>';
}
table += `<td class='popCheckboxItem'>${prefixStrings[index]}<input type="checkbox" _type="${typeof one}" key="${one}" class="uieventCheckboxSet" ${value.indexOf(one) >= 0? 'checked' : ''}/></td>`;
if (index % 3 == 2) {
table += '</tr>';
}
}
if (keys.length % 3 != 0) table += '</tr>';
table += '</table>';
uievent.elements.extraBody.innerHTML = "<p>"+table+"</p>";
}
editor.constructor.prototype.uievent=uievent;
} }

1068
_server/editor_uievent.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -138,9 +138,9 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"equipName": { "equipName": {
"_leaf": true, "_leaf": true,
"_type": "textarea", "_type": "textarea",
"_range": "(thiseval instanceof Array && thiseval.length<=6)||thiseval==null", "_range": "(thiseval instanceof Array)||thiseval==null",
"_docs": "装备孔", "_docs": "装备孔",
"_data": "装备位名称,为不超过6个的数组此项的顺序与equiptype数值关联例如可写[\"武器\",\"防具\",\"首饰\"]等等。" "_data": "装备位名称,为一个数组此项的顺序与equiptype数值关联例如可写[\"武器\",\"防具\",\"首饰\"]等等。"
}, },
"startBgm": { "startBgm": {
"_leaf": true, "_leaf": true,
@ -344,7 +344,6 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"flags": { "flags": {
"_leaf": true, "_leaf": true,
"_type": "textarea", "_type": "textarea",
"_hide": true,
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)", "_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
"_data": "游戏变量" "_data": "游戏变量"
}, },
@ -490,10 +489,10 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_leaf": true, "_leaf": true,
"_type": "select", "_type": "select",
"_select": { "_select": {
"values": [1, 2, 3, 4] "values": [1, 2, 3, 4, 5]
}, },
"_docs": "竖状态栏自绘行数", "_docs": "竖状态栏自绘行数",
"_data": "竖屏模式下顶端状态栏canvas化后的行数。\n此项将决定竖屏的状态栏高度如果设置则不小于1且不大于4。\n仅在statusCanvas开启时才有效" "_data": "竖屏模式下顶端状态栏canvas化后的行数。\n此项将决定竖屏的状态栏高度如果设置则不小于1且不大于5。\n仅在statusCanvas开启时才有效"
}, },
"floorChangeTime": { "floorChangeTime": {
"_leaf": true, "_leaf": true,

View File

@ -192,6 +192,7 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_leaf": true, "_leaf": true,
"_type": "textarea", "_type": "textarea",
"_lint": true, "_lint": true,
"_preview": "statusBar",
"_data": "自绘状态栏" "_data": "自绘状态栏"
}, },
"drawStatistics": { "drawStatistics": {

View File

@ -109,7 +109,7 @@
} }
}); });
if (!isInput) if (!isInput)
style.whiteSpace = 'pre'; style.whiteSpace = 'pre-wrap';
if (isFirefox) { if (isFirefox) {
// Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275 // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 593 KiB

View File

@ -29,9 +29,9 @@
<div id="editTip"> <div id="editTip">
<input id='newFileName' placeholder="新楼层id" style="width: 100px"/> <input id='newFileName' placeholder="新楼层id" style="width: 100px"/>
<span style="vertical-align: bottom"></span> <span style="vertical-align: bottom"></span>
<input id='newMapWidth' value="13" style="width: 20px"/> <input id='newMapWidth' style="width: 20px"/>
<span style="vertical-align: bottom"></span> <span style="vertical-align: bottom"></span>
<input id='newMapHeight' value="13" style="width: 20px"/> <input id='newMapHeight' style="width: 20px"/>
<input type="checkbox" id='newMapStatus' checked='checked' style='vertical-align: bottom'/> <input type="checkbox" id='newMapStatus' checked='checked' style='vertical-align: bottom'/>
<span style='vertical-align: bottom;'>保留楼层属性</span> <span style='vertical-align: bottom;'>保留楼层属性</span>
<br/> <br/>
@ -55,9 +55,9 @@
<input id='newFloorNames' style="width: 70px" value='${i}'/> <input id='newFloorNames' style="width: 70px" value='${i}'/>
<br/> <br/>
<span style="vertical-align: bottom"></span> <span style="vertical-align: bottom"></span>
<input id='newMapsWidth' value="13" style="width: 20px"/> <input id='newMapsWidth' style="width: 20px"/>
<span style="vertical-align: bottom"></span> <span style="vertical-align: bottom"></span>
<input id='newMapsHeight' value="13" style="width: 20px"/> <input id='newMapsHeight' style="width: 20px"/>
<input type="checkbox" id='newMapsStatus' checked='checked' style='vertical-align: bottom'/> <input type="checkbox" id='newMapsStatus' checked='checked' style='vertical-align: bottom'/>
<span style='vertical-align: bottom; margin-left: -4px'>保留楼层属性</span> <span style='vertical-align: bottom; margin-left: -4px'>保留楼层属性</span>
<br/> <br/>
@ -150,12 +150,14 @@
<button>确定</button> <button>确定</button>
<br/> <br/>
<button style="margin-top: 10px">自动注册</button> <button style="margin-top: 10px">自动注册</button>
<button style="margin-top: 10px; margin-left: 10px">删除此素材</button> <button style="margin-top: 10px; margin-left: 5px">删除此素材</button>
<button style="margin-top: 10px; margin-left: 5px">以此素材为模板追加</button>
</div> </div>
<div id='changeId'><!-- id and idnum --> <div id='changeId'><!-- id and idnum -->
<input placeholder="修改图块id为"/> <input placeholder="修改图块id为" style="width: 100px"/>
<button>确定</button> <button>确定</button>
<button style="margin-left: 10px">删除此素材</button> <button style="margin-left: 5px">删除此素材</button>
<button style="margin-left: 5px">以此素材为模板追加</button>
</div> </div>
</div> </div>
</div> </div>
@ -210,6 +212,7 @@
<button onclick="editor_blockly.runCode()">console.log(obj=code)</button> <button onclick="editor_blockly.runCode()">console.log(obj=code)</button>
--> -->
<button onclick="editor_blockly.confirm()">确认</button> <button onclick="editor_blockly.confirm()">确认</button>
<button onclick="editor_blockly.confirm(true)">应用</button>
<button id='blocklyParse' onclick="editor_blockly.parse()">解析</button> <button id='blocklyParse' onclick="editor_blockly.parse()">解析</button>
<button onclick="editor_blockly.cancel()">取消</button> <button onclick="editor_blockly.cancel()">取消</button>
<!-- 手机端放不下,因此不显示搜索框 --> <!-- 手机端放不下,因此不显示搜索框 -->
@ -241,7 +244,9 @@
<div id="left7" style="z-index:-1;opacity: 0;"><!-- 多行文本编辑器 --> <div id="left7" style="z-index:-1;opacity: 0;"><!-- 多行文本编辑器 -->
<button onclick="editor_multi.confirm()">确认</button> <button onclick="editor_multi.confirm()">确认</button>
<button onclick="editor_multi.cancel()">取消</button> <button onclick="editor_multi.cancel()">取消</button>
<button onclick="editor_multi.confirm(true)">应用</button>
<button onclick="editor_multi.format()">格式化</button> <button onclick="editor_multi.format()">格式化</button>
<button id="editor_multi_preview" style="display: none;">预览</button>
<input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox" <input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox"
style="vertical-align: middle;margin-left:6px"/> style="vertical-align: middle;margin-left:6px"/>
<span style="vertical-align: middle; margin-left: -3px">语法检查</span> <span style="vertical-align: middle; margin-left: -3px">语法检查</span>
@ -346,7 +351,7 @@
<div id='clearLoc' class="menuitem"><div class="menuitem-content">清空此点及事件</div></div> <div id='clearLoc' class="menuitem"><div class="menuitem-content">清空此点及事件</div></div>
</div> </div>
</div> </div>
<select id="editModeSelect"> <select id="editModeSelect" style="font-size: 12px">
<option value="map">地图编辑</option> <option value="map">地图编辑</option>
<option value="loc">地图选点</option> <option value="loc">地图选点</option>
<option value="enemyitem">图块属性</option> <option value="enemyitem">图块属性</option>
@ -381,8 +386,9 @@
<input type="button" id="bigmapBtn" value="大地图" style="margin-left: 5px"/> <input type="button" id="bigmapBtn" value="大地图" style="margin-left: 5px"/>
</div> </div>
<select id="selectFloor" style="clear:left"></select> <select id="selectFloor" style="clear:left"></select>
<input type="button" value="选层" id='selectFloorBtn'/>
<input type="button" value="保存地图" id='saveFloor'/> <input type="button" value="保存地图" id='saveFloor'/>
<input type="button" value="后退" id="undoFloor" /> <input type="button" value="后退" id="undoFloor" style="display: none;"/>
<input type="button" value="帮助文档" id="openDoc" /> <input type="button" value="帮助文档" id="openDoc" />
<span id='mobileeditdata' style="display:none"> <span id='mobileeditdata' style="display:none">
<input type="button" value="编辑"/> <input type="button" value="编辑"/>
@ -403,12 +409,7 @@
<div id='uieventDialog'> <div id='uieventDialog'>
<div id="uieventHead"> <div id="uieventHead">
<span id="uieventTitle"></span> <span id="uieventTitle"></span>
<select id="uieventBackground" style="margin-left: 20px"> <select id="uieventSelect" style="margin-left: 20px"></select>
<option value="thumbnail" selected>缩略图</option>
<option value="#000000">黑色</option>
<option value="#FFFFFF">白色</option>
</select>
<select id="uieventUsedFlags" style="margin-left: 10px; display: none" onchange="editor.uievent.doSearchUsedFlags()"></select>
<button id="uieventNo">关闭</button> <button id="uieventNo">关闭</button>
<button id="uieventYes">确定</button> <button id="uieventYes">确定</button>
</div> </div>
@ -446,6 +447,7 @@
<script src='_server/editor_table.js'></script> <script src='_server/editor_table.js'></script>
<script src='_server/editor_mode.js'></script> <script src='_server/editor_mode.js'></script>
<script src='_server/editor_ui.js'></script> <script src='_server/editor_ui.js'></script>
<script src='_server/editor_uievent.js'></script>
<script src='_server/editor_mappanel.js'></script> <script src='_server/editor_mappanel.js'></script>
<script src='_server/editor_datapanel.js'></script> <script src='_server/editor_datapanel.js'></script>
<script src='_server/editor_materialpanel.js'></script> <script src='_server/editor_materialpanel.js'></script>

View File

@ -29,9 +29,9 @@
<input type="button" value="新建空白地图" id='newMap'/> <input type="button" value="新建空白地图" id='newMap'/>
<input id='newFileName' placeholder="新楼层id" style="width: 70px"/> <input id='newFileName' placeholder="新楼层id" style="width: 70px"/>
<span style="vertical-align: bottom"></span> <span style="vertical-align: bottom"></span>
<input id='newMapWidth' value="13" style="width: 20px"/> <input id='newMapWidth' style="width: 20px"/>
<span style="vertical-align: bottom"></span> <span style="vertical-align: bottom"></span>
<input id='newMapHeight' value="13" style="width: 20px"/> <input id='newMapHeight' style="width: 20px"/>
<input type="checkbox" id='newMapStatus' checked='checked' style='vertical-align: bottom'/> <input type="checkbox" id='newMapStatus' checked='checked' style='vertical-align: bottom'/>
<span style='vertical-align: bottom; margin-left: -4px'>保留楼层属性</span> <span style='vertical-align: bottom; margin-left: -4px'>保留楼层属性</span>
</div> </div>
@ -51,9 +51,9 @@
<span style="vertical-align: bottom">状态栏名称: </span> <span style="vertical-align: bottom">状态栏名称: </span>
<input id='newFloorNames' style="width: 70px" value='${i}'/> <input id='newFloorNames' style="width: 70px" value='${i}'/>
<span style="vertical-align: bottom"></span> <span style="vertical-align: bottom"></span>
<input id='newMapsWidth' value="13" style="width: 20px"/> <input id='newMapsWidth' style="width: 20px"/>
<span style="vertical-align: bottom"></span> <span style="vertical-align: bottom"></span>
<input id='newMapsHeight' value="13" style="width: 20px"/> <input id='newMapsHeight' style="width: 20px"/>
<input type="checkbox" id='newMapsStatus' checked='checked' style='vertical-align: bottom'/> <input type="checkbox" id='newMapsStatus' checked='checked' style='vertical-align: bottom'/>
<span style='vertical-align: bottom; margin-left: -4px'>保留楼层属性</span> <span style='vertical-align: bottom; margin-left: -4px'>保留楼层属性</span>
<br/> <br/>
@ -147,12 +147,14 @@
<button>确定</button> <button>确定</button>
<br/> <br/>
<button style="margin-top: 10px">自动注册</button> <button style="margin-top: 10px">自动注册</button>
<button style="margin-top: 10px; margin-left: 10px">删除此素材</button> <button style="margin-top: 10px; margin-left: 5px">删除此素材</button>
<button style="margin-top: 10px; margin-left: 5px">以此素材为模板追加</button>
</div> </div>
<div id='changeId'><!-- id and idnum --> <div id='changeId'><!-- id and idnum -->
<input placeholder="修改图块id为"/> <input placeholder="修改图块id为" style="width: 100px"/>
<button>确定</button> <button>确定</button>
<button style="margin-left: 10px">删除此素材</button> <button style="margin-left: 5px">删除此素材</button>
<button style="margin-left: 5px">以此素材为模板追加</button>
</div> </div>
</div> </div>
</div> </div>
@ -207,6 +209,7 @@
<button onclick="editor_blockly.runCode()">console.log(obj=code)</button> <button onclick="editor_blockly.runCode()">console.log(obj=code)</button>
--> -->
<button onclick="editor_blockly.confirm()">确认</button> <button onclick="editor_blockly.confirm()">确认</button>
<button onclick="editor_blockly.confirm(true)">应用</button>
<button id='blocklyParse' onclick="editor_blockly.parse()">解析</button> <button id='blocklyParse' onclick="editor_blockly.parse()">解析</button>
<button onclick="editor_blockly.cancel()">取消</button> <button onclick="editor_blockly.cancel()">取消</button>
<div style="position: relative; display: inline-block; margin-left: 10px"> <div style="position: relative; display: inline-block; margin-left: 10px">
@ -237,7 +240,9 @@
<div id="left7" style="z-index:-1;opacity: 0;"><!-- 多行文本编辑器 --> <div id="left7" style="z-index:-1;opacity: 0;"><!-- 多行文本编辑器 -->
<button onclick="editor_multi.confirm()">确认</button> <button onclick="editor_multi.confirm()">确认</button>
<button onclick="editor_multi.cancel()">取消</button> <button onclick="editor_multi.cancel()">取消</button>
<button onclick="editor_multi.confirm(true)">应用</button>
<button onclick="editor_multi.format()">格式化</button> <button onclick="editor_multi.format()">格式化</button>
<button id="editor_multi_preview" style="display: none;">预览</button>
<input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox" <input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox"
style="vertical-align: middle;margin-left:6px"/> style="vertical-align: middle;margin-left:6px"/>
<span style="vertical-align: middle; margin-left: -3px">语法检查</span> <span style="vertical-align: middle; margin-left: -3px">语法检查</span>
@ -305,16 +310,16 @@
</div> </div>
<div class="tools"> <div class="tools">
<div id="tip"></div> <div id="tip"></div>
<select id="editModeSelect"> <select id="editModeSelect" style="font-size: 12px">
<option value="map">地图编辑Z</option> <option value="map">地图编辑(Z)</option>
<option value="loc">地图选点X</option> <option value="loc">地图选点(X)</option>
<option value="enemyitem">图块属性C</option> <option value="enemyitem">图块属性(C)</option>
<option value="floor">楼层属性V</option> <option value="floor">楼层属性(V)</option>
<option value="tower">全塔属性B</option> <option value="tower">全塔属性(B)</option>
<option value="functions">脚本编辑N</option> <option value="functions">脚本编辑(N)</option>
<option value="appendpic">追加素材M</option> <option value="appendpic">追加素材(M)</option>
<option value="commonevent">公共事件 ,</option> <option value="commonevent">公共事件(,)</option>
<option value="plugins">插件编写 .</option> <option value="plugins">插件编写(.)</option>
</select> </select>
<span style="font-size: 12px"><input type="checkbox" id="showMovable" style="margin-left:0;margin-right: 2px"/>通行度</span> <span style="font-size: 12px"><input type="checkbox" id="showMovable" style="margin-left:0;margin-right: 2px"/>通行度</span>
<select id="editorTheme" style="margin-left: 0; font-size: 11px;"> <select id="editorTheme" style="margin-left: 0; font-size: 11px;">
@ -336,17 +341,17 @@
<input type="radio" id="layerMod3" name="layerMod" value="fgmap" style="margin-left: 5px" />前景层 <input type="radio" id="layerMod3" name="layerMod" value="fgmap" style="margin-left: 5px" />前景层
</span> </span>
<br> <br>
<div id="viewportButtons"> <div id="viewportButtons" style="margin-bottom: 7px">
<input type="button" value="←"/> <input type="button" value="←"/>
<input type="button" value="↑"/> <input type="button" value="↑"/>
<input type="button" value="↓"/> <input type="button" value="↓"/>
<input type="button" value="→"/> <input type="button" value="→"/>
<input type="button" id='bigmapBtn' value="大地图" style="margin-left: 5px"/> <input type="button" id='bigmapBtn' value="大地图" style="margin-left: 5px"/>
</div> </div>
<br>
<select id="selectFloor" style="margin-bottom: 5px;"></select> <select id="selectFloor" style="margin-bottom: 5px;"></select>
<input type="button" value="选层" id='selectFloorBtn'/>
<input type="button" value="保存地图" id='saveFloor'/> <input type="button" value="保存地图" id='saveFloor'/>
<input type="button" value="后退" id="undoFloor" /> <input type="button" value="后退" id="undoFloor" style="display: none;" />
<input type="button" value="帮助文档" id="openDoc" /> <input type="button" value="帮助文档" id="openDoc" />
<input type="button" value="前往游戏" onclick="window.open('./index.html', '_blank')"/> <input type="button" value="前往游戏" onclick="window.open('./index.html', '_blank')"/>
</div> </div>
@ -387,12 +392,7 @@
<div id='uieventDialog'> <div id='uieventDialog'>
<div id="uieventHead"> <div id="uieventHead">
<span id="uieventTitle"></span> <span id="uieventTitle"></span>
<select id="uieventBackground" style="margin-left: 20px"> <select id="uieventSelect" style="margin-left: 20px"></select>
<option value="thumbnail" selected>缩略图</option>
<option value="#000000">黑色</option>
<option value="#FFFFFF">白色</option>
</select>
<select id="uieventUsedFlags" style="margin-left: 10px; display: none" onchange="editor.uievent.doSearchUsedFlags()"></select>
<button id="uieventNo">关闭</button> <button id="uieventNo">关闭</button>
<button id="uieventYes">确定</button> <button id="uieventYes">确定</button>
</div> </div>
@ -432,6 +432,7 @@
<script src='_server/editor_table.js'></script> <script src='_server/editor_table.js'></script>
<script src='_server/editor_mode.js'></script> <script src='_server/editor_mode.js'></script>
<script src='_server/editor_ui.js'></script> <script src='_server/editor_ui.js'></script>
<script src='_server/editor_uievent.js'></script>
<script src='_server/editor_mappanel.js'></script> <script src='_server/editor_mappanel.js'></script>
<script src='_server/editor_datapanel.js'></script> <script src='_server/editor_datapanel.js'></script>
<script src='_server/editor_materialpanel.js'></script> <script src='_server/editor_materialpanel.js'></script>

110
extensions/localSave.js Normal file
View File

@ -0,0 +1,110 @@
/**
* 离线游戏使用本地存储扩展
* 开启本拓展后将会把所有存档存至 _saves 目录下
* 需配合样板V2.8.2+使用
*/
"use strict";
(function () {
// 将这一行改成 false 可以禁用本拓展
var __enabled = true;
if (window.jsinterface || !window.fs || !__enabled) return;
function rewrite() {
core.utils._setLocalForage_set = function (name, str, callback) {
var data = LZString.compressToBase64(str);
core.saves.cache[name] = data;
fs.writeFile('_saves/' + name, data, 'utf-8', callback);
}
core.utils._getLocalForage_get = function (name, callback) {
fs.readFile('_saves/' + name, 'utf-8', function (err, data) {
if (err) return callback(err);
callback(null, data);
});
}
core.utils.decompress = function (data) {
try {
return JSON.parse(LZString.decompressFromBase64(data))
} catch (e) {
return null;
}
}
core.utils._removeLocalForage_remove = function (name, callback) {
fs.deleteFile('_saves/' + name, callback);
}
core.utils.clearLocalForage = function (callback) {
fs.deleteFile('_saves', function () {
fs.mkdir('_saves', callback);
})
}
core.utils.iterateLocalForage = function (iter, callback) {
fs.readdir('_saves', function (err, data) {
if (err) callback(err);
else {
data.forEach(function (one) {
iter(null, one, null);
});
callback();
}
});
}
core.utils.keysLocalForage = function (callback) {
fs.readdir('_saves', callback);
}
core.utils.lengthLocalForage = function (callback) {
fs.readdir('_saves', function (err, data) {
if (err) callback(err);
else callback(null, data.length);
});
}
}
var _export = function () {
var toExport = [];
localforage.iterate(function (value, key, n) {
if (value == null || !key.startsWith(core.firstData.name)) return;
value = core.decompress(value);
if (value == null) return;
var str = JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) {
return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4)
});
str = LZString.compressToBase64(str);
toExport.push(key);
core.saves.cache[key] = str;
fs.writeFile('_saves/' + key, str, 'utf-8', function () {});
}, function () {
if (toExport.length > 0) {
alert('提示!本塔已开启存档本地化!原始存档已全部导出至 _saves/ 目录下。');
}
fs.writeFile('_saves/.exported', '1', 'utf-8', function () {});
rewrite();
core.control.getSaveIndexes(function (indexes) { core.saves.ids = indexes; });
});
}
fs.mkdir('_saves', function (err) {
if (err) return;
fs.readFile('_saves/.exported', 'utf-8', function(err, data) {
if (!err && data) {
rewrite();
core.control.getSaveIndexes(function (indexes) { core.saves.ids = indexes; });
return;
}
_export();
});
});
})();

View File

@ -47,17 +47,13 @@ actions.prototype._init = function () {
// --- onup注册 // --- onup注册
this.registerAction('onup', '_sys_checkReplay', this._sys_checkReplay, 100); this.registerAction('onup', '_sys_checkReplay', this._sys_checkReplay, 100);
this.registerAction('onup', '_sys_onup', this._sys_onup, 0); this.registerAction('onup', '_sys_onup', this._sys_onup, 0);
// --- onclick注册 // --- onclick已废弃将视为ondown
this.registerAction('onclick', '_sys_checkReplay', this._sys_checkReplay, 100);
this.registerAction('onclick', '_sys_onclick_lockControl', this._sys_onclick_lockControl, 50);
this.registerAction('onclick', '_sys_onclick', this._sys_onclick, 0);
// --- onmousewheel注册 // --- onmousewheel注册
this.registerAction('onmousewheel', '_sys_onmousewheel', this._sys_onmousewheel, 0); this.registerAction('onmousewheel', '_sys_onmousewheel', this._sys_onmousewheel, 0);
// --- keyDownCtrl注册 // --- keyDownCtrl注册
this.registerAction('keyDownCtrl', '_sys_keyDownCtrl', this._sys_keyDownCtrl, 0); this.registerAction('keyDownCtrl', '_sys_keyDownCtrl', this._sys_keyDownCtrl, 0);
// --- longClick注册 // --- longClick注册
this.registerAction('longClick', '_sys_longClick_lockControl', this._sys_longClick_lockControl, 50); this.registerAction('longClick', '_sys_longClick_lockControl', this._sys_longClick_lockControl, 50);
this.registerAction('longClick', '_sys_longClick', this._sys_longClick, 0);
// --- onStatusBarClick注册 // --- onStatusBarClick注册
this.registerAction('onStatusBarClick', '_sys_onStatusBarClick', this._sys_onStatusBarClick, 0); this.registerAction('onStatusBarClick', '_sys_onStatusBarClick', this._sys_onStatusBarClick, 0);
@ -66,7 +62,7 @@ actions.prototype._init = function () {
////// 注册一个用户交互行为 ////// ////// 注册一个用户交互行为 //////
/* /*
* 此函数将注册一个用户交互行为 * 此函数将注册一个用户交互行为
* action要注册的交互类型 ondown, onclick, keyDown 等等 * action要注册的交互类型 ondown, onup, keyDown 等等
* name你的自定义名称可被注销使用同名重复注册将后者覆盖前者 * name你的自定义名称可被注销使用同名重复注册将后者覆盖前者
* func执行函数 * func执行函数
* priority优先级优先级高的将会被执行此项可不填默认为0 * priority优先级优先级高的将会被执行此项可不填默认为0
@ -75,6 +71,8 @@ actions.prototype._init = function () {
actions.prototype.registerAction = function (action, name, func, priority) { actions.prototype.registerAction = function (action, name, func, priority) {
if (!name || !func) if (!name || !func)
return; return;
// 将onclick视为ondown处理
if (action == 'onclick') action = 'ondown';
priority = priority || 0; priority = priority || 0;
if (!this.actions[action]) { if (!this.actions[action]) {
this.actions[action] = []; this.actions[action] = [];
@ -90,6 +88,8 @@ actions.prototype.registerAction = function (action, name, func, priority) {
////// 注销一个用户交互行为 ////// ////// 注销一个用户交互行为 //////
actions.prototype.unregisterAction = function (action, name) { actions.prototype.unregisterAction = function (action, name) {
// 将onclick视为ondown处理
if (action == 'onclick') action = 'ondown';
if (!this.actions[action]) return; if (!this.actions[action]) return;
this.actions[action] = this.actions[action].filter(function (x) { this.actions[action] = this.actions[action].filter(function (x) {
return x.name != name; return x.name != name;
@ -286,6 +286,7 @@ actions.prototype._sys_keyDown_lockControl = function (keyCode) {
case 'load': case 'load':
case 'replayLoad': case 'replayLoad':
case 'replayRemain': case 'replayRemain':
case 'replaySince':
this._keyDownSL(keyCode); this._keyDownSL(keyCode);
break; break;
case 'selectShop': case 'selectShop':
@ -388,6 +389,7 @@ actions.prototype._sys_keyUp_lockControl = function (keyCode, altKey) {
case 'load': case 'load':
case 'replayLoad': case 'replayLoad':
case 'replayRemain': case 'replayRemain':
case 'replaySince':
this._keyUpSL(keyCode); this._keyUpSL(keyCode);
break; break;
case 'keyBoard': case 'keyBoard':
@ -460,176 +462,6 @@ actions.prototype.ondown = function (loc) {
actions.prototype._sys_ondown_lockControl = function (x, y, px, py) { actions.prototype._sys_ondown_lockControl = function (x, y, px, py) {
if (core.status.played && !core.status.lockControl) return false; if (core.status.played && !core.status.lockControl) return false;
core.actions.onclick(x, y, px, py, []);
// --- 长按判定
if (core.timeout.onDownTimeout == null) {
core.timeout.onDownTimeout = setTimeout(function () {
if (core.interval.onDownInterval == null) {
core.interval.onDownInterval = setInterval(function () {
if (!core.actions.longClick(x, y, px, py)) {
clearInterval(core.interval.onDownInterval);
core.interval.onDownInterval = null;
}
}, 40)
}
}, 500);
}
return true;
}
actions.prototype._sys_ondown = function (x, y, px, py) {
core.status.downTime = new Date();
core.deleteCanvas('route');
var pos = {'x': x, 'y': y}
core.status.stepPostfix = [];
core.status.stepPostfix.push(pos);
core.fillPosWithPoint(pos);
}
////// 当在触摸屏上滑动时 //////
actions.prototype.onmove = 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('onmove', 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') {
this._onMoveChoices(x, y);
return true;
}
if (core.status.event.data.type == 'confirm') {
this._onMoveConfirmBox(x, y);
return true;
}
break;
case 'selectShop':
case 'switchs':
case 'switchs-sounds':
case 'switchs-display':
case 'switchs-action':
case 'notes':
case 'settings':
case 'syncSave':
case 'syncSelect':
case 'localSaveSelect':
case 'storageRemove':
case 'replay':
case 'gameInfo':
this._onMoveChoices(x, y);
return true;
case 'confirmBox':
this._onMoveConfirmBox(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};
var pos0 = core.status.stepPostfix[core.status.stepPostfix.length - 1];
var directionDistance = [pos.y - pos0.y, pos0.x - pos.x, pos0.y - pos.y, pos.x - pos0.x];
var max = 0, index = 4;
for (var ii = 0; ii < 4; ii++) {
if (directionDistance[ii] > max) {
index = ii;
max = directionDistance[ii];
}
}
pos = [{'x': 0, 'y': 1}, {'x': -1, 'y': 0}, {'x': 0, 'y': -1}, {'x': 1, 'y': 0}, false][index]
if (pos) {
pos.x += pos0.x;
pos.y += pos0.y;
core.status.stepPostfix.push(pos);
core.fillPosWithPoint(pos);
}
}
return true;
}
////// 当点击(触摸)事件放开时 //////
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 = function () {
clearTimeout(core.timeout.onDownTimeout);
core.timeout.onDownTimeout = null;
clearInterval(core.interval.onDownInterval);
core.interval.onDownInterval = null;
if ((core.status.stepPostfix || []).length == 0) return false;
var stepPostfix = [];
var direction = {'0': {'1': 'down', '-1': 'up'}, '-1': {'0': 'left'}, '1': {'0': 'right'}};
for (var ii = 1; ii < core.status.stepPostfix.length; ii++) {
var pos0 = core.status.stepPostfix[ii - 1];
var pos = core.status.stepPostfix[ii];
stepPostfix.push({
'direction': direction[pos.x - pos0.x][pos.y - pos0.y],
'x': pos.x + parseInt(core.bigmap.offsetX / 32),
'y': pos.y + parseInt(core.bigmap.offsetY / 32)
});
}
var posx = core.status.stepPostfix[0].x;
var posy = core.status.stepPostfix[0].y;
core.status.stepPostfix = [];
if (!core.status.lockControl) {
core.clearMap('ui');
}
// 长按
if (!core.status.lockControl && stepPostfix.length == 0 && core.status.downTime != null && new Date() - core.status.downTime >= 1000) {
core.actions.longClick(posx, posy, 32 * posx + 16, 32 * posy + 16);
}
else {
//posx,posy是寻路的目标点,stepPostfix是后续的移动
core.actions.onclick(posx, posy, 32 * posx + 16, 32 * posy + 16, stepPostfix);
}
core.status.downTime = null;
return true;
}
////// 获得点击事件相对左上角的坐标 //////
actions.prototype._getClickLoc = function (x, y) {
var statusBar = {'x': 0, 'y': 0};
var size = 32;
size = size * core.domStyle.scale;
if (core.domStyle.isVertical) {
statusBar.x = 3;
statusBar.y = core.dom.statusBar.offsetHeight + 3;
}
else {
statusBar.x = core.dom.statusBar.offsetWidth + 3;
statusBar.y = 3;
}
var left = core.dom.gameGroup.offsetLeft + statusBar.x;
var top = core.dom.gameGroup.offsetTop + statusBar.y;
var loc = {'x': Math.max(x - left), 'y': Math.max(y - top, 0), 'size': size};
return loc;
}
////// 具体点击屏幕上(x,y)点时,执行的操作 //////
actions.prototype.onclick = function (x, y, px, py, stepPostfix) {
// console.log("Click: (" + x + "," + y + ")");
return this.doRegisteredAction('onclick', x, y, px, py, stepPostfix || []);
}
actions.prototype._sys_onclick_lockControl = function (x, y, px, py) {
if (!core.status.lockControl) return false;
switch (core.status.event.id) { switch (core.status.event.id) {
case 'centerFly': case 'centerFly':
this._clickCenterFly(x, y, px, py); this._clickCenterFly(x, y, px, py);
@ -674,6 +506,7 @@ actions.prototype._sys_onclick_lockControl = function (x, y, px, py) {
case 'load': case 'load':
case 'replayLoad': case 'replayLoad':
case 'replayRemain': case 'replayRemain':
case 'replaySince':
this._clickSL(x, y, px, py); this._clickSL(x, y, px, py);
break; break;
case 'confirmBox': case 'confirmBox':
@ -717,15 +550,211 @@ actions.prototype._sys_onclick_lockControl = function (x, y, px, py) {
core.ui.closePanel(); core.ui.closePanel();
break; break;
} }
// --- 长按判定
if (core.timeout.onDownTimeout == null) {
core.timeout.onDownTimeout = setTimeout(function () {
if (core.interval.onDownInterval == null) {
core.interval.onDownInterval = setInterval(function () {
if (!core.actions.longClick(x, y, px, py)) {
clearInterval(core.interval.onDownInterval);
core.interval.onDownInterval = null;
}
}, 40)
}
}, 500);
}
return true; return true;
} }
actions.prototype._sys_onclick = function (x, y, px, py, stepPostfix) { actions.prototype._sys_ondown = function (x, y, px, py) {
// 寻路 if (core.status.lockControl) return false;
core.setAutomaticRoute(x + parseInt(core.bigmap.offsetX / 32), y + parseInt(core.bigmap.offsetY / 32), stepPostfix); core.status.downTime = new Date();
core.deleteCanvas('route');
var pos = {'x': parseInt((px + core.bigmap.offsetX) / 32), 'y': parseInt((py + core.bigmap.offsetY) / 32)};
core.status.stepPostfix = [];
core.status.stepPostfix.push(pos);
core.fillRect('ui', pos.x*32+12-core.bigmap.offsetX,pos.y*32+12-core.bigmap.offsetY,8,8, '#bfbfbf');
clearTimeout(core.timeout.onDownTimeout);
core.timeout.onDownTimeout = null;
core.status.preview.prepareDragging = false;
if (!core.hasFlag('__lockViewport__') && (core.status.thisMap.width > core.__SIZE__ || core.status.thisMap.height > core.__SIZE__)) {
core.status.preview.prepareDragging = true;
core.status.preview.px = px;
core.status.preview.py = py;
core.timeout.onDownTimeout = setTimeout(function () {
core.clearMap('ui');
core.status.preview.prepareDragging = false;
core.status.preview.enabled = true;
core.status.preview.dragging = true;
core.drawTip('已进入预览模式,可直接拖动大地图');
core.status.stepPostfix = [];
}, 500);
}
}
////// 当在触摸屏上滑动时 //////
actions.prototype.onmove = 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('onmove', x, y, px, py);
}
actions.prototype._sys_onmove_choices = function (x, y, px, py) {
if (!core.status.lockControl) return false;
switch (core.status.event.id) {
case 'action':
if (core.status.event.data.type == 'choices') {
this._onMoveChoices(x, y);
return true;
}
if (core.status.event.data.type == 'confirm') {
this._onMoveConfirmBox(x, y, px, py);
return true;
}
break;
case 'selectShop':
case 'switchs':
case 'switchs-sounds':
case 'switchs-display':
case 'switchs-action':
case 'notes':
case 'settings':
case 'syncSave':
case 'syncSelect':
case 'localSaveSelect':
case 'storageRemove':
case 'replay':
case 'gameInfo':
this._onMoveChoices(x, y);
return true;
case 'confirmBox':
this._onMoveConfirmBox(x, y, px, py);
return true;
default:
break;
}
return false;
}
actions.prototype._sys_onmove = function (x, y, px, py) {
if (core.status.lockControl) return false;
if (core.status.preview.dragging) {
core.setViewport(core.bigmap.offsetX - px + core.status.preview.px, core.bigmap.offsetY - py + core.status.preview.py);
core.status.preview.px = px;
core.status.preview.py = py;
return true;
}
if (core.status.preview.prepareDragging) {
if (Math.abs(px - core.status.preview.px) <= 20 && Math.abs(py - core.status.preview.py) <= 20)
return true;
else core.status.preview.prepareDragging = false;
}
clearTimeout(core.timeout.onDownTimeout);
core.timeout.onDownTimeout = null;
if ((core.status.stepPostfix || []).length > 0) {
var pos = {'x': parseInt((px + core.bigmap.offsetX) / 32), 'y': parseInt((py + core.bigmap.offsetY) / 32)};
var pos0 = core.status.stepPostfix[core.status.stepPostfix.length - 1];
var directionDistance = [pos.y - pos0.y, pos0.x - pos.x, pos0.y - pos.y, pos.x - pos0.x];
var max = 0, index = 4;
for (var ii = 0; ii < 4; ii++) {
if (directionDistance[ii] > max) {
index = ii;
max = directionDistance[ii];
}
}
pos = [{'x': 0, 'y': 1}, {'x': -1, 'y': 0}, {'x': 0, 'y': -1}, {'x': 1, 'y': 0}, false][index]
if (pos) {
pos.x += pos0.x;
pos.y += pos0.y;
core.status.stepPostfix.push(pos);
core.fillRect('ui', pos.x*32+12-core.bigmap.offsetX,pos.y*32+12-core.bigmap.offsetY,8,8, '#bfbfbf');
}
}
return true; return true;
} }
////// 当点击(触摸)事件放开时 //////
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 = function (x, y, px, py) {
clearTimeout(core.timeout.onDownTimeout);
core.timeout.onDownTimeout = null;
clearInterval(core.interval.onDownInterval);
core.interval.onDownInterval = null;
if (core.isPlaying()) {
core.status.preview.prepareDragging = false;
if (core.status.preview.dragging) {
core.status.preview.dragging = false;
return true;
}
}
if ((core.status.stepPostfix || []).length == 0) return false;
var stepPostfix = [];
var direction = {'0': {'1': 'down', '-1': 'up'}, '-1': {'0': 'left'}, '1': {'0': 'right'}};
for (var ii = 1; ii < core.status.stepPostfix.length; ii++) {
var pos0 = core.status.stepPostfix[ii - 1];
var pos = core.status.stepPostfix[ii];
stepPostfix.push({
'direction': direction[pos.x - pos0.x][pos.y - pos0.y],
'x': pos.x,
'y': pos.y
});
}
var posx = core.status.stepPostfix[0].x;
var posy = core.status.stepPostfix[0].y;
core.status.stepPostfix = [];
if (!core.status.lockControl) {
core.clearMap('ui');
}
// 长按
if (!core.status.lockControl && stepPostfix.length == 0 && core.status.downTime != null && new Date() - core.status.downTime >= 1000) {
core.actions.longClick(x, y, px, py);
}
else {
//posx,posy是寻路的目标点,stepPostfix是后续的移动
core.setAutomaticRoute(posx, posy, stepPostfix);
}
core.status.downTime = null;
return true;
}
////// 获得点击事件相对左上角的坐标 //////
actions.prototype._getClickLoc = function (x, y) {
var statusBar = {'x': 0, 'y': 0};
var size = 32;
size = size * core.domStyle.scale;
if (core.domStyle.isVertical) {
statusBar.x = 3;
statusBar.y = core.dom.statusBar.offsetHeight + 3;
}
else {
statusBar.x = core.dom.statusBar.offsetWidth + 3;
statusBar.y = 3;
}
var left = core.dom.gameGroup.offsetLeft + statusBar.x;
var top = core.dom.gameGroup.offsetTop + statusBar.y;
var loc = {'x': Math.max(x - left), 'y': Math.max(y - top, 0), 'size': size};
return loc;
}
////// 滑动鼠标滚轮时的操作 ////// ////// 滑动鼠标滚轮时的操作 //////
actions.prototype.onmousewheel = function (direct) { actions.prototype.onmousewheel = function (direct) {
this.doRegisteredAction('onmousewheel', direct); this.doRegisteredAction('onmousewheel', direct);
@ -766,8 +795,8 @@ actions.prototype._sys_onmousewheel = function (direct) {
// 浏览地图 // 浏览地图
if (core.status.lockControl && core.status.event.id == 'viewMaps') { if (core.status.lockControl && core.status.event.id == 'viewMaps') {
if (direct == 1) this._clickViewMaps(this.HSIZE, this.HSIZE - 3); if (direct == 1) this._clickViewMaps(this.HSIZE, this.HSIZE - 3, core.__PIXELS__ / 2, core.__PIXELS__ / 5 * 1.5);
if (direct == -1) this._clickViewMaps(this.HSIZE, this.HSIZE + 3); if (direct == -1) this._clickViewMaps(this.HSIZE, this.HSIZE + 3, core.__PIXELS__ / 2, core.__PIXELS__ / 5 * 3.5);
return; return;
} }
@ -816,9 +845,9 @@ actions.prototype._sys_keyDownCtrl = function () {
} }
////// 长按 ////// ////// 长按 //////
actions.prototype.longClick = function (x, y, px, py, fromEvent) { actions.prototype.longClick = function (x, y, px, py) {
if (!core.isPlaying()) return false; if (!core.isPlaying()) return false;
return this.doRegisteredAction('longClick', x, y, px, py, fromEvent); return this.doRegisteredAction('longClick', x, y, px, py);
} }
actions.prototype._sys_longClick_lockControl = function (x, y, px, py) { actions.prototype._sys_longClick_lockControl = function (x, y, px, py) {
@ -839,7 +868,7 @@ actions.prototype._sys_longClick_lockControl = function (x, y, px, py) {
} }
} }
// 长按SL上下页快速翻页 // 长按SL上下页快速翻页
if (["save","load","replayLoad","replayRemain"].indexOf(core.status.event.id) >= 0) { if (["save","load","replayLoad","replayRemain","replaySince"].indexOf(core.status.event.id) >= 0) {
if ([this.HSIZE-2, this.HSIZE-3, this.HSIZE+2, this.HSIZE+3].indexOf(x) >= 0 && y == this.LAST) { if ([this.HSIZE-2, this.HSIZE-3, this.HSIZE+2, this.HSIZE+3].indexOf(x) >= 0 && y == this.LAST) {
this._clickSL(x, y); this._clickSL(x, y);
return true; return true;
@ -858,15 +887,6 @@ actions.prototype._sys_longClick_lockControl = function (x, y, px, py) {
return false; return false;
} }
actions.prototype._sys_longClick = function (x, y, px, py, fromEvent) {
if (core.status.lockControl) return false;
// 虚拟键盘
core.waitHeroToStop(function () {
core.ui._drawKeyBoard();
});
return true;
}
actions.prototype.onStatusBarClick = function (e) { actions.prototype.onStatusBarClick = function (e) {
if (!core.isPlaying()) return false; if (!core.isPlaying()) return false;
var left = core.dom.gameGroup.offsetLeft + 3; var left = core.dom.gameGroup.offsetLeft + 3;
@ -958,10 +978,12 @@ actions.prototype._keyUpCenterFly = function (keycode) {
} }
////// 点击确认框时 ////// ////// 点击确认框时 //////
actions.prototype._clickConfirmBox = function (x, y) { actions.prototype._clickConfirmBox = function (x, y, px, py) {
if ((x == this.HSIZE-2 || x == this.HSIZE-1) && y == this.HSIZE+1 && core.status.event.data.yes) if (px >= core.__PIXELS__ / 2 - 70 && px <= core.__PIXELS__ / 2 - 10
&& py >= core.__PIXELS__ / 2 && py <= core.__PIXELS__ / 2 + 64 && core.status.event.data.yes)
core.status.event.data.yes(); core.status.event.data.yes();
if ((x == this.HSIZE+2 || x == this.HSIZE+1) && y == this.HSIZE+1 && core.status.event.data.no) if (px >= core.__PIXELS__ / 2 + 10 && px <= core.__PIXELS__ / 2 + 70
&& py >= core.__PIXELS__ / 2 && py <= core.__PIXELS__ / 2 + 64 && core.status.event.data.no)
core.status.event.data.no(); core.status.event.data.no();
} }
@ -990,9 +1012,9 @@ actions.prototype._keyUpConfirmBox = function (keycode) {
} }
////// 鼠标在确认框上移动时 ////// ////// 鼠标在确认框上移动时 //////
actions.prototype._onMoveConfirmBox = function (x, y) { actions.prototype._onMoveConfirmBox = function (x, y, px, py) {
if (y == this.HSIZE + 1) { if (py >= core.__PIXELS__ / 2 && py <= core.__PIXELS__ / 2 + 64) {
if (x == this.HSIZE - 2 || x == this.HSIZE - 1) { if (px >= core.__PIXELS__ / 2 - 70 && px <= core.__PIXELS__ / 2 - 10) {
if (core.status.event.selection != 0) { if (core.status.event.selection != 0) {
core.status.event.selection = 0; core.status.event.selection = 0;
core.playSound('光标移动'); core.playSound('光标移动');
@ -1004,7 +1026,7 @@ actions.prototype._onMoveConfirmBox = function (x, y) {
} }
return; return;
} }
if (x == this.HSIZE + 2 || x == this.HSIZE + 1) { if (px >= core.__PIXELS__ / 2 + 10 && px <= core.__PIXELS__ / 2 + 70) {
if (core.status.event.selection != 1) { if (core.status.event.selection != 1) {
core.status.event.selection = 1; core.status.event.selection = 1;
core.playSound('光标移动'); core.playSound('光标移动');
@ -1084,7 +1106,12 @@ actions.prototype._clickAction = function (x, y, px, py) {
var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0; var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0;
delete core.status.event.timeout; delete core.status.event.timeout;
core.setFlag('timeout', timeout); core.setFlag('timeout', timeout);
core.status.route.push("choices:" + (100 * timeout + y - topIndex)); // 对全局商店特殊处理
var index = y - topIndex;
if (index == choices.length - 1 && core.hasFlag('@temp@shop')) {
index = -1;
}
core.status.route.push("choices:" + (100 * timeout + index));
core.insertAction(choice.action); core.insertAction(choice.action);
core.doAction(); core.doAction();
} }
@ -1309,7 +1336,7 @@ actions.prototype._keyUpFly = function (keycode) {
} }
////// 查看地图界面时的点击操作 ////// ////// 查看地图界面时的点击操作 //////
actions.prototype._clickViewMaps = function (x, y) { actions.prototype._clickViewMaps = function (x, y, px, py) {
if (core.status.event.data == null) { if (core.status.event.data == null) {
core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId));
return; return;
@ -1318,50 +1345,50 @@ actions.prototype._clickViewMaps = function (x, y) {
var index = core.status.event.data.index; var index = core.status.event.data.index;
var cx = core.status.event.data.x, cy = core.status.event.data.y; var cx = core.status.event.data.x, cy = core.status.event.data.y;
var floorId = core.floorIds[index], mw = core.floors[floorId].width, mh = core.floors[floorId].height; var floorId = core.floorIds[index], mw = core.floors[floorId].width, mh = core.floors[floorId].height;
var per = this.HSIZE - 4; var perpx = core.__PIXELS__ / 5, cornerpx = perpx * 3 / 4;
if (x <= per - 2 && y <= per - 2) { if (px <= cornerpx && py <= cornerpx) {
core.status.event.data.damage = !core.status.event.data.damage; core.status.event.data.damage = !core.status.event.data.damage;
core.playSound('光标移动'); core.playSound('光标移动');
core.ui._drawViewMaps(index, cx, cy); core.ui._drawViewMaps(index, cx, cy);
return; return;
} }
if (x <= per - 2 && y >= this.SIZE + 1 - per) { if (px <= cornerpx && py >= core.__PIXELS__ - cornerpx) {
if (core.markedFloorIds[floorId]) delete core.markedFloorIds[floorId]; if (core.markedFloorIds[floorId]) delete core.markedFloorIds[floorId];
else core.markedFloorIds[floorId] = true; else core.markedFloorIds[floorId] = true;
core.playSound('光标移动'); core.playSound('光标移动');
core.ui._drawViewMaps(index, cx, cy); core.ui._drawViewMaps(index, cx, cy);
return; return;
} }
if (x >= this.SIZE + 1 - per && y <= per - 2) { if (px >= core.__PIXELS__ - cornerpx && py <= cornerpx) {
core.status.event.data.all = !core.status.event.data.all; core.status.event.data.all = !core.status.event.data.all;
core.playSound('光标移动'); core.playSound('光标移动');
core.ui._drawViewMaps(index, cx, cy); core.ui._drawViewMaps(index, cx, cy);
return; return;
} }
if (x >= per && x <= this.LAST - per && y <= per - 1 && (!core.status.event.data.all && mh > this.SIZE)) { if (px >= perpx && px <= core.__PIXELS__ - perpx && py <= perpx && (!core.status.event.data.all && mh > this.SIZE)) {
core.playSound('光标移动'); core.playSound('光标移动');
core.ui._drawViewMaps(index, cx, cy - 1); core.ui._drawViewMaps(index, cx, cy - 1);
return; return;
} }
if (x >= per && x <= this.LAST - per && y >= this.SIZE - per && (!core.status.event.data.all && mh > this.SIZE)) { if (px >= perpx && px <= core.__PIXELS__ - perpx && py >= core.__PIXELS__ - perpx && (!core.status.event.data.all && mh > this.SIZE)) {
core.playSound('光标移动'); core.playSound('光标移动');
core.ui._drawViewMaps(index, cx, cy + 1); core.ui._drawViewMaps(index, cx, cy + 1);
return; return;
} }
if (x <= per - 1 && y >= per && y <= this.LAST - per) { if (px <= perpx && py >= perpx && py <= core.__PIXELS__ - perpx) {
core.playSound('光标移动'); core.playSound('光标移动');
core.ui._drawViewMaps(index, cx - 1, cy); core.ui._drawViewMaps(index, cx - 1, cy);
return; return;
} }
if (x >= this.SIZE - per && y >= per && y <= this.LAST - per) { if (px >= core.__PIXELS__ - perpx && py >= perpx && py <= core.__PIXELS__ - perpx) {
core.playSound('光标移动'); core.playSound('光标移动');
core.ui._drawViewMaps(index, cx + 1, cy); core.ui._drawViewMaps(index, cx + 1, cy);
return; return;
} }
if (y <= this.HSIZE - 2 && (mh == this.SIZE || (x >= per && x <= this.LAST - per))) { if (py <= 2 * perpx && (mh == this.SIZE || (px >= perpx && px <= core.__PIXELS__ - perpx))) {
core.playSound('光标移动'); core.playSound('光标移动');
index++; index++;
while (index < core.floorIds.length && index != now && core.status.maps[core.floorIds[index]].cannotViewMap) while (index < core.floorIds.length && index != now && core.status.maps[core.floorIds[index]].cannotViewMap)
@ -1370,7 +1397,7 @@ actions.prototype._clickViewMaps = function (x, y) {
core.ui._drawViewMaps(index); core.ui._drawViewMaps(index);
return; return;
} }
if (y >= this.HSIZE + 2 && (mh == this.SIZE || (x >= per && x <= this.LAST - per))) { if (py >= 3 * perpx && (mh == this.SIZE || (px >= perpx && px <= core.__PIXELS__ - perpx))) {
core.playSound('光标移动'); core.playSound('光标移动');
index--; index--;
while (index >= 0 && index != now && core.status.maps[core.floorIds[index]].cannotViewMap) while (index >= 0 && index != now && core.status.maps[core.floorIds[index]].cannotViewMap)
@ -1379,7 +1406,7 @@ actions.prototype._clickViewMaps = function (x, y) {
core.ui._drawViewMaps(index); core.ui._drawViewMaps(index);
return; return;
} }
if (x >= per && x <= this.LAST - per && y >= this.HSIZE - 1 && y <= this.HSIZE + 1) { if (px >= perpx && px <= core.__PIXELS__ - perpx && py >= perpx * 2 && py <= perpx * 3) {
core.clearMap('data'); core.clearMap('data');
core.playSound('取消'); core.playSound('取消');
core.ui.closePanel(); core.ui.closePanel();
@ -1393,12 +1420,12 @@ actions.prototype._keyDownViewMaps = function (keycode) {
var floorId = core.floorIds[core.status.event.data.index], mh = core.floors[floorId].height; var floorId = core.floorIds[core.status.event.data.index], mh = core.floors[floorId].height;
if (keycode == 38 || keycode == 33) this._clickViewMaps(this.HSIZE, this.HSIZE - 3); if (keycode == 38 || keycode == 33) this._clickViewMaps(this.HSIZE, this.HSIZE - 3, core.__PIXELS__ / 2, core.__PIXELS__ / 5 * 1.5);
if (keycode == 40 || keycode == 34) this._clickViewMaps(this.HSIZE, this.HSIZE + 3); if (keycode == 40 || keycode == 34) this._clickViewMaps(this.HSIZE, this.HSIZE + 3, core.__PIXELS__ / 2, core.__PIXELS__ / 5 * 3.5);
if (keycode == 87 && mh > this.SIZE) this._clickViewMaps(this.HSIZE, 0); if (keycode == 87 && mh > this.SIZE) this._clickViewMaps(this.HSIZE, 0, core.__PIXELS__ / 2, 1);
if (keycode == 65) this._clickViewMaps(0, this.HSIZE); if (keycode == 65) this._clickViewMaps(0, this.HSIZE, 1, core.__PIXELS__ / 2);
if (keycode == 83 && mh > this.SIZE) this._clickViewMaps(this.HSIZE, this.LAST); if (keycode == 83 && mh > this.SIZE) this._clickViewMaps(this.HSIZE, this.LAST, core.__PIXELS__ / 2, core.__PIXELS__ - 1);
if (keycode == 68) this._clickViewMaps(this.LAST, this.HSIZE); if (keycode == 68) this._clickViewMaps(this.LAST, this.HSIZE, core.__PIXELS__, core.__PIXELS__ / 2 - 1);
return; return;
} }
@ -2754,7 +2781,8 @@ actions.prototype._clickLocalSaveSelect = function (x, y) {
"version": core.firstData.version, "version": core.firstData.version,
"data": saves "data": saves
} }
core.download(core.firstData.name + "_" + core.formatDate2(new Date()) + ".h5save", JSON.stringify(content)); core.download(core.firstData.name + "_" + core.formatDate2(new Date()) + ".h5save",
LZString.compressToBase64(JSON.stringify(content)));
} }
}; };
if (selection == 0) core.getAllSaves(callback); if (selection == 0) core.getAllSaves(callback);
@ -2804,11 +2832,13 @@ actions.prototype._clickStorageRemove = function (x, y) {
actions.prototype._clickStorageRemove_all = function () { actions.prototype._clickStorageRemove_all = function () {
core.myconfirm("你确定要清除【全部游戏】的所有本地存档?\n此行为不可逆", function () { core.myconfirm("你确定要清除【全部游戏】的所有本地存档?\n此行为不可逆", function () {
var done = function () { core.ui.drawWaiting("正在清空,请稍候...");
core.clearLocalForage(function () {
core.saves.ids = {}; core.saves.ids = {};
core.saves.autosave.data = null; core.saves.autosave.data = null;
core.saves.autosave.updated = false; core.saves.autosave.updated = false;
core.saves.autosave.now = 0; core.saves.autosave.now = 0;
core.saves.cache = {};
core.ui.closePanel(); core.ui.closePanel();
core.saves.saveIndex = 1; core.saves.saveIndex = 1;
core.saves.favorite = []; core.saves.favorite = [];
@ -2816,15 +2846,7 @@ actions.prototype._clickStorageRemove_all = function () {
core.control._updateFavoriteSaves(); core.control._updateFavoriteSaves();
core.removeLocalStorage('saveIndex'); core.removeLocalStorage('saveIndex');
core.drawText("\t[操作成功]你的所有存档已被清空。"); core.drawText("\t[操作成功]你的所有存档已被清空。");
}; });
if (core.platform.useLocalForage) {
core.ui.drawWaiting("正在清空,请稍候...");
localforage.clear(done);
}
else {
localStorage.clear();
done();
}
}); });
} }
@ -2843,20 +2865,11 @@ actions.prototype._clickStorageRemove_current = function () {
core.removeLocalStorage('saveIndex'); core.removeLocalStorage('saveIndex');
core.drawText("\t[操作成功]当前塔的存档已被清空。"); core.drawText("\t[操作成功]当前塔的存档已被清空。");
} }
if (core.platform.useLocalForage) { core.ui.drawWaiting("正在清空,请稍候...");
core.ui.drawWaiting("正在清空,请稍候..."); Object.keys(core.saves.ids).forEach(function (v) {
Object.keys(core.saves.ids).forEach(function (v) { core.removeLocalForage("save" + v);
core.removeLocalForage("save" + v); });
}); core.removeLocalForage("autoSave", done);
core.removeLocalForage("autoSave", done);
}
else {
Object.keys(core.saves.ids).forEach(function (v) {
core.removeLocalStorage("save" + v);
});
core.removeLocalStorage("autoSave");
done();
}
}); });
} }
@ -2885,9 +2898,10 @@ actions.prototype._clickReplay = function (x, y) {
case 0: core.playSound('确定'); return this._clickReplay_fromBeginning(); case 0: core.playSound('确定'); return this._clickReplay_fromBeginning();
case 1: core.playSound('确定'); return this._clickReplay_fromLoad(); case 1: core.playSound('确定'); return this._clickReplay_fromLoad();
case 2: core.playSound('确定'); return this._clickReplay_replayRemain(); case 2: core.playSound('确定'); return this._clickReplay_replayRemain();
case 3: core.playSound('确定'); return core.chooseReplayFile(); case 3: core.playSound('确定'); return this._clickReplay_replaySince();
case 4: core.playSound('确定'); return this._clickReplay_download(); case 4: core.playSound('确定'); return core.chooseReplayFile();
case 5: core.playSound('取消'); return core.ui.closePanel(); case 5: core.playSound('确定'); return this._clickReplay_download();
case 6: core.playSound('取消'); return core.ui.closePanel();
} }
} }
} }
@ -2922,14 +2936,32 @@ actions.prototype._clickReplay_replayRemain = function () {
}); });
} }
actions.prototype._clickReplay_replaySince = function () {
core.closePanel();
core.drawText([
"\t[播放存档剩余录像]该功能为【接续播放录像】的简化版本,允许你播放\r[yellow]一个存档中剩余的录像\r常常用于\r[yellow]录像局部优化\r。\n" +
"在录像正常播放中你随时可以暂停并按S键进行存档此时\r[yellow]剩余录像\r也会被记在存档中在读档界面用\r[yellow][R]\r标识。\n" +
"之后,你可以选择在路线优化后直接播放该存档的\r[yellow]剩余录像\r而无需再像接续播放一样选择录像起点和终点。\n\n" +
"详细使用方法参见露珠录制的视频教程:\n\r[yellow]https://bilibili.com/video/BV1az4y1C78x",
"请选择一个存档。\n\n\r[yellow]该存档需为录像播放中存的,且坐标必须和当前勇士坐标完全相同。\r\n将尝试播放此存档的剩余录像。",
], function () {
core.status.event.id = 'replaySince';
core.lockControl();
var saveIndex = core.saves.saveIndex;
var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page;
core.ui._drawSLPanel(10 * page + offset);
});
}
actions.prototype._clickReplay_download = function () { actions.prototype._clickReplay_download = function () {
// if (core.hasFlag('debug')) return core.drawText("\t[系统提示]调试模式下无法下载录像"); // if (core.hasFlag('debug')) return core.drawText("\t[系统提示]调试模式下无法下载录像");
core.download(core.firstData.name + "_" + core.formatDate2() + ".h5route", JSON.stringify({ core.download(core.firstData.name + "_" + core.formatDate2() + ".h5route",
'name': core.firstData.name, LZString.compressToBase64(JSON.stringify({
'hard': core.status.hard, 'name': core.firstData.name,
'seed': core.getFlag('__seed__'), 'hard': core.status.hard,
'route': core.encodeRoute(core.status.route) 'seed': core.getFlag('__seed__'),
})); 'route': core.encodeRoute(core.status.route)
})));
} }
@ -3085,7 +3117,9 @@ actions.prototype._clickKeyBoard = function (x, y) {
actions.prototype._clickCursor = function (x, y, px, py) { actions.prototype._clickCursor = function (x, y, px, py) {
if (x == core.status.automaticRoute.cursorX && y == core.status.automaticRoute.cursorY) { if (x == core.status.automaticRoute.cursorX && y == core.status.automaticRoute.cursorY) {
core.ui.closePanel(); core.ui.closePanel();
core.onclick(x, y, px, py, []); // 视为按下再放起
this.doRegisteredAction('ondown', x, y, px, py);
this.doRegisteredAction('onup', x, y, px, py);
return; return;
} }
core.status.automaticRoute.cursorX = x; core.status.automaticRoute.cursorX = x;
@ -3133,7 +3167,9 @@ actions.prototype._keyUpCursor = function (keycode) {
core.ui.closePanel(); core.ui.closePanel();
var x = core.status.automaticRoute.cursorX; var x = core.status.automaticRoute.cursorX;
var y = core.status.automaticRoute.cursorY; var y = core.status.automaticRoute.cursorY;
core.onclick(x, y, 32 * x + 16, 32 * y + 16, []); // 视为按下再放起
this.doRegisteredAction('ondown', x, y, 32 * x + 16, 32 * y + 16);
this.doRegisteredAction('onup', x, y, 32 * x + 16, 32 * y + 16);
return; return;
} }
} }

View File

@ -159,7 +159,7 @@ control.prototype._animationFrame_globalAnimate = function (timestamp) {
}); });
// Global hero animate // Global hero animate
if ((core.status.hero || {}).animate && core.status.heroMoving == 0 && main.mode == 'play') { if ((core.status.hero || {}).animate && core.status.heroMoving == 0 && main.mode == 'play' && !core.status.preview.enabled) {
core.drawHero('stop', null, core.status.globalAnimateStatus); core.drawHero('stop', null, core.status.globalAnimateStatus);
} }
} }
@ -498,11 +498,6 @@ control.prototype.clearContinueAutomaticRoute = function (callback) {
if (callback) callback(); if (callback) callback();
} }
////// 显示离散的寻路点 //////
control.prototype.fillPosWithPoint = function (pos) {
core.fillRect('ui', pos.x*32+12,pos.y*32+12,8,8, '#bfbfbf');
}
////// 设置自动寻路路线 ////// ////// 设置自动寻路路线 //////
control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
if (!core.status.played || core.status.lockControl) return; if (!core.status.played || core.status.lockControl) return;
@ -831,20 +826,15 @@ control.prototype.drawHero = function (status, offset, frame) {
core.status.heroCenter.py = 32 * y + offsetY + 32 - core.material.icons.hero.height / 2; core.status.heroCenter.py = 32 * y + offsetY + 32 - core.material.icons.hero.height / 2;
// 重置hero层画布 // 重置hero层画布
var px = parseFloat(core.canvas.hero.canvas.getAttribute('_px')) || 0;
var py = parseFloat(core.canvas.hero.canvas.getAttribute('_py')) || 0;
core.setGameCanvasTranslate('hero', 0, 0); core.setGameCanvasTranslate('hero', 0, 0);
core.canvas.hero.canvas.removeAttribute('_px'); delete core.canvas.hero._px;
core.canvas.hero.canvas.removeAttribute('_py'); delete core.canvas.hero._py;
offset.px = px; core.status.preview.enabled = false;
offset.py = py;
if (!core.hasFlag('__lockViewport__')) { if (!core.hasFlag('__lockViewport__')) {
this._drawHero_updateViewport(x, y, offset); this._drawHero_updateViewport(x, y, offset);
} }
if (!core.hasFlag('hideHero')) { this._drawHero_draw(direction, x, y, status, offset, frame);
this._drawHero_draw(direction, x, y, status, offset, frame);
}
} }
control.prototype._drawHero_updateViewport = function (x, y, offset) { control.prototype._drawHero_updateViewport = function (x, y, offset) {
@ -855,11 +845,13 @@ control.prototype._drawHero_updateViewport = function (x, y, offset) {
control.prototype._drawHero_draw = function (direction, x, y, status, offset, frame) { control.prototype._drawHero_draw = function (direction, x, y, status, offset, frame) {
offset = offset || {x: 0, y: 0, offset: 0, px: 0, py: 0}; offset = offset || {x: 0, y: 0, offset: 0, px: 0, py: 0};
var opacity = core.setAlpha('hero', core.getFlag('__heroOpacity__', 1))
this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function (block) { this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function (block) {
core.drawImage('hero', block.img, (block.heroIcon[block.status] + (frame || 0))%4*block.width, core.drawImage('hero', block.img, (block.heroIcon[block.status] + (frame || 0))%4*block.width,
block.heroIcon.loc * block.height, block.width, block.height, block.heroIcon.loc * block.height, block.width, block.height,
offset.px+block.posx+(32-block.width)/2, offset.py+block.posy+32-block.height, block.width, block.height); block.posx+(32-block.width)/2, block.posy+32-block.height, block.width, block.height);
}); });
core.setAlpha('hero', opacity);
} }
control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, offset) { control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, offset) {
@ -893,45 +885,34 @@ control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, off
}); });
} }
control.prototype.triggerHero = function (type, time, callback) { control.prototype.setHeroOpacity = function (opacity, moveMode, time, callback) {
if (type == null) {
type = core.hasFlag('hideHero') ? 'show' : 'hide';
}
if ((core.hasFlag('hideHero') && type != 'show') || (!core.hasFlag('hideHero') && type != 'hide')) {
if (callback) callback();
return;
}
core.removeFlag('hideHero');
var cb = function () {
if (type == 'hide') core.setFlag('hideHero', true);
core.drawHero();
if (callback) callback();
return;
}
time = time || 0; time = time || 0;
if (time == 0) return cb(); if (time == 0) {
time /= Math.max(core.status.replay.speed, 1) core.setFlag('__heroOpacity__', opacity);
this._triggerHero_animate(type, 10 / time, cb);
}
control.prototype._triggerHero_animate = function (type, delta, callback) {
var opacity = type != 'show' ? 1 : 0;
var animate = setInterval(function () {
opacity += type != 'show' ? -delta : delta;
core.setAlpha('hero', opacity);
core.drawHero(); core.drawHero();
core.setAlpha('hero', 1); if (callback) callback();
if (opacity >= 1 || opacity <= 0) { return;
}
time /= Math.max(core.status.replay.speed, 1)
var fromOpacity = core.getFlag('__heroOpacity__', 1);
var step = 0, steps = parseInt(time / 10);
if (steps <= 0) steps = 1;
var moveFunc = core.applyEasing(moveMode);
var animate = setInterval(function () {
step++;
core.setFlag('__heroOpacity__', fromOpacity + (opacity - fromOpacity) * moveFunc(step / steps));
core.drawHero();
if (step == steps) {
delete core.animateFrame.asyncId[animate]; delete core.animateFrame.asyncId[animate];
clearInterval(animate); clearInterval(animate);
core.drawHero();
if (callback) callback(); if (callback) callback();
} }
}, 10); }, 10);
core.animateFrame.asyncId[animate] = true; core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = callback;
} }
// ------ 画布、位置、阻激夹域,显伤 ------ // // ------ 画布、位置、阻激夹域,显伤 ------ //
@ -1015,14 +996,13 @@ control.prototype.setViewport = function (px, py) {
core.bigmap.offsetY = core.clamp(py, 0, 32 * core.bigmap.height - core.__PIXELS__); core.bigmap.offsetY = core.clamp(py, 0, 32 * core.bigmap.height - core.__PIXELS__);
this.updateViewport(); this.updateViewport();
// ------ hero层也需要 // ------ hero层也需要
var canvas = core.canvas.hero.canvas; var px = parseFloat(core.canvas.hero._px) || 0;
var px = parseFloat(canvas.getAttribute('_px')) || 0; var py = parseFloat(core.canvas.hero._py) || 0;
var py = parseFloat(canvas.getAttribute('_py')) || 0;
px += originOffsetX - core.bigmap.offsetX; px += originOffsetX - core.bigmap.offsetX;
py += originOffsetY - core.bigmap.offsetY; py += originOffsetY - core.bigmap.offsetY;
core.control.setGameCanvasTranslate('hero', px, py); core.control.setGameCanvasTranslate('hero', px, py);
core.canvas.hero.canvas.setAttribute('_px', px); core.canvas.hero._px = px;
core.canvas.hero.canvas.setAttribute('_py', py); core.canvas.hero._py = py;
} }
////// 移动视野范围 ////// ////// 移动视野范围 //////
@ -1052,7 +1032,8 @@ control.prototype.moveViewport = function (x, y, moveMode, time, callback) {
} }
}, per_time); }, per_time);
core.animateFrame.asyncId[animate] = true; core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = callback;
} }
////// 获得勇士面对位置的x坐标 ////// ////// 获得勇士面对位置的x坐标 //////
@ -1303,15 +1284,9 @@ control.prototype.drawDamage = function (ctx) {
control.prototype._drawDamage_draw = function (ctx, onMap) { control.prototype._drawDamage_draw = function (ctx, onMap) {
if (!core.hasItem('book')) return; if (!core.hasItem('book')) return;
// 双缓冲
var cacheCtx = core.bigmap.cacheCanvas;
cacheCtx.canvas.width = ctx.canvas.width;
cacheCtx.canvas.height = ctx.canvas.height;
cacheCtx.clearRect(0, 0, cacheCtx.canvas.width, cacheCtx.canvas.height);
if (onMap && core.bigmap.v2) cacheCtx.translate(32, 32);
core.setFont(cacheCtx, "bold 11px Arial"); core.setFont(ctx, "bold 11px Arial");
core.setTextAlign(cacheCtx, 'left'); core.setTextAlign(ctx, 'left');
core.status.damage.data.forEach(function (one) { core.status.damage.data.forEach(function (one) {
var px = one.px, py = one.py; var px = one.px, py = one.py;
if (onMap && core.bigmap.v2) { if (onMap && core.bigmap.v2) {
@ -1320,10 +1295,10 @@ control.prototype._drawDamage_draw = function (ctx, onMap) {
if (px < -32 * 2 || px > core.__PIXELS__ + 32 || py < -32 || py > core.__PIXELS__ + 32) if (px < -32 * 2 || px > core.__PIXELS__ + 32 || py < -32 || py > core.__PIXELS__ + 32)
return; return;
} }
core.fillBoldText(cacheCtx, one.text, px, py, one.color); core.fillBoldText(ctx, one.text, px, py, one.color);
}); });
core.setTextAlign(cacheCtx, 'center'); core.setTextAlign(ctx, 'center');
core.status.damage.extraData.forEach(function (one) { core.status.damage.extraData.forEach(function (one) {
var px = one.px, py = one.py; var px = one.px, py = one.py;
if (onMap && core.bigmap.v2) { if (onMap && core.bigmap.v2) {
@ -1332,13 +1307,10 @@ control.prototype._drawDamage_draw = function (ctx, onMap) {
if (px < -32 || px > core.__PIXELS__ + 32 || py < -32 || py > core.__PIXELS__ + 32) if (px < -32 || px > core.__PIXELS__ + 32 || py < -32 || py > core.__PIXELS__ + 32)
return; return;
} }
var alpha = core.setAlpha(cacheCtx, one.alpha); var alpha = core.setAlpha(ctx, one.alpha);
core.fillBoldText(cacheCtx, one.text, px, py, one.color); core.fillBoldText(ctx, one.text, px, py, one.color);
core.setAlpha(cacheCtx, alpha); core.setAlpha(ctx, alpha);
}); });
cacheCtx.translate(0, 0);
core.drawImage(ctx, cacheCtx.canvas, onMap && core.bigmap.v2 ? -32 : 0, onMap && core.bigmap.v2 ? -32 : 0);
} }
// ------ 录像相关 ------ // // ------ 录像相关 ------ //
@ -1364,6 +1336,7 @@ control.prototype.startReplay = function (list) {
if (!core.isPlaying()) return; if (!core.isPlaying()) return;
core.status.replay.replaying=true; core.status.replay.replaying=true;
core.status.replay.pausing=true; core.status.replay.pausing=true;
core.status.replay.failed = false;
core.status.replay.speed=1.0; core.status.replay.speed=1.0;
core.status.replay.toReplay = core.cloneArray(list); core.status.replay.toReplay = core.cloneArray(list);
core.status.replay.totalList = core.status.route.concat(list); core.status.replay.totalList = core.status.route.concat(list);
@ -1459,6 +1432,7 @@ control.prototype.stopReplay = function (force) {
core.status.replay.totalList = []; core.status.replay.totalList = [];
core.status.replay.replaying=false; core.status.replay.replaying=false;
core.status.replay.pausing=false; core.status.replay.pausing=false;
core.status.replay.failed = false;
core.status.replay.speed=1.0; core.status.replay.speed=1.0;
core.status.replay.steps = 0; core.status.replay.steps = 0;
core.status.replay.save = []; core.status.replay.save = [];
@ -1614,7 +1588,7 @@ control.prototype.isReplaying = function () {
////// 回放 ////// ////// 回放 //////
control.prototype.replay = function (force) { control.prototype.replay = function (force) {
if (!core.isPlaying() || !core.isReplaying() if (!core.isPlaying() || !core.isReplaying()
|| core.status.replay.animate || core.status.event.id) return; || core.status.replay.animate || core.status.event.id || core.status.replay.failed) return;
if (core.status.replay.pausing && !force) return; if (core.status.replay.pausing && !force) return;
this._replay_drawProgress(); this._replay_drawProgress();
if (core.status.replay.toReplay.length==0) if (core.status.replay.toReplay.length==0)
@ -1656,6 +1630,7 @@ control.prototype._doReplayAction = function (action) {
control.prototype._replay_finished = function () { control.prototype._replay_finished = function () {
core.status.replay.replaying = false; core.status.replay.replaying = false;
core.status.replay.failed = false;
core.status.event.selection = 0; core.status.event.selection = 0;
var str = "录像播放完毕,你想退出播放吗?"; var str = "录像播放完毕,你想退出播放吗?";
if (core.status.route.length != core.status.replay.totalList.length if (core.status.route.length != core.status.replay.totalList.length
@ -1688,6 +1663,7 @@ control.prototype._replay_save = function () {
control.prototype._replay_error = function (action, callback) { control.prototype._replay_error = function (action, callback) {
core.ui.closePanel(); core.ui.closePanel();
core.status.replay.replaying = false; core.status.replay.replaying = false;
core.status.replay.failed = true;
var len = core.status.replay.toReplay.length; var len = core.status.replay.toReplay.length;
var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1); var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1);
var nextList = core.status.replay.toReplay.slice(0, 10); var nextList = core.status.replay.toReplay.slice(0, 10);
@ -1695,6 +1671,7 @@ control.prototype._replay_error = function (action, callback) {
main.log("之前的10个操作是\n" + prevList.toString()); main.log("之前的10个操作是\n" + prevList.toString());
main.log("接下来10个操作是\n" + nextList.toString()); main.log("接下来10个操作是\n" + nextList.toString());
core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () { core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () {
core.status.replay.failed = false;
core.ui.closePanel(); core.ui.closePanel();
if (core.status.replay.save.length > 0) { if (core.status.replay.save.length > 0) {
core.status.replay.replaying = true; core.status.replay.replaying = true;
@ -1708,6 +1685,7 @@ control.prototype._replay_error = function (action, callback) {
if (callback) callback(); if (callback) callback();
} }
}, function () { }, function () {
core.status.replay.failed = false;
core.ui.closePanel(); core.ui.closePanel();
core.stopReplay(true); core.stopReplay(true);
if (callback) callback(); if (callback) callback();
@ -1977,6 +1955,7 @@ control.prototype.doSL = function (id, type) {
case 'reload': this._doSL_reload(id, this._doSL_load_afterGet); break; case 'reload': this._doSL_reload(id, this._doSL_load_afterGet); break;
case 'replayLoad': this._doSL_load(id, this._doSL_replayLoad_afterGet); break; case 'replayLoad': this._doSL_load(id, this._doSL_replayLoad_afterGet); break;
case 'replayRemain': this._doSL_load(id, this._doSL_replayRemain_afterGet); break; case 'replayRemain': this._doSL_load(id, this._doSL_replayRemain_afterGet); break;
case 'replaySince': this._doSL_load(id, this._doSL_replaySince_afterGet); break;
} }
} }
@ -1988,7 +1967,11 @@ control.prototype._doSL_save = function (id) {
// 在事件中的存档 // 在事件中的存档
if (core.status.event.interval != null) if (core.status.event.interval != null)
core.setFlag("__events__", core.status.event.interval); core.setFlag("__events__", core.status.event.interval);
core.setLocalForage("save"+id, core.saveData(), function() { var data = core.saveData();
if (core.isReplaying() && core.status.replay.toReplay.length > 0) {
data.__toReplay__ = core.encodeRoute(core.status.replay.toReplay);
}
core.setLocalForage("save"+id, data, function() {
core.saves.saveIndex = id; core.saves.saveIndex = id;
core.setLocalStorage('saveIndex', core.saves.saveIndex); core.setLocalStorage('saveIndex', core.saves.saveIndex);
// 恢复事件 // 恢复事件
@ -1998,12 +1981,7 @@ control.prototype._doSL_save = function (id) {
core.drawTip('存档成功!'); core.drawTip('存档成功!');
}, function(err) { }, function(err) {
main.log(err); main.log(err);
if (core.platform.useLocalForage) { alert("存档失败,错误信息:\n"+err);
alert("存档失败,错误信息:\n"+err);
}
else {
alert("存档失败,错误信息:\n"+err+"\n建议使用垃圾存档清理工具进行清理");
}
}); });
core.removeFlag("__events__"); core.removeFlag("__events__");
return; return;
@ -2084,25 +2062,20 @@ control.prototype._doSL_replayLoad_afterGet = function (id, data) {
core.playSound('操作失败'); core.playSound('操作失败');
return core.drawTip("存档版本不匹配"); return core.drawTip("存档版本不匹配");
} }
if (data.hard != core.status.hard) {
core.playSound('操作失败');
return core.drawTip("游戏难度不匹配!");
}
if (data.hero.flags.__events__ && data.guid != core.getGuid()) { if (data.hero.flags.__events__ && data.guid != core.getGuid()) {
core.playSound('操作失败'); core.playSound('操作失败');
return core.drawTip("此存档可能存在风险,无法读档"); return core.drawTip("此存档可能存在风险,无法读档");
} }
var route = core.subarray(core.status.route, core.decodeRoute(data.route)); var route = core.subarray(core.status.route, core.decodeRoute(data.route));
if (route == null || data.hero.flags.__seed__ != core.getFlag('__seed__')) { if (route == null) {
core.playSound('操作失败'); core.playSound('操作失败');
return core.drawTip("种子不一致,无法从此存档回放录像"); return core.drawTip("无法从此存档回放录像");
} }
core.loadData(data, function () { core.loadData(data, function () {
core.removeFlag('__fromLoad__'); core.removeFlag('__fromLoad__');
core.startReplay(route); core.startReplay(route);
core.drawTip("回退到存档节点"); core.drawTip("回退到存档节点");
}); });
} }
control.prototype._doSL_replayRemain_afterGet = function (id, data) { control.prototype._doSL_replayRemain_afterGet = function (id, data) {
@ -2135,6 +2108,16 @@ control.prototype._doSL_replayRemain_afterGet = function (id, data) {
}); });
} }
control.prototype._doSL_replaySince_afterGet = function (id, data) {
if (data.floorId != core.status.floorId || data.hero.loc.x != core.getHeroLoc('x') || data.hero.loc.y != core.getHeroLoc('y'))
return alert("楼层或坐标不一致!");
if (!data.__toReplay__) return alert('该存档没有剩余录像!');
core.ui.closePanel();
core.startReplay(core.decodeRoute(data.__toReplay__));
core.drawTip("播放存档剩余录像");
return;
}
////// 同步存档到服务器 ////// ////// 同步存档到服务器 //////
control.prototype.syncSave = function (type) { control.prototype.syncSave = function (type) {
core.ui.drawWaiting("正在同步,请稍候..."); core.ui.drawWaiting("正在同步,请稍候...");
@ -2150,7 +2133,7 @@ control.prototype._syncSave_http = function (type, saves) {
var formData = new FormData(); var formData = new FormData();
formData.append('type', 'save'); formData.append('type', 'save');
formData.append('name', core.firstData.name); formData.append('name', core.firstData.name);
formData.append('data', JSON.stringify(saves)); formData.append('data', LZString.compressToBase64(JSON.stringify(saves)));
formData.append('shorten', '1'); formData.append('shorten', '1');
core.http("POST", "/games/sync.php", formData, function (data) { core.http("POST", "/games/sync.php", formData, function (data) {
@ -2195,7 +2178,20 @@ control.prototype._syncLoad_http = function (id, password) {
core.http("POST", "/games/sync.php", formData, function (data) { core.http("POST", "/games/sync.php", formData, function (data) {
var response = JSON.parse(data); var response = JSON.parse(data);
if (response.code == 0) { if (response.code == 0) {
core.control._syncLoad_write(JSON.parse(response.msg)); var msg = null;
try {
msg = JSON.parse(LZString.decompressFromBase64(response.msg));
} catch (e) {}
if (!msg) {
try {
msg = JSON.parse(response.msg);
} catch (e) {}
}
if (msg) {
core.control._syncLoad_write(msg);
} else {
core.drawText("出错啦!\n存档解析失败");
}
} }
else { else {
core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因"+response.msg); core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因"+response.msg);
@ -2299,19 +2295,16 @@ control.prototype.getAllSaves = function (callback) {
////// 获得所有存在存档的存档位 ////// ////// 获得所有存在存档的存档位 //////
control.prototype.getSaveIndexes = function (callback) { control.prototype.getSaveIndexes = function (callback) {
var indexes = {}; var indexes = {};
if (core.platform.useLocalForage) { core.keysLocalForage(function (err, keys) {
localforage.iterate(function (value, key, n) { if (err) {
main.log(err);
return callback(indexes);
}
keys.forEach(function (key) {
core.control._getSaveIndexes_getIndex(indexes, key); core.control._getSaveIndexes_getIndex(indexes, key);
}, function () { });
callback(indexes); callback(indexes);
}); });
}
else {
Object.keys(localStorage).forEach(function (key) {
core.control._getSaveIndexes_getIndex(indexes, key);
});
callback(indexes);
}
} }
control.prototype._getSaveIndexes_getIndex = function (indexes, name) { control.prototype._getSaveIndexes_getIndex = function (indexes, name) {
@ -2384,7 +2377,7 @@ control.prototype.getStatus = function (name) {
if (!core.status.hero) return null; if (!core.status.hero) return null;
if (name == 'x' || name == 'y' || name == 'direction') if (name == 'x' || name == 'y' || name == 'direction')
return this.getHeroLoc(name); return this.getHeroLoc(name);
if (main.mode == 'editor') { if (main.mode == 'editor' && !core.hasFlag('__statistics__')) {
return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name]; return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name];
} }
return core.status.hero[name]; return core.status.hero[name];
@ -2691,10 +2684,9 @@ control.prototype._weather_snow = function (level) {
control.prototype._weather_fog = function (level) { control.prototype._weather_fog = function (level) {
if (!core.animateFrame.weather.fog) return; if (!core.animateFrame.weather.fog) return;
var number = level * parseInt(20*core.bigmap.width*core.bigmap.height/(core.__SIZE__*core.__SIZE__));
core.animateFrame.weather.nodes = [{ core.animateFrame.weather.nodes = [{
'image': core.animateFrame.weather.fog, 'image': core.animateFrame.weather.fog,
'level': number, 'level': 40 * level,
'x': 0, 'x': 0,
'y': -core.__PIXELS__ / 2, 'y': -core.__PIXELS__ / 2,
'dx': -Math.random() * 1.5, 'dx': -Math.random() * 1.5,
@ -2705,10 +2697,9 @@ control.prototype._weather_fog = function (level) {
control.prototype._weather_cloud = function (level) { control.prototype._weather_cloud = function (level) {
if (!core.animateFrame.weather.cloud) return; if (!core.animateFrame.weather.cloud) return;
var number = level * parseInt(20*core.bigmap.width*core.bigmap.height/(core.__SIZE__*core.__SIZE__));
core.animateFrame.weather.nodes = [{ core.animateFrame.weather.nodes = [{
'image': core.animateFrame.weather.cloud, 'image': core.animateFrame.weather.cloud,
'level': number, 'level': 40 * level,
'x': 0, 'x': 0,
'y': -core.__PIXELS__ / 2, 'y': -core.__PIXELS__ / 2,
'dx': -Math.random() * 1.5, 'dx': -Math.random() * 1.5,
@ -2752,10 +2743,16 @@ control.prototype._setCurtain_animate = function (nowColor, color, time, moveMod
time /= Math.max(core.status.replay.speed, 1) time /= Math.max(core.status.replay.speed, 1)
var per_time = 10, step = 0, steps = parseInt(time / per_time); var per_time = 10, step = 0, steps = parseInt(time / per_time);
if (steps <= 0) steps = 1; if (steps <= 0) steps = 1;
var curr = nowColor;
var moveFunc = core.applyEasing(moveMode); var moveFunc = core.applyEasing(moveMode);
var cb = function () {
core.status.curtainColor = curr;
if (callback) callback();
}
var animate = setInterval(function() { var animate = setInterval(function() {
step++; step++;
var curr = [ curr = [
nowColor[0] + (color[0] - nowColor[0]) * moveFunc(step / steps), nowColor[0] + (color[0] - nowColor[0]) * moveFunc(step / steps),
nowColor[1] + (color[1] - nowColor[1]) * moveFunc(step / steps), nowColor[1] + (color[1] - nowColor[1]) * moveFunc(step / steps),
nowColor[2] + (color[2] - nowColor[2]) * moveFunc(step / steps), nowColor[2] + (color[2] - nowColor[2]) * moveFunc(step / steps),
@ -2766,12 +2763,12 @@ control.prototype._setCurtain_animate = function (nowColor, color, time, moveMod
if (step == steps) { if (step == steps) {
delete core.animateFrame.asyncId[animate]; delete core.animateFrame.asyncId[animate];
clearInterval(animate); clearInterval(animate);
core.status.curtainColor = color; cb();
if (core.isset(callback)) callback();
} }
}, per_time); }, per_time);
core.animateFrame.asyncId[animate] = true; core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = cb;
} }
////// 画面闪烁 ////// ////// 画面闪烁 //////
@ -3246,9 +3243,9 @@ control.prototype.resize = function() {
var statusDisplayArr = this._shouldDisplayStatus(), count = statusDisplayArr.length; var statusDisplayArr = this._shouldDisplayStatus(), count = statusDisplayArr.length;
var statusCanvas = core.flags.statusCanvas, statusCanvasRows = core.values.statusCanvasRowsOnMobile || 3; var statusCanvas = core.flags.statusCanvas, statusCanvasRows = core.values.statusCanvasRowsOnMobile || 3;
var col = statusCanvas ? statusCanvasRows : Math.ceil(count / 3); var col = statusCanvas ? statusCanvasRows : Math.ceil(count / 3);
if (col > 4) { if (col > 5) {
if (statusCanvas) alert("自绘状态栏的在竖屏下的行数应不超过4"); if (statusCanvas) alert("自绘状态栏的在竖屏下的行数应不超过5");
else alert("当前状态栏数目("+count+")大于12请调整到不超过12以避免手机端出现显示问题。"); else alert("当前状态栏数目("+count+")大于15请调整到不超过15以避免手机端出现显示问题。");
} }
var globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute; var globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute;
@ -3258,7 +3255,7 @@ control.prototype.resize = function() {
CANVAS_WIDTH: CANVAS_WIDTH, CANVAS_WIDTH: CANVAS_WIDTH,
BORDER: BORDER, BORDER: BORDER,
BAR_WIDTH: BAR_WIDTH, BAR_WIDTH: BAR_WIDTH,
TOOLBAR_HEIGHT: extendToolbar ? 38 : 44, TOOLBAR_HEIGHT: 38,
outerSize: CANVAS_WIDTH * core.domStyle.scale + 2 * BORDER, outerSize: CANVAS_WIDTH * core.domStyle.scale + 2 * BORDER,
globalAttribute: globalAttribute, globalAttribute: globalAttribute,
border: '3px ' + core.arrayToRGBA(globalAttribute.borderColor) + ' solid', border: '3px ' + core.arrayToRGBA(globalAttribute.borderColor) + ' solid',
@ -3266,7 +3263,7 @@ control.prototype.resize = function() {
count: count, count: count,
col: col, col: col,
statusBarHeightInVertical: core.domStyle.isVertical ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER : 0, statusBarHeightInVertical: core.domStyle.isVertical ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER : 0,
toolbarHeightInVertical: core.domStyle.isVertical ? 44 * core.domStyle.scale + 2 * BORDER : 0, toolbarHeightInVertical: core.domStyle.isVertical ? 38 * core.domStyle.scale + 2 * BORDER : 0,
extendToolbar: extendToolbar, extendToolbar: extendToolbar,
is15x15: core.__SIZE__ == 15 is15x15: core.__SIZE__ == 15
}; };
@ -3473,7 +3470,7 @@ control.prototype._resize_tools = function (obj) {
var style = core.dom.tools[i].style; var style = core.dom.tools[i].style;
style.height = toolsHeight + "px"; style.height = toolsHeight + "px";
style.marginLeft = toolsMarginLeft + "px"; style.marginLeft = toolsMarginLeft + "px";
style.marginTop = (obj.extendToolbar ? 3 : 6) * core.domStyle.scale + "px" style.marginTop = 3 * core.domStyle.scale + "px"
} }
core.dom.hard.style.lineHeight = toolsHeight + "px"; core.dom.hard.style.lineHeight = toolsHeight + "px";
if (core.domStyle.isVertical || obj.extendToolbar) { if (core.domStyle.isVertical || obj.extendToolbar) {

View File

@ -54,7 +54,8 @@ function core() {
'sun': null 'sun': null
}, },
"tip": null, "tip": null,
"asyncId": {} "asyncId": {},
"lastAsyncId": null
} }
this.musicStatus = { this.musicStatus = {
'audioContext': null, // WebAudioContext 'audioContext': null, // WebAudioContext
@ -82,7 +83,6 @@ function core() {
'isQQ': false, // 是否是QQ 'isQQ': false, // 是否是QQ
'isChrome': false, // 是否是Chrome 'isChrome': false, // 是否是Chrome
'supportCopy': false, // 是否支持复制到剪切板 'supportCopy': false, // 是否支持复制到剪切板
'useLocalForage': true,
'fileInput': null, // FileInput 'fileInput': null, // FileInput
'fileReader': null, // 是否支持FileReader 'fileReader': null, // 是否支持FileReader
@ -126,7 +126,8 @@ function core() {
"now": 0, "now": 0,
}, },
"favorite": [], "favorite": [],
"favoriteName": {} "favoriteName": {},
"cache": {}
} }
this.initStatus = { this.initStatus = {
'played': false, 'played': false,
@ -178,6 +179,13 @@ function core() {
// 按下键的时间:为了判定双击 // 按下键的时间:为了判定双击
'downTime': null, 'downTime': null,
'ctrlDown': false, 'ctrlDown': false,
'preview': {
'enabled': false,
'prepareDragging': false,
'dragging': false,
'px': 0,
'py': 0,
},
// 路线&回放 // 路线&回放
'route': [], 'route': [],
@ -185,6 +193,7 @@ function core() {
'replaying': false, 'replaying': false,
'pausing': false, 'pausing': false,
'animate': false, // 正在某段动画中 'animate': false, // 正在某段动画中
'failed': false,
'toReplay': [], 'toReplay': [],
'totalList': [], 'totalList': [],
'speed': 1.0, 'speed': 1.0,
@ -242,6 +251,11 @@ function core() {
this.markedFloorIds = {}; this.markedFloorIds = {};
this.status = {}; this.status = {};
this.dymCanvas = {}; this.dymCanvas = {};
if (main.mode == 'editor') {
document.documentElement.style.setProperty('--size', this.__SIZE__);
document.documentElement.style.setProperty('--pixel', this.__PIXELS__ + 'px');
}
} }
/////////// 系统事件相关 /////////// /////////// 系统事件相关 ///////////
@ -402,7 +416,6 @@ core.prototype._init_platform = function () {
core.platform.isSafari = /Safari/i.test(navigator.userAgent) && !/Chrome/i.test(navigator.userAgent); core.platform.isSafari = /Safari/i.test(navigator.userAgent) && !/Chrome/i.test(navigator.userAgent);
core.platform.isQQ = /QQ/i.test(navigator.userAgent); core.platform.isQQ = /QQ/i.test(navigator.userAgent);
core.platform.isWeChat = /MicroMessenger/i.test(navigator.userAgent); core.platform.isWeChat = /MicroMessenger/i.test(navigator.userAgent);
this._init_checkLocalForage();
if (window.FileReader) { if (window.FileReader) {
core.platform.fileReader = new FileReader(); core.platform.fileReader = new FileReader();
core.platform.fileReader.onload = function () { core.platform.fileReader.onload = function () {
@ -421,37 +434,6 @@ core.prototype._init_platform = function () {
} }
} }
core.prototype._init_checkLocalForage = function () {
core.platform.useLocalForage = core.getLocalStorage('useLocalForage', true);
var _error = function (e) {
main.log(e);
core.platform.useLocalForage = false;
};
if (core.platform.useLocalForage) {
try {
core.setLocalForage("__test__", lzw_encode("__test__"), function () {
try {
core.getLocalForage("__test__", null, function (data) {
try {
if (lzw_decode(data) != "__test__") {
console.log("localForage unsupported!");
core.platform.useLocalForage = false;
}
else {
console.log("localForage supported!");
core.removeLocalForage("__test__");
}
}
catch (e) {_error(e);}
}, _error)
}
catch (e) {_error(e);}
}, _error)
}
catch (e) {_error(e);}
}
}
core.prototype._init_others = function () { core.prototype._init_others = function () {
// 一些额外的东西 // 一些额外的东西
core.material.groundCanvas = document.createElement('canvas').getContext('2d'); core.material.groundCanvas = document.createElement('canvas').getContext('2d');

View File

@ -228,13 +228,12 @@ enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) {
if (specialCriticals != null) return specialCriticals; if (specialCriticals != null) return specialCriticals;
var info = this.getDamageInfo(enemy, null, x, y, floorId); var info = this.getDamageInfo(enemy, null, x, y, floorId);
if (info == null) { // 如果未破防... if (info == null) { // 如果未破防...
var enemyInfo = this.getEnemyInfo(enemy, null, x, y, floorId); var overAtk = this._nextCriticals_overAtk(enemy, x, y, floorId);
if (enemyInfo.def == null || enemyInfo.def < core.status.hero.atk) return []; if (overAtk == null) return [];
// 再次尝试获得破防后伤害 if (typeof overAtk[1] == 'number') return [[overAtk[0], -overAtk[1]]];
info = this.getDamageInfo(enemy, {atk: enemyInfo.def + 1}, x, y, floorId); info = overAtk[1];
if (info == null || info.mon_def != enemyInfo.def) return [];
info.__over__ = true; info.__over__ = true;
info.__overAtk__ = info.mon_def + 1 - core.status.hero.atk; info.__overAtk__ = overAtk[0];
} }
if (typeof info == 'number') return [[0,0]]; if (typeof info == 'number') return [[0,0]];
@ -255,6 +254,26 @@ enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) {
} }
} }
/// 未破防临界采用二分计算
enemys.prototype._nextCriticals_overAtk = function (enemy, x, y, floorId) {
var calNext = function (currAtk, maxAtk) {
var start = currAtk, end = maxAtk;
if (start > end) return null;
while (start < end) {
var mid = Math.floor((start + end) / 2);
if (mid - start > end - mid) mid--;
var nextInfo = core.enemys.getDamageInfo(enemy, {"atk": mid}, x, y, floorId);
if (nextInfo != null) end = mid;
else start = mid + 1;
}
var nextInfo = core.enemys.getDamageInfo(enemy, {"atk": start}, x, y, floorId);
return nextInfo == null ? null : [start - core.status.hero.atk, nextInfo];
}
return calNext(core.status.hero.atk + 1,
core.getEnemyValue(enemy, 'hp', x, y, floorId) + core.getEnemyValue(enemy, 'def', x, y, floorId));
}
enemys.prototype._nextCriticals_special = function (enemy, number, x, y, floorId) { enemys.prototype._nextCriticals_special = function (enemy, number, x, y, floorId) {
if (this.hasSpecial(enemy.special, 10) || this.hasSpecial(enemy.special, 3)) if (this.hasSpecial(enemy.special, 10) || this.hasSpecial(enemy.special, 3))
return []; // 模仿or坚固临界 return []; // 模仿or坚固临界
@ -266,15 +285,15 @@ enemys.prototype._nextCriticals_useLoop = function (enemy, info, number, x, y, f
var list = []; var list = [];
var start_atk = hero_atk; var start_atk = hero_atk;
if (info.__over__) { if (info.__over__) {
start_atk = mon_def + 1; start_atk += info.__overAtk__;
list.push([info.__overAtk__, -info.damage]); list.push([info.__overAtk__, -info.damage]);
} }
for (var atk = start_atk + 1; atk <= mon_hp + mon_def; atk++) { for (var atk = start_atk + 1; atk <= mon_hp + mon_def; atk++) {
var nextInfo = this.getDamageInfo(enemy, {"atk": Math.ceil(atk / core.getBuff('atk'))}, x, y, floorId); var nextInfo = this.getDamageInfo(enemy, {"atk": atk}, x, y, floorId);
if (nextInfo == null || (typeof nextInfo == 'number')) break; if (nextInfo == null || (typeof nextInfo == 'number')) break;
if (pre > nextInfo.damage) { if (pre > nextInfo.damage) {
pre = nextInfo.damage; pre = nextInfo.damage;
list.push([Math.ceil(atk / core.getBuff('atk')) - hero_atk, info.damage - nextInfo.damage]); list.push([atk - hero_atk, info.damage - nextInfo.damage]);
if (nextInfo.damage <= 0 && !core.flags.enableNegativeDamage) break; if (nextInfo.damage <= 0 && !core.flags.enableNegativeDamage) break;
if (list.length >= number) break; if (list.length >= number) break;
} }
@ -288,7 +307,7 @@ enemys.prototype._nextCriticals_useBinarySearch = function (enemy, info, number,
var list = []; var list = [];
var start_atk = hero_atk; var start_atk = hero_atk;
if (info.__over__) { if (info.__over__) {
start_atk = mon_def + 1; start_atk += info.__overAtk__;
list.push([info.__overAtk__, -info.damage]); list.push([info.__overAtk__, -info.damage]);
} }
var calNext = function (currAtk, maxAtk) { var calNext = function (currAtk, maxAtk) {
@ -298,12 +317,12 @@ enemys.prototype._nextCriticals_useBinarySearch = function (enemy, info, number,
while (start < end) { while (start < end) {
var mid = Math.floor((start + end) / 2); var mid = Math.floor((start + end) / 2);
if (mid - start > end - mid) mid--; if (mid - start > end - mid) mid--;
var nextInfo = core.enemys.getDamageInfo(enemy, {"atk": Math.ceil(mid / core.getBuff('atk'))}, x, y, floorId); var nextInfo = core.enemys.getDamageInfo(enemy, {"atk": mid}, x, y, floorId);
if (nextInfo == null || (typeof nextInfo == 'number')) return null; if (nextInfo == null || (typeof nextInfo == 'number')) return null;
if (pre > nextInfo.damage) end = mid; if (pre > nextInfo.damage) end = mid;
else start = mid + 1; else start = mid + 1;
} }
var nextInfo = core.enemys.getDamageInfo(enemy, {"atk": Math.ceil(start / core.getBuff('atk'))}, x, y, floorId); var nextInfo = core.enemys.getDamageInfo(enemy, {"atk": start}, x, y, floorId);
return nextInfo == null || (typeof nextInfo == 'number') || nextInfo.damage >= pre ? null : [start, nextInfo.damage]; return nextInfo == null || (typeof nextInfo == 'number') || nextInfo.damage >= pre ? null : [start, nextInfo.damage];
} }
var currAtk = start_atk; var currAtk = start_atk;
@ -312,7 +331,7 @@ enemys.prototype._nextCriticals_useBinarySearch = function (enemy, info, number,
if (next == null) break; if (next == null) break;
currAtk = next[0]; currAtk = next[0];
pre = next[1]; pre = next[1];
list.push([Math.ceil(currAtk / core.getBuff('atk')) - hero_atk, info.damage - pre]); list.push([currAtk - hero_atk, info.damage - pre]);
if (pre <= 0 && !core.flags.enableNegativeDamage) break; if (pre <= 0 && !core.flags.enableNegativeDamage) break;
if (list.length >= number) break; if (list.length >= number) break;
} }
@ -330,7 +349,7 @@ enemys.prototype._nextCriticals_useTurn = function (enemy, info, number, x, y, f
var list = [], pre = null; var list = [], pre = null;
var start_atk = hero_atk; var start_atk = hero_atk;
if (info.__over__) { if (info.__over__) {
start_atk = mon_def + 1; start_atk += info.__overAtk__;
list.push([info.__overAtk__, -info.damage]); list.push([info.__overAtk__, -info.damage]);
} }
for (var t = turn - 1; t >= 1; t--) { for (var t = turn - 1; t >= 1; t--) {
@ -460,11 +479,15 @@ enemys.prototype._getCurrentEnemys_addEnemy = function (enemyId, enemys, used, x
e.damage = this.getDamage(enemy, x, y, floorId); e.damage = this.getDamage(enemy, x, y, floorId);
e.critical = critical[0]; e.critical = critical[0];
e.criticalDamage = critical[1]; e.criticalDamage = critical[1];
var ratio = core.status.maps[floorId || core.status.floorId].ratio || 1; e.defDamage = this._getCurrentEnemys_addEnemy_defDamage(enemy, x, y, floorId);
e.defDamage = this.getDefDamage(enemy, ratio, x, y, floorId);
enemys.push(e); enemys.push(e);
} }
enemys.prototype._getCurrentEnemys_addEnemy_defDamage = function (enemy, x, y, floorId) {
var ratio = core.status.maps[floorId || core.status.floorId].ratio || 1;
return this.getDefDamage(enemy, ratio, x, y, floorId);
}
enemys.prototype._getCurrentEnemys_sort = function (enemys) { enemys.prototype._getCurrentEnemys_sort = function (enemys) {
return enemys.sort(function (a, b) { return enemys.sort(function (a, b) {
if (a.damage == b.damage) { if (a.damage == b.damage) {

View File

@ -217,7 +217,8 @@ events.prototype._gameOver_confirmDownload = function (ending) {
'seed': core.getFlag('__seed__'), 'seed': core.getFlag('__seed__'),
'route': core.encodeRoute(core.status.route) 'route': core.encodeRoute(core.status.route)
} }
core.download(core.firstData.name + "_" + core.formatDate2(new Date()) + ".h5route", JSON.stringify(obj)); core.download(core.firstData.name + "_" + core.formatDate2(new Date()) + ".h5route",
LZString.compressToBase64(JSON.stringify(obj)));
core.events._gameOver_askRate(ending); core.events._gameOver_askRate(ending);
}, function () { }, function () {
core.events._gameOver_askRate(ending); core.events._gameOver_askRate(ending);
@ -422,7 +423,7 @@ events.prototype._trigger_ignoreChangeFloor = function (block) {
events.prototype._sys_battle = function (data, callback) { events.prototype._sys_battle = function (data, callback) {
// 检查是否需要改变朝向 // 检查是否需要改变朝向
if (data.x == core.nextX() && data.y == core.nextY()) { /* if (data.x == core.nextX() && data.y == core.nextY()) {
var dir = core.turnDirection(":back"); var dir = core.turnDirection(":back");
var id = data.event.id, toId = (data.event.faceIds || {})[dir]; var id = data.event.id, toId = (data.event.faceIds || {})[dir];
if (toId && id != toId) { if (toId && id != toId) {
@ -430,7 +431,7 @@ events.prototype._sys_battle = function (data, callback) {
if (number > 0) if (number > 0)
core.setBlock(number, data.x, data.y); core.setBlock(number, data.x, data.y);
} }
} } */
// 检查战前事件 // 检查战前事件
var beforeBattle = []; var beforeBattle = [];
@ -580,21 +581,28 @@ events.prototype._openDoor_animate = function (block, x, y, callback) {
blockInfo.posX = 0; blockInfo.posX = 0;
core.maps._drawBlockInfo(blockInfo, x, y); core.maps._drawBlockInfo(blockInfo, x, y);
var cb = function () {
core.maps._removeBlockFromMap(core.status.floorId, block);
if (!locked) core.unlockControl();
core.status.replay.animate = false;
core.events.afterOpenDoor(block.event.id, x, y);
if (callback) callback();
}
var animate = window.setInterval(function() { var animate = window.setInterval(function() {
blockInfo.posX++; blockInfo.posX++;
if (blockInfo.posX == 4) { if (blockInfo.posX == 4) {
core.maps._removeBlockFromMap(core.status.floorId, block);
clearInterval(animate); clearInterval(animate);
delete core.animateFrame.asyncId[animate]; delete core.animateFrame.asyncId[animate];
if (!locked) core.unlockControl(); cb();
core.status.replay.animate = false;
core.events.afterOpenDoor(block.event.id, x, y);
if (callback) callback();
return; return;
} }
core.maps._drawBlockInfo(blockInfo, x, y); core.maps._drawBlockInfo(blockInfo, x, y);
}, core.status.replay.speed == 24 ? 1 : speed / Math.max(core.status.replay.speed, 1)); }, core.status.replay.speed == 24 ? 1 : speed / Math.max(core.status.replay.speed, 1));
core.animateFrame.asyncId[animate] = true;
core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = cb;
} }
////// 开一个门后触发的事件 ////// ////// 开一个门后触发的事件 //////
@ -775,6 +783,7 @@ events.prototype._changeFloor_getHeroLoc = function (floorId, stair, heroLoc) {
} }
events.prototype._changeFloor_beforeChange = function (info, callback) { events.prototype._changeFloor_beforeChange = function (info, callback) {
this._changeFloor_playSound();
// 需要 setTimeout 执行,不然会出错 // 需要 setTimeout 执行,不然会出错
window.setTimeout(function () { window.setTimeout(function () {
if (info.time == 0) if (info.time == 0)
@ -786,6 +795,16 @@ events.prototype._changeFloor_beforeChange = function (info, callback) {
}, 25) }, 25)
} }
events.prototype._changeFloor_playSound = function () {
// 播放换层音效
if (core.hasFlag('__fromLoad__')) // 是否是读档造成的切换
core.playSound('读档');
else if (core.hasFlag('__isFlying__')) // 是否是楼传造成的切换
core.playSound('飞行器');
else
core.playSound('上下楼');
}
events.prototype._changeFloor_changing = function (info, callback) { events.prototype._changeFloor_changing = function (info, callback) {
this.changingFloor(info.floorId, info.heroLoc); this.changingFloor(info.floorId, info.heroLoc);
// 回归视角 // 回归视角
@ -984,9 +1003,10 @@ events.prototype.doAction = function () {
clearInterval(core.status.event.animateUI); clearInterval(core.status.event.animateUI);
core.status.event.interval = null; core.status.event.interval = null;
delete core.status.event.aniamteUI; delete core.status.event.aniamteUI;
core.clearUI(); if (core.status.gameOver || core.status.replay.failed) return;
// 判定是否执行完毕 // 判定是否执行完毕
if (this._doAction_finishEvents()) return; if (this._doAction_finishEvents()) return;
core.clearUI();
var floorId = core.status.event.data.floorId || core.status.floorId; var floorId = core.status.event.data.floorId || core.status.floorId;
// 当前点坐标和前缀 // 当前点坐标和前缀
var x = core.status.event.data.x, y = core.status.event.data.y; var x = core.status.event.data.x, y = core.status.event.data.y;
@ -1007,8 +1027,7 @@ events.prototype.doAction = function () {
} }
events.prototype._doAction_finishEvents = function () { events.prototype._doAction_finishEvents = function () {
if (core.status.gameOver) return true; if (core.status.event.id != 'action') return true;
// 事件处理完毕 // 事件处理完毕
if (core.status.event.data.list.length == 0) { if (core.status.event.data.list.length == 0) {
// 检测并执行延迟自动事件 // 检测并执行延迟自动事件
@ -1358,12 +1377,18 @@ events.prototype._action_text = function (data, x, y, prefix) {
if (core.getContextByName(ctx) && !data.showAll) { if (core.getContextByName(ctx) && !data.showAll) {
core.ui._animateUI('hide', ctx, function () { core.ui._animateUI('hide', ctx, function () {
core.ui.drawTextBox(data.text, data); core.ui.drawTextBox(data.text, data);
core.ui._animateUI('show', ctx); core.ui._animateUI('show', ctx, function () {
if (data.async) core.doAction();
});
}); });
return; return;
} }
core.ui.drawTextBox(data.text, data); core.ui.drawTextBox(data.text, data);
if (!data.showAll) core.ui._animateUI('show', ctx); if (!data.showAll) {
core.ui._animateUI('show', ctx, function () {
if (data.async) core.doAction();
});
}
} }
events.prototype._action_moveTextBox = function (data, x, y, prefix) { events.prototype._action_moveTextBox = function (data, x, y, prefix) {
@ -1521,6 +1546,11 @@ events.prototype._action_animate = function (data, x, y, prefix) {
} }
} }
events.prototype._action_stopAnimate = function (data, x, y, prefix) {
core.stopAnimate(null, data.doCallback);
core.doAction();
}
events.prototype._action_setViewport = function (data, x, y, prefix) { events.prototype._action_setViewport = function (data, x, y, prefix) {
if (data.dxy != null) { if (data.dxy != null) {
data.loc = [core.bigmap.offsetX / 32 + (core.calValue(data.dxy[0], prefix) || 0), core.bigmap.offsetY / 32 + (core.calValue(data.dxy[1], prefix) || 0)]; data.loc = [core.bigmap.offsetX / 32 + (core.calValue(data.dxy[0], prefix) || 0), core.bigmap.offsetY / 32 + (core.calValue(data.dxy[1], prefix) || 0)];
@ -1682,12 +1712,12 @@ events.prototype._precompile_scaleImage = function (data) {
events.prototype._action_setCurtain = function (data, x, y, prefix) { events.prototype._action_setCurtain = function (data, x, y, prefix) {
if (data.async) { if (data.async) {
core.setCurtain(data.color, data.time, data.moveMode); core.setCurtain(data.color || core.status.thisMap.color, data.time, data.moveMode);
if (data.color == null || data.keep) core.setFlag('__color__', data.color || null); if (data.color == null || data.keep) core.setFlag('__color__', data.color || null);
core.doAction(); core.doAction();
} }
else { else {
core.setCurtain(data.color, data.time, data.moveMode, function () { core.setCurtain(data.color || core.status.thisMap.color, data.time, data.moveMode, function () {
if (data.color == null || data.keep) core.setFlag('__color__', data.color || null); if (data.color == null || data.keep) core.setFlag('__color__', data.color || null);
core.doAction(); core.doAction();
}); });
@ -1871,14 +1901,14 @@ events.prototype._action_addValue = function (data, x, y, prefix) {
} }
events.prototype._action_setEnemy = function (data, x, y, prefix) { events.prototype._action_setEnemy = function (data, x, y, prefix) {
this.setEnemy(data.id, data.name, data.value, data.operator, prefix); this.setEnemy(data.id, data.name, data.value, data.operator, prefix, data.norefresh);
core.doAction(); core.doAction();
} }
events.prototype._action_setEnemyOnPoint = function (data, x, y, prefix) { events.prototype._action_setEnemyOnPoint = function (data, x, y, prefix) {
var loc = this.__action_getLoc2D(data.loc, x, y, prefix); var loc = this.__action_getLoc2D(data.loc, x, y, prefix);
loc.forEach(function (one) { loc.forEach(function (one) {
core.setEnemyOnPoint(one[0], one[1], data.floorId, data.name, data.value, data.operator, prefix); core.setEnemyOnPoint(one[0], one[1], data.floorId, data.name, data.value, data.operator, prefix, data.norefresh);
}); });
core.doAction(); core.doAction();
} }
@ -1886,7 +1916,7 @@ events.prototype._action_setEnemyOnPoint = function (data, x, y, prefix) {
events.prototype._action_resetEnemyOnPoint = function (data, x, y, prefix) { events.prototype._action_resetEnemyOnPoint = function (data, x, y, prefix) {
var loc = this.__action_getLoc2D(data.loc, x, y, prefix); var loc = this.__action_getLoc2D(data.loc, x, y, prefix);
loc.forEach(function (one) { loc.forEach(function (one) {
core.resetEnemyOnPoint(one[0], one[1], data.floorId); core.resetEnemyOnPoint(one[0], one[1], data.floorId, data.norefresh);
}); });
core.doAction(); core.doAction();
} }
@ -1905,7 +1935,7 @@ events.prototype._action_moveEnemyOnPoint = function (data, x, y, prefix) {
} else { } else {
to = this.__action_getLoc(data.to, x, y, prefix); to = this.__action_getLoc(data.to, x, y, prefix);
} }
this.moveEnemyOnPoint(from[0], from[1], to[0], to[1], data.floorId); this.moveEnemyOnPoint(from[0], from[1], to[0], to[1], data.floorId, data.norefresh);
core.doAction(); core.doAction();
} }
@ -2037,9 +2067,7 @@ events.prototype._action_choices = function (data, x, y, prefix) {
var action = core.status.replay.toReplay.shift(); var action = core.status.replay.toReplay.shift();
if (action.indexOf('choices:') == 0 && !(action == 'choices:none' && !data.timeout)) { if (action.indexOf('choices:') == 0 && !(action == 'choices:none' && !data.timeout)) {
var index = action.substring(8); var index = action.substring(8);
if (index == 'none' || ((index = parseInt(index)) >= 0) && index % 100 < data.choices.length) { if (!this.__action_choices_replaying(data, index)) {
this.__action_choices_replaying(data, index);
} else {
core.control._replay_error(action); core.control._replay_error(action);
return; return;
} }
@ -2057,7 +2085,7 @@ events.prototype._action_choices = function (data, x, y, prefix) {
return; return;
} }
if (action != 'choices:none') core.status.replay.toReplay.unshift(action); // 首先归还刚才读出的下一步操作 if (action != 'choices:none') core.status.replay.toReplay.unshift(action); // 首先归还刚才读出的下一步操作
core.events.__action_choices_replaying(data, core.clamp(parseInt(value), 0, data.choices.length - 1)) core.events.__action_choices_replaying(data, ((parseInt(value) || 0) + data.choices.length) % data.choices.length);
}); });
} }
} }
@ -2080,17 +2108,24 @@ events.prototype._action_choices = function (data, x, y, prefix) {
} }
events.prototype.__action_choices_replaying = function (data, index) { events.prototype.__action_choices_replaying = function (data, index) {
var selection = index;
if (index != 'none') { if (index != 'none') {
var timeout = Math.floor(index / 100) || 0; selection = parseInt(index);
if (isNaN(selection)) return false;
if (selection < 0) selection += data.choices.length;
if (selection < 0) return false;
if (selection % 100 > 50) selection += data.choices.length;
if (selection % 100 > data.choices.length) return false;
var timeout = Math.floor(selection / 100) || 0;
core.setFlag('timeout', timeout); core.setFlag('timeout', timeout);
index %= 100; selection %= 100;
} else core.setFlag('timeout', 0); } else core.setFlag('timeout', 0);
core.status.event.selection = index; core.status.event.selection = selection;
setTimeout(function () { setTimeout(function () {
core.status.route.push("choices:"+index); core.status.route.push("choices:"+index);
if (index != 'none') { if (selection != 'none') {
// 检查 // 检查
var choice = data.choices[index]; var choice = data.choices[selection];
if (choice.need != null && choice.need != '' && !core.calValue(choice.need)) { if (choice.need != null && choice.need != '' && !core.calValue(choice.need)) {
// 无法选择此项 // 无法选择此项
core.control._replay_error("无法选择项:"+index); core.control._replay_error("无法选择项:"+index);
@ -2101,6 +2136,7 @@ events.prototype.__action_choices_replaying = function (data, index) {
} }
core.doAction(); core.doAction();
}, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed)); }, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed));
return true;
} }
events.prototype._precompile_choices = function (data) { events.prototype._precompile_choices = function (data) {
@ -2339,22 +2375,22 @@ events.prototype._action_hideStatusBar = function (data, x, y, prefix) {
} }
events.prototype._action_showHero = function (data, x, y, prefix) { events.prototype._action_showHero = function (data, x, y, prefix) {
data.time = data.time || 0; data.opacity = 1;
if (data.time > 0) { return this._action_setHeroOpacity(data, x, y, prefix);
this.__action_doAsyncFunc(data.async, core.triggerHero, 'show', data.time);
} else {
core.removeFlag('hideHero');
core.drawHero();
core.doAction();
}
} }
events.prototype._action_hideHero = function (data, x, y, prefix) { events.prototype._action_hideHero = function (data, x, y, prefix) {
data.opacity = 0;
return this._action_setHeroOpacity(data, x, y, prefix);
}
events.prototype._action_setHeroOpacity = function (data, x, y, prefix) {
data.time = data.time || 0; data.time = data.time || 0;
if (data.opacity == null) data.opacity = 1;
if (data.time > 0) { if (data.time > 0) {
this.__action_doAsyncFunc(data.async, core.triggerHero, 'hide', data.time); this.__action_doAsyncFunc(data.async, core.setHeroOpacity, data.opacity, data.moveMode, data.time);
} else { } else {
core.setFlag('hideHero', true); core.setFlag('__heroOpacity__', data.opacity);
core.drawHero(); core.drawHero();
core.doAction(); core.doAction();
} }
@ -2501,6 +2537,11 @@ events.prototype._action_waitAsync = function (data, x, y, prefix) {
}, 50 / core.status.replay.speed); }, 50 / core.status.replay.speed);
} }
events.prototype._action_stopAsync = function (data, x, y, prefix) {
core.stopAsync();
core.doAction();
}
events.prototype._action_callBook = function (data, x, y, prefix) { events.prototype._action_callBook = function (data, x, y, prefix) {
if (core.isReplaying() || !core.hasItem('book')) { if (core.isReplaying() || !core.hasItem('book')) {
core.doAction(); core.doAction();
@ -2878,6 +2919,19 @@ events.prototype.hasAsync = function () {
return Object.keys(core.animateFrame.asyncId).length > 0; return Object.keys(core.animateFrame.asyncId).length > 0;
} }
////// 立刻停止所有异步事件 //////
events.prototype.stopAsync = function () {
var callbacks = [];
for (var id in core.animateFrame.asyncId) {
clearInterval(id);
callbacks.push(core.animateFrame.asyncId[id]);
}
core.animateFrame.asyncId = {};
callbacks.forEach(function (cb) {
if (cb && cb instanceof Function) cb();
});
}
events.prototype.hasAsyncAnimate = function () { events.prototype.hasAsyncAnimate = function () {
return (core.status.animateObjs || []).length > 0; return (core.status.animateObjs || []).length > 0;
} }
@ -2980,7 +3034,7 @@ events.prototype._setValue_setGlobal = function (name, value) {
} }
////// 设置一个怪物属性 ////// ////// 设置一个怪物属性 //////
events.prototype.setEnemy = function (id, name, value, operator, prefix) { events.prototype.setEnemy = function (id, name, value, operator, prefix, norefresh) {
if (!core.hasFlag('enemyInfo')) { if (!core.hasFlag('enemyInfo')) {
core.setFlag('enemyInfo', {}); core.setFlag('enemyInfo', {});
} }
@ -2990,11 +3044,11 @@ events.prototype.setEnemy = function (id, name, value, operator, prefix) {
value = this._updateValueByOperator(core.calValue(value, prefix), (core.material.enemys[id]||{})[name], operator); value = this._updateValueByOperator(core.calValue(value, prefix), (core.material.enemys[id]||{})[name], operator);
enemyInfo[id][name] = value; enemyInfo[id][name] = value;
(core.material.enemys[id]||{})[name] = core.clone(value); (core.material.enemys[id]||{})[name] = core.clone(value);
core.updateStatusBar(); if (!norefresh) core.updateStatusBar();
} }
////// 设置某个点上的怪物属性 ////// ////// 设置某个点上的怪物属性 //////
events.prototype.setEnemyOnPoint = function (x, y, floorId, name, value, operator, prefix) { events.prototype.setEnemyOnPoint = function (x, y, floorId, name, value, operator, prefix, norefresh) {
floorId = floorId || core.status.floorId; floorId = floorId || core.status.floorId;
var block = core.getBlock(x, y, floorId); var block = core.getBlock(x, y, floorId);
if (block == null) return; if (block == null) return;
@ -3007,22 +3061,22 @@ events.prototype.setEnemyOnPoint = function (x, y, floorId, name, value, operato
flags.enemyOnPoint[floorId] = flags.enemyOnPoint[floorId] || {}; flags.enemyOnPoint[floorId] = flags.enemyOnPoint[floorId] || {};
flags.enemyOnPoint[floorId][x+","+y] = flags.enemyOnPoint[floorId][x+","+y] || {}; flags.enemyOnPoint[floorId][x+","+y] = flags.enemyOnPoint[floorId][x+","+y] || {};
flags.enemyOnPoint[floorId][x+","+y][name] = value; flags.enemyOnPoint[floorId][x+","+y][name] = value;
core.updateStatusBar(); if (!norefresh) core.updateStatusBar();
} }
////// 重置某个点上的怪物属性 ////// ////// 重置某个点上的怪物属性 //////
events.prototype.resetEnemyOnPoint = function (x, y, floorId) { events.prototype.resetEnemyOnPoint = function (x, y, floorId, norefresh) {
delete ((flags.enemyOnPoint||{})[floorId||core.status.floorId]||{})[x+","+y]; delete ((flags.enemyOnPoint||{})[floorId||core.status.floorId]||{})[x+","+y];
core.updateStatusBar(); if (!norefresh) core.updateStatusBar();
} }
////// 将某个点上已经设置的怪物属性移动到其他点 ////// ////// 将某个点上已经设置的怪物属性移动到其他点 //////
events.prototype.moveEnemyOnPoint = function (fromX, fromY, toX, toY, floorId) { events.prototype.moveEnemyOnPoint = function (fromX, fromY, toX, toY, floorId, norefresh) {
floorId = floorId || core.status.floorId; floorId = floorId || core.status.floorId;
if (((flags.enemyOnPoint||{})[floorId]||{})[fromX+","+fromY]) { if (((flags.enemyOnPoint||{})[floorId]||{})[fromX+","+fromY]) {
flags.enemyOnPoint[floorId][toX+","+toY] = flags.enemyOnPoint[floorId][fromX+","+fromY]; flags.enemyOnPoint[floorId][toX+","+toY] = flags.enemyOnPoint[floorId][fromX+","+fromY];
delete flags.enemyOnPoint[floorId][fromX+","+fromY]; delete flags.enemyOnPoint[floorId][fromX+","+fromY];
core.updateStatusBar(); if (!norefresh) core.updateStatusBar();
} }
} }
@ -3067,7 +3121,7 @@ events.prototype.setGlobalFlag = function (name, value) {
core.setFlag("globalFlags", flags); core.setFlag("globalFlags", flags);
core.resize(); core.resize();
if (name == 'blurFg') if (name == 'blurFg')
core.drawMap(); core.redrawMap();
} }
////// 设置文件别名 ////// ////// 设置文件别名 //////
@ -3143,7 +3197,9 @@ events.prototype._moveTextBox_moving = function (ctx, moveInfo, callback) {
if (callback) callback(); if (callback) callback();
} }
}, 10); }, 10);
core.animateFrame.asyncId[animate] = true;
core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = callback;
} }
////// 清除对话框 ////// ////// 清除对话框 //////
@ -3191,19 +3247,25 @@ events.prototype.closeDoor = function (x, y, id, callback) {
blockInfo.posX = 3; blockInfo.posX = 3;
core.maps._drawBlockInfo(blockInfo, x, y); core.maps._drawBlockInfo(blockInfo, x, y);
var cb = function () {
core.setBlock(id, x, y);
core.showBlock(x, y);
if (callback) callback();
}
var animate = window.setInterval(function () { var animate = window.setInterval(function () {
blockInfo.posX--; blockInfo.posX--;
if (blockInfo.posX < 0) { if (blockInfo.posX < 0) {
clearInterval(animate); clearInterval(animate);
delete core.animateFrame.asyncId[animate]; delete core.animateFrame.asyncId[animate];
core.setBlock(id, x, y); cb();
core.showBlock(x, y);
if (callback) callback();
return; return;
} }
core.maps._drawBlockInfo(blockInfo, x, y); core.maps._drawBlockInfo(blockInfo, x, y);
}, core.status.replay.speed == 24 ? 1 : speed / Math.max(core.status.replay.speed, 1)); }, core.status.replay.speed == 24 ? 1 : speed / Math.max(core.status.replay.speed, 1));
core.animateFrame.asyncId[animate] = true;
core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = cb;
} }
////// 显示图片 ////// ////// 显示图片 //////
@ -3307,13 +3369,14 @@ events.prototype._moveImage_moving = function (name, moveInfo, callback) {
core.setOpacity(name, currOpacity); core.setOpacity(name, currOpacity);
core.relocateCanvas(name, currX, currY); core.relocateCanvas(name, currX, currY);
if (step == steps) { if (step == steps) {
core.setOpacity(name, toOpacity);
delete core.animateFrame.asyncId[animate]; delete core.animateFrame.asyncId[animate];
clearInterval(animate); clearInterval(animate);
if (callback) callback(); if (callback) callback();
} }
}, per_time); }, per_time);
core.animateFrame.asyncId[animate] = true;
core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = callback;
} }
////// 旋转图片 ////// ////// 旋转图片 //////
@ -3356,8 +3419,9 @@ events.prototype._rotateImage_rotating = function (name, rotateInfo, callback) {
if (callback) callback(); if (callback) callback();
} }
}, per_time); }, per_time);
core.animateFrame.asyncId[animate] = true;
core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = callback;
} }
////// 放缩一张图片 ////// ////// 放缩一张图片 //////
@ -3416,7 +3480,9 @@ events.prototype._scaleImage_scale = function (ctx, scaleInfo, callback) {
if (callback) callback(); if (callback) callback();
} }
}, per_time); }, per_time);
core.animateFrame.asyncId[animate] = true;
core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = callback;
} }
////// 绘制或取消一张gif图片 ////// ////// 绘制或取消一张gif图片 //////
@ -3454,16 +3520,18 @@ events.prototype.setVolume = function (value, time, callback) {
time /= Math.max(core.status.replay.speed, 1); time /= Math.max(core.status.replay.speed, 1);
var per_time = 10, step = 0, steps = parseInt(time / per_time); var per_time = 10, step = 0, steps = parseInt(time / per_time);
if (steps <= 0) steps = 1; if (steps <= 0) steps = 1;
var fade = setInterval(function () { var animate = setInterval(function () {
step++; step++;
set(currVolume + (value - currVolume) * step / steps); set(currVolume + (value - currVolume) * step / steps);
if (step >= steps) { if (step >= steps) {
delete core.animateFrame.asyncId[fade]; delete core.animateFrame.asyncId[animate];
clearInterval(fade); clearInterval(animate);
if (callback) callback(); if (callback) callback();
} }
}, per_time); }, per_time);
core.animateFrame.asyncId[fade] = true;
core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = callback;
} }
////// 画面震动 ////// ////// 画面震动 //////
@ -3476,6 +3544,13 @@ events.prototype.vibrate = function (direction, time, speed, power, callback) {
speed = speed || 10; speed = speed || 10;
power = power || 10; power = power || 10;
var shakeInfo = {duration: parseInt(time / 10), speed: speed, power: power, direction: 1, shake: 0}; var shakeInfo = {duration: parseInt(time / 10), speed: speed, power: power, direction: 1, shake: 0};
if (direction == 'random') {
direction = ['horizontal', 'vertical', 'diagonal1', 'diagonal2'][Math.floor(Math.random() * 4)];
}
var cb = function () {
core.addGameCanvasTranslate(0, 0);
if (callback) callback();
}
var animate = setInterval(function () { var animate = setInterval(function () {
core.events._vibrate_update(shakeInfo); core.events._vibrate_update(shakeInfo);
switch (direction) { switch (direction) {
@ -3487,11 +3562,12 @@ events.prototype.vibrate = function (direction, time, speed, power, callback) {
if (shakeInfo.duration === 0 && shakeInfo.shake == 0) { if (shakeInfo.duration === 0 && shakeInfo.shake == 0) {
delete core.animateFrame.asyncId[animate]; delete core.animateFrame.asyncId[animate];
clearInterval(animate); clearInterval(animate);
if (callback) callback(); cb();
} }
}, 10); }, 10);
core.animateFrame.asyncId[animate] = true; core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = cb;
} }
events.prototype._vibrate_update = function (shakeInfo) { events.prototype._vibrate_update = function (shakeInfo) {
@ -3525,13 +3601,17 @@ events.prototype.eventMoveHero = function(steps, time, callback) {
}); });
core.status.heroMoving = -1; core.status.heroMoving = -1;
var _run = function () { var _run = function () {
var cb = function () {
core.status.heroMoving = 0;
core.drawHero();
if (callback) callback();
}
var animate=window.setInterval(function() { var animate=window.setInterval(function() {
if (moveSteps.length==0) { if (moveSteps.length==0) {
delete core.animateFrame.asyncId[animate]; delete core.animateFrame.asyncId[animate];
clearInterval(animate); clearInterval(animate);
core.status.heroMoving = 0; cb();
core.drawHero();
if (callback) callback();
} }
else { else {
if (step == 0 && moveSteps[0][0] == 'speed' && moveSteps[0][1] >= 16) { if (step == 0 && moveSteps[0][0] == 'speed' && moveSteps[0][1] >= 16) {
@ -3546,7 +3626,8 @@ events.prototype.eventMoveHero = function(steps, time, callback) {
} }
}, core.status.replay.speed == 24 ? 1 : time / 8 / core.status.replay.speed); }, core.status.replay.speed == 24 ? 1 : time / 8 / core.status.replay.speed);
core.animateFrame.asyncId[animate] = true; core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = cb;
} }
_run(); _run();
} }
@ -3601,15 +3682,27 @@ events.prototype.jumpHero = function (ex, ey, time, callback) {
} }
events.prototype._jumpHero_doJump = function (jumpInfo, callback) { events.prototype._jumpHero_doJump = function (jumpInfo, callback) {
var cb = function () {
core.setHeroLoc('x', jumpInfo.ex);
core.setHeroLoc('y', jumpInfo.ey);
core.status.heroMoving = 0;
core.drawHero();
if (callback) callback();
}
core.status.heroMoving = -1; core.status.heroMoving = -1;
var animate = window.setInterval(function () { var animate = window.setInterval(function () {
if (jumpInfo.jump_count > 0) if (jumpInfo.jump_count > 0)
core.events._jumpHero_jumping(jumpInfo) core.events._jumpHero_jumping(jumpInfo)
else else {
core.events._jumpHero_finished(animate, jumpInfo.ex, jumpInfo.ey, callback); delete core.animateFrame.asyncId[animate];
clearInterval(animate);
cb();
}
}, jumpInfo.per_time); }, jumpInfo.per_time);
core.animateFrame.asyncId[animate] = true; core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = cb;
} }
events.prototype._jumpHero_jumping = function (jumpInfo) { events.prototype._jumpHero_jumping = function (jumpInfo) {
@ -3621,16 +3714,6 @@ events.prototype._jumpHero_jumping = function (jumpInfo) {
core.drawHero('stop', { x: nowx - 32 * x, y: nowy - 32 * y }); core.drawHero('stop', { x: nowx - 32 * x, y: nowy - 32 * y });
} }
events.prototype._jumpHero_finished = function (animate, ex, ey, callback) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
core.setHeroLoc('x', ex);
core.setHeroLoc('y', ey);
core.status.heroMoving = 0;
core.drawHero();
if (callback) callback();
}
////// 设置角色行走图 ////// ////// 设置角色行走图 //////
events.prototype.setHeroIcon = function (name, noDraw) { events.prototype.setHeroIcon = function (name, noDraw) {
name = core.getMappedName(name); name = core.getMappedName(name);

View File

@ -305,6 +305,22 @@ loader.prototype.loadImagesFromZip = function (url, names, toSave, onprogress, o
loader.prototype._loadAnimates_sync = function () { loader.prototype._loadAnimates_sync = function () {
this._setStartLoadTipText("正在加载动画文件..."); this._setStartLoadTipText("正在加载动画文件...");
if (main.supportBunch) {
if (core.animates.length > 0) {
core.http('GET', '__all_animates__?v=' + main.version + '&id=' + core.animates.join(','), null, function (content) {
var u = content.split('@@@~~~###~~~@@@');
for (var i = 0; i < core.animates.length; ++i) {
if (u[i] != '') {
core.material.animates[core.animates[i]] = core.loader._loadAnimate(u[i]);
} else {
console.error('无法找到动画文件' + core.animates[i] + '');
}
}
}, "text/plain; charset=x-user-defined");
}
return;
}
core.animates.forEach(function (t) { core.animates.forEach(function (t) {
core.http('GET', 'project/animates/' + t + ".animate?v=" + main.version, null, function (content) { core.http('GET', 'project/animates/' + t + ".animate?v=" + main.version, null, function (content) {
core.material.animates[t] = core.loader._loadAnimate(content); core.material.animates[t] = core.loader._loadAnimate(content);

View File

@ -385,7 +385,7 @@ maps.prototype.setBlockOpacity = function (opacity, x, y, floorId) {
block.opacity = opacity; block.opacity = opacity;
if (floorId == core.status.floorId && !block.disable) { if (floorId == core.status.floorId && !block.disable) {
if (block.event.cls == 'autotile') { if (block.event.cls == 'autotile') {
core.drawMap(); core.redrawMap();
} else { } else {
core.drawBlock(block); core.drawBlock(block);
core.addGlobalAnimate(block); core.addGlobalAnimate(block);
@ -416,7 +416,7 @@ maps.prototype.setBlockFilter = function (filter, x, y, floorId) {
block.filter = core.clone(filter); block.filter = core.clone(filter);
if (floorId == core.status.floorId && !block.disable) { if (floorId == core.status.floorId && !block.disable) {
if (block.event.cls == 'autotile') { if (block.event.cls == 'autotile') {
core.drawMap(); core.redrawMap();
} else { } else {
core.drawBlock(block); core.drawBlock(block);
core.addGlobalAnimate(block); core.addGlobalAnimate(block);
@ -968,10 +968,9 @@ maps.prototype._getBigImageInfo = function (bigImage, face, animate) {
} }
var dx, dy; var dx, dy;
switch (face) { switch (face) {
case "down": dx = 16 - per_width / 2; dy = 32 - per_height; break; case "down": case "up": case "left": case "right": dx = 16 - per_width / 2; dy = 32 - per_height; break;
case "left": dx = 0; dy = 16 - per_height / 2; break; // case "left": dx = 0; dy = 32 - per_height; break;
case "right": dx = 32 - per_width; dy = 16 - per_height / 2; break; // case "right": dx = 32 - per_width; dy = 32 - per_height; break;
case "up": dx = 16 - per_width / 2; dy = 0; break;
} }
return {sx: sx, sy: sy, per_width: per_width, per_height: per_height, face: face, dx: dx, dy: dy}; return {sx: sx, sy: sy, per_width: per_width, per_height: per_height, face: face, dx: dx, dy: dy};
@ -1034,43 +1033,36 @@ maps.prototype._drawBlockInfo_bigImage = function (blockInfo, x, y, ctx) {
var dx = bigImageInfo.dx, dy = bigImageInfo.dy; var dx = bigImageInfo.dx, dy = bigImageInfo.dy;
switch (bigImageInfo.face) { switch (bigImageInfo.face) {
case "down": case "down": case "up": case "left": case "right":
core.createCanvas(header, px + dx, py + dy, per_width, per_height - 32, 51); core.createCanvas(header, px + dx, py + dy, per_width, -dy, 51);
this._drawBlockInfo_drawWithFilter(blockInfo, header, function () { this._drawBlockInfo_drawWithFilter(blockInfo, header, function () {
core.drawImage(header, bigImage, sx, sy, per_width, per_height - 32, 0, 0, per_width, per_height - 32); core.drawImage(header, bigImage, sx, sy, per_width, -dy, 0, 0, per_width, -dy);
}); });
core.createCanvas(body, px + dx, py, per_width, 32, 31); core.createCanvas(body, px + dx, py, per_width, 32, 31);
this._drawBlockInfo_drawWithFilter(blockInfo, body, function () { this._drawBlockInfo_drawWithFilter(blockInfo, body, function () {
core.drawImage(body, bigImage, sx, sy + per_height - 32, per_width, 32, 0, 0, per_width, 32); core.drawImage(body, bigImage, sx, sy - dy, per_width, 32, 0, 0, per_width, 32);
}) })
break; break;
case "left": /*case "left":
core.createCanvas(header, px + dx, py + dy, per_width, per_height / 2 - 16, 51); core.createCanvas(header, px + dx, py + dy, per_width, -dy, 51);
this._drawBlockInfo_drawWithFilter(blockInfo, header, function () { this._drawBlockInfo_drawWithFilter(blockInfo, header, function () {
core.drawImage(header, bigImage, sx, sy, per_width, per_height / 2 - 16, 0, 0, per_width, per_height / 2 - 16); core.drawImage(header, bigImage, sx, sy, per_width, -dy, 0, 0, per_width, -dy);
}); });
core.createCanvas(body, px + dx, py, per_width, per_height / 2 + 16, 31); core.createCanvas(body, px + dx, py, per_width, 32, 31);
this._drawBlockInfo_drawWithFilter(blockInfo, body, function () { this._drawBlockInfo_drawWithFilter(blockInfo, body, function () {
core.drawImage(body, bigImage, sx, sy + per_height / 2 - 16, per_width, per_height / 2 + 16, 0, 0, per_width, per_height / 2 + 16); core.drawImage(body, bigImage, sx, sy - dy, per_width, 32, 0, 0, per_width, 32);
}); });
break; break;
case "right": case "right":
core.createCanvas(header, px + dx, py + dy, per_width, per_height / 2 - 16, 51); core.createCanvas(header, px + dx, py + dy, per_width, -dy, 51);
this._drawBlockInfo_drawWithFilter(blockInfo, header, function () { this._drawBlockInfo_drawWithFilter(blockInfo, header, function () {
core.drawImage(header, bigImage, sx, sy, per_width, per_height / 2 - 16, 0, 0, per_width, per_height / 2 - 16); core.drawImage(header, bigImage, sx, sy, per_width, -dy, 0, 0, per_width, -dy);
}); });
core.createCanvas(body, px + dx, py, per_width, per_height / 2 + 16, 31); core.createCanvas(body, px + dx, py, per_width, per_height / 2 + 16, 31);
this._drawBlockInfo_drawWithFilter(blockInfo, body, function () { this._drawBlockInfo_drawWithFilter(blockInfo, body, function () {
core.drawImage(body, bigImage, sx, sy + per_height / 2 - 16, per_width, per_height / 2 + 16, 0, 0, per_width, per_height / 2 + 16); core.drawImage(body, bigImage, sx, sy - dy, per_width, 32, 0, 0, per_width, 32);
}); });
break; break;*/
case "up":
core.deleteCanvas(header);
core.createCanvas(body, px + dx, py, per_width, per_height, 31);
this._drawBlockInfo_drawWithFilter(blockInfo, body, function () {
core.drawImage(body, bigImage, sx, sy, per_width, per_height, 0, 0, per_width, per_height);
});
break;
} }
if (core.dymCanvas[header]) { if (core.dymCanvas[header]) {
core.dymCanvas[header].canvas.setAttribute('_ox', 32 * x + dx); core.dymCanvas[header].canvas.setAttribute('_ox', 32 * x + dx);
@ -1684,25 +1676,28 @@ maps.prototype._makeAutotileEdges = function () {
ctx.msImageSmoothingEnabled = false; ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false; ctx.imageSmoothingEnabled = false;
var first = {}, second = {};
autotileIds.forEach(function (t) { autotileIds.forEach(function (t) {
var n = core.maps.getNumberById(t); var n = core.maps.getNumberById(t);
core.material.autotileEdges[n] = [n];
core.clearMap(ctx, 0, 0, 32, 32); core.clearMap(ctx, 0, 0, 32, 32);
core.drawImage(ctx, core.material.images.autotile[t], 0, 0, 32, 32, 0, 0, 32, 32); core.drawImage(ctx, core.material.images.autotile[t], 0, 0, 32, 32, 0, 0, 32, 32);
var data = canvas.toDataURL("image/png"); first[n] = canvas.toDataURL("image/png");
core.clearMap(ctx, 0, 0, 32, 32);
core.drawImage(ctx, core.material.images.autotile[t], 32, 0, 32, 32, 0, 0, 32, 32);
second[n] = canvas.toDataURL("image/png");
});
autotileIds.forEach(function (t2) { for (var n in first) {
if (t == t2) return; n = parseInt(n);
var n2 = core.maps.getNumberById(t2); core.material.autotileEdges[n] = [n];
for (var n2 in second) {
core.clearMap(ctx, 0, 0, 32, 32); n2 = parseInt(n2);
core.drawImage(ctx, core.material.images.autotile[t2], 32, 0, 32, 32, 0, 0, 32, 32); if (n == n2) continue;
if (data == canvas.toDataURL("image/png")) { if (first[n] == second[n2]) {
core.material.autotileEdges[n].push(n2); core.material.autotileEdges[n].push(n2);
} }
}); }
}); }
} }
////// 绘制缩略图 ////// ////// 绘制缩略图 //////
@ -1785,8 +1780,9 @@ maps.prototype._drawThumbnail_realDrawTempCanvas = function (floorId, blocks, op
options.heroIcon = core.getMappedName(options.heroIcon); options.heroIcon = core.getMappedName(options.heroIcon);
var icon = core.material.icons.hero[options.heroLoc.direction]; var icon = core.material.icons.hero[options.heroLoc.direction];
var height = core.material.images.images[options.heroIcon].height / 4; var height = core.material.images.images[options.heroIcon].height / 4;
core.drawImage(options.ctx, core.material.images.images[options.heroIcon], icon.stop * 32, icon.loc * height, 32, height, var width = core.material.images.images[options.heroIcon].width || 32;
32 * options.heroLoc.x, 32 * options.heroLoc.y + 32 - height, 32, height); core.drawImage(options.ctx, core.material.images.images[options.heroIcon], icon.stop * width, icon.loc * height, width, height,
32 * options.heroLoc.x + 32 - width, 32 * options.heroLoc.y + 32 - height, width, height);
} }
// 缩略图:前景 // 缩略图:前景
this.drawFg(floorId, options); this.drawFg(floorId, options);
@ -2054,7 +2050,7 @@ maps.prototype.showBlock = function (x, y, floorId) {
// 在本层,添加动画 // 在本层,添加动画
if (floorId == core.status.floorId) { if (floorId == core.status.floorId) {
if (block.event.cls == 'autotile') { if (block.event.cls == 'autotile') {
core.drawMap(); core.redrawMap();
} else { } else {
core.drawBlock(block); core.drawBlock(block);
core.addGlobalAnimate(block); core.addGlobalAnimate(block);
@ -2104,7 +2100,7 @@ maps.prototype._removeBlockFromMap = function (floorId, block) {
if (floorId != core.status.floorId) return; if (floorId != core.status.floorId) return;
var filter = block.filter || {}; var filter = block.filter || {};
if (block.event.cls == 'autotile' || filter.blur > 0 || filter.shadow > 0) { if (block.event.cls == 'autotile' || filter.blur > 0 || filter.shadow > 0) {
core.drawMap(); core.redrawMap();
} else { } else {
var x = block.x, y = block.y; var x = block.x, y = block.y;
var px = 32 * x - core.bigmap.posX * 32; var px = 32 * x - core.bigmap.posX * 32;
@ -2193,7 +2189,7 @@ maps.prototype._triggerBgFgMap = function (type, name, loc, floorId, callback) {
core.status[name + "maps"][floorId] = null; core.status[name + "maps"][floorId] = null;
if (floorId == core.status.floorId) { if (floorId == core.status.floorId) {
core.drawMap(floorId); core.redrawMap();
} }
if (callback) callback(); if (callback) callback();
} }
@ -2225,7 +2221,7 @@ maps.prototype._triggerFloorImage = function (type, loc, floorId, callback) {
}) })
if (floorId == core.status.floorId) { if (floorId == core.status.floorId) {
core.drawMap(floorId); core.redrawMap();
} }
if (callback) callback(); if (callback) callback();
} }
@ -2264,7 +2260,7 @@ maps.prototype.setBlock = function (number, x, y, floorId) {
if (floorId == core.status.floorId) { if (floorId == core.status.floorId) {
// 有任何一个是autotile直接重绘地图 // 有任何一个是autotile直接重绘地图
if ((originEvent != null && originEvent.cls == 'autotile') || block.event.cls == 'autotile') { if ((originEvent != null && originEvent.cls == 'autotile') || block.event.cls == 'autotile') {
core.drawMap(); core.redrawMap();
} else { } else {
if (originEvent != null) { if (originEvent != null) {
this._removeBlockFromMap(floorId, {x: x, y: y, event: originEvent}); this._removeBlockFromMap(floorId, {x: x, y: y, event: originEvent});
@ -2415,7 +2411,7 @@ maps.prototype.replaceBlock = function (fromNumber, toNumber, floorId) {
this._updateMapArray(floorId, block.x, block.y); this._updateMapArray(floorId, block.x, block.y);
} }
}, this); }, this);
if (floorId == core.status.floorId) core.drawMap(); if (floorId == core.status.floorId) core.redrawMap();
} }
////// 改变前景背景的图块 ////// ////// 改变前景背景的图块 //////
@ -2461,7 +2457,7 @@ maps.prototype.resetMap = function (floorId) {
delete (core.status.mapBlockObjs || {})[t]; delete (core.status.mapBlockObjs || {})[t];
if (t == core.status.floorId) needRefresh = true; if (t == core.status.floorId) needRefresh = true;
}); });
if (needRefresh) this.drawMap(); if (needRefresh) this.redrawMap();
core.drawTip("地图重置成功"); core.drawTip("地图重置成功");
} }
@ -2522,7 +2518,18 @@ maps.prototype._moveDetachedBlock = function (blockInfo, nowX, nowY, opacity, ca
} }
if (bodyCanvas) { if (bodyCanvas) {
if (blockInfo.bigImage) { if (blockInfo.bigImage) {
var bigImageInfo = this._getBigImageInfo(blockInfo.bigImage, blockInfo.face, blockInfo.posX); var face = blockInfo.face;
if (!blockInfo.faceIds) face = 'down';
else if (!blockInfo.faceIds[face]) {
// 维持此时朝向
face = 'down';
for (var f in blockInfo.faceIds) {
if (blockInfo.faceIds[f] == blockInfo.id) {
face = f;
}
}
}
var bigImageInfo = this._getBigImageInfo(blockInfo.bigImage, face, blockInfo.posX);
var per_width = bigImageInfo.per_width, per_height = bigImageInfo.per_height; var per_width = bigImageInfo.per_width, per_height = bigImageInfo.per_height;
core.dymCanvas[bodyCanvas].clearRect(0, 0, bigImageInfo.per_width, bigImageInfo.per_height); core.dymCanvas[bodyCanvas].clearRect(0, 0, bigImageInfo.per_width, bigImageInfo.per_height);
core.dymCanvas[bodyCanvas].drawImage(blockInfo.bigImage, bigImageInfo.sx, bigImageInfo.sy, per_width, per_height, 0, 0, per_width, per_height); core.dymCanvas[bodyCanvas].drawImage(blockInfo.bigImage, bigImageInfo.sx, bigImageInfo.sy, per_width, per_height, 0, 0, per_width, per_height);
@ -2586,6 +2593,17 @@ maps.prototype.moveBlock = function (x, y, steps, time, keep, callback) {
maps.prototype._moveBlock_doMove = function (blockInfo, canvases, moveInfo, callback) { maps.prototype._moveBlock_doMove = function (blockInfo, canvases, moveInfo, callback) {
var animateTotal = blockInfo.animate, animateTime = 0; var animateTotal = blockInfo.animate, animateTime = 0;
var _run = function () { var _run = function () {
var cb = function () {
core.maps._deleteDetachedBlock(canvases);
// 不消失
if (moveInfo.keep) {
core.setBlock(blockInfo.number, moveInfo.x, moveInfo.y);
core.showBlock(moveInfo.x, moveInfo.y);
core.moveEnemyOnPoint(moveInfo.sx, moveInfo.sy, moveInfo.x, moveInfo.y);
}
if (callback) callback();
}
var animate = window.setInterval(function () { var animate = window.setInterval(function () {
if (blockInfo.cls != 'tileset') { if (blockInfo.cls != 'tileset') {
animateTime += moveInfo.per_time; animateTime += moveInfo.per_time;
@ -2603,9 +2621,11 @@ maps.prototype._moveBlock_doMove = function (blockInfo, canvases, moveInfo, call
else core.maps._moveBlock_moving(blockInfo, canvases, moveInfo); else core.maps._moveBlock_moving(blockInfo, canvases, moveInfo);
} }
else else
core.maps._moveJumpBlock_finished(blockInfo, canvases, moveInfo, animate, callback); core.maps._moveJumpBlock_finished(blockInfo, canvases, moveInfo, animate, cb);
}, moveInfo.per_time); }, moveInfo.per_time);
core.animateFrame.asyncId[animate] = true;
core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = cb;
} }
_run(); _run();
} }
@ -2719,14 +2739,26 @@ maps.prototype.__generateJumpInfo = function (sx, sy, ex, ey, time) {
} }
maps.prototype._jumpBlock_doJump = function (blockInfo, canvases, jumpInfo, callback) { maps.prototype._jumpBlock_doJump = function (blockInfo, canvases, jumpInfo, callback) {
var cb = function () {
core.maps._deleteDetachedBlock(canvases);
// 不消失
if (jumpInfo.keep) {
core.setBlock(blockInfo.number, jumpInfo.ex, jumpInfo.ey);
core.showBlock(jumpInfo.ex, jumpInfo.ey);
core.moveEnemyOnPoint(jumpInfo.sx, jumpInfo.sy, jumpInfo.ex, jumpInfo.ey);
}
if (callback) callback();
}
var animate = window.setInterval(function () { var animate = window.setInterval(function () {
if (jumpInfo.jump_count > 0) if (jumpInfo.jump_count > 0)
core.maps._jumpBlock_jumping(blockInfo, canvases, jumpInfo) core.maps._jumpBlock_jumping(blockInfo, canvases, jumpInfo)
else else
core.maps._moveJumpBlock_finished(blockInfo, canvases, jumpInfo, animate, callback); core.maps._moveJumpBlock_finished(blockInfo, canvases, jumpInfo, animate, cb);
}, jumpInfo.per_time); }, jumpInfo.per_time);
core.animateFrame.asyncId[animate] = true; core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = cb;
} }
maps.prototype.__updateJumpInfo = function (jumpInfo) { maps.prototype.__updateJumpInfo = function (jumpInfo) {
@ -2743,20 +2775,13 @@ maps.prototype._jumpBlock_jumping = function (blockInfo, canvases, jumpInfo) {
core.maps._moveDetachedBlock(blockInfo, jumpInfo.px, jumpInfo.py, jumpInfo.opacity, canvases); core.maps._moveDetachedBlock(blockInfo, jumpInfo.px, jumpInfo.py, jumpInfo.opacity, canvases);
} }
maps.prototype._moveJumpBlock_finished = function (blockInfo, canvases, info, animate, callback) { maps.prototype._moveJumpBlock_finished = function (blockInfo, canvases, info, animate, cb) {
if (info.keep) info.opacity = 0; if (info.keep) info.opacity = 0;
else info.opacity -= 0.06; else info.opacity -= 0.06;
if (info.opacity <= 0) { if (info.opacity <= 0) {
delete core.animateFrame.asyncId[animate]; delete core.animateFrame.asyncId[animate];
clearInterval(animate); clearInterval(animate);
this._deleteDetachedBlock(canvases); cb();
// 不消失
if (info.keep) {
core.setBlock(blockInfo.number, info.x, info.y);
core.showBlock(info.x, info.y);
core.moveEnemyOnPoint(info.sx, info.sy, info.x, info.y);
}
if (callback) callback();
} }
else { else {
this._moveDetachedBlock(blockInfo, info.px, info.py, info.opacity, canvases); this._moveDetachedBlock(blockInfo, info.px, info.py, info.opacity, canvases);
@ -2784,30 +2809,35 @@ maps.prototype.animateBlock = function (loc, type, time, callback) {
maps.prototype._animateBlock_doAnimate = function (loc, list, type, time, callback) { maps.prototype._animateBlock_doAnimate = function (loc, list, type, time, callback) {
var step = 0, steps = Math.max(parseInt(time / 10), 1); var step = 0, steps = Math.max(parseInt(time / 10), 1);
var cb = function () {
list.forEach(function (t) {
if (t.blockInfo)
core.maps._deleteDetachedBlock(t.canvases);
});
loc.forEach(function (t) {
if (type == 'show') core.showBlock(t[0], t[1]);
else if (type == 'hide') core.hideBlock(t[0], t[1]);
else if (type == 'remove') core.removeBlock(t[0], t[1]);
else {
core.setBlockOpacity(type, t[0], t[1]);
core.showBlock(t[0], t[1]);
}
});
if (callback) callback();
}
var animate = setInterval(function () { var animate = setInterval(function () {
step++; step++;
core.maps._animateBlock_drawList(list, step / steps); core.maps._animateBlock_drawList(list, step / steps);
if (step == steps) { if (step == steps) {
delete core.animateFrame.asyncId[animate]; delete core.animateFrame.asyncId[animate];
clearInterval(animate); clearInterval(animate);
list.forEach(function (t) { cb();
if (t.blockInfo)
core.maps._deleteDetachedBlock(t.canvases);
});
loc.forEach(function (t) {
if (type == 'show') core.showBlock(t[0], t[1]);
else if (type == 'hide') core.hideBlock(t[0], t[1]);
else if (type == 'remove') core.removeBlock(t[0], t[1]);
else {
core.setBlockOpacity(type, t[0], t[1]);
core.showBlock(t[0], t[1]);
}
});
if (callback) callback();
} }
}, 10); }, 10);
core.animateFrame.asyncId[animate] = true; core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = cb;
} }
maps.prototype._animateBlock_getList = function (loc, type) { maps.prototype._animateBlock_getList = function (loc, type) {
@ -3028,7 +3058,7 @@ maps.prototype._drawAnimateFrame = function (name, animate, centerX, centerY, in
maps.prototype.stopAnimate = function (id, doCallback) { maps.prototype.stopAnimate = function (id, doCallback) {
for (var i = 0; i < core.status.animateObjs.length; i++) { for (var i = 0; i < core.status.animateObjs.length; i++) {
var obj = core.status.animateObjs[i]; var obj = core.status.animateObjs[i];
if (obj.id == id) { if (id == null || obj.id == id) {
if (doCallback) { if (doCallback) {
(function (callback) { (function (callback) {
setTimeout(function () { setTimeout(function () {
@ -3038,7 +3068,7 @@ maps.prototype.stopAnimate = function (id, doCallback) {
} }
} }
} }
core.status.animateObjs = core.status.animateObjs.filter(function (x) { return x.id != id }); core.status.animateObjs = core.status.animateObjs.filter(function (x) { return id != null && x.id != id });
if (core.status.animateObjs.length == 0) if (core.status.animateObjs.length == 0)
core.clearMap('animate'); core.clearMap('animate');
} }

View File

@ -1463,7 +1463,7 @@ ui.prototype.drawTextBox = function(content, config) {
// Step 5: 绘制正文 // Step 5: 绘制正文
var config = this.drawTextContent(config.ctx || 'ui', content, { var config = this.drawTextContent(config.ctx || 'ui', content, {
left: hPos.content_left, top: content_top, maxWidth: hPos.validWidth, left: hPos.content_left, top: content_top, maxWidth: hPos.validWidth,
lineHeight: vPos.lineHeight, time: (config.showAll || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time lineHeight: vPos.lineHeight, time: (config.showAll || config.async || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time
}); });
// Step 6: 绘制光标 // Step 6: 绘制光标
@ -1683,7 +1683,8 @@ ui.prototype._drawScrollText_animate = function (ctx, time, callback) {
core.drawImage('ui', ctx.canvas, 0, currH); core.drawImage('ui', ctx.canvas, 0, currH);
}, per_time); }, per_time);
core.animateFrame.asyncId[animate] = true; core.animateFrame.lastAsyncId = animate;
core.animateFrame.asyncId[animate] = callback;
} }
////// 文本图片化 ////// ////// 文本图片化 //////
@ -2031,7 +2032,7 @@ ui.prototype._drawReplay = function () {
core.status.event.id = 'replay'; core.status.event.id = 'replay';
core.playSound('打开界面'); core.playSound('打开界面');
this.drawChoices(null, [ this.drawChoices(null, [
"从头回放录像", "从存档开始回放", "接续播放剩余录像", "选择录像文件", "下载当前录像", "返回游戏" "从头回放录像", "从存档开始回放", "接续播放剩余录像", "播放存档剩余录像", "选择录像文件", "下载当前录像", "返回游戏"
]); ]);
} }
@ -2069,6 +2070,7 @@ ui.prototype._drawCursor = function () {
if (automaticRoute.cursorY == null) if (automaticRoute.cursorY == null)
automaticRoute.cursorY = core.getHeroLoc('y'); automaticRoute.cursorY = core.getHeroLoc('y');
automaticRoute.cursorX = core.clamp(automaticRoute.cursorX, 0, this.LAST); automaticRoute.cursorX = core.clamp(automaticRoute.cursorX, 0, this.LAST);
automaticRoute.cursorY = core.clamp(automaticRoute.cursorY, 0, this.LAST);
core.status.event.id = 'cursor'; core.status.event.id = 'cursor';
core.lockControl(); core.lockControl();
core.clearUI(); core.clearUI();
@ -2481,14 +2483,6 @@ ui.prototype._drawBookDetail_turnAndCriticals = function (enemy, floorId, texts)
}); });
while (criticals[0]=='0:0') criticals.shift(); while (criticals[0]=='0:0') criticals.shift();
texts.push("\r[#FF6A6A]\\d临界表\\d\r[]"+JSON.stringify(criticals)); texts.push("\r[#FF6A6A]\\d临界表\\d\r[]"+JSON.stringify(criticals));
var prevInfo = core.getDamageInfo(enemy.id, {atk: core.status.hero.atk-1}, null, null, floorId);
if (prevInfo != null && damageInfo != null) {
if (damageInfo.damage != null) damageInfo = damageInfo.damage;
if (prevInfo.damage != null) prevInfo = prevInfo.damage;
if (prevInfo > damageInfo) {
texts.push("(当前攻击力正位于临界点上)")
}
}
} }
ui.prototype._drawBookDetail_drawContent = function (enemy, content, pos) { ui.prototype._drawBookDetail_drawContent = function (enemy, content, pos) {
@ -2524,7 +2518,7 @@ ui.prototype.drawFly = function(page) {
var lines = core.splitLines('ui', title, 120, this._buildFont(19, true)); var lines = core.splitLines('ui', title, 120, this._buildFont(19, true));
var start_y = middle - (lines.length - 1) * 11; var start_y = middle - (lines.length - 1) * 11;
for (var i in lines) { for (var i in lines) {
core.fillText('ui', lines[i], this.PIXEL - 60, start_y); core.fillText('ui', lines[i], this.PIXEL - 60, start_y, '#FFFFFF');
start_y += 22; start_y += 22;
} }
@ -2593,34 +2587,35 @@ ui.prototype._drawViewMaps_drawHint = function () {
core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, 'rgba(0,0,0,0.7)'); core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, 'rgba(0,0,0,0.7)');
core.setTextAlign('ui', 'center'); core.setTextAlign('ui', 'center');
var stroke = function (left, top, width, height, fillStyle, lineWidth) { var stroke = function (left, top, width, height, fillStyle, lineWidth) {
core.strokeRect('ui', left*32+2, top*32+2, width*32-4, height*32-4, fillStyle, lineWidth); core.strokeRect('ui', left+2, top+2, width-4, height-4, fillStyle, lineWidth);
} }
var per = this.HSIZE - 4;
stroke(per, 0, 9, per, core.status.globalAttribute.selectColor, 4); // up var perpx = this.PIXEL / 5, cornerpx = perpx * 3 / 4;
stroke(0, per, per, 9); // left stroke(perpx, 0, 3 * perpx, perpx, core.status.globalAttribute.selectColor, 4); // up
stroke(per, this.SIZE - per, 9, per); // down stroke(0, perpx, perpx, 3 * perpx); // left
stroke(this.SIZE - per, per, per, 9); // right stroke(perpx, 4 * perpx, 3 * perpx, perpx); // down
stroke(per, per, 9, 3); // prev stroke(4 * perpx, perpx, perpx, 3 * perpx); // right
stroke(per, this.SIZE - per - 3, 9, 3); // next stroke(perpx, perpx, 3 * perpx, perpx); // prev
stroke(0, 0, per-1, per-1); // left top stroke(perpx, 3 * perpx, 3 * perpx, perpx); // next
stroke(this.SIZE-(per - 1), 0, per-1, per-1); // right top stroke(0, 0, cornerpx, cornerpx); // left top
stroke(0, this.SIZE-(per-1), per-1, per-1); // left bottom stroke(this.PIXEL - cornerpx, 0, cornerpx, cornerpx); // right top
stroke(0, this.PIXEL - cornerpx, cornerpx, cornerpx); // left bottom;
core.setTextBaseline('ui', 'middle'); core.setTextBaseline('ui', 'middle');
core.fillText('ui', "上移地图 [W]", this.HPIXEL, per * 16, core.status.globalAttribute.selectColor, '20px Arial'); core.fillText('ui', "上移地图 [W]", this.HPIXEL, perpx / 2, core.status.globalAttribute.selectColor, '20px Arial');
core.fillText('ui', "下移地图 [S]", this.HPIXEL, this.PIXEL - per * 16); core.fillText('ui', "下移地图 [S]", this.HPIXEL, this.PIXEL - perpx / 2);
core.fillText('ui', 'V', (per-1)*16, (per-1)*16); core.fillText('ui', 'V', cornerpx / 2, cornerpx / 2);
core.fillText('ui', 'Z', this.PIXEL - (per-1)*16, (per-1)*16); core.fillText('ui', 'Z', this.PIXEL - cornerpx / 2, cornerpx / 2);
core.fillText('ui', 'B', (per-1)*16, this.PIXEL - (per-1)*16); core.fillText('ui', 'B', cornerpx / 2, this.PIXEL - cornerpx / 2);
var top = this.HPIXEL - 66, left = per * 16, right = this.PIXEL - left; var top = this.HPIXEL - 66, left = perpx / 2, right = this.PIXEL - left;
var lt = ["左", "移", "地", "图", "[A]"], rt = ["右", "移", "地", "图", "[D]"]; var lt = ["左", "移", "地", "图", "[A]"], rt = ["右", "移", "地", "图", "[D]"];
for (var i = 0; i < 5; ++i) { for (var i = 0; i < 5; ++i) {
core.fillText("ui", lt[i], left, top + 32 * i); core.fillText("ui", lt[i], left, top + 32 * i);
core.fillText("ui", rt[i], right, top + 32 * i); core.fillText("ui", rt[i], right, top + 32 * i);
} }
core.fillText('ui', "前张地图 [▲ / PGUP]", this.HPIXEL, 32 * per + 48); core.fillText('ui', "前张地图 [▲ / PGUP]", this.HPIXEL, perpx * 1.5);
core.fillText('ui', "后张地图 [▼ / PGDN]", this.HPIXEL, this.PIXEL - (32 * per + 48)); core.fillText('ui', "后张地图 [▼ / PGDN]", this.HPIXEL, this.PIXEL - perpx * 1.5);
core.fillText('ui', "退出 [ESC / ENTER]", this.HPIXEL, this.HPIXEL); core.fillText('ui', "退出 [ESC / ENTER]", this.HPIXEL, this.HPIXEL);
core.fillText('ui', "[X] 可查看" + core.material.items['book'].name + " [G] 可使用" + core.material.items.fly.name, this.HPIXEL, this.HPIXEL + 32, null, '12px Arial'); core.fillText('ui', "[X] 可查看" + core.material.items['book'].name + " [G] 可使用" + core.material.items.fly.name, this.HPIXEL, this.HPIXEL + 32, null, '12px Arial');
@ -3026,6 +3021,7 @@ ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, hi
var strokeColor = globalAttribute.selectColor; var strokeColor = globalAttribute.selectColor;
if (core.status.event.selection) strokeColor = '#FF6A6A'; if (core.status.event.selection) strokeColor = '#FF6A6A';
if (!data || !data.floorId) highLight = false; if (!data || !data.floorId) highLight = false;
if (data && data.__toReplay__) title = '[R]' + title;
core.fillText('ui', title, x, y, highLight?globalAttribute.selectColor:'#FFFFFF', this._buildFont(17, true)); core.fillText('ui', title, x, y, highLight?globalAttribute.selectColor:'#FFFFFF', this._buildFont(17, true));
core.strokeRect('ui', x-size/2, y+15, size, size, cho?strokeColor:'#FFFFFF', cho?6:2); core.strokeRect('ui', x-size/2, y+15, size, size, cho?strokeColor:'#FFFFFF', cho?6:2);
@ -3105,17 +3101,20 @@ ui.prototype._drawKeyBoard = function () {
core.clearUI(); core.clearUI();
core.playSound('打开界面'); core.playSound('打开界面');
var offset = this.SIZE % 2 == 0 ? 16 : 0;
var width = 384, height = 320; var width = 384, height = 320;
var left = (this.PIXEL - width) / 2, right = left + width; var left = (this.PIXEL - width) / 2 + offset, right = left + width;
var top = (this.PIXEL - height) / 2, bottom = top + height; var top = (this.PIXEL - height) / 2 + offset, bottom = top + height;
var isWindowSkin = this.drawBackground(left, top, right, bottom); var isWindowSkin = this.drawBackground(left, top, right, bottom);
core.setTextAlign('ui', 'center'); core.setTextAlign('ui', 'center');
core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.title)); core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.title));
core.fillText('ui', '虚拟键盘', this.HPIXEL, top + 35, null, this._buildFont(22, true)); core.fillText('ui', '虚拟键盘', this.HPIXEL + offset, top + 35, null, this._buildFont(22, true));
core.setFont('ui', this._buildFont(17, false)); core.setFont('ui', this._buildFont(17, false));
core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.text)); core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.text));
var offset = this.HPIXEL - 89; var now = this.HPIXEL - 89 + offset;
var lines = [ var lines = [
["F1","F2","F3","F4","F5","F6","F7","F8","F9","10","11"], ["F1","F2","F3","F4","F5","F6","F7","F8","F9","10","11"],
@ -3129,17 +3128,17 @@ ui.prototype._drawKeyBoard = function () {
lines.forEach(function (line) { lines.forEach(function (line) {
for (var i=0;i<line.length;i++) { for (var i=0;i<line.length;i++) {
core.fillText('ui', line[i], core.ui.HPIXEL + 32*(i-5), offset); core.fillText('ui', line[i], core.ui.HPIXEL + 32*(i-5) + offset, now);
} }
offset+=32; now+=32;
}); });
core.fillText("ui", "返回游戏", this.HPIXEL + 128, offset-3, '#FFFFFF', this._buildFont(15, true)); core.fillText("ui", "返回游戏", this.HPIXEL + 128 + offset, now-3, '#FFFFFF', this._buildFont(15, true));
if (isWindowSkin) if (isWindowSkin)
this._drawWindowSelector(core.status.textAttribute.background, this.HPIXEL + 92, offset - 22, 72, 27); this._drawWindowSelector(core.status.textAttribute.background, this.HPIXEL + 92 + offset, now - 22, 72, 27);
else else
core.strokeRoundRect('ui', this.HPIXEL + 92, offset - 22, 72, 27, 6, core.status.globalAttribute.selectColor, 2); core.strokeRoundRect('ui', this.HPIXEL + 92 + offset, now - 22, 72, 27, 6, core.status.globalAttribute.selectColor, 2);
} }
////// 绘制状态栏 ///// ////// 绘制状态栏 /////
@ -3386,6 +3385,7 @@ ui.prototype.createCanvas = function (name, x, y, width, height, z) {
newCanvas.style.top = y * core.domStyle.scale + 'px'; newCanvas.style.top = y * core.domStyle.scale + 'px';
newCanvas.style.zIndex = z; newCanvas.style.zIndex = z;
newCanvas.style.position = 'absolute'; newCanvas.style.position = 'absolute';
newCanvas.style.pointerEvents = 'none';
core.dymCanvas[name] = newCanvas.getContext('2d'); core.dymCanvas[name] = newCanvas.getContext('2d');
core.maps._setHDCanvasSize(core.dymCanvas[name], width, height); core.maps._setHDCanvasSize(core.dymCanvas[name], width, height);
core.dom.gameDraw.appendChild(newCanvas); core.dom.gameDraw.appendChild(newCanvas);
@ -3393,14 +3393,22 @@ ui.prototype.createCanvas = function (name, x, y, width, height, z) {
} }
////// canvas重定位 ////// ////// canvas重定位 //////
ui.prototype.relocateCanvas = function (name, x, y) { ui.prototype.relocateCanvas = function (name, x, y, useDelta) {
var ctx = core.getContextByName(name); var ctx = core.getContextByName(name);
if (!ctx) return null; if (!ctx) return null;
if (x != null) { if (x != null) {
// 增量模式
if (useDelta) {
x += parseFloat(ctx.canvas.getAttribute("_left")) || 0;
}
ctx.canvas.style.left = x * core.domStyle.scale + 'px'; ctx.canvas.style.left = x * core.domStyle.scale + 'px';
ctx.canvas.setAttribute("_left", x); ctx.canvas.setAttribute("_left", x);
} }
if (y != null) { if (y != null) {
// 增量模式
if (useDelta) {
y += parseFloat(ctx.canvas.getAttribute("_top")) || 0;
}
ctx.canvas.style.top = y * core.domStyle.scale + 'px'; ctx.canvas.style.top = y * core.domStyle.scale + 'px';
ctx.canvas.setAttribute("_top", y); ctx.canvas.setAttribute("_top", y);
} }

View File

@ -214,18 +214,7 @@ utils.prototype.setLocalStorage = function (key, value) {
var str = JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) { var str = JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) {
return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4) return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4)
}); });
var compressed = lzw_encode(str); localStorage.setItem(core.firstData.name + "_" + key, str);
// test if we can save to localStorage
localStorage.setItem("__tmp__", compressed);
if (lzw_decode(localStorage.getItem("__tmp__")) == str) {
localStorage.setItem(core.firstData.name + "_" + key, compressed);
}
else {
// We cannot compress the data
localStorage.setItem(core.firstData.name + "_" + key, str);
}
localStorage.removeItem("__tmp__");
if (key == 'autoSave') core.saves.ids[0] = true; if (key == 'autoSave') core.saves.ids[0] = true;
else if (/^save\d+$/.test(key)) core.saves.ids[parseInt(key.substring(4))] = true; else if (/^save\d+$/.test(key)) core.saves.ids[parseInt(key.substring(4))] = true;
@ -240,8 +229,13 @@ utils.prototype.setLocalStorage = function (key, value) {
////// 获得本地存储 ////// ////// 获得本地存储 //////
utils.prototype.getLocalStorage = function (key, defaultValue) { utils.prototype.getLocalStorage = function (key, defaultValue) {
var res = this.decompress(localStorage.getItem(core.firstData.name + "_" + key)); try {
return res == null ? defaultValue : res; var value = JSON.parse(localStorage.getItem(core.firstData.name + "_" + key));
if (value == null) return defaultValue;
return value;
} catch (e) {
return defaultValue;
}
} }
////// 移除本地存储 ////// ////// 移除本地存储 //////
@ -252,28 +246,16 @@ utils.prototype.removeLocalStorage = function (key) {
} }
utils.prototype.setLocalForage = function (key, value, successCallback, errorCallback) { utils.prototype.setLocalForage = function (key, value, successCallback, errorCallback) {
if (!core.platform.useLocalForage) {
if (this.setLocalStorage(key, value)) {
if (successCallback) successCallback();
}
else {
if (errorCallback) errorCallback();
}
return;
}
if (value == null) { if (value == null) {
this.removeLocalForage(key); this.removeLocalForage(key);
return; return;
} }
// Save to localforage var name = core.firstData.name + "_" + key;
var str = JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) { var str = JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) {
return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4) return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4)
}); });
var compressed = str.length > 100000 ? LZString.compress(str) : lzw_encode(str); var callback = function (err) {
localforage.setItem(core.firstData.name + "_" + key, compressed, function (err) {
if (err) { if (err) {
if (errorCallback) errorCallback(err); if (errorCallback) errorCallback(err);
} }
@ -282,22 +264,31 @@ utils.prototype.setLocalForage = function (key, value, successCallback, errorCal
else if (/^save\d+$/.test(key)) core.saves.ids[parseInt(key.substring(4))] = true; else if (/^save\d+$/.test(key)) core.saves.ids[parseInt(key.substring(4))] = true;
if (successCallback) successCallback(); if (successCallback) successCallback();
} }
}); }
this._setLocalForage_set(name, str, callback);
}
utils.prototype._setLocalForage_set = function (name, str, callback) {
if (window.jsinterface && window.jsinterface.setLocalForage) {
var id = setTimeout(null);
core['__callback' + id] = callback;
core.saves.cache[name] = str;
window.jsinterface.setLocalForage(id, name, str);
} else {
var compressed = str.length > 100000 ? LZString.compress(str) : lzw_encode(str);
core.saves.cache[name] = compressed;
localforage.setItem(name, compressed, callback);
}
} }
utils.prototype.getLocalForage = function (key, defaultValue, successCallback, errorCallback) { utils.prototype.getLocalForage = function (key, defaultValue, successCallback, errorCallback) {
var name = core.firstData.name + "_" + key;
if (!core.platform.useLocalForage) { var callback = function (err, value) {
var value = this.getLocalStorage(key, defaultValue);
if (successCallback) successCallback(value);
return;
}
localforage.getItem(core.firstData.name + "_" + key, function (err, value) {
if (err) { if (err) {
if (errorCallback) errorCallback(err); if (errorCallback) errorCallback(err);
} }
else { else {
core.saves.cache[name] = value;
if (!successCallback) return; if (!successCallback) return;
if (value != null) { if (value != null) {
var res = core.utils.decompress(value); var res = core.utils.decompress(value);
@ -306,18 +297,26 @@ utils.prototype.getLocalForage = function (key, defaultValue, successCallback, e
} }
successCallback(defaultValue); successCallback(defaultValue);
} }
}) };
if (core.saves.cache[name] != null) {
return callback(null, core.saves.cache[name]);
}
this._getLocalForage_get(name, callback);
}
utils.prototype._getLocalForage_get = function (name, callback) {
if (window.jsinterface && window.jsinterface.getLocalForage) {
var id = setTimeout(null);
core['__callback' + id] = callback;
window.jsinterface.getLocalForage(id, name);
} else {
localforage.getItem(name, callback);
}
} }
utils.prototype.removeLocalForage = function (key, successCallback, errorCallback) { utils.prototype.removeLocalForage = function (key, successCallback, errorCallback) {
var name = core.firstData.name + "_" + key;
if (!core.platform.useLocalForage) { var callback = function (err) {
this.removeLocalStorage(key);
if (successCallback) successCallback();
return;
}
localforage.removeItem(core.firstData.name + "_" + key, function (err) {
if (err) { if (err) {
if (errorCallback) errorCallback(err); if (errorCallback) errorCallback(err);
} }
@ -326,7 +325,61 @@ utils.prototype.removeLocalForage = function (key, successCallback, errorCallbac
else if (/^save\d+$/.test(key)) delete core.saves.ids[parseInt(key.substring(4))]; else if (/^save\d+$/.test(key)) delete core.saves.ids[parseInt(key.substring(4))];
if (successCallback) successCallback(); if (successCallback) successCallback();
} }
}) }
delete core.saves.cache[name];
this._removeLocalForage_remove(name, callback);
}
utils.prototype._removeLocalForage_remove = function (name, callback) {
if (window.jsinterface && window.jsinterface.removeLocalForage) {
var id = setTimeout(null);
core['__callback' + id] = callback;
window.jsinterface.removeLocalForage(id, name);
} else {
localforage.removeItem(name, callback);
}
}
utils.prototype.clearLocalForage = function (callback) {
core.saves.cache = {};
if (window.jsinterface && window.jsinterface.clearLocalForage) {
var id = setTimeout(null);
core['__callback' + id] = callback;
window.jsinterface.clearLocalForage(id);
} else {
localforage.clear(callback);
}
}
utils.prototype.iterateLocalForage = function (iter, callback) {
if (window.jsinterface && window.jsinterface.iterateLocalForage) {
var id = setTimeout(null);
core['__iter' + id] = iter;
core['__callback' + id] = callback;
window.jsinterface.iterateLocalForage(id);
} else {
localforage.iterate(iter, callback);
}
}
utils.prototype.keysLocalForage = function (callback) {
if (window.jsinterface && window.jsinterface.keysLocalForage) {
var id = setTimeout(null);
core['__callback' + id] = callback;
window.jsinterface.keysLocalForage(id);
} else {
localforage.keys(callback);
}
}
utils.prototype.lengthLocalForage = function (callback) {
if (window.jsinterface && window.jsinterface.lengthLocalForage) {
var id = setTimeout(null);
core['__callback' + id] = callback;
window.jsinterface.lengthLocalForage(id);
} else {
localforage.length(callback);
}
} }
utils.prototype.setGlobal = function (key, value) { utils.prototype.setGlobal = function (key, value) {
@ -450,7 +503,7 @@ utils.prototype.formatTime = function (time) {
////// 两位数显示 ////// ////// 两位数显示 //////
utils.prototype.setTwoDigits = function (x) { utils.prototype.setTwoDigits = function (x) {
return parseInt(x) < 10 ? "0" + x : x; return (parseInt(x) < 10 && parseInt(x) >= 0) ? "0" + x : x;
} }
utils.prototype.formatSize = function (size) { utils.prototype.formatSize = function (size) {
@ -459,41 +512,34 @@ utils.prototype.formatSize = function (size) {
else return (size/1024/1024).toFixed(2) + "MB"; else return (size/1024/1024).toFixed(2) + "MB";
} }
utils.prototype.formatBigNumber = function (x, onMap) { utils.prototype.formatBigNumber = function (x, digits) {
x = Math.floor(parseFloat(x)); if (digits === true) digits = 5; // 兼容旧版onMap参数
if (!core.isset(x) || !Number.isFinite(x)) return '???'; if (!digits || digits < 5) digits = 6; // 连同负号、小数点和后缀字母在内的总位数至少需为5默认为6
if (x > 1e24 || x < -1e24) return x.toExponential(2); x = Math.trunc(parseFloat(x)); // 尝试识别为小数然后向0取整
if (x == null || !Number.isFinite(x)) return '???'; // 无法识别的数或正负无穷大,显示'???'
var units = [ // 单位及其后缀字母可自定义如改成千进制下的K、M、G、T、P
{ "val": 1e4, "suffix": "w" },
{ "val": 1e8, "suffix": "e" },
{ "val": 1e12, "suffix": "z" },
{ "val": 1e16, "suffix": "j" },
{ "val": 1e20, "suffix": "g" },
];
if (Math.abs(x) > 1e20 * Math.pow(10, digits - 2))
return x.toExponential(0); // 绝对值过大以致于失去精度的数,直接使用科学记数法,系数只保留整数
var sign = x < 0 ? '-' : '';
if (sign) --digits; // 符号位单独处理,负号要占一位
x = Math.abs(x);
var c = x < 0 ? "-" : ""; if (x < Math.pow(10, digits)) return sign + x;
x = Math.abs(x);
if (x <= 99999 || (!onMap && x <= 999999)) return c + x; for (var i = 0; i < units.length; ++i) {
var each = units[i];
var all = [ var u = (x / each.val).toFixed(digits).substring(0, digits);
{"val": 1e20, "c": "g"}, if (u.indexOf('.') < 0) continue;
{"val": 1e16, "c": "j"}, u = u.substring(0, u[u.length - 2] == '.' ? u.length - 2 : u.length - 1);
{"val": 1e12, "c": "z"}, return sign + u + each.suffix;
{"val": 1e8, "c": "e"},
{"val": 1e4, "c": "w"},
]
for (var i = 0; i < all.length; i++) {
var one = all[i];
if (onMap) {
if (x >= one.val) {
var v = x / one.val;
return c + v.toFixed(Math.max(0, Math.floor(3 - Math.log10(v + 1)))) + one.c;
}
}
else {
if (x >= 10 * one.val) {
var v = x / one.val;
return c + v.toFixed(Math.max(0, Math.floor(4 - Math.log10(v + 1)))) + one.c;
}
}
} }
return sign + x.toExponential(0);
return c + x;
} }
////// 变速移动 ////// ////// 变速移动 //////
@ -514,6 +560,10 @@ utils.prototype.applyEasing = function(name) {
return t return t
} }
} }
if (name == 'random') {
var keys = Object.keys(list);
name = keys[Math.floor(Math.random() * keys.length)];
}
return list[name] || list.linear; return list[name] || list.linear;
} }
@ -635,8 +685,14 @@ utils.prototype.decodeRoute = function (route) {
utils.prototype._decodeRoute_getNumber = function (decodeObj, noparse) { utils.prototype._decodeRoute_getNumber = function (decodeObj, noparse) {
var num = ""; var num = "";
while (decodeObj.index < decodeObj.route.length && !isNaN(decodeObj.route.charAt(decodeObj.index))) { var first = true;
num += decodeObj.route.charAt(decodeObj.index++); while (true) {
var ch = decodeObj.route.charAt(decodeObj.index);
if (ch >= '0' && ch <= '9') num += ch;
else if (ch == '-' && first) num += ch;
else break;
first = false;
decodeObj.index++;
} }
if (num.length == 0) num = "1"; if (num.length == 0) num = "1";
return noparse ? num : parseInt(num); return noparse ? num : parseInt(num);
@ -814,6 +870,8 @@ utils.prototype.turnDirection = function (turn, direction) {
direction = direction || core.getHeroLoc('direction'); direction = direction || core.getHeroLoc('direction');
var directionList = ["left", "leftup", "up", "rightup", "right", "rightdown", "down", "leftdown"]; var directionList = ["left", "leftup", "up", "rightup", "right", "rightdown", "down", "leftdown"];
if (directionList.indexOf(turn) >= 0) return turn; if (directionList.indexOf(turn) >= 0) return turn;
if (turn == ':hero') return core.getHeroLoc('direction');
if (turn == ':backhero') return this.turnDirection(':back', core.getHeroLoc('direction'));
if (typeof turn === 'number' && turn % 45 == 0) turn /= 45; if (typeof turn === 'number' && turn % 45 == 0) turn /= 45;
else { else {
switch (turn) { switch (turn) {
@ -969,19 +1027,23 @@ utils.prototype.readFileContent = function (content) {
core.platform.successCallback(content); core.platform.successCallback(content);
return; return;
} }
// 检查base64
try { try {
obj = JSON.parse(content); obj = JSON.parse(LZString.decompressFromBase64(content));
if (obj) { } catch (e) {}
if (core.platform.successCallback) if (!obj) {
core.platform.successCallback(obj); try {
return; obj = JSON.parse(content);
} catch (e) {
main.log(e)
} }
} }
catch (e) {
main.log(e); if (obj) {
alert(e); if (core.platform.successCallback)
core.platform.successCallback(obj);
return;
} }
// alert("不是有效的JSON文件");
if (core.platform.errorCallback) if (core.platform.errorCallback)
core.platform.errorCallback(); core.platform.errorCallback();
@ -1195,10 +1257,10 @@ utils.prototype.same = function (a, b) {
return true; return true;
} }
if (a instanceof Object && b instanceof Object) { if (a instanceof Object && b instanceof Object) {
for (var i in a) { var obj = {};
if (!this.same(a[i], b[i])) return false; for (var i in a) obj[i] = true;
} for (var i in b) obj[i] = true;
for (var i in b) { for (var i in obj) {
if (!this.same(a[i], b[i])) return false; if (!this.same(a[i], b[i])) return false;
} }
return true; return true;

20
main.js
View File

@ -2,7 +2,7 @@ function main() {
//------------------------ 用户修改内容 ------------------------// //------------------------ 用户修改内容 ------------------------//
this.version = "2.8.1"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。 this.version = "2.8.2"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.useCompress = false; // 是否使用压缩文件 this.useCompress = false; // 是否使用压缩文件
// 当你即将发布你的塔时请使用“JS代码压缩工具”将所有js代码进行压缩然后将这里的useCompress改为true。 // 当你即将发布你的塔时请使用“JS代码压缩工具”将所有js代码进行压缩然后将这里的useCompress改为true。
@ -188,8 +188,8 @@ function main() {
this.floors = {} this.floors = {}
this.canvas = {}; this.canvas = {};
this.__VERSION__ = "2.8.1"; this.__VERSION__ = "2.8.2";
this.__VERSION_CODE__ = 443; this.__VERSION_CODE__ = 507;
} }
main.prototype.init = function (mode, callback) { main.prototype.init = function (mode, callback) {
@ -290,8 +290,19 @@ main.prototype.loadFloors = function (callback) {
main.dom.mainTips.style.display = 'none'; main.dom.mainTips.style.display = 'none';
callback(); callback();
} }
return;
} }
else {
// 高层塔优化
var script = document.createElement('script');
script.src = '__all_floors__.js?v=' + this.version + '&id=' + main.floorIds.join(',');
script.onload = function () {
main.dom.mainTips.style.display = 'none';
main.supportBunch = true;
callback();
}
script.onerror = script.onabort = script.ontimeout = function (e) {
console.clear();
for (var i = 0; i < main.floorIds.length; i++) { for (var i = 0; i < main.floorIds.length; i++) {
main.loadFloor(main.floorIds[i], function (modName) { main.loadFloor(main.floorIds[i], function (modName) {
main.setMainTipsText("楼层 " + modName + '.js 加载完毕'); main.setMainTipsText("楼层 " + modName + '.js 加载完毕');
@ -302,6 +313,7 @@ main.prototype.loadFloors = function (callback) {
}); });
} }
} }
main.dom.body.appendChild(script);
} }
////// 加载某一个楼层 ////// ////// 加载某一个楼层 //////

View File

@ -9,7 +9,9 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
], ],
"floorPartitions": [], "floorPartitions": [],
"images": [ "images": [
"bear.png",
"bg.jpg", "bg.jpg",
"dragon.png",
"hero.png", "hero.png",
"winskin.png" "winskin.png"
], ],
@ -150,12 +152,20 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
], ],
"floorChangingStyle": "background-color: black; color: white", "floorChangingStyle": "background-color: black; color: white",
"font": "Verdana" "font": "Verdana"
} },
"splitImages": [
{
"name": "dragon.png",
"width": 384,
"height": 96,
"prefix": "dragon_"
}
]
}, },
"firstData": { "firstData": {
"title": "魔塔样板", "title": "魔塔样板",
"name": "template", "name": "template",
"version": "Ver 2.8.1", "version": "Ver 2.8.2",
"floorId": "sample0", "floorId": "sample0",
"hero": { "hero": {
"image": "hero.png", "image": "hero.png",

View File

@ -35,7 +35,7 @@ var enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 =
"whiteHornSlime": {"name":"尖角怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "whiteHornSlime": {"name":"尖角怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
"redSwordsman": {"name":"剑王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[]}, "redSwordsman": {"name":"剑王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[]},
"poisonZombie": {"name":"绿兽人","hp":100,"atk":120,"def":0,"money":13,"exp":0,"point":0,"special":[12]}, "poisonZombie": {"name":"绿兽人","hp":100,"atk":120,"def":0,"money":13,"exp":0,"point":0,"special":[12]},
"octopus": {"name":"血影","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "octopus": {"name":"血影","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"bigImage":"dragon_1.png"},
"princessEnemy": {"name":"假公主","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "princessEnemy": {"name":"假公主","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
"angel": {"name":"天使","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "angel": {"name":"天使","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
"elemental": {"name":"元素生物","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "elemental": {"name":"元素生物","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
@ -52,7 +52,7 @@ var enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 =
"magicMaster": {"name":"黑暗大法师","hp":100,"atk":120,"def":0,"money":12,"exp":0,"point":0,"special":11,"value":0.3333333333333333,"add":true,"notBomb":true}, "magicMaster": {"name":"黑暗大法师","hp":100,"atk":120,"def":0,"money":12,"exp":0,"point":0,"special":11,"value":0.3333333333333333,"add":true,"notBomb":true},
"devilWarrior": {"name":"魔神武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "devilWarrior": {"name":"魔神武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
"fairyEnemy": {"name":"仙子","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "fairyEnemy": {"name":"仙子","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
"dragon": {"name":"魔龙","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "dragon": {"name":"魔龙","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"bigImage":"dragon_0.png"},
"skeletonKnight": {"name":"骷髅武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "skeletonKnight": {"name":"骷髅武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
"skeletonPresbyter": {"name":"骷髅巫师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "skeletonPresbyter": {"name":"骷髅巫师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
"ironRock": {"name":"铁面人","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "ironRock": {"name":"铁面人","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
@ -76,5 +76,9 @@ var enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 =
"blueKing": {"name":"白衣武士","hp":100,"atk":120,"def":0,"money":17,"exp":0,"point":0,"special":16}, "blueKing": {"name":"白衣武士","hp":100,"atk":120,"def":0,"money":17,"exp":0,"point":0,"special":16},
"keiskeiFairy": {"name":"铃兰花妖","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "keiskeiFairy": {"name":"铃兰花妖","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
"tulipFairy": {"name":"郁金香花妖","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, "tulipFairy": {"name":"郁金香花妖","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
"purpleBowman": {"name":"高级弓兵","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0} "purpleBowman": {"name":"高级弓兵","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0},
"bearDown": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"},"bigImage":"bear.png"},
"bearLeft": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"}},
"bearRight": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"}},
"bearUp": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"}}
} }

View File

@ -12,7 +12,7 @@ main.floors.sample0=
"ratio": 1, "ratio": 1,
"map": [ "map": [
[ 0, 0,220, 0, 0, 20, 87, 3, 58, 59, 60, 61, 64], [ 0, 0,220, 0, 0, 20, 87, 3, 58, 59, 60, 61, 64],
[ 0,246, 0,246, 0, 20, 0, 3, 57, 62, 63, 43, 44], [ 0,246, 0,246, 0, 20, 0, 3, 57, 72, 63, 43, 44],
[219, 0, 0, 0,219, 20, 0, 3, 53, 54, 55, 56, 69], [219, 0, 0, 0,219, 20, 0, 3, 53, 54, 55, 56, 69],
[ 20, 20,125, 20, 20, 20, 0, 3, 49, 50, 51, 52, 68], [ 20, 20,125, 20, 20, 20, 0, 3, 49, 50, 51, 52, 68],
[251,247,256,234,248, 6, 0, 3, 35, 36, 46, 47, 48], [251,247,256,234,248, 6, 0, 3, 35, 36, 46, 47, 48],
@ -177,13 +177,13 @@ main.floors.sample0=
}, },
"afterGetItem": { "afterGetItem": {
"9,1": [ "9,1": [
"样板给出的道具素材中有很多道具都是未定义甚至未注册的,需要自行实现功能。\n比如屠龙匕首就是一个没有功能的道具\n如果你想为未定的道具添加自定义功能请参照样板中其他道具的写法如果有更多疑问请查阅帮助文档。" "技能的支持需要依赖状态栏的“魔力”以及脚本编辑的“按键处理”,详见帮助文档“个性化”一节。"
], ],
"12,2": [ "12,2": [
"跳跃本身没有音效,使用跳跃鞋时播放的音效是通过跳跃鞋的道具效果实现的。\n如果想为跳跃设置音效请在 events.js 的 jumpHero 函数执行前插入一行代码,用 core.playSound 的方式来播放音效即可。\n如果想了解更多关于这方面的内容请参与帮助文档中的“脚本——复写函数”章节。\n\n类似的是敌人的“支援”技能也是通过在支援技能中播放音效实现的。" "跳跃靴和支援怪的跳跃音效是用脚本额外添加的,\n如果想为任意跳跃指令添加音效请查阅帮助文档中的“脚本——复写函数”章节。"
], ],
"8,3": [ "8,3": [
"炸弹是只能炸面前的怪物还是四个方向的怪物由其图块属性快捷键C中的“使用效果”决定。\n不能被炸的怪物请直接在该怪物的图块属性中勾选“不可炸”可参见样板里黑衣魔王和黑暗大法师的写法。" "炸弹是只能炸面前的怪物还是四个甚至八个方向的怪物,\n由其图块属性快捷键C中的“使用效果”决定。\n不能被炸的怪物请直接在该怪物的图块属性中勾选“不可炸”\n可参见样板里黑衣魔王和黑暗大法师的写法。\nV2.8.1起,炸弹炸怪可以添加获得金经/触发战后事件,详见其使用效果中的注释。"
], ],
"10,3": [ "10,3": [
"“上楼”和“下楼”的目标层由全塔属性快捷键B的“楼层列表”顺序所决定。" "“上楼”和“下楼”的目标层由全塔属性快捷键B的“楼层列表”顺序所决定。"
@ -209,11 +209,7 @@ main.floors.sample0=
"在 2.8.1 版更新后,能够被破冰镐摧毁的冰块被移动到了 animates 下。\n如果想制作一个可以以特定触发器的方式移除特定图块的道具可以参照破冰镐物品图块属性中\n useItemEffect 和 canUseItemEffect 的写法。" "在 2.8.1 版更新后,能够被破冰镐摧毁的冰块被移动到了 animates 下。\n如果想制作一个可以以特定触发器的方式移除特定图块的道具可以参照破冰镐物品图块属性中\n useItemEffect 和 canUseItemEffect 的写法。"
], ],
"11,8": [ "11,8": [
"由于状态栏放不下,铁门钥匙(根据全塔属性的系统开关勾选与否,可能还有绿钥匙)会被放入道具栏中。\n碰到绿门和铁门时仍然会自动使用钥匙开门。", "由于状态栏放不下,铁门钥匙(根据全塔属性的系统开关勾选与否,可能还有绿钥匙)会被放入道具栏中。\n碰到绿门和铁门时仍然会自动使用钥匙开门。"
{
"type": "comment",
"text": "由于状态栏放不下,铁门钥匙(根据全塔属性的系统开关勾选与否,可能还有绿钥匙)会被放入道具栏中。\n碰到绿门和铁门仍然会自动使用钥匙根据全塔属性的系统开关勾选与否铁门可能不需要钥匙开门。"
}
], ],
"12,8": [ "12,8": [
"该道具默认是大黄门钥匙如需改为钥匙盒直接修改其图块属性快捷键C的“道具类别”为items即可。" "该道具默认是大黄门钥匙如需改为钥匙盒直接修改其图块属性快捷键C的“道具类别”为items即可。"

View File

@ -7,7 +7,14 @@ main.floors.sample1=
"canFlyFrom": true, "canFlyFrom": true,
"canUseQuickShop": true, "canUseQuickShop": true,
"defaultGround": "grass", "defaultGround": "grass",
"images": null, "images": [
{
"name": "bg.jpg",
"canvas": "bg",
"x": 0,
"y": 0
}
],
"weather": [ "weather": [
"snow", "snow",
6 6
@ -441,7 +448,10 @@ main.floors.sample1=
} }
], ],
"false": [ "false": [
"\t[老人,trader]你的金钱不足!" "\t[老人,trader]你的金钱不足!",
{
"type": "continue"
}
] ]
} }
] ]
@ -464,13 +474,13 @@ main.floors.sample1=
"name": "item:blueKey", "name": "item:blueKey",
"operator": "+=", "operator": "+=",
"value": "1" "value": "1"
},
{
"type": "continue"
} }
], ],
"false": [ "false": [
"\t[老人,trader]你的金钱不足!" "\t[老人,trader]你的金钱不足!",
{
"type": "continue"
}
] ]
} }
] ]

View File

@ -13,22 +13,22 @@ main.floors.sample2=
"map": [ "map": [
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,202, 0, 0, 0, 0, 0, 0], [ 1, 27, 28, 29, 1, 0,202, 1, 27, 28, 29, 1, 0, 0, 0, 1, 0, 0, 0,202, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 1, 31, 32, 33, 1, 0, 0, 1, 31, 32, 33, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 1, 21,258, 22, 1, 0, 0, 1, 21,257, 22, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [ 1, 1, 82, 1, 1, 0, 0, 1, 1, 81, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [ 0, 0, 22, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0],
[ 0, 0, 0, 0, 1, 1, 45, 0, 1, 0,202,202, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0,202,202, 0], [ 0, 0, 0, 0, 0, 0, 45, 0, 1, 0,202,202, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0,202,202, 0],
[ 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 88, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [ 0,327, 0, 0, 0, 0, 88, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0,202, 0, 0, 0, 0,328, 0, 0, 0, 0, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0,329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0,330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,202, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,202, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0],
@ -42,9 +42,6 @@ main.floors.sample2=
"height": 26, "height": 26,
"firstArrive": [], "firstArrive": [],
"events": { "events": {
"3,2": [
"123"
],
"12,12": [ "12,12": [
"234" "234"
] ]
@ -71,5 +68,6 @@ main.floors.sample2=
], ],
"autoEvent": {}, "autoEvent": {},
"beforeBattle": {} "beforeBattle": {},
"cannotMoveIn": {}
} }

View File

@ -112,14 +112,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// core.deleteAllCanvas(); // core.deleteAllCanvas();
// } // }
// 播放换层音效
if (fromLoad)
core.playSound('读档');
else if (isFlying)
core.playSound('飞行器');
else if (currentId)
core.playSound('上下楼');
// 根据分区信息自动砍层与恢复 // 根据分区信息自动砍层与恢复
if (core.autoRemoveMaps) core.autoRemoveMaps(floorId); if (core.autoRemoveMaps) core.autoRemoveMaps(floorId);
@ -149,6 +141,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
var bgm = core.status.maps[floorId].bgm; var bgm = core.status.maps[floorId].bgm;
if (bgm instanceof Array) bgm = bgm[Math.floor(Math.random() * bgm.length)]; // 多个bgm则随机播放一个 if (bgm instanceof Array) bgm = bgm[Math.floor(Math.random() * bgm.length)]; // 多个bgm则随机播放一个
if (!core.hasFlag("__bgm__")) core.playBgm(bgm); if (!core.hasFlag("__bgm__")) core.playBgm(bgm);
} else if (fromLoad && !core.hasFlag("__bgm__")) {
core.pauseBgm();
} }
// 更改画面色调 // 更改画面色调
var color = core.getFlag('__color__', null); var color = core.getFlag('__color__', null);
@ -1141,11 +1135,14 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
core.setFlag('curse', true); core.setFlag('curse', true);
} }
} else if (action == 'remove') { } else if (action == 'remove') {
var success = false;
if (core.inArray(type, "poison") && core.hasFlag("poison")) { if (core.inArray(type, "poison") && core.hasFlag("poison")) {
success = true;
// 移除毒效果 // 移除毒效果
core.setFlag("poison", false); core.setFlag("poison", false);
} }
if (core.inArray(type, "weak") && core.hasFlag("weak")) { if (core.inArray(type, "weak") && core.hasFlag("weak")) {
success = true;
// 移除衰效果 // 移除衰效果
core.setFlag("weak", false); core.setFlag("weak", false);
if (core.values.weakValue >= 1) { if (core.values.weakValue >= 1) {
@ -1159,9 +1156,11 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
} }
} }
if (core.inArray(type, "curse") && core.hasFlag("curse")) { if (core.inArray(type, "curse") && core.hasFlag("curse")) {
success = true;
// 移除咒效果 // 移除咒效果
core.setFlag("curse", false); core.setFlag("curse", false);
} }
if (success) core.playSound('回血');
} }
}, },
"updateStatusBar": function () { "updateStatusBar": function () {

View File

@ -109,24 +109,8 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 =
"expShop": 9, "expShop": 9,
"moneyShop": 10, "moneyShop": 10,
"princess": 11, "princess": 11,
"greenMan": 28, "greenMan": 12,
"blueTrader": 29, "blueTrader": 13
"octopusLeftTop": 12,
"octopusTop": 13,
"octopusRightTop": 14,
"octopusLeft": 15,
"octopusCenter": 16,
"octopusRight": 17,
"octopusLeftBottom": 18,
"octopusRightBottom": 19,
"dragonLeftTop": 20,
"dragonTop": 21,
"dragonRightTop": 22,
"dragonLeft": 23,
"dragonCenter": 24,
"dragonRight": 25,
"dragonLeftBottom": 26,
"dragonRightBottom": 27
}, },
"npc48": { "npc48": {
"npc0": 0, "npc0": 0,
@ -219,7 +203,11 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 =
"angel": 0, "angel": 0,
"elemental": 1, "elemental": 1,
"steelGuard": 2, "steelGuard": 2,
"evilBat": 3 "evilBat": 3,
"bearDown": 4,
"bearLeft": 5,
"bearRight": 6,
"bearUp": 7
}, },
"items": { "items": {
"yellowKey": 0, "yellowKey": 0,

BIN
project/images/bear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
project/images/dragon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -297,7 +297,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"name": "圣水", "name": "圣水",
"itemEffect": "core.status.hero.hp *= 2", "itemEffect": "core.status.hero.hp *= 2",
"itemEffectTip": ",生命值翻倍", "itemEffectTip": ",生命值翻倍",
"useItemEffect": "core.status.hero.hp *= 2;\ncore.playSound('回血');", "useItemEffect": "core.status.hero.hp *= 2;core.playSound('回血');",
"canUseItemEffect": "true", "canUseItemEffect": "true",
"text": "生命值翻倍" "text": "生命值翻倍"
}, },
@ -327,7 +327,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"cls": "constants", "cls": "constants",
"name": "冰冻徽章", "name": "冰冻徽章",
"text": "可以将面前的熔岩变成平地", "text": "可以将面前的熔岩变成平地",
"useItemEffect": "(function () {\n\tvar success = false;\n\n\tvar snowFourDirections = false; // 是否四方向雪花如果是将其改成true\n\tif (snowFourDirections) {\n\t\t// 四方向雪花\n\t\tfor (var direction in core.utils.scan) {\n\t\t\tvar delta = core.utils.scan[direction];\n\t\t\tvar nx = core.getHeroLoc('x') + delta.x,\n\t\t\t\tny = core.getHeroLoc('y') + delta.y;\n\t\t\tif (core.getBlockId(nx, ny) == 'lava') {\n\t\t\t\tcore.removeBlock(nx, ny);\n\t\t\t\tsuccess = true;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (core.getBlockId(core.nextX(), core.nextY()) == 'lava') {\n\t\t\tcore.removeBlock(core.nextX(), core.nextY());\n\t\t\tsuccess = true;\n\t\t}\n\t}\n\n\tif (success) {\n\t\tcore.playSound('打开界面');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t} else {\n\t\tcore.playSound('操作失败');\n\t\tcore.drawTip(\"当前无法使用\" + core.material.items[itemId].name);\n\t\tcore.addItem(itemId, 1);\n\t\treturn;\n\t}\n})();", "useItemEffect": "(function () {\n\tvar success = false;\n\n\tvar snowFourDirections = false; // 是否多方向雪花如果是将其改成true\n\tif (snowFourDirections) {\n\t\t// 多方向雪花\n\t\tfor (var direction in core.utils.scan) { // 多方向雪花默认四方向如需改为八方向请将这两个scan改为scan2\n\t\t\tvar delta = core.utils.scan[direction];\n\t\t\tvar nx = core.getHeroLoc('x') + delta.x,\n\t\t\t\tny = core.getHeroLoc('y') + delta.y;\n\t\t\tif (core.getBlockId(nx, ny) == 'lava') {\n\t\t\t\tcore.removeBlock(nx, ny);\n\t\t\t\tsuccess = true;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (core.getBlockId(core.nextX(), core.nextY()) == 'lava') {\n\t\t\tcore.removeBlock(core.nextX(), core.nextY());\n\t\t\tsuccess = true;\n\t\t}\n\t}\n\n\tif (success) {\n\t\tcore.playSound('打开界面');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功', itemId);\n\t} else {\n\t\tcore.playSound('操作失败');\n\t\tcore.drawTip(\"当前无法使用\" + core.material.items[itemId].name, itemId);\n\t\tcore.addItem(itemId, 1);\n\t\treturn;\n\t}\n})();",
"canUseItemEffect": "true" "canUseItemEffect": "true"
}, },
"cross": { "cross": {
@ -368,21 +368,21 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"cls": "tools", "cls": "tools",
"name": "破墙镐", "name": "破墙镐",
"text": "可以破坏勇士面前的墙", "text": "可以破坏勇士面前的墙",
"useItemEffect": "(function () {\n\tvar canBreak = function (x, y) {\n\t\tvar block = core.getBlock(x, y);\n\t\tif (block == null || block.disable) return false;\n\t\treturn block.event.canBreak;\n\t};\n\n\tvar success = false;\n\tvar pickaxeFourDirections = false; // 是否四方向破如果是将其改成true\n\tif (pickaxeFourDirections) {\n\t\t// 四方向破\n\t\tfor (var direction in core.utils.scan) {\n\t\t\tvar delta = core.utils.scan[direction];\n\t\t\tvar nx = core.getHeroLoc('x') + delta.x,\n\t\t\t\tny = core.getHeroLoc('y') + delta.y;\n\t\t\tif (canBreak(nx, ny)) {\n\t\t\t\tcore.removeBlock(nx, ny);\n\t\t\t\tsuccess = true;\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// 仅破当前\n\t\tif (canBreak(core.nextX(), core.nextY())) {\n\t\t\tcore.removeBlock(core.nextX(), core.nextY());\n\t\t\tsuccess = true;\n\t\t}\n\t}\n\n\tif (success) {\n\t\tcore.playSound('破墙镐');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t} else {\n\t\t// 无法使用\n\t\tcore.playSound('操作失败');\n\t\tcore.drawTip(\"当前无法使用\" + core.material.items[itemId].name);\n\t\tcore.addItem(itemId, 1);\n\t\treturn;\n\t}\n})();", "useItemEffect": "(function () {\n\tvar canBreak = function (x, y) {\n\t\tvar block = core.getBlock(x, y);\n\t\tif (block == null || block.disable) return false;\n\t\treturn block.event.canBreak;\n\t};\n\n\tvar success = false;\n\tvar pickaxeFourDirections = false; // 是否多方向破如果是将其改成true\n\tif (pickaxeFourDirections) {\n\t\t// 多方向破\n\t\tfor (var direction in core.utils.scan) { // 多方向破默认四方向如需改成八方向请将这两个scan改为scan2\n\t\t\tvar delta = core.utils.scan[direction];\n\t\t\tvar nx = core.getHeroLoc('x') + delta.x,\n\t\t\t\tny = core.getHeroLoc('y') + delta.y;\n\t\t\tif (canBreak(nx, ny)) {\n\t\t\t\tcore.removeBlock(nx, ny);\n\t\t\t\tsuccess = true;\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// 仅破当前\n\t\tif (canBreak(core.nextX(), core.nextY())) {\n\t\t\tcore.removeBlock(core.nextX(), core.nextY());\n\t\t\tsuccess = true;\n\t\t}\n\t}\n\n\tif (success) {\n\t\tcore.playSound('破墙镐');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功', itemId);\n\t} else {\n\t\t// 无法使用\n\t\tcore.playSound('操作失败');\n\t\tcore.drawTip(\"当前无法使用\" + core.material.items[itemId].name, itemId);\n\t\tcore.addItem(itemId, 1);\n\t\treturn;\n\t}\n})();",
"canUseItemEffect": "true" "canUseItemEffect": "true"
}, },
"icePickaxe": { "icePickaxe": {
"cls": "tools", "cls": "tools",
"name": "破冰镐", "name": "破冰镐",
"text": "可以破坏勇士面前的一堵冰墙", "text": "可以破坏勇士面前的一堵冰墙",
"useItemEffect": "(function () {\n\tcore.openDoor(core.nextX(), core.nextY(), false);\n\tcore.playSound('破冰镐');\n\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n})();", "useItemEffect": "(function () {\n\tcore.drawTip(core.material.items[itemId].name + '使用成功', itemId);\n\tcore.insertAction({ \"type\": \"openDoor\", \"loc\": [\"core.nextX()\", \"core.nextY()\"] });\n})();",
"canUseItemEffect": "(function () {\n\treturn core.getBlockId(core.nextX(), core.nextY()) == 'ice';\n})();" "canUseItemEffect": "(function () {\n\treturn core.getBlockId(core.nextX(), core.nextY()) == 'ice';\n})();"
}, },
"bomb": { "bomb": {
"cls": "tools", "cls": "tools",
"name": "炸弹", "name": "炸弹",
"text": "可以炸掉勇士面前的怪物", "text": "可以炸掉勇士面前的怪物",
"useItemEffect": "(function () {\n\tvar bombList = []; // 炸掉的怪物坐标列表\n\tvar todo = []; // 炸弹后事件\n\tvar money = 0,\n\t\texp = 0; // 炸弹获得的金币和经验\n\n\tvar canBomb = function (x, y) {\n\t\tvar block = core.getBlock(x, y);\n\t\tif (block == null || block.disable || block.event.cls.indexOf('enemy') != 0) return false;\n\t\tvar enemy = core.material.enemys[block.event.id];\n\t\treturn enemy && !enemy.notBomb;\n\t};\n\n\tvar bomb = function (x, y) {\n\t\tif (!canBomb(x, y)) return;\n\t\tbombList.push([x, y]);\n\t\tvar id = core.getBlockId(x, y),\n\t\t\tenemy = core.material.enemys[id];\n\t\tmoney += core.getEnemyValue(enemy, 'money', x, y) || 0;\n\t\texp += core.getEnemyValue(enemy, 'exp', x, y) || 0;\n\t\tcore.push(todo, core.floors[core.status.floorId].afterBattle[x + \",\" + y]);\n\t\tcore.push(todo, enemy.afterBattle);\n\t\tcore.removeBlock(x, y);\n\t}\n\n\t// 如果要四方形可炸把这里的false改成true\n\tif (false) {\n\t\tvar scan = core.utils.scan; // 如果要改成八方向炸可以改成 core.utils.scan2\n\t\tfor (var direction in scan) {\n\t\t\tvar delta = scan[direction];\n\t\t\tbomb(core.getHeroLoc('x') + delta.x, core.getHeroLoc('y') + delta.y);\n\t\t}\n\t} else {\n\t\t// 仅炸当前\n\t\tbomb(core.nextX(), core.nextY());\n\t}\n\n\tif (bombList.length > 0) {\n\t\tcore.playSound('炸弹');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t\t// 取消这里的注释可以炸弹后获得金币和经验\n\t\t// core.status.hero.money += money;\n\t\t// core.status.hero.exp += exp;\n\n\t\t// 取消这里的注释可以炸弹引发战后事件\n\t\t// if (todo.length > 0) core.insertAction(todo);\n\t} else {\n\t\tcore.playSound('操作失败');\n\t\tcore.drawTip('当前无法使用' + core.material.items[itemId].name);\n\t\tcore.addItem(itemId, 1);\n\t\treturn;\n\t}\n\n\t// 炸弹后事件\n\t// 这是一个使用炸弹也能开门的例子\n\t/*\n\tif (core.status.floorId=='xxx' && core.terrainExists(x0,y0,'specialDoor') // 某个楼层,该机关门存在\n\t\t&& !core.enemyExists(x1,y1) && !core.enemyExists(x2,y2)) // 且守门的怪物都不存在\n\t{\n\t\tcore.insertAction([ // 插入事件\n\t\t\t{\"type\": \"openDoor\", \"loc\": [x0,y0]} // 开门\n\t\t])\n\t}\n\t*/\n})();", "useItemEffect": "(function () {\n\tvar bombList = []; // 炸掉的怪物坐标列表\n\tvar todo = []; // 炸弹后事件\n\tvar money = 0,\n\t\texp = 0; // 炸弹获得的金币和经验\n\n\tvar canBomb = function (x, y) {\n\t\tvar block = core.getBlock(x, y);\n\t\tif (block == null || block.disable || block.event.cls.indexOf('enemy') != 0) return false;\n\t\tvar enemy = core.material.enemys[block.event.id];\n\t\treturn enemy && !enemy.notBomb;\n\t};\n\n\tvar bomb = function (x, y) {\n\t\tif (!canBomb(x, y)) return;\n\t\tbombList.push([x, y]);\n\t\tvar id = core.getBlockId(x, y),\n\t\t\tenemy = core.material.enemys[id];\n\t\tmoney += core.getEnemyValue(enemy, 'money', x, y) || 0;\n\t\texp += core.getEnemyValue(enemy, 'exp', x, y) || 0;\n\t\tcore.push(todo, core.floors[core.status.floorId].afterBattle[x + \",\" + y]);\n\t\tcore.push(todo, enemy.afterBattle);\n\t\tcore.removeBlock(x, y);\n\t}\n\n\t// 如果要多方向可炸把这里的false改成true\n\tif (false) {\n\t\tvar scan = core.utils.scan; // 多方向炸时默认四方向,如果要改成八方向炸可以改成 core.utils.scan2\n\t\tfor (var direction in scan) {\n\t\t\tvar delta = scan[direction];\n\t\t\tbomb(core.getHeroLoc('x') + delta.x, core.getHeroLoc('y') + delta.y);\n\t\t}\n\t} else {\n\t\t// 仅炸当前\n\t\tbomb(core.nextX(), core.nextY());\n\t}\n\n\tif (bombList.length == 0) {\n\t\tcore.playSound('操作失败');\n\t\tcore.drawTip('当前无法使用' + core.material.items[itemId].name, itemId);\n\t\tcore.addItem(itemId, 1);\n\t\treturn;\n\t}\n\n\tcore.playSound('炸弹');\n\tcore.drawTip(core.material.items[itemId].name + '使用成功', itemId);\n\n\t// 取消这里的注释可以炸弹后获得金币和经验\n\t// core.status.hero.money += money;\n\t// core.status.hero.exp += exp;\n\n\t// 取消这里的注释可以炸弹引发战后事件\n\t// if (todo.length > 0) core.insertAction(todo);\n\n})();",
"canUseItemEffect": "true" "canUseItemEffect": "true"
}, },
"centerFly": { "centerFly": {
@ -410,35 +410,35 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"cls": "tools", "cls": "tools",
"name": "地震卷轴", "name": "地震卷轴",
"text": "可以破坏当前层的所有墙", "text": "可以破坏当前层的所有墙",
"useItemEffect": "(function () {\n\tvar indexes = [];\n\tfor (var index in core.status.thisMap.blocks) {\n\t\tvar block = core.status.thisMap.blocks[index];\n\t\tif (!block.disable && block.event.canBreak) {\n\t\t\tindexes.push(index);\n\t\t}\n\t}\n\tcore.removeBlockByIndexes(indexes);\n\tcore.drawMap();\n\tcore.playSound('炸弹');\n\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n})();", "useItemEffect": "(function () {\n\tvar indexes = [];\n\tfor (var index in core.status.thisMap.blocks) {\n\t\tvar block = core.status.thisMap.blocks[index];\n\t\tif (!block.disable && block.event.canBreak) {\n\t\t\tindexes.push(index);\n\t\t}\n\t}\n\tcore.removeBlockByIndexes(indexes);\n\tcore.redrawMap();\n\tcore.playSound('炸弹');\n\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n})();",
"canUseItemEffect": "(function () {\n\treturn core.status.thisMap.blocks.filter(function (block) {\n\t\treturn !block.disable && block.event.canBreak;\n\t}).length > 0;\n})();" "canUseItemEffect": "(function () {\n\treturn core.status.thisMap.blocks.filter(function (block) {\n\t\treturn !block.disable && block.event.canBreak;\n\t}).length > 0;\n})();"
}, },
"poisonWine": { "poisonWine": {
"cls": "tools", "cls": "tools",
"name": "解毒药水", "name": "解毒药水",
"text": "可以解除中毒状态", "text": "可以解除中毒状态",
"useItemEffect": "core.triggerDebuff('remove', 'poison');\ncore.playSound('回血');", "useItemEffect": "core.triggerDebuff('remove', 'poison');",
"canUseItemEffect": "core.hasFlag('poison');" "canUseItemEffect": "core.hasFlag('poison');"
}, },
"weakWine": { "weakWine": {
"cls": "tools", "cls": "tools",
"name": "解衰药水", "name": "解衰药水",
"text": "可以解除衰弱状态", "text": "可以解除衰弱状态",
"useItemEffect": "core.triggerDebuff('remove', 'weak');\ncore.playSound('回血');", "useItemEffect": "core.triggerDebuff('remove', 'weak');",
"canUseItemEffect": "core.hasFlag('weak');" "canUseItemEffect": "core.hasFlag('weak');"
}, },
"curseWine": { "curseWine": {
"cls": "tools", "cls": "tools",
"name": "解咒药水", "name": "解咒药水",
"text": "可以解除诅咒状态", "text": "可以解除诅咒状态",
"useItemEffect": "core.triggerDebuff('remove', 'curse');\ncore.playSound('回血');", "useItemEffect": "core.triggerDebuff('remove', 'curse');",
"canUseItemEffect": "core.hasFlag('curse');" "canUseItemEffect": "core.hasFlag('curse');"
}, },
"superWine": { "superWine": {
"cls": "tools", "cls": "tools",
"name": "万能药水", "name": "万能药水",
"text": "可以解除所有不良状态", "text": "可以解除所有不良状态",
"useItemEffect": "core.triggerDebuff('remove', ['poison', 'weak', 'curse']);\ncore.playSound('回血');", "useItemEffect": "core.triggerDebuff('remove', ['poison', 'weak', 'curse']);",
"canUseItemEffect": "(function() {\n\treturn core.hasFlag('poison') || core.hasFlag('weak') || core.hasFlag('curse');\n})();" "canUseItemEffect": "(function() {\n\treturn core.hasFlag('poison') || core.hasFlag('weak') || core.hasFlag('curse');\n})();"
}, },
"hammer": { "hammer": {

View File

@ -5,7 +5,7 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
"3": {"cls":"animates","id":"blueWall","canBreak":true,"animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{}}}, "3": {"cls":"animates","id":"blueWall","canBreak":true,"animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{}}},
"4": {"cls":"animates","id":"star","name":"星空"}, "4": {"cls":"animates","id":"star","name":"星空"},
"5": {"cls":"animates","id":"lava","name":"岩浆"}, "5": {"cls":"animates","id":"lava","name":"岩浆"},
"6": {"cls":"animates","id":"ice","doorInfo":{"time":160,"openSound":"icepickaxe.mp3","closeSound":"door.mp3","keys":{"specialKey":1}},"animate":1}, "6": {"cls":"animates","id":"ice","doorInfo":{"time":160,"openSound":"破冰镐","closeSound":"door.mp3","keys":{"icePickaxe":1}},"animate":1},
"7": {"cls":"terrains","id":"blueShopLeft"}, "7": {"cls":"terrains","id":"blueShopLeft"},
"8": {"cls":"terrains","id":"blueShopRight"}, "8": {"cls":"terrains","id":"blueShopRight"},
"9": {"cls":"terrains","id":"pinkShopLeft"}, "9": {"cls":"terrains","id":"pinkShopLeft"},
@ -118,22 +118,6 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
"168": {"cls":"terrains","id":"flower","canPass":true}, "168": {"cls":"terrains","id":"flower","canPass":true},
"169": {"cls":"terrains","id":"box","trigger":"pushBox"}, "169": {"cls":"terrains","id":"box","trigger":"pushBox"},
"170": {"cls":"terrains","id":"boxed","trigger":"pushBox"}, "170": {"cls":"terrains","id":"boxed","trigger":"pushBox"},
"181": {"cls":"npcs","id":"octopusLeftTop"},
"182": {"cls":"npcs","id":"octopusTop"},
"183": {"cls":"npcs","id":"octopusRightTop"},
"184": {"cls":"npcs","id":"octopusLeft"},
"185": {"cls":"npcs","id":"octopusCenter"},
"186": {"cls":"npcs","id":"octopusRight"},
"187": {"cls":"npcs","id":"octopusLeftBottom"},
"188": {"cls":"npcs","id":"octopusRightBottom"},
"189": {"cls":"npcs","id":"dragonLeftTop"},
"190": {"cls":"npcs","id":"dragonTop"},
"191": {"cls":"npcs","id":"dragonRightTop"},
"192": {"cls":"npcs","id":"dragonLeft"},
"193": {"cls":"npcs","id":"dragonCenter"},
"194": {"cls":"npcs","id":"dragonRight"},
"195": {"cls":"npcs","id":"dragonLeftBottom"},
"196": {"cls":"npcs","id":"dragonRightBottom"},
"201": {"cls":"enemys","id":"greenSlime"}, "201": {"cls":"enemys","id":"greenSlime"},
"202": {"cls":"enemys","id":"redSlime"}, "202": {"cls":"enemys","id":"redSlime"},
"203": {"cls":"enemys","id":"blackSlime"}, "203": {"cls":"enemys","id":"blackSlime"},
@ -235,5 +219,9 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
"323": {"cls":"npc48","id":"tallSpecialDoor","trigger":"openDoor","name":"高机关门","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"specialKey":1}}}, "323": {"cls":"npc48","id":"tallSpecialDoor","trigger":"openDoor","name":"高机关门","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"specialKey":1}}},
"324": {"cls":"npc48","id":"tallSteelDoor","trigger":"openDoor","name":"高铁门","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"steelKey":1}}}, "324": {"cls":"npc48","id":"tallSteelDoor","trigger":"openDoor","name":"高铁门","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"steelKey":1}}},
"325": {"cls":"enemys","id":"keiskeiFairy"}, "325": {"cls":"enemys","id":"keiskeiFairy"},
"326": {"cls":"enemys","id":"tulipFairy"} "326": {"cls":"enemys","id":"tulipFairy"},
"327": {"cls":"enemy48","id":"bearDown"},
"328": {"cls":"enemy48","id":"bearLeft"},
"329": {"cls":"enemy48","id":"bearRight"},
"330": {"cls":"enemy48","id":"bearUp"}
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -112,6 +112,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
return; return;
} }
_shouldProcessKeyUp = true;
// Step 4: 执行标准公共商店 // Step 4: 执行标准公共商店
core.insertAction(this._convertShop(shop)); core.insertAction(this._convertShop(shop));
return true; return true;
@ -120,7 +122,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
////// 将一个全局商店转变成可预览的公共事件 ////// ////// 将一个全局商店转变成可预览的公共事件 //////
this._convertShop = function (shop) { this._convertShop = function (shop) {
return [ return [
{ "type": "function", "function": "function() {core.setFlag('@temp@shop', true);}" }, { "type": "function", "function": "function() {core.addFlag('@temp@shop', 1);}" },
{ {
"type": "while", "type": "while",
"condition": "true", "condition": "true",
@ -154,7 +156,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
} }
] ]
}, },
{ "type": "function", "function": "function() {core.removeFlag('@temp@shop');}" } { "type": "function", "function": "function() {core.addFlag('@temp@shop', -1);}" }
]; ];
} }
@ -221,10 +223,17 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
return null; return null;
} }
var _shouldProcessKeyUp = true;
/// 允许商店X键退出 /// 允许商店X键退出
core.registerAction('keyUp', 'shops', function (keycode) { core.registerAction('keyUp', 'shops', function (keycode) {
if (!core.status.lockControl || !core.hasFlag("@temp@shop") || core.status.event.id != 'action') return false; if (!core.status.lockControl || core.status.event.id != 'action') return false;
if (core.status.event.data.type != 'choices') return false; if ((keycode == 13 || keycode == 32) && !_shouldProcessKeyUp) {
_shouldProcessKeyUp = true;
return true;
}
if (!core.hasFlag("@temp@shop") || core.status.event.data.type != 'choices') return false;
var data = core.status.event.data.current; var data = core.status.event.data.current;
var choices = data.choices; var choices = data.choices;
var topIndex = core.actions._getChoicesTopIndex(choices.length); var topIndex = core.actions._getChoicesTopIndex(choices.length);
@ -232,7 +241,6 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
core.actions._clickAction(core.actions.HSIZE, topIndex + choices.length - 1); core.actions._clickAction(core.actions.HSIZE, topIndex + choices.length - 1);
return true; return true;
} }
if (keycode == 13 || keycode == 32) return true;
return false; return false;
}, 60); }, 60);
@ -245,6 +253,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
var topIndex = core.actions._getChoicesTopIndex(choices.length); var topIndex = core.actions._getChoicesTopIndex(choices.length);
if (keycode == 13 || keycode == 32) { // Space, Enter if (keycode == 13 || keycode == 32) { // Space, Enter
core.actions._clickAction(core.actions.HSIZE, topIndex + core.status.event.selection); core.actions._clickAction(core.actions.HSIZE, topIndex + core.status.event.selection);
_shouldProcessKeyUp = false;
return true; return true;
} }
return false; return false;
@ -438,13 +447,16 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
// 背景层2插入事件层前 // 背景层2插入事件层前
parent.insertBefore(input, child); parent.insertBefore(input, child);
// 不能直接更改背景层2的innerText 所以创建文本节点 // 不能直接更改背景层2的innerText 所以创建文本节点
var txt = document.createTextNode('背景层2'); var txt = document.createTextNode('bg2');
// 插入事件层前(即新插入的背景层2前) // 插入事件层前(即新插入的背景层2前)
parent.insertBefore(txt, child); parent.insertBefore(txt, child);
// 向最后插入前景层2(即插入前景层后) // 向最后插入前景层2(即插入前景层后)
parent.appendChild(input2); parent.appendChild(input2);
var txt2 = document.createTextNode('前景层2'); var txt2 = document.createTextNode('fg2');
parent.appendChild(txt2); parent.appendChild(txt2);
parent.childNodes[2].replaceWith("bg");
parent.childNodes[6].replaceWith("事件");
parent.childNodes[8].replaceWith("fg");
} else { } else {
var input = createCanvasBtn_mobile('bg2'); var input = createCanvasBtn_mobile('bg2');
var input2 = createCanvasBtn_mobile('fg2'); var input2 = createCanvasBtn_mobile('fg2');
@ -1054,6 +1066,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
core.ui.drawTip = _drawTip; core.ui.drawTip = _drawTip;
core.control.playSound = _playSound; core.control.playSound = _playSound;
core.status.route = core.status.route.slice(0, routeLength); core.status.route = core.status.route.slice(0, routeLength);
core.control._bindRoutePush();
// 插入事件:改变角色行走图并进行楼层切换 // 插入事件:改变角色行走图并进行楼层切换
var toFloorId = data.floorId || core.status.floorId; var toFloorId = data.floorId || core.status.floorId;

Binary file not shown.

Binary file not shown.

15
runtime.d.ts vendored
View File

@ -623,9 +623,6 @@ declare class control {
/** 清空剩下的自动寻路列表 */ /** 清空剩下的自动寻路列表 */
clearContinueAutomaticRoute(callback?: () => any): void clearContinueAutomaticRoute(callback?: () => any): void
/** 显示离散的寻路点 */
fillPosWithPoint(pos?: any): void
/** 设置行走的效果动画 */ /** 设置行走的效果动画 */
setHeroMoveInterval(callback?: () => any): void setHeroMoveInterval(callback?: () => any): void
@ -638,8 +635,8 @@ declare class control {
/** 瞬间移动 */ /** 瞬间移动 */
moveDirectly(destX?: any, destY?: any, ignoreSteps?: any): void moveDirectly(destX?: any, destY?: any, ignoreSteps?: any): void
/** 改变勇士的显隐状态 */ /** 改变勇士的不透明度 */
triggerHero(type?: 'show' | 'hide', time?: any, callback?: () => any): void setHeroOpacity(opacity?: number, moveMode?: string, time?: any, callback?: () => any): void
/** 加减画布偏移 */ /** 加减画布偏移 */
addGameCanvasTranslate(x?: number, y?: number): void addGameCanvasTranslate(x?: number, y?: number): void
@ -1235,6 +1232,9 @@ declare class events {
/** 当前是否有未处理完毕的异步事件(不包含动画和音效) */ /** 当前是否有未处理完毕的异步事件(不包含动画和音效) */
hasAsync(): boolean hasAsync(): boolean
/** 立刻停止所有异步事件 */
stopAsync(): void
/** /**
* *
* @param name 4x4的行走图名称 * @param name 4x4的行走图名称
@ -1781,7 +1781,7 @@ declare class maps {
* @param id drawAnimate或drawHeroAnimate返回值 * @param id drawAnimate或drawHeroAnimate返回值
* @param doCallback * @param doCallback
*/ */
stopAnimate(id: number, doCallback?: boolean): void stopAnimate(id?: number, doCallback?: boolean): void
/** 获得当前正在播放的所有指定动画的id列表 */ /** 获得当前正在播放的所有指定动画的id列表 */
getPlayingAnimates(name?: string) : Array<number> getPlayingAnimates(name?: string) : Array<number>
@ -2148,7 +2148,7 @@ declare class ui {
createCanvas(name: string, x: number, y: number, width: number, height: number, zIndex: number): CanvasRenderingContext2D createCanvas(name: string, x: number, y: number, width: number, height: number, zIndex: number): CanvasRenderingContext2D
/** 重新定位一个自定义画布 */ /** 重新定位一个自定义画布 */
relocateCanvas(name: string, x: number, y: number): void relocateCanvas(name: string, x: number, y: number, useDelta: boolean): void
/** 重新设置一个自定义画布的大小 */ /** 重新设置一个自定义画布的大小 */
resizeCanvas(name: string, x: number, y: number): void resizeCanvas(name: string, x: number, y: number): void
@ -2774,7 +2774,6 @@ type core = {
/** 是否是QQ */isQQ: boolean /** 是否是QQ */isQQ: boolean
/** 是否是Chrome */isChrome: boolean /** 是否是Chrome */isChrome: boolean
/** 是否支持复制到剪切板 */supportCopy: boolean /** 是否支持复制到剪切板 */supportCopy: boolean
useLocalForage: boolean,
fileInput: null fileInput: null
/** 是否支持FileReader */fileReader: null /** 是否支持FileReader */fileReader: null

View File

@ -47,11 +47,12 @@ def get_mimetype(path):
def get_file(path): def get_file(path):
if not os.path.isfile(path): if not os.path.isfile(path):
if path.startswith('_saves/'):
return ''
abort(404) abort(404)
return None return None
if not is_sub(path): if not is_sub(path):
abort(403) abort(403)
return None
with open(path, 'rb') as f: with open(path, 'rb') as f:
content = f.read() # str in py2 and bytes in py3 content = f.read() # str in py2 and bytes in py3
return content return content
@ -60,6 +61,32 @@ def get_file(path):
def root(): def root():
return static_file('index.html') return static_file('index.html')
@app.route('/__all_floors__.js', methods=['GET'])
def all_floors():
ids = request.args.get('id', '').split(',')
if len(ids) == 0:
abort(404)
return None
return Response('\n'.join([get_file('project/floors/%s.js' % id) for id in ids]), mimetype = 'text/javascript')
@app.route('/__all_animates__', methods=['GET'])
def all_animates():
ids = request.args.get('id', '').split(',')
if len(ids) == 0:
abort(404)
return None
content = []
for id in ids:
animate = 'project/animates/%s.animate' % id
if os.path.exists(animate):
content.append(get_file(animate))
else: content.append('')
return '@@@~~~###~~~@@@'.join(content)
@app.route('/favicon.ico', methods=['GET'])
def favicon():
return ''
@app.route('/<path:path>', methods=['GET']) @app.route('/<path:path>', methods=['GET'])
def static_file(path): def static_file(path):
if os.path.isdir(path): if os.path.isdir(path):
@ -184,6 +211,10 @@ def deleteFile():
shutil.rmtree(name) shutil.rmtree(name)
return 'Success' return 'Success'
@app.route('/games/upload.php', methods=['POST'])
def upload():
return ''
def port_used(port): def port_used(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = True result = True

Binary file not shown.