diff --git a/_docs/api.md b/_docs/api.md
index b75d25d1..737333e3 100644
--- a/_docs/api.md
+++ b/_docs/api.md
@@ -1222,13 +1222,16 @@ nearStair: fn() -> bool
turnBlock: fn(direction?: string, x?: number, y?: number, floorId?: string)
事件转向
-getMapArray: fn(floorId?: string) -> [[number]]
+getMapArray: fn(floorId?: string, noCache?: bool) -> [[number]]
生成事件层矩阵
例如:core.getMapArray('MT0'); // 生成主塔0层的事件层矩阵,隐藏的图块视为0
floorId: 地图id,不填视为当前地图
showDisable: 可选,true表示隐藏的图块也会被表示出来
返回值:事件层矩阵,注意对其阵元的访问是[y][x]
+getMapNumber: fn(x: number, y: number, floorId?: string, noCache?: bool) -> number
+获得事件层某个点的数字
+
jumpBlock: fn(sx: number, sy: number, ex: number, ey: number, time?: number, keep?: bool, callback?: fn())
跳跃图块;从V2.7开始不再有音效
例如:core.jumpBlock(0, 0, 0, 0); // 令地图左上角的图块原地跳跃半秒,再花半秒淡出
@@ -1358,9 +1361,12 @@ canMoveDirectlyArray: fn(locs?: [[number]])
hideFloorImage: fn(loc?: [number]|[[number]], floorId?: string, callback?: fn())
隐藏一个楼层贴图
-extractBlocks: fn(map?: [[number]], flags?: flags)
+extractBlocks: fn(map?: ?)
根据需求解析出blocks
+extractBlocksForUI: fn(map?: ?, flags?: flags)
+根据需求为UI解析出blocks
+
getBlockId: fn(x: number, y: number, floorId?: string, showDisable?: bool) -> string
判定某个点的图块id
例如:if(core.getBlockId(x1, y1) != 'greenSlime' && core.getBlockId(x2, y2) != 'redSlime') core.openDoor(x3, y3); // 一个简单的机关门事件,打败或炸掉这一对绿头怪和红头怪就开门
@@ -1370,17 +1376,22 @@ floorId: 地图id,不填视为当前地图
showDisable: 隐藏点是否不返回null,true表示不返回null
返回值:图块id,该点无图块则返回null
+getBlockNumber: fn(x: number, y: number, floorId?: string, showDisable?: bool) -> number
+判定某个点的图块数字
+x: 横坐标
+y: 纵坐标
+floorId: 地图id,不填视为当前地图
+showDisable: 隐藏点是否不返回null,true表示不返回null
+返回值:图块数字,该点无图块则返回null
+
loadFloor: fn(floorId?: string, map?: ?)
从文件或存档中加载某个楼层
-generateMovableArray: fn(floorId?: string, x?: number, y?: number, direction?: string)
+generateMovableArray: fn(floorId?: string)
可通行性判定
例如:core.generateMovableArray(); // 判断当前地图主角从各点能向何方向移动
floorId: 地图id,不填视为当前地图
-x: 起点横坐标,不填视为挨个判定
-y: 起点纵坐标,不填视为挨个判定
-direction: 可选,必须和坐标一起使用。填写后将只检查是否可向该方向移动并返回布尔值
-返回值:不设置坐标时为从各点可移动方向的三维数组,设置坐标但不设置方向时为该点可移动方向的一维数组,都设置时为布尔值
+返回值:从各点可移动方向的三维数组
terrainExists: fn(x: number, y: number, id?: string, floorId?: string) -> bool
某个点是否存在(指定的)地形
@@ -1401,7 +1412,7 @@ x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图
-getMapBlocksObj: fn(floorId?: string, showDisable?: bool)
+getMapBlocksObj: fn(floorId?: string, noCache?: bool)
以x,y的形式返回每个点的事件
removeGlobalAnimate: fn(x?: number, y?: number, name?: string)
@@ -1442,10 +1453,10 @@ drawFg: fn(floorId?: string, ctx?: CanvasRenderingContext2D)
floorId: 地图id,不填视为当前地图
ctx: 某画布的ctx,用于绘制缩略图,一般不需要
-getBlock: fn(x: number, y: number, floorId?: string, showDisable?: bool) -> {index: number, block: block}
+getBlock: fn(x: number, y: number, floorId?: string, showDisable?: bool) -> block: block
获得某个点的block
-initBlock: fn(x: number, y: number, id: string|number, addInfo?: bool, eventFloor?: ?, flags?: ?) -> block
+initBlock: fn(x: number, y: number, id: string|number, addInfo?: bool, eventFloor?: ?) -> block
初始化一个图块
addGlobalAnimate: fn(block?: block)
@@ -1486,13 +1497,12 @@ y: 起点纵坐标,不填视为主角当前的
direction: 移动的方向,不填视为主角面对的方向
floorId: 地图id,不填视为当前地图
-drawThumbnail: fn(floorId?: string, blocks?: [block], options?: ?, toDraw?: string|CanvasRenderingContext2D|?)
+drawThumbnail: fn(floorId?: string, blocks?: [block], options?: ?)
绘制缩略图
例如:core.drawThumbnail(); // 绘制当前地图的缩略图
floorId: 地图id,不填视为当前地图
blocks: 一般不需要
options: 额外的绘制项,可选。可以增绘主角位置和朝向、采用不同于游戏中的主角行走图、增绘显伤、提供flags用于存读档
-toDraw: 要绘制到的画布名或画布的ctx或还有其他信息,如起绘坐标、绘制大小、是否绘制全图、截取中心
hideBlockByIndex: fn(index?: number, floorId?: string)
根据图块的索引来隐藏图块
@@ -1846,6 +1856,10 @@ filter: 过滤器,可选,表示data为数组或对象时拷贝哪些项或
recursion: 过滤器是否递归,可选。true表示过滤器也被递归
返回值:拷贝的结果,注意函数将原样返回
+cloneArray: fn(data?: [number]|[[number]]) -> [number]|[[number]]
+深拷贝一个1D或2D数组对象
+例如:core.cloneArray(core.status.thisMap.map)
+
setLocalForage: fn(key: string, value?: ?, successCallback?: fn(), errorCallback?: fn())
往数据库写入一段数据
diff --git a/_docs/personalization.md b/_docs/personalization.md
index c950a2ee..2a552e91 100644
--- a/_docs/personalization.md
+++ b/_docs/personalization.md
@@ -260,9 +260,9 @@ this.statusBar = {
6. 显示内容的设置。在脚本编辑的updateStatusBar函数,可以对该状态栏显示内容进行设置,下面是几个例子。
``` js
// 设置其显示内容为status:speed值;需要在project/data.js中firstData的hero那里新增初始值`"speed": 0`。
-core.statusBar.speed.innerHTML = core.getStatus('speed');
+core.setStatusBarInnerHTML('speed', core.getStatus('speed'));
// 设置其显示内容为flag:speed值,无需额外进行定义。
-core.statusBar.speed.innerHTML = core.getFlag('speed', 0);
+core.setStatusBarInnerHTML('speed', core.getFlag('speed', 0));
```
总的来说不建议这样做,因为 `main.js` 和 `html` 文件不在 `project` 文件夹,会导致随样板更新迁移接档变得困难。
@@ -302,7 +302,7 @@ else {
}
// 设置技能栏
// 可以用flag:skill表示当前开启的技能类型,flag:skillName显示技能名
-core.statusBar.skill.innerHTML = core.getFlag('skillName', '无');
+core.setStatusBarInnerHTML('skill', core.getFlag('skillName', '无'));
```
### 技能的触发
diff --git a/_docs/script.md b/_docs/script.md
index 521fcf9c..c448045a 100644
--- a/_docs/script.md
+++ b/_docs/script.md
@@ -313,9 +313,9 @@ core.events.openShop = function (shopId, needVisited) {
```js
var drawMap = core.maps.drawMap; // 先把原始函数用一个变量记录下来
-core.maps.drawMap = function (floorId, callback) {
+core.maps.drawMap = function (floorId) {
console.log("drawMap..."); // 控制台打出一条信息
- return drawMap.call(core.maps, floorId, callback); // 需要使用`call`来告知this是core.maps
+ return drawMap.call(core.maps, floorId); // 需要使用`call`来告知this是core.maps
}
```
diff --git a/_server/CodeMirror/defs.js b/_server/CodeMirror/defs.js
index 95efd9b0..22b340a8 100644
--- a/_server/CodeMirror/defs.js
+++ b/_server/CodeMirror/defs.js
@@ -1867,6 +1867,30 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!type": "number",
"!doc": "大地图视角纵向偏移量"
},
+ "posX": {
+ "!type": "number",
+ "!doc": "大地图视角横向基准格"
+ },
+ "posY": {
+ "!type": "number",
+ "!doc": "大地图视角纵向基准格"
+ },
+ "v2": {
+ "!type": "bool",
+ "!doc": "是否是新版大地图绘制方式"
+ },
+ "threshold": {
+ "!type": "number",
+ "!doc": "新版大地图绘制方式的分界线"
+ },
+ "extend": {
+ "!type": "number",
+ "!doc": "新版大地图模式下向每一侧额外计算的数量"
+ },
+ "scale": {
+ "!type": "number",
+ "!doc": "缩略图的比例放缩"
+ },
"tempCanvas": {
"!type": "CanvasRenderingContext2D",
"!doc": "临时画布"
@@ -1908,6 +1932,9 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"fgmaps": {
"!doc": "各地图前景层"
},
+ "mapBlockObjs": {
+ "!doc": "以<位置,block>存放的各地图图块信息"
+ },
"boxAnimateObjs": {
"!doc": "(手册和剧情文本的)帧动画对象"
},
@@ -1933,6 +1960,9 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!doc": "每个点的光环缓存"
},
},
+ "damage": {
+ "!doc": "每个点的显伤信息",
+ },
"ctrlDown": {
"!type": "bool",
"!doc": "Ctrl键是否被按下"
@@ -2111,9 +2141,13 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!type": "fn(color?: [number], time?: number, callback?: fn())"
},
"updateDamage": {
- "!doc": "更新地图显伤
例如:core.updateDamage(); // 更新当前地图的显伤,绘制在显伤层(废话)
floorId: 地图id,不填视为当前地图。预览地图时填写
ctx: 绘制到的画布,如果填写了就会画在该画布而不是显伤层",
+ "!doc": "重算并绘制地图显伤
例如:core.updateDamage(); // 更新当前地图的显伤,绘制在显伤层(废话)
floorId: 地图id,不填视为当前地图。预览地图时填写
ctx: 绘制到的画布,如果填写了就会画在该画布而不是显伤层",
"!type": "fn(floorId?: string, ctx?: string|CanvasRenderingContext2D)"
},
+ "drawDamage": {
+ "!doc": "仅绘制地图显伤",
+ "!type": "fn(string|CanvasRenderingContext2D)"
+ },
"nextX": {
"!doc": "获取主角面前第n格的横坐标
例如:core.closeDoor(core.nextX(), core.nextY(), 'yellowDoor', core.turnHero); // 在主角面前关上一扇黄门,然后主角顺时针旋转90°
n: 目标格与主角的距离,面前为正数,背后为负数,脚下为0,不填视为1",
"!type": "fn(n?: number) -> number"
@@ -2694,6 +2728,10 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!doc": "深拷贝一个对象(函数将原样返回)
例如:core.clone(core.status.hero, (name, value) => (name == 'items' || typeof value == 'number'), false); // 深拷贝主角的属性和道具
data: 待拷贝对象
filter: 过滤器,可选,表示data为数组或对象时拷贝哪些项或属性,true表示拷贝
recursion: 过滤器是否递归,可选。true表示过滤器也被递归
返回值:拷贝的结果,注意函数将原样返回",
"!type": "fn(data?: ?, filter?: fn(name: string, value: ?) -> bool, recursion?: bool)"
},
+ "cloneArray": {
+ "!doc": "深拷贝一个1D或2D数组对象
例如:core.cloneArray(core.status.thisMap.map)",
+ "!type": "fn(data?: [number]|[[number]]) -> [number]|[[number]]"
+ },
"setLocalForage": {
"!doc": "往数据库写入一段数据",
"!type": "fn(key: string, value?: ?, successCallback?: fn(), errorCallback?: fn())"
@@ -3025,8 +3063,12 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
},
"getMapArray": {
"!doc": "生成事件层矩阵
例如:core.getMapArray('MT0'); // 生成主塔0层的事件层矩阵,隐藏的图块视为0
floorId: 地图id,不填视为当前地图
showDisable: 可选,true表示隐藏的图块也会被表示出来
返回值:事件层矩阵,注意对其阵元的访问是[y][x]",
- "!type": "fn(floorId?: string) -> [[number]]"
+ "!type": "fn(floorId?: string, noCache?: bool) -> [[number]]"
},
+ "getMapNumber": {
+ "!doc": "获得事件层某个点的数字",
+ "!type": "fn(x: number, y: number, floorId?: string, noCache?: bool) -> number"
+ },
"jumpBlock": {
"!doc": "跳跃图块;从V2.7开始不再有音效
例如:core.jumpBlock(0, 0, 0, 0); // 令地图左上角的图块原地跳跃半秒,再花半秒淡出
sx: 起点的横坐标
sy: 起点的纵坐标
ex: 终点的横坐标
ey: 终点的纵坐标
time: 单步和淡出用时,单位为毫秒。不填视为半秒
keep: 是否不淡出,true表示不淡出
callback: 落地或淡出后的回调函数,可选",
"!type": "fn(sx: number, sy: number, ex: number, ey: number, time?: number, keep?: bool, callback?: fn())"
@@ -3141,19 +3183,27 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
},
"extractBlocks": {
"!doc": "根据需求解析出blocks",
- "!type": "fn(map?: [[number]], flags?: flags)"
+ "!type": "fn(map?: ?)"
+ },
+ "extractBlocksForUI": {
+ "!doc": "根据需求为UI解析出blocks",
+ "!type": "fn(map?: ?, flags?: ?)"
},
"getBlockId": {
"!doc": "判定某个点的图块id
例如:if(core.getBlockId(x1, y1) != 'greenSlime' && core.getBlockId(x2, y2) != 'redSlime') core.openDoor(x3, y3); // 一个简单的机关门事件,打败或炸掉这一对绿头怪和红头怪就开门
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图
showDisable: 隐藏点是否不返回null,true表示不返回null
返回值:图块id,该点无图块则返回null",
"!type": "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> string"
},
+ "getBlockNumber": {
+ "!doc": "判定某个点的图块数字
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图
showDisable: 隐藏点是否不返回null,true表示不返回null
返回值:图块数字,该点无图块则返回null",
+ "!type": "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> number"
+ },
"loadFloor": {
"!doc": "从文件或存档中加载某个楼层",
"!type": "fn(floorId?: string, map?: ?)"
},
"generateMovableArray": {
- "!doc": "可通行性判定
例如:core.generateMovableArray(); // 判断当前地图主角从各点能向何方向移动
floorId: 地图id,不填视为当前地图
x: 起点横坐标,不填视为挨个判定
y: 起点纵坐标,不填视为挨个判定
direction: 可选,必须和坐标一起使用。填写后将只检查是否可向该方向移动并返回布尔值
返回值:不设置坐标时为从各点可移动方向的三维数组,设置坐标但不设置方向时为该点可移动方向的一维数组,都设置时为布尔值",
- "!type": "fn(floorId?: string, x?: number, y?: number, direction?: string)"
+ "!doc": "可通行性判定
例如:core.generateMovableArray(); // 判断当前地图主角从各点能向何方向移动
floorId: 地图id,不填视为当前地图
返回值:从各点可移动方向的三维数组",
+ "!type": "fn(floorId?: string) -> [[[string]]]"
},
"terrainExists": {
"!doc": "某个点是否存在(指定的)地形",
@@ -3173,7 +3223,7 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
},
"getMapBlocksObj": {
"!doc": "以x,y的形式返回每个点的事件",
- "!type": "fn(floorId?: string, showDisable?: bool)"
+ "!type": "fn(floorId?: string, noCache?: bool)"
},
"removeGlobalAnimate": {
"!doc": "删除一个或所有全局动画",
@@ -3205,11 +3255,11 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
},
"getBlock": {
"!doc": "获得某个点的block",
- "!type": "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> {index: number, block: block}"
+ "!type": "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> block"
},
"initBlock": {
"!doc": "初始化一个图块",
- "!type": "fn(x: number, y: number, id: string|number, addInfo?: bool, eventFloor?: ?, flags?: ?) -> block"
+ "!type": "fn(x: number, y: number, id: string|number, addInfo?: bool, eventFloor?: ?) -> block"
},
"addGlobalAnimate": {
"!doc": "添加一个全局动画",
@@ -3240,8 +3290,8 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!type": "fn(x?: number, y?: number, direction?: string, floorId?: string) -> bool"
},
"drawThumbnail": {
- "!doc": "绘制缩略图
例如:core.drawThumbnail(); // 绘制当前地图的缩略图
floorId: 地图id,不填视为当前地图
blocks: 一般不需要
options: 额外的绘制项,可选。可以增绘主角位置和朝向、采用不同于游戏中的主角行走图、增绘显伤、提供flags用于存读档
toDraw: 要绘制到的画布名或画布的ctx或还有其他信息,如起绘坐标、绘制大小、是否绘制全图、截取中心",
- "!type": "fn(floorId?: string, blocks?: [block], options?: ?, toDraw?: string|CanvasRenderingContext2D|?)"
+ "!doc": "绘制缩略图
例如:core.drawThumbnail(); // 绘制当前地图的缩略图
floorId: 地图id,不填视为当前地图
blocks: 一般不需要
options: 绘制信息,可选。可以增绘主角位置和朝向、采用不同于游戏中的主角行走图、增绘显伤、提供flags用于存读档,同时包含要绘制到的画布名或画布的ctx或还有其他信息,如起绘坐标、绘制大小、是否绘制全图、截取中心",
+ "!type": "fn(floorId?: string, blocks?: [block], options?: ?)"
},
"hideBlockByIndex": {
"!doc": "根据图块的索引来隐藏图块",
diff --git a/_server/config.json b/_server/config.json
index 0414c1bc..a2a81f0c 100644
--- a/_server/config.json
+++ b/_server/config.json
@@ -1 +1 @@
-{"lastUsed":[],"foldPerCol":50,"folded":false,"editorLastFloorId":"sample0","disableBlocklyReplace":false,"disableBlocklyExpandCompare":false,"shortcut":{"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0}}
\ No newline at end of file
+{"lastUsed":[],"foldPerCol":50,"folded":false,"editorLastFloorId":"sample0","disableBlocklyReplace":false,"disableBlocklyExpandCompare":false,"shortcut":{"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0},"viewportLoc":[0,0]}
\ No newline at end of file
diff --git a/_server/editor.js b/_server/editor.js
index 6adec79d..45b1b554 100644
--- a/_server/editor.js
+++ b/_server/editor.js
@@ -223,13 +223,17 @@ editor.prototype.init = function (callback) {
for (var one in canvases) {
canvases[one].width = canvases[one].height = core.__PIXELS__;
}
+ core.resetGame(core.firstData.hero, null, core.firstData.floorId, core.cloneArray(core.initStatus.maps));
+ var floorId = editor.config.get('editorLastFloorId', core.status.floorId);
+ if (core.floorIds.indexOf(floorId) < 0) floorId = core.status.floorId;
- core.resetGame(core.firstData.hero, null, core.firstData.floorId, core.clone(core.initStatus.maps));
- var lastFloorId = editor.config.get('editorLastFloorId', core.status.floorId);
- if (core.floorIds.indexOf(lastFloorId) < 0) lastFloorId = core.status.floorId;
- core.changeFloor(lastFloorId, null, {x: 0, y: 0, direction:"up"}, null, function () {
- afterCoreReset();
- }, true);
+ core.status.floorId = floorId;
+ core.resizeMap(floorId);
+ core.clearMap('all');
+ core.generateGroundPattern(floorId);
+ core.extractBlocks(floorId);
+ core.status.thisMap = core.status.maps[floorId];
+ afterCoreReset();
});
}
@@ -239,11 +243,13 @@ editor.prototype.init = function (callback) {
editor.drawInitData(core.icons.icons); // 初始化绘图
editor.game.fetchMapFromCore();
+ editor.pos = {x: 0, y: 0};
editor.updateMap();
editor.buildMark();
+ var viewportLoc = editor.config.get('viewportLoc', []);
+ editor.setViewport(viewportLoc[0] || 0, viewportLoc[1] || 0);
editor.drawEventBlock();
-
- editor.pos = {x: 0, y: 0};
+
editor.mode.loc();
editor.info = editor.ids[editor.indexs[201]];
editor.mode.enemyitem();
@@ -335,20 +341,26 @@ editor.prototype.changeFloor = function (floorId, callback) {
editor.uivalues.preMapData = [];
editor.uivalues.postMapData = [];
editor.uifunctions._extraEvent_bindSpecialDoor_doAction(true);
- core.changeFloor(floorId, null, {"x": 0, "y": 0, "direction": "up"}, null, function () {
- editor.game.fetchMapFromCore();
- editor.updateMap();
- editor_mode.floor();
- editor.drawEventBlock();
- editor.viewportLoc = editor.viewportLoc || {};
- var loc = editor.viewportLoc[floorId] || [], x = loc[0] || 0, y = loc[1] || 0;
- editor.setViewport(x, y);
- editor.uifunctions.unhighlightSaveFloorButton();
+ core.status.floorId = floorId;
+ core.resizeMap(floorId);
+ core.clearMap('all');
+ core.generateGroundPattern(floorId);
+ core.extractBlocks(floorId);
+ core.status.thisMap = core.status.maps[floorId];
- editor.config.set('editorLastFloorId', floorId, function() {
- if (callback) callback();
- });
+ editor.game.fetchMapFromCore();
+ editor.updateMap();
+ editor_mode.floor();
+ editor.drawEventBlock();
+
+ editor.viewportLoc = editor.viewportLoc || {};
+ var loc = editor.viewportLoc[floorId] || [], x = loc[0] || 0, y = loc[1] || 0;
+ editor.setViewport(x, y);
+ editor.uifunctions.unhighlightSaveFloorButton();
+
+ editor.config.set('editorLastFloorId', floorId, function() {
+ if (callback) callback();
});
}
@@ -445,8 +457,7 @@ editor.prototype._updateMap_bigmap = function () {
bm.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
bm.fillStyle = '#000000';
bm.fillRect(0, 0, core.__PIXELS__, core.__PIXELS__);
- core.drawThumbnail(editor.currentFloorId, core.status.thisMap.blocks, null,
- {ctx: bm, all: true});
+ core.drawThumbnail(editor.currentFloorId, null, {ctx: bm, all: true});
var width = editor.currentFloorData.width;
var height = editor.currentFloorData.height;
editor.uivalues.bigmapInfo.top = core.__PIXELS__ * Math.max(0, (1 - height / width) / 2);
@@ -573,6 +584,7 @@ editor.prototype.setViewport=function (x, y) {
editor.viewportLoc = editor.viewportLoc || {};
editor.viewportLoc[editor.currentFloorId] = [core.bigmap.offsetX, core.bigmap.offsetY];
core.control.updateViewport();
+ editor.config.set('viewportLoc', editor.viewportLoc[editor.currentFloorId]);
editor.buildMark();
editor.drawPosSelection();
}
diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js
index 36e122a9..ce76e341 100644
--- a/_server/editor_blockly.js
+++ b/_server/editor_blockly.js
@@ -631,7 +631,6 @@ editor_blockly = function () {
namesObj.allIds = ["this"].concat(core.getAllIconIds());
namesObj.allIconIds = namesObj.allIds.concat(Object.keys(core.statusBar.icons).filter(function (x) {
-
return core.statusBar.icons[x] instanceof Image;
}));
namesObj.allImages = Object.keys(core.material.images.images);
diff --git a/_server/editor_datapanel.js b/_server/editor_datapanel.js
index 3d6a6771..425a6a10 100644
--- a/_server/editor_datapanel.js
+++ b/_server/editor_datapanel.js
@@ -148,8 +148,8 @@ editor_datapanel_wrapper = function (editor) {
}
var width = parseInt(document.getElementById('newMapWidth').value);
var height = parseInt(document.getElementById('newMapHeight').value);
- if (!core.isset(width) || !core.isset(height) || width < core.__SIZE__ || height < core.__SIZE__ || width * height > 1000) {
- printe("新建地图的宽高都不得小于" + core.__SIZE__ + ",且宽高之积不能超过1000");
+ if (!core.isset(width) || !core.isset(height) || width < core.__SIZE__ || height < core.__SIZE__ || width > 128 || height > 128) {
+ printe("新建地图的宽高都不得小于" + core.__SIZE__ + ",且都不得大于128");
return;
}
@@ -217,8 +217,8 @@ editor_datapanel_wrapper = function (editor) {
var width = parseInt(document.getElementById('newMapsWidth').value);
var height = parseInt(document.getElementById('newMapsHeight').value);
- if (!core.isset(width) || !core.isset(height) || width < core.__SIZE__ || height < core.__SIZE__ || width * height > 1000) {
- printe("新建地图的宽高都不得小于" + core.__SIZE__ + ",且宽高之积不能超过1000");
+ if (!core.isset(width) || !core.isset(height) || width < core.__SIZE__ || height < core.__SIZE__ || width > 128 || height > 128) {
+ printe("新建地图的宽高都不得小于" + core.__SIZE__ + ",且都不得大于128");
return;
}
editor_mode.onmode('');
diff --git a/_server/editor_ui.js b/_server/editor_ui.js
index 12ae8e41..ad2f6582 100644
--- a/_server/editor_ui.js
+++ b/_server/editor_ui.js
@@ -375,7 +375,7 @@ editor_ui_wrapper = function (editor) {
// 绘制UI
var background = uievent.elements.selectBackground.value;
if (background == 'thumbnail') {
- core.drawThumbnail(editor.currentFloorId, null, {}, 'uievent');
+ core.drawThumbnail(editor.currentFloorId, null, {ctx: 'uievent'});
}
else {
core.fillRect('uievent', 0, 0, core.__PIXELS__, core.__PIXELS__, background);
@@ -482,11 +482,10 @@ editor_ui_wrapper = function (editor) {
if (redraw) {
core.setAlpha('uievent', 1);
core.clearMap('uievent');
- core.drawThumbnail(uievent.values.floorId, null, null,
- {
- ctx: 'uievent', centerX: uievent.values.left + core.__HALF_SIZE__,
- centerY: uievent.values.top + core.__HALF_SIZE__, all: uievent.values.bigmap
- });
+ 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) {
@@ -857,7 +856,7 @@ editor_ui_wrapper = function (editor) {
var canvas = document.createElement('canvas');
canvas.width = canvas.height = core.__PIXELS__;
canvas.style.position = 'absolute';
- core.drawThumbnail(editor.currentFloorId, null, {}, canvas.getContext('2d'));
+ core.drawThumbnail(editor.currentFloorId, null, {ctx: canvas.getContext('2d')});
dom.appendChild(canvas);
var canvas2 = document.createElement('canvas');
canvas2.style.position = 'absolute';
diff --git a/_server/table/plugins.comment.js b/_server/table/plugins.comment.js
index e19c11ff..c9e37646 100644
--- a/_server/table/plugins.comment.js
+++ b/_server/table/plugins.comment.js
@@ -75,12 +75,6 @@ var plugins_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_range": "typeof(thiseval)=='string' || thiseval==null",
"_data": "物品分类插件"
},
- "smoothCamera": {
- "_leaf": true,
- "_type": "textarea",
- "_range": "typeof(thiseval)=='string' || thiseval==null",
- "_data": "平滑移动镜头"
- },
}
if (obj[key]) return obj[key];
return {
diff --git a/libs/actions.js b/libs/actions.js
index 3ba55a3e..3b9a4923 100644
--- a/libs/actions.js
+++ b/libs/actions.js
@@ -1211,11 +1211,11 @@ actions.prototype._clickViewMaps = function (x, y) {
return;
}
- if (x >= per && x <= this.LAST - per && y <= per - 1 && mh > this.SIZE) {
+ if (x >= per && x <= this.LAST - per && y <= per - 1 && (!core.status.event.data.all && mh > this.SIZE)) {
core.ui.drawMaps(index, cx, cy - 1);
return;
}
- if (x >= per && x <= this.LAST - per && y >= this.SIZE - per && mh > this.SIZE) {
+ if (x >= per && x <= this.LAST - per && y >= this.SIZE - per && (!core.status.event.data.all && mh > this.SIZE)) {
core.ui.drawMaps(index, cx, cy + 1);
return;
}
@@ -2531,7 +2531,7 @@ actions.prototype._clickReplay = function (x, y) {
actions.prototype._clickReplay_fromBeginning = function () {
core.ui.closePanel();
- core.startGame(core.status.hard, core.getFlag('__seed__'), core.clone(core.status.route));
+ core.startGame(core.status.hard, core.getFlag('__seed__'), core.cloneArray(core.status.route));
}
actions.prototype._clickReplay_fromLoad = function () {
diff --git a/libs/control.js b/libs/control.js
index 202c2357..c2507578 100644
--- a/libs/control.js
+++ b/libs/control.js
@@ -143,7 +143,7 @@ control.prototype._animationFrame_globalAnimate = function (timestamp) {
core.maps._drawFloorImages(core.status.floorId, core.canvas.fg, 'fg', core.status.floorAnimateObjs||[], core.status.globalAnimateStatus);
// Global Autotile Animate
- core.status.autotileAnimateObjs.blocks.forEach(function (block) {
+ core.status.autotileAnimateObjs.forEach(function (block) {
core.maps._drawAutotileAnimate(block, core.status.globalAnimateStatus);
});
@@ -770,7 +770,7 @@ control.prototype.tryMoveDirectly = function (destX, destY) {
if (this.nearHero(destX, destY)) return false;
var canMoveArray = core.maps.generateMovableArray();
var dirs = [[destX,destY],[destX-1,destY,"right"],[destX,destY-1,"down"],[destX,destY+1,"up"],[destX+1,destY,"left"]];
- var canMoveDirectlyArray = core.canMoveDirectlyArray(dirs);
+ var canMoveDirectlyArray = core.canMoveDirectlyArray(dirs, canMoveArray);
for (var i = 0; i < dirs.length; ++i) {
var d = dirs[i], dx = d[0], dy = d[1], dir = d[2];
@@ -915,8 +915,13 @@ control.prototype.addGameCanvasTranslate = function (x, y) {
if (id=='ui' || id=='data') continue; // UI层和data层不移动
var offsetX = x, offsetY = y;
if (core.bigmap.canvas.indexOf(id)>=0) {
- offsetX -= core.bigmap.offsetX;
- offsetY -= core.bigmap.offsetY;
+ if (core.bigmap.v2) {
+ offsetX -= (core.bigmap.offsetX - 32 * core.bigmap.posX) + 32;
+ offsetY -= (core.bigmap.offsetY - 32 * core.bigmap.posY) + 32;
+ } else {
+ offsetX -= core.bigmap.offsetX;
+ offsetY -= core.bigmap.offsetY;
+ }
}
core.control.setGameCanvasTranslate(id, offsetX, offsetY);
}
@@ -924,8 +929,24 @@ control.prototype.addGameCanvasTranslate = function (x, y) {
////// 更新视野范围 //////
control.prototype.updateViewport = function() {
+ // 当前是否应该重绘?
+ if (core.bigmap.v2) {
+ if (core.bigmap.offsetX >= core.bigmap.posX * 32 + 32
+ || core.bigmap.offsetX <= core.bigmap.posX * 32 - 32
+ || core.bigmap.offsetY >= core.bigmap.posY * 32 + 32
+ || core.bigmap.offsetY <= core.bigmap.posY * 32 - 32) {
+ core.bigmap.posX = parseInt(core.bigmap.offsetX / 32);
+ core.bigmap.posY = parseInt(core.bigmap.offsetY / 32);
+ core.redrawMap();
+ }
+ } else {
+ core.bigmap.posX = core.bigmap.posY = 0;
+ }
+ var offsetX = core.bigmap.v2 ? -(core.bigmap.offsetX - 32 * core.bigmap.posX) - 32 : -core.bigmap.offsetX;
+ var offsetY = core.bigmap.v2 ? -(core.bigmap.offsetY - 32 * core.bigmap.posY) - 32 : -core.bigmap.offsetY;
+
core.bigmap.canvas.forEach(function(cn){
- core.control.setGameCanvasTranslate(cn,-core.bigmap.offsetX,-core.bigmap.offsetY);
+ core.control.setGameCanvasTranslate(cn, offsetX, offsetY);
});
// ------ 路线
core.relocateCanvas('route', core.status.automaticRoute.offsetX - core.bigmap.offsetX, core.status.automaticRoute.offsetY - core.bigmap.offsetY);
@@ -1095,65 +1116,136 @@ control.prototype._checkBlock_ambush = function (ambush) {
////// 更新全地图显伤 //////
control.prototype.updateDamage = function (floorId, ctx) {
floorId = floorId || core.status.floorId;
- if (!core.isset(floorId) || core.status.gameOver) return;
- if (core.status.gameOver) return;
- var refreshCheckBlock = true;
- if (!core.isset(ctx)) {
- ctx = core.canvas.damage;
- core.clearMap('damage');
- refreshCheckBlock = false;
- }
+ if (!floorId || core.status.gameOver) return;
+ var onMap = ctx == null;
// 没有怪物手册
if (!core.hasItem('book')) return;
- core.setFont(ctx, "bold 11px Arial");
- this._updateDamage_damage(floorId, ctx);
- this._updateDamage_extraDamage(floorId, ctx, refreshCheckBlock);
+ core.status.damage.posX = core.bigmap.posX;
+ core.status.damage.posY = core.bigmap.posY;
+ if (!onMap) {
+ var width = core.floors[floorId].width, height = core.floors[floorId].height;
+ // 地图过大的缩略图不绘制显伤
+ if (width * height > (core.__SIZE__ + 2 * core.bigmap.extend) * (core.__SIZE__ + 2 * core.bigmap.extend)) return;
+ }
+ this._updateDamage_damage(floorId, onMap);
+ this._updateDamage_extraDamage(floorId, onMap);
+ this.drawDamage(ctx);
}
-control.prototype._updateDamage_damage = function (floorId, ctx) {
- core.setTextAlign(ctx, 'left');
+control.prototype._updateDamage_damage = function (floorId, onMap) {
+ core.status.damage.data = [];
+ if (!core.flags.displayEnemyDamage && !core.flags.displayExtraDamage) return;
+
core.extractBlocks(floorId);
core.status.maps[floorId].blocks.forEach(function (block) {
var x = block.x, y = block.y;
+
+ // v2优化,只绘制范围内的部分
+ if (onMap && core.bigmap.v2) {
+ if (x < core.bigmap.posX - core.bigmap.extend || x > core.bigmap.posX + core.__SIZE__ + core.bigmap.extend
+ || y < core.bigmap.posY - core.bigmap.extend || y > core.bigmap.posY + core.__SIZE__ + core.bigmap.extend) {
+ return;
+ }
+ }
+
if (!block.disable && block.event.cls.indexOf('enemy') == 0 && block.event.displayDamage !== false) {
- if (core.flags.displayEnemyDamage) {
+ if (core.flags.displayEnemyDamage) {
var damageString = core.enemys.getDamageString(block.event.id, x, y, floorId);
- var damage = damageString.damage, color = damageString.color;
- core.fillBoldText(ctx, damage, 32*x+1, 32*(y+1)-1, color);
- }
- if (core.flags.displayCritical) {
+ core.status.damage.data.push({text: damageString.damage, px: 32*x+1, py: 32*(y+1)-1, color: damageString.color});
+ }
+ if (core.flags.displayCritical) {
var critical = core.enemys.nextCriticals(block.event.id, 1, x, y, floorId);
critical = core.formatBigNumber((critical[0]||[])[0], true);
if (critical == '???') critical = '?';
- core.fillBoldText(ctx, critical, 32*x+1, 32*(y+1)-11, '#FFFFFF');
- }
+ core.status.damage.data.push({text: critical, px: 32*x+1, py: 32*(y+1)-11, color: '#FFFFFF'});
+ }
}
});
}
-control.prototype._updateDamage_extraDamage = function (floorId, ctx, refresh) {
- core.setTextAlign(ctx, 'center');
- if (refresh) this.updateCheckBlock(floorId);
- if (core.flags.displayExtraDamage) {
- var width = core.floors[floorId].width, height = core.floors[floorId].height;
- for (var x=0;x0) { // 该点伤害
- damage = core.formatBigNumber(damage, true);
- core.fillBoldText(ctx, damage, 32*x+16, 32*(y+1)-14, '#ffaa33');
- }
- else { // 检查捕捉
- if (core.status.checkBlock.ambush[x+","+y]) {
- core.fillBoldText(ctx, '!', 32*x+16, 32*(y+1)-14, '#ffaa33');
- }
+control.prototype._updateDamage_extraDamage = function (floorId, onMap) {
+ core.status.damage.extraData = [];
+ if (!core.flags.displayExtraDamage) return;
+
+ var width = core.floors[floorId].width, height = core.floors[floorId].height;
+ var startX = onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posX - core.bigmap.extend) : 0;
+ var endX = onMap && core.bigmap.v2 ? Math.min(width, core.bigmap.posX + core.__SIZE__ + core.bigmap.extend + 1) : width;
+ var startY = onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posY - core.bigmap.extend) : 0;
+ var endY = onMap && core.bigmap.v2 ? Math.min(height, core.bigmap.posY + core.__SIZE__ + core.bigmap.extend + 1) : height;
+
+ for (var x=startX;x0) { // 该点伤害
+ damage = core.formatBigNumber(damage, true);
+ core.status.damage.extraData.push({text: damage, px: 32*x+16, py: 32*(y+1)-14, color: '#ffaa33'});
+ }
+ else { // 检查捕捉
+ if (core.status.checkBlock.ambush[x+","+y]) {
+ core.status.damage.extraData.push({text: '!', px: 32*x+16, py: 32*(y+1)-14, color: '#ffaa33'});
}
}
}
}
}
+////// 重绘地图显伤 //////
+control.prototype.drawDamage = function (ctx) {
+ if (core.status.gameOver || !core.status.damage) return;
+ var onMap = false;
+ if (ctx == null) {
+ ctx = core.canvas.damage;
+ core.clearMap('damage');
+ onMap = true;
+ }
+
+ if (onMap && core.bigmap.v2) {
+ // 检查是否需要重算...
+ if (Math.abs(core.bigmap.posX - core.status.damage.posX) >= core.bigmap.extend - 1
+ || Math.abs(core.bigmap.posY - core.status.damage.posY) >= core.bigmap.extend - 1) {
+ return this.updateDamage();
+ }
+ }
+ return this._drawDamage_draw(ctx, onMap);
+}
+
+control.prototype._drawDamage_draw = function (ctx, onMap) {
+ 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);
+
+ core.setFont(cacheCtx, "bold 11px Arial");
+ core.setTextAlign(cacheCtx, 'left');
+ core.status.damage.data.forEach(function (one) {
+ var px = one.px, py = one.py;
+ if (onMap && core.bigmap.v2) {
+ px -= core.bigmap.posX * 32;
+ py -= core.bigmap.posY * 32;
+ if (px < -32 * 2 || px > core.__PIXELS__ + 32 || py < -32 || py > core.__PIXELS__ + 32)
+ return;
+ }
+ core.fillBoldText(cacheCtx, one.text, px, py, one.color);
+ });
+
+ core.setTextAlign(cacheCtx, 'center');
+ core.status.damage.extraData.forEach(function (one) {
+ var px = one.px, py = one.py;
+ if (onMap && core.bigmap.v2) {
+ px -= core.bigmap.posX * 32;
+ py -= core.bigmap.posY * 32;
+ if (px < -32 || px > core.__PIXELS__ + 32 || py < -32 || py > core.__PIXELS__ + 32)
+ return;
+ }
+ core.fillBoldText(cacheCtx, one.text, px, py, one.color);
+ });
+
+ core.drawImage(ctx, cacheCtx.canvas, 0, 0);
+}
+
// ------ 录像相关 ------ //
////// 选择录像文件 //////
@@ -1178,7 +1270,7 @@ control.prototype.startReplay = function (list) {
core.status.replay.replaying=true;
core.status.replay.pausing=true;
core.status.replay.speed=1.0;
- core.status.replay.toReplay = core.clone(list);
+ core.status.replay.toReplay = core.cloneArray(list);
core.status.replay.totalList = core.status.route.concat(list);
core.status.replay.steps = 0;
core.status.replay.save = [];
@@ -1433,8 +1525,8 @@ control.prototype._replay_save = function () {
if (core.status.replay.save.length == 30)
core.status.replay.save.shift();
core.status.replay.save.push({"data": core.saveData(), "replay": {
- "totalList": core.clone(core.status.replay.totalList),
- "toReplay": core.clone(core.status.replay.toReplay),
+ "totalList": core.cloneArray(core.status.replay.totalList),
+ "toReplay": core.cloneArray(core.status.replay.toReplay),
"speed": core.status.replay.speed,
"steps": core.status.replay.steps
}});
@@ -2541,8 +2633,12 @@ control.prototype.checkBgm = function() {
////// 清空状态栏 //////
control.prototype.clearStatusBar = function() {
Object.keys(core.statusBar).forEach(function (e) {
- if (core.statusBar[e].innerHTML != null)
+ if (core.statusBar[e].innerHTML != null) {
core.statusBar[e].innerHTML = " ";
+ core.statusBar[e].removeAttribute('_isNumber');
+ core.statusBar[e].removeAttribute('_style');
+ core.statusBar[e].removeAttribute('_value');
+ }
})
core.statusBar.image.book.style.opacity = 0.3;
if (!core.flags.equipboxButton)
@@ -2856,9 +2952,9 @@ control.prototype._resize_canvas = function (obj) {
core.dom.gameDraw.style.right = 0;
core.dom.gameDraw.style.border = obj.border;
// resize bigmap
- core.bigmap.canvas.forEach(function(cn){
- core.canvas[cn].canvas.style.width = core.bigmap.width * 32 * core.domStyle.scale + "px";
- core.canvas[cn].canvas.style.height = core.bigmap.height * 32 * core.domStyle.scale + "px";
+ core.bigmap.canvas.forEach(function (cn) {
+ core.canvas[cn].canvas.style.width = core.canvas[cn].canvas.width * core.domStyle.scale + "px";
+ core.canvas[cn].canvas.style.height = core.canvas[cn].canvas.height * core.domStyle.scale + "px";
});
// resize dynamic canvas
for (var name in core.dymCanvas) {
diff --git a/libs/core.js b/libs/core.js
index bba8f4fc..77baf55e 100644
--- a/libs/core.js
+++ b/libs/core.js
@@ -93,9 +93,16 @@ function core() {
canvas: ["bg", "event", "event2", "fg", "damage"],
offsetX: 0, // in pixel
offsetY: 0,
+ posX: 0, //
+ posY: 0,
width: this.__SIZE__, // map width and height
height: this.__SIZE__,
+ v2: false,
+ threshold: 512,
+ extend: 10,
+ scale: 1.0,
tempCanvas: null, // A temp canvas for drawing
+ cacheCanvas: null, // A cache canvas
}
this.saves = {
"saveIndex": null,
@@ -125,7 +132,14 @@ function core() {
'maps': null,
'bgmaps': {},
'fgmaps': {},
- 'checkBlock': {}, // 显伤伤害
+ 'mapBlockObjs': {},
+ 'checkBlock': {}, // 每个点的阻激夹域信息
+ 'damage': { // 每个点的显伤绘制
+ 'posX': 0,
+ 'posY': 0,
+ 'data': [],
+ 'extraData': [],
+ },
'lockControl': false,
@@ -208,7 +222,7 @@ function core() {
'globalAnimateObjs': [],
'floorAnimateObjs': [],
'boxAnimateObjs': [],
- 'autotileAnimateObjs': {"blocks": [], "map": null, "bgmap": null, "fgmap": null},
+ 'autotileAnimateObjs': [],
"globalAnimateStatus": 0,
'animateObjs': [],
};
@@ -392,6 +406,7 @@ core.prototype._init_others = function () {
core.material.groundCanvas.canvas.width = core.material.groundCanvas.canvas.height = 32;
core.material.groundPattern = core.material.groundCanvas.createPattern(core.material.groundCanvas.canvas, 'repeat');
core.bigmap.tempCanvas = document.createElement('canvas').getContext('2d');
+ core.bigmap.cacheCanvas = document.createElement('canvas').getContext('2d');
core.loadImage("materials", 'fog', function (name, img) { core.animateFrame.weather.fog = img; });
core.loadImage("materials", "cloud", function (name, img) { core.animateFrame.weather.cloud = img; })
core.loadImage("materials", 'keyboard', function (name, img) {core.material.images.keyboard = img; });
diff --git a/libs/enemys.js b/libs/enemys.js
index 978a89e7..bbd05e97 100644
--- a/libs/enemys.js
+++ b/libs/enemys.js
@@ -336,12 +336,11 @@ enemys.prototype.getCurrentEnemys = function (floorId) {
floorId = floorId || core.status.floorId;
var enemys = [], used = {};
core.extractBlocks(floorId);
- var mapBlocks = core.status.maps[floorId].blocks;
- for (var b = 0; b < mapBlocks.length; b++) {
- if (!mapBlocks[b].disable && mapBlocks[b].event.cls.indexOf('enemy') == 0) {
- this._getCurrentEnemys_addEnemy(mapBlocks[b].event.id, enemys, used, floorId);
+ core.status.maps[floorId].blocks.forEach(function (block) {
+ if (!block.disable && block.event.cls.indexOf('enemy') == 0) {
+ this._getCurrentEnemys_addEnemy(block.event.id, enemys, used, floorId);
}
- }
+ }, this);
return this._getCurrentEnemys_sort(enemys);
}
diff --git a/libs/events.js b/libs/events.js
index 92572803..b7e0a2c8 100644
--- a/libs/events.js
+++ b/libs/events.js
@@ -43,7 +43,7 @@ events.prototype.startGame = function (hard, seed, route, callback) {
events.prototype._startGame_start = function (hard, seed, route, callback) {
console.log('开始游戏');
- core.resetGame(core.firstData.hero, hard, null, core.clone(core.initStatus.maps));
+ core.resetGame(core.firstData.hero, hard, null, core.cloneArray(core.initStatus.maps));
core.setHeroLoc('x', -1);
core.setHeroLoc('y', -1);
@@ -335,7 +335,6 @@ events.prototype.trigger = function (x, y, callback) {
var block = core.getBlock(x, y);
if (block == null) return _executeCallback();
- block = block.block;
// 执行该点的脚本
if (block.event.script) {
@@ -363,7 +362,6 @@ events.prototype._trigger_inAction = function (x, y) {
var block = core.getBlock(x, y);
if (block == null) return core.doAction();
- block = block.block;
// 执行该点的脚本
try {
@@ -612,7 +610,7 @@ events.prototype._canGetNextItem = function (direction) {
var nx = core.getHeroLoc('x') + core.utils.scan[direction].x;
var ny = core.getHeroLoc('y') + core.utils.scan[direction].y;
var block = core.getBlock(nx, ny);
- return block != null && block.block.event.trigger == 'getItem';
+ return block != null && block.event.trigger == 'getItem';
}
events.prototype._getNextItem = function (direction, noRoute) {
diff --git a/libs/maps.js b/libs/maps.js
index 52ca529c..86bccf70 100644
--- a/libs/maps.js
+++ b/libs/maps.js
@@ -43,8 +43,7 @@ maps.prototype.loadFloor = function (floorId, map) {
map = {"map": map};
}
var content = {};
- var notCopy = ["firstArrive", "eachArrive", "parallelDo", "map", "bgmap", "fgmap",
- "events", "changeFloor", "afterBattle", "afterGetItem", "afterOpenDoor", "cannotMove"];
+ var notCopy = this._loadFloor_doNotCopy();
for (var name in floor) {
if (notCopy.indexOf(name) == -1 && floor[name] != null)
content[name] = core.clone(floor[name]);
@@ -60,8 +59,15 @@ maps.prototype.loadFloor = function (floorId, map) {
return content;
}
+maps.prototype._loadFloor_doNotCopy = function () {
+ return [
+ "firstArrive", "eachArrive", "blocks", "parallelDo", "map", "bgmap", "fgmap",
+ "events", "changeFloor", "afterBattle", "afterGetItem", "afterOpenDoor", "cannotMove"
+ ];
+}
+
/// 根据需求解析出blocks
-maps.prototype.extractBlocks = function (map, flags) {
+maps.prototype.extractBlocks = function (map) {
map = map || core.status.floorId;
if (typeof map == 'string') map = (core.status.maps||{})[map];
if (!map) return;
@@ -71,16 +77,16 @@ maps.prototype.extractBlocks = function (map, flags) {
return;
}
var floorId = map.floorId;
- map.blocks = this._mapIntoBlocks(this.decompressMap(map.map, floorId), core.floors[floorId], floorId, flags);
+ map.blocks = this._mapIntoBlocks(this.decompressMap(map.map, floorId), core.floors[floorId], floorId);
}
-maps.prototype._mapIntoBlocks = function (map, floor, floorId, flags) {
+maps.prototype._mapIntoBlocks = function (map, floor, floorId) {
var blocks = [];
var mw = core.floors[floorId].width;
var mh = core.floors[floorId].height;
for (var i = 0; i < mh; i++) {
for (var j = 0; j < mw; j++) {
- var block = this.initBlock(j, i, (map[i] || [])[j], true, floor, flags);
+ var block = this.initBlock(j, i, (map[i] || [])[j], true, floor);
if (block.id != 0 || block.event.trigger)
blocks.push(block);
}
@@ -88,6 +94,23 @@ maps.prototype._mapIntoBlocks = function (map, floor, floorId, flags) {
return blocks;
}
+maps.prototype.extractBlocksForUI = function (map, flags) {
+ if (!map || map.blocks) return;
+ if (map.deleted) return map.blocks = [];
+ var floorId = map.floorId;
+ var decompressed = this.decompressMap(map.map, floorId);
+ map.blocks = [];
+ var mw = core.floors[floorId].width;
+ var mh = core.floors[floorId].height;
+ for (var i = 0; i < mh; i++) {
+ for (var j = 0; j < mw; j++) {
+ var number = (decompressed[i] || [])[j] || 0;
+ if (!number || number == 17 || this.isMapBlockDisabled(floorId, j, i, flags)) continue;
+ map.blocks.push(this.initBlock(j, i, number));
+ }
+ }
+}
+
////// 从ID获得数字 //////
maps.prototype.getNumberById = function (id) {
id = this.getIdOfThis(id);
@@ -129,11 +152,10 @@ maps.prototype.getIdOfThis = function (id) {
}
////// 数字和ID的对应关系 //////
-maps.prototype.initBlock = function (x, y, id, addInfo, eventFloor, flags) {
+maps.prototype.initBlock = function (x, y, id, addInfo, eventFloor) {
var disable = null;
if (eventFloor != null) {
- if (flags == null) flags = (core.status.hero || {}).flags || {};
- disable = this.isMapBlockDisabled(eventFloor.floorId, x, y, flags);
+ disable = this.isMapBlockDisabled(eventFloor.floorId, x, y);
}
var block = {'x': x, 'y': y, 'id': id};
if (disable != null) block.disable = disable;
@@ -247,14 +269,9 @@ maps.prototype.compressMap = function (mapArr, floorId) {
maps.prototype._processInvalidMap = function (mapArr, width, height) {
if (mapArr.length == height && mapArr[0].length == width) return mapArr;
-
- var allZeros = [];
- for (var i = 0; i < width; ++i) {
- allZeros.push(0);
- }
var map = [];
for (var i = 0; i < height; ++i) {
- map.push(core.clone(allZeros));
+ map.push(Array(width).fill(0));
}
for (var j = 0; j < height; ++j) {
for (var i = 0; i < width; ++i) {
@@ -302,14 +319,14 @@ maps.prototype.decompressMap = function (mapArr, floorId) {
var mh = core.floors[floorId].height;
var floorMap = this._processInvalidMap(core.floors[floorId].map, mw, mh);
- if (!mapArr) return core.clone(floorMap);
+ if (!mapArr) return core.cloneArray(floorMap);
for (var x = 0; x < mh; x++) {
if (x >= mapArr.length) {
mapArr.push(0);
}
if (mapArr[x] === 0) {
- mapArr[x] = core.clone(floorMap[x]);
+ mapArr[x] = core.cloneArray(floorMap[x]);
}
else {
for (var y = 0; y < mw; y++) {
@@ -342,7 +359,7 @@ maps.prototype.saveMap = function (floorId) {
var map = maps[floorId];
var thisFloor = this._compressFloorData(map, core.floors[floorId]);
if (map.blocks) {
- var mapArr = this.compressMap(this._getMapArrayFromBlocks(map.blocks, map.width, map.height), floorId);
+ var mapArr = this.compressMap(this._getMapArrayFromBlocks(map.blocks, map.width, map.height, true), floorId);
if (mapArr != null) thisFloor.map = mapArr;
}
return thisFloor;
@@ -350,8 +367,9 @@ maps.prototype.saveMap = function (floorId) {
maps.prototype._compressFloorData = function (map, floor) {
var thisFloor = {};
+ var notCopy = this._loadFloor_doNotCopy();
for (var name in map) {
- if (name != 'blocks') {
+ if (notCopy.indexOf(name) == -1) {
var floorData = floor[name];
if (!core.utils.same(map[name], floorData)) {
thisFloor[name] = core.clone(map[name]);
@@ -379,50 +397,71 @@ maps.prototype.resizeMap = function (floorId) {
if (!floorId) return;
core.bigmap.width = core.floors[floorId].width;
core.bigmap.height = core.floors[floorId].height;
- var cwidth = core.bigmap.width * 32;
- var cheight = core.bigmap.height * 32;
+ core.bigmap.posX = core.bigmap.posY = 0;
+
+ core.bigmap.v2 = core.bigmap.width * core.bigmap.height > core.bigmap.threshold;
+ var width = core.bigmap.v2 ? core.__PIXELS__ + 64 : core.bigmap.width * 32;
+ var height = core.bigmap.v2 ? core.__PIXELS__ + 64 : core.bigmap.width * 32;
+
core.bigmap.canvas.forEach(function (cn) {
- core.canvas[cn].canvas.setAttribute("width", cwidth);
- core.canvas[cn].canvas.setAttribute("height", cheight);
- core.canvas[cn].canvas.style.width = cwidth * core.domStyle.scale + "px";
- core.canvas[cn].canvas.style.height = cheight * core.domStyle.scale + "px";
+ core.canvas[cn].canvas.setAttribute("width", width);
+ core.canvas[cn].canvas.setAttribute("height", height);
+ core.canvas[cn].canvas.style.width = width * core.domStyle.scale + "px";
+ core.canvas[cn].canvas.style.height = height * core.domStyle.scale + "px";
+ core.canvas[cn].translate(core.bigmap.v2 ? 32 : 0, core.bigmap.v2 ? 32 : 0);
if (main.mode === 'editor' && editor.isMobile) {
- core.canvas[cn].canvas.style.width = core.bigmap.width * 32 / core.__PIXELS__ * 96 + "vw";
- core.canvas[cn].canvas.style.height = core.bigmap.height * 32 / core.__PIXELS__ * 96 + "vw";
+ core.canvas[cn].canvas.style.width = width / core.__PIXELS__ * 96 + "vw";
+ core.canvas[cn].canvas.style.height = height / core.__PIXELS__ * 96 + "vw";
}
});
}
////// 将当前地图重新变成二维数组形式 //////
-maps.prototype.getMapArray = function (floorId) {
+maps.prototype.getMapArray = function (floorId, noCache) {
floorId = floorId || core.status.floorId;
var map = core.status.maps[floorId];
- if (!map.blocks) return map.map;
- return this._getMapArrayFromBlocks(map.blocks, map.width, map.height);
+ if (!map.blocks || !noCache) return map.map;
+ return map.map = this._getMapArrayFromBlocks(map.blocks, map.width, map.height);
}
-maps.prototype._getMapArrayFromBlocks = function (blockArray, width, height) {
+////// 获得地图上某点的数字
+maps.prototype.getMapNumber = function (x, y, floorId, noCache) {
+ return this.getMapArray(floorId, noCache)[y][x];
+}
+
+maps.prototype._updateMapArray = function (floorId, x, y) {
+ floorId = floorId || core.status.floorId;
+ var map = core.status.maps[floorId];
+ if (!map.blocks) return;
+ if (x == null || y == null) return this.getMapArray(floorId, true);
+ var block = this.getBlock(x, y, floorId, true);
+ if (block == null || block.disable) map.map[y][x] = 0;
+ else map.map[y][x] = block.id;
+}
+
+maps.prototype._getMapArrayFromBlocks = function (blockArray, width, height, showDisable) {
var blocks = [];
- var allzero = [];
- for (var y = 0; y < width; y++) allzero.push(0);
- for (var x = 0; x < height; x++) blocks.push(core.clone(allzero));
+ for (var x = 0; x < height; x++) blocks.push(Array(width).fill(0));
blockArray.forEach(function (block) {
- blocks[block.y][block.x] = block.id;
+ if (showDisable || !block.disable)
+ blocks[block.y][block.x] = block.id;
});
return blocks;
}
////// 以x,y的形式返回每个点的事件 //////
-maps.prototype.getMapBlocksObj = function (floorId, showDisable) {
+maps.prototype.getMapBlocksObj = function (floorId, noCache) {
floorId = floorId || core.status.floorId;
+ if (core.status.mapBlockObjs[floorId] && !noCache)
+ return core.status.mapBlockObjs[floorId];
+
var obj = {};
core.extractBlocks(floorId);
core.status.maps[floorId].blocks.forEach(function (block) {
- if (!block.disable || showDisable)
- obj[block.x + "," + block.y] = block;
+ obj[block.x + "," + block.y] = block;
});
- return obj;
+ return core.status.mapBlockObjs[floorId] = obj;
}
////// 将背景前景层变成二维数组的形式 //////
@@ -435,90 +474,104 @@ maps.prototype._getBgFgMapArray = function (name, floorId, noCache) {
if (!noCache && core.status[name + "maps"][floorId])
return core.status[name + "maps"][floorId];
- var arr = core.clone(core.floors[floorId][name + "map"] || []);
- if (main.mode == 'editor' && !(window.editor && editor.uievent && editor.uievent.isOpen))
- arr = core.clone(editor[name + "map"]) || arr;
- for (var x = 0; x < width; x++) {
- for (var y = 0; y < height; y++) {
- arr[y] = arr[y] || [];
- var flag = [floorId, x, y, name+'_disable'].join('@');
- var vFlag = [floorId, x, y, name+'_value'].join('@');
- if (core.hasFlag(flag)) arr[y][x] = 0;
- else arr[y][x] = core.getFlag(vFlag, arr[y][x] || 0);
- if (main.mode == 'editor') arr[y][x] = arr[y][x].idnum || arr[y][x] || 0;
+ var arr = (main.mode == 'editor' && !(window.editor && editor.uievent && editor.uievent.isOpen))
+ ? core.cloneArray(editor[name + 'map']) : null;
+ if (arr == null)
+ arr = core.cloneArray(core.floors[floorId][name + "map"] || []);
+
+ for (var y = 0; y < height; ++y) {
+ if (arr[y] == null) arr[y] = Array(width).fill(0);
+ }
+ (core.getFlag('__'+name+'v__', {})[floorId] || []).forEach(function (one) {
+ arr[one[1]][one[0]] = one[2] || 0;
+ });
+ (core.getFlag('__'+name+'d__', {})[floorId] || []).forEach(function (one) {
+ arr[one[1]][one[0]] = 0;
+ });
+ if (main.mode == 'editor') {
+ for (var x = 0; x < width; x++) {
+ for (var y = 0; y < height; y++) {
+ arr[y][x] = arr[y][x].idnum || arr[y][x] || 0;
+ }
}
}
if (core.status[name + "maps"])
- core.status[name + "maps"][floorId] = core.clone(arr);
+ core.status[name + "maps"][floorId] = arr;
return arr;
}
-maps.prototype.getBgMapArray = function (floorId, noCache) {
- return this._getBgFgMapArray('bg', floorId, noCache);
+maps.prototype.getBgMapArray = function (floorId) {
+ return this._getBgFgMapArray('bg', floorId);
}
-maps.prototype.getFgMapArray = function (floorId, noCache) {
- return this._getBgFgMapArray('fg', floorId, noCache);
+maps.prototype.getFgMapArray = function (floorId) {
+ return this._getBgFgMapArray('fg', floorId);
}
-maps.prototype._getBgFgNumber = function (name, x, y, floorId, noCache) {
+maps.prototype._getBgFgNumber = function (name, x, y, floorId) {
if (x == null) x = core.getHeroLoc('x');
if (y == null) y = core.getHeroLoc('y');
- return this._getBgFgMapArray(name, floorId, noCache)[y][x];
+ return this._getBgFgMapArray(name, floorId)[y][x];
}
-maps.prototype.getBgNumber = function (x, y, floorId, noCache) {
- return this._getBgFgNumber('bg', x, y, floorId, noCache);
+maps.prototype.getBgNumber = function (x, y, floorId) {
+ return this._getBgFgNumber('bg', x, y, floorId);
}
-maps.prototype.getFgNumber = function (x, y, floorId, noCache) {
- return this._getBgFgNumber('fg', x, y, floorId, noCache);
+maps.prototype.getFgNumber = function (x, y, floorId) {
+ return this._getBgFgNumber('fg', x, y, floorId);
}
// ------ 当前能否朝某方向移动,能否瞬间移动 ------ //
////// 生成全图的当前可移动信息 //////
-maps.prototype.generateMovableArray = function (floorId, x, y, direction) {
+maps.prototype.generateMovableArray = function (floorId) {
floorId = floorId || core.status.floorId;
if (!floorId) return null;
+ var arrays = this._generateMovableArray_arrays(floorId);
+
var width = core.floors[floorId].width, height = core.floors[floorId].height;
- var bgArray = this.getBgMapArray(floorId),
- fgArray = this.getFgMapArray(floorId),
- eventArray = this.getMapArray(floorId);
-
- var generate = function (x, y, direction) {
- if (direction != null) {
- return core.maps._canMoveHero_checkPoint(x, y, direction, floorId, {
- bgArray: bgArray, fgArray: fgArray, eventArray: eventArray
- });
- }
- return ["left", "down", "up", "right"].filter(function (direction) {
- return core.maps._canMoveHero_checkPoint(x, y, direction, floorId, {
- bgArray: bgArray, fgArray: fgArray, eventArray: eventArray
- });
- });
- }
-
- if (x != null && y != null) return generate(x, y, direction);
var array = [];
- for (var x = 0; x < width; x++) {
- array[x] = [];
- for (var y = 0; y < height; y++) {
- array[x][y] = generate(x, y);
+ for (var x = 0; x < width; ++x) {
+ array[x] = Array(height).fill([]);
+ }
+ var v2 = floorId == core.status.floorId && core.bigmap.v2;
+ var startX = v2 ? Math.max(0, core.bigmap.posX - core.bigmap.extend) : 0;
+ var endX = v2 ? Math.min(width, core.bigmap.posX + core.__SIZE__ + core.bigmap.extend + 1) : width;
+ var startY = v2 ? Math.max(0, core.bigmap.posY - core.bigmap.extend) : 0;
+ var endY = v2 ? Math.min(height, core.bigmap.posY + core.__SIZE__ + core.bigmap.extend + 1) : height;
+
+ for (var x = startX; x < endX; x++) {
+ for (var y = startY; y < endY; y++) {
+ array[x][y] = ["left", "down", "up", "right"].filter(function (direction) {
+ return core.maps._canMoveHero_checkPoint(x, y, direction, floorId, arrays);
+ });
}
}
return array;
}
+maps.prototype._generateMovableArray_arrays = function (floorId) {
+ return {
+ bgArray: this.getBgMapArray(floorId),
+ fgArray: this.getFgMapArray(floorId),
+ eventArray: this.getMapArray(floorId)
+ };
+}
+
////// 勇士能否前往某方向 //////
maps.prototype.canMoveHero = function (x, y, direction, floorId) {
if (x == null) x = core.getHeroLoc('x');
if (y == null) y = core.getHeroLoc('y');
direction = direction || core.getHeroLoc('direction');
- return this.generateMovableArray(floorId, x, y, direction);
+ return this._canMoveHero_checkPoint(x, y, direction, floorId);
}
-maps.prototype._canMoveHero_checkPoint = function (x, y, direction, floorId, extraData) {
+maps.prototype._canMoveHero_checkPoint = function (x, y, direction, floorId, arrays) {
+ floorId = floorId || core.status.floorId;
+ if (!floorId) return false;
+ arrays = arrays || this._generateMovableArray_arrays(floorId);
+
// 1. 检查该点 cannotMove
if (core.inArray((core.floors[floorId].cannotMove || {})[x + "," + y], direction))
return false;
@@ -528,19 +581,15 @@ maps.prototype._canMoveHero_checkPoint = function (x, y, direction, floorId, ext
return false;
// 2. 检查该点素材的 cannotOut 和下一个点的 cannotIn
- if (this._canMoveHero_checkCannotInOut([
- extraData.bgArray[y][x], extraData.fgArray[y][x], extraData.eventArray[y][x]
- ], "cannotOut", direction))
+ if (this._canMoveHero_checkCannotInOut(Object.keys(arrays).map(function (name) { return arrays[name][y][x]; }), "cannotOut", direction))
return false;
- if (this._canMoveHero_checkCannotInOut([
- extraData.bgArray[ny][nx], extraData.fgArray[ny][nx], extraData.eventArray[ny][nx]
- ], "cannotIn", direction))
+ if (this._canMoveHero_checkCannotInOut(Object.keys(arrays).map(function (name) { return arrays[name][ny][nx]; }), "cannotIn", direction))
return false;
// 3. 检查是否能进将死的领域
if (floorId == core.status.floorId && !core.flags.canGoDeadZone &&
core.status.hero.hp <= (core.status.checkBlock.damage[nx + "," + ny]||0)
- && extraData.eventArray[ny][nx] == 0)
+ && arrays.eventArray[ny][nx] == 0)
return false;
return true;
@@ -563,7 +612,7 @@ maps.prototype.canMoveDirectly = function (destX, destY) {
return this.canMoveDirectlyArray([[destX,destY]])[0];
}
-maps.prototype.canMoveDirectlyArray = function (locs) {
+maps.prototype.canMoveDirectlyArray = function (locs, canMoveArray) {
var ans = [], number = locs.length;
var fromX = core.getHeroLoc('x'), fromY = core.getHeroLoc('y');
@@ -592,7 +641,7 @@ maps.prototype.canMoveDirectlyArray = function (locs) {
return ans;
}
- return this._canMoveDirectly_bfs(fromX, fromY, locs, number, ans);
+ return this._canMoveDirectly_bfs(fromX, fromY, locs, number, ans, canMoveArray);
}
maps.prototype._canMoveDirectly_checkGlobal = function () {
@@ -611,14 +660,14 @@ maps.prototype._canMoveDirectly_checkStartPoint = function (sx, sy) {
var block = core.getBlock(sx, sy);
if (block != null) {
// 只有起点是传送点才是能无视
- return block.block.event.trigger == 'changeFloor';
+ return block.event.trigger == 'changeFloor';
}
return true;
}
-maps.prototype._canMoveDirectly_bfs = function (sx, sy, locs, number, ans) {
- var canMoveArray = this.generateMovableArray();
- var blocksObj = this.getMapBlocksObj(core.status.floorId);
+maps.prototype._canMoveDirectly_bfs = function (sx, sy, locs, number, ans, canMoveArray) {
+ canMoveArray = canMoveArray || this.generateMovableArray();
+ var blocksObj = this.getMapBlocksObj();
// 滑冰
var bgMap = this.getBgMapArray();
@@ -639,7 +688,8 @@ maps.prototype._canMoveDirectly_bfs = function (sx, sy, locs, number, ans) {
for (var i in ans) {
if (locs[i][0] == nx && locs[i][1] == ny && ans[i] == null) {
// 不可以绿点为终点
- if (blocksObj[nx + "," + ny] && blocksObj[nx + "," + ny].event.trigger) {
+ var block = blocksObj[nx + "," + ny];
+ if (block && !block.disable && block.event.trigger) {
ans[i] = -1;
} else {
ans[i] = visited[nindex];
@@ -660,15 +710,16 @@ maps.prototype._canMoveDirectly_bfs = function (sx, sy, locs, number, ans) {
maps.prototype._canMoveDirectly_checkNextPoint = function (blocksObj, x, y) {
var index = x + "," + y;
+ var block = blocksObj[index];
// 该点是否不可通行或有脚本
- if (blocksObj[index] && (blocksObj[index].event.noPass || blocksObj[index].event.script))
+ if (block && !block.disable && (block.event.noPass || block.event.script))
return false;
// 该点是否是绿点可触发
- if (blocksObj[index] && blocksObj[index].event.trigger) {
- if (blocksObj[index].event.trigger != 'changeFloor') return false;
+ if (block && !block.disable && block.event.trigger) {
+ if (block.event.trigger != 'changeFloor') return false;
var ignore = core.flags.ignoreChangeFloor;
- if (blocksObj[index].event.data && blocksObj[index].event.data.ignoreChangeFloor != null)
- ignore = blocksObj[index].event.data.ignoreChangeFloor;
+ if (block.event.data && block.event.data.ignoreChangeFloor != null)
+ ignore = block.event.data.ignoreChangeFloor;
if (!ignore) return false;
}
// 是否存在阻激夹域伤害
@@ -731,7 +782,7 @@ maps.prototype._automaticRoute_deepAdd = function (x, y, blocks) {
// 判定每个可通行点的损耗值,越高越应该绕路
var deepAdd = 1;
var block = blocks[x+","+y];
- if (block != null){
+ if (block && !block.disable) {
var id = block.event.id;
// 绕过亮灯
if (id == "light") deepAdd += 100;
@@ -740,7 +791,7 @@ maps.prototype._automaticRoute_deepAdd = function (x, y, blocks) {
// 绕过血瓶和绿宝石
if (core.hasFlag('__potionNoRouting__') && (id.endsWith("Potion") || id == 'greenGem')) deepAdd += 100;
// 绕过传送点
- // if (block.block.event.trigger == 'changeFloor') deepAdd+=10;
+ // if (block.event.trigger == 'changeFloor') deepAdd+=10;
}
// 绕过存在伤害的地方
deepAdd += (core.status.checkBlock.damage[x+","+y]||0) * 100;
@@ -752,50 +803,65 @@ maps.prototype._automaticRoute_deepAdd = function (x, y, blocks) {
// -------- 绘制地图,各层图块,楼层贴图,Autotile -------- //
////// 绘制一个图块 //////
-maps.prototype.drawBlock = function (block, animate) {
+maps.prototype.drawBlock = function (block, animate, ctx) {
if (block.event.id == 'none') return;
var redraw = animate != null;
if (!redraw) animate = 0;
var x = block.x, y = block.y;
// --- 在界面外的动画不绘制
- if (redraw && block.event.animate > 1 &&
- (32 * x < core.bigmap.offsetX - 64 || 32 * x > core.bigmap.offsetX + core.__PIXELS__ + 32
- || 32 * y < core.bigmap.offsetY - 64 || 32 * y > core.bigmap.offsetY + core.__PIXELS__ + 32 + 16)) {
- return;
+
+ // 判定是否绘制
+ if (core.bigmap.v2) {
+ var posX = core.bigmap.posX, posY = core.bigmap.posY;
+ if (x < posX - 1 || y < posY - 1 || x > posX + core.__SIZE__ || y > posY + core.__SIZE__ + 1) { // +1 for 48 height
+ return;
+ }
+ } else {
+ if (redraw && block.event.animate > 1 &&
+ (32 * x < core.bigmap.offsetX - 64 || 32 * x > core.bigmap.offsetX + core.__PIXELS__ + 32
+ || 32 * y < core.bigmap.offsetY - 64 || 32 * y > core.bigmap.offsetY + core.__PIXELS__ + 32 + 16)) {
+ return;
+ }
}
var blockInfo = this.getBlockInfo(block);
if (blockInfo == null) return;
if (blockInfo.cls != 'tileset') blockInfo.posX = animate % block.event.animate;
if (!block.name)
- this._drawBlockInfo(blockInfo, block.x, block.y);
+ this._drawBlockInfo(blockInfo, block.x, block.y, ctx);
else
- this._drawBlockInfo_bgfg(blockInfo, block.name, block.x, block.y);
+ this._drawBlockInfo_bgfg(blockInfo, block.name, block.x, block.y, ctx);
}
-maps.prototype._drawBlockInfo = function (blockInfo, x, y) {
+maps.prototype._drawBlockInfo = function (blockInfo, x, y, ctx) {
var image = blockInfo.image, posX = blockInfo.posX, posY = blockInfo.posY, height = blockInfo.height;
+ var px = 32 * x - 32 * core.bigmap.posX;
+ var py = 32 * y - 32 * core.bigmap.posY;
+ if (ctx == null) ctx = 'event';
- core.clearMap('event', x * 32, y * 32, 32, 32);
- core.drawImage('event', image, posX * 32, posY * height + height - 32, 32, 32, x * 32, y * 32, 32, 32);
+ core.clearMap(ctx, px, py, 32, 32);
+ core.drawImage(ctx, image, posX * 32, posY * height + height - 32, 32, 32, px, py, 32, 32);
if (height > 32) {
- core.clearMap('event2', x * 32, y * 32 + 32 - height, 32, height - 32)
- core.drawImage('event2', image, posX * 32, posY * height, 32, height - 32, x * 32, y * 32 + 32 - height, 32, height - 32);
+ core.clearMap('event2', px, py + 32 - height, 32, height - 32)
+ core.drawImage('event2', image, posX * 32, posY * height, 32, height - 32, px, py + 32 - height, 32, height - 32);
}
}
-maps.prototype._drawBlockInfo_bgfg = function (blockInfo, name, x, y) {
+maps.prototype._drawBlockInfo_bgfg = function (blockInfo, name, x, y, ctx) {
var image = blockInfo.image, posX = blockInfo.posX, posY = blockInfo.posY, height = blockInfo.height;
+ var px = 32 * x - 32 * core.bigmap.posX;
+ var py = 32 * y - 32 * core.bigmap.posY;
+ if (ctx == null) ctx = name;
- core.clearMap(name, x * 32, y * 32 + 32 - height, 32, height);
+ core.clearMap(ctx, px, py + 32 - height, 32, height);
if (name == 'bg') {
if (height > 32) {
- core.clearMap('bg', x * 32, y * 32 - 32, 32, 32);
- core.drawImage('bg', core.material.groundCanvas.canvas, x * 32, y * 32 - 32);
+ core.clearMap(ctx, px, py - 32, 32, 32);
+ core.drawImage(ctx, core.material.groundCanvas.canvas, px, py - 32);
}
- core.drawImage('bg', core.material.groundCanvas.canvas, x * 32, y * 32);
+ core.drawImage(ctx, core.material.groundCanvas.canvas, px, py);
}
- core.drawImage(name, image, posX * 32, posY * height, 32, height, x * 32, y * 32 + 32 - height, 32, height);
+ core.drawImage(ctx, image, posX * 32, posY * height, 32, height, px, py + 32 - height, 32, height);
}
////// 生成groundPattern //////
@@ -812,12 +878,9 @@ maps.prototype.generateGroundPattern = function (floorId) {
}
////// 绘制某张地图 //////
-maps.prototype.drawMap = function (floorId, callback) {
+maps.prototype.drawMap = function (floorId) {
floorId = floorId || core.status.floorId;
- if (!floorId) {
- if (callback) callback();
- return;
- }
+ if (!floorId) return;
core.clearMap('all');
this.generateGroundPattern(floorId);
core.status.floorId = floorId;
@@ -831,20 +894,36 @@ maps.prototype.drawMap = function (floorId, callback) {
}
core.drawHero();
core.updateStatusBar();
- if (callback) callback();
}
-maps.prototype._drawMap_drawAll = function (floorId) {
+////// 重绘某张地图 //////
+maps.prototype.redrawMap = function () {
+ core.bigmap.canvas.forEach(function (one) {
+ core.clearMap(one);
+ });
+ this._drawMap_drawAll(null, {redraw: true});
+ core.drawDamage();
+}
+
+maps.prototype._drawMap_drawAll = function (floorId, config) {
floorId = floorId || core.status.floorId;
- this.drawBg(floorId);
+ this.drawBg(floorId, config);
this.drawEvents(floorId);
- this.drawFg(floorId);
+ this.drawFg(floorId, config);
}
maps.prototype._drawMap_drawBlockInfo = function (ctx, block, blockInfo, arr, onMap) {
if (blockInfo == null) return;
+ if (onMap && core.bigmap.v2) {
+ // 判定是否绘制
+ var posX = core.bigmap.posX, posY = core.bigmap.posY;
+ if (block.x < posX - 1 || block.y < posY - 1 || block.x > posX + core.__SIZE__ || block.y > posY + core.__SIZE__ + 1) { // +1 for 48 height
+ return;
+ }
+ }
+
if (blockInfo.cls == 'autotile') { // Autotile单独处理
- this._drawAutotile(ctx, arr, block, 32, 0, 0);
+ this._drawAutotile(ctx, arr, block, 32, 0, 0, 0, onMap);
if (onMap) this.addGlobalAnimate(block);
return;
}
@@ -853,69 +932,155 @@ maps.prototype._drawMap_drawBlockInfo = function (ctx, block, blockInfo, arr, on
core.drawImage(ctx, blockInfo.image, 32 * blockInfo.posX, height * blockInfo.posY, 32, height, 32 * block.x, 32 * block.y + 32 - height, 32, height);
return;
}
- this.drawBlock(block);
+ this.drawBlock(block, null, ctx);
this.addGlobalAnimate(block);
}
////// 绘制背景层 //////
-maps.prototype.drawBg = function (floorId, ctx) {
+// config:绘制的参数,可包含如下项:
+// redraw - 是否是重绘;ctx - 要绘制到的画布(仅限缩略图使用);
+maps.prototype.drawBg = function (floorId, config) {
floorId = floorId || core.status.floorId;
- var onMap = ctx == null;
- if (onMap) {
- ctx = core.canvas.bg;
- core.clearMap(ctx);
+ if (config == null) config = {};
+ if (typeof config == 'string' || config.canvas) config = {ctx: config};
+ config = Object.assign({}, config);
+ if (config.ctx == null) {
+ config.onMap = true;
+ config.ctx = 'bg';
+ core.clearMap('bg');
core.status.floorAnimateObjs = this._getFloorImages(floorId);
}
- core.maps._drawBg_drawBackground(floorId, ctx);
- // ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
- core.maps._drawFloorImages(floorId, ctx, 'bg');
- core.maps._drawBgFgMap(floorId, ctx, 'bg', onMap);
+ var toDrawCtx = core.getContextByName(config.ctx);
+ if (!toDrawCtx) return;
+
+ var cacheCtx = toDrawCtx;
+ if (config.onMap) {
+ cacheCtx = core.bigmap.cacheCanvas;
+ cacheCtx.canvas.width = toDrawCtx.canvas.width;
+ cacheCtx.canvas.height = toDrawCtx.canvas.height;
+ if (core.bigmap.v2) cacheCtx.translate(32, 32);
+ }
+ this._drawBg_draw(floorId, toDrawCtx, cacheCtx, config);
+ if (config.onMap) cacheCtx.translate(0, 0);
}
-maps.prototype._drawBg_drawBackground = function (floorId, ctx) {
- var width = core.floors[floorId].width, height = core.floors[floorId].height;
+maps.prototype._drawBg_draw = function (floorId, toDrawCtx, cacheCtx, config) {
+ config.ctx = cacheCtx;
+ core.maps._drawBg_drawBackground(floorId, config);
+ // ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
+ core.maps._drawFloorImages(floorId, config.ctx, 'bg', null, null, config.onMap);
+ core.maps._drawBgFgMap(floorId, 'bg', config);
+ if (config.onMap) core.drawImage(toDrawCtx, cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
+ config.ctx = toDrawCtx;
+}
+
+maps.prototype._drawBg_drawBackground = function (floorId, config) {
var groundId = (core.status.maps || core.floors)[floorId].defaultGround || "ground";
var groundInfo = core.getBlockInfo(groundId);
+ var onMap = config.onMap;
if (groundInfo != null) {
- for (var i = 0; i < width; i++) {
- for (var j = 0; j < height; j++) {
- core.drawImage(ctx, groundInfo.image, 32 * groundInfo.posX, groundInfo.height * groundInfo.posY, 32, 32, i * 32, j * 32, 32, 32);
- }
- }
+ var start = onMap && core.bigmap.v2 ? -1 : 0;
+ var endX = onMap && core.bigmap.v2 ? core.__SIZE__ + 1 : core.floors[floorId].width;
+ var endY = onMap && core.bigmap.v2 ? core.__SIZE__ + 1 : core.floors[floorId].height;
+
+ var patternCanvas = document.createElement('canvas');
+ patternCanvas.width = patternCanvas.height = 32;
+ var patternCtx = patternCanvas.getContext('2d');
+ core.drawImage(patternCtx, groundInfo.image, 32 * groundInfo.posX, groundInfo.height * groundInfo.posY, 32, 32, 0, 0, 32, 32)
+
+ core.fillRect(config.ctx, 32 * start, 32 * start, 32 * (endX - start), 32 * (endY - start), patternCtx.createPattern(patternCanvas, 'repeat'));
}
}
////// 绘制事件层 //////
-maps.prototype.drawEvents = function (floorId, blocks, ctx) {
+maps.prototype.drawEvents = function (floorId, blocks, config) {
floorId = floorId || core.status.floorId;
- core.extractBlocks(floorId);
- if (!blocks) blocks = core.status.maps[floorId].blocks;
- var arr = this._getMapArrayFromBlocks(blocks, core.floors[floorId].width, core.floors[floorId].height);
- var onMap = ctx == null;
- if (onMap) ctx = core.canvas.event;
+ if (config == null) config = {};
+ if (typeof config == 'string' || config.canvas) config = {ctx: config};
+ config = Object.assign({}, config);
+ if (config.ctx == null) {
+ config.onMap = true;
+ config.ctx = 'event';
+ core.clearMap('event');
+ core.clearMap('event2');
+ }
+ var toDrawCtx = core.getContextByName(config.ctx);
+ if (!toDrawCtx) return;
+
+ var cacheCtx = toDrawCtx;
+ if (config.onMap) {
+ cacheCtx = core.bigmap.cacheCanvas;
+ cacheCtx.canvas.width = toDrawCtx.canvas.width;
+ cacheCtx.canvas.height = toDrawCtx.canvas.height;
+ if (core.bigmap.v2) cacheCtx.translate(32, 32);
+ }
+
+ var arr = null;
+ if (!blocks) {
+ core.extractBlocks(floorId);
+ blocks = core.status.maps[floorId].blocks;
+ arr = this.getMapArray(floorId, !config.redraw)
+ } else {
+ arr = this._getMapArrayFromBlocks(blocks, core.floors[floorId].width, core.floors[floorId].height);
+ }
+
blocks.filter(function (block) {
+ if (config.onMap && core.bigmap.v2) {
+ // 判定是否绘制
+ var posX = core.bigmap.posX, posY = core.bigmap.posY;
+ if (block.x < posX - 1 || block.y < posY - 1 || block.x > posX + core.__SIZE__ || block.y > posY + core.__SIZE__ + 1) { // +1 for 48 height
+ return false;
+ }
+ }
return block.event && !block.disable;
}).forEach(function (block) {
- core.maps._drawMap_drawBlockInfo(ctx, block, core.maps.getBlockInfo(block), arr, onMap);
+ core.maps._drawMap_drawBlockInfo(cacheCtx, block, core.maps.getBlockInfo(block), arr, config.onMap);
});
- if (onMap) core.status.autotileAnimateObjs.map = core.clone(arr);
+
+ if (config.onMap) {
+ core.drawImage(toDrawCtx, cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
+ cacheCtx.translate(0, 0);
+ }
}
////// 绘制前景层 //////
-maps.prototype.drawFg = function (floorId, ctx) {
+// config:绘制的参数,可包含如下项:
+// redraw - 是否是重绘;ctx - 要绘制到的画布(仅限缩略图使用);
+maps.prototype.drawFg = function (floorId, config) {
floorId = floorId || core.status.floorId;
- var onMap = ctx == null;
- if (onMap) {
- ctx = core.canvas.fg;
- core.status.floorAnimateObjs = this._getFloorImages(floorId);
+ if (config == null) config = {};
+ if (typeof config == 'string' || config.canvas) config = {ctx: config};
+ config = Object.assign({}, config);
+ if (config.ctx == null) {
+ config.onMap = true;
+ config.ctx = 'fg';
+ core.clearMap('fg');
}
- // ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
- this._drawFloorImages(floorId, ctx, 'fg');
- this._drawBgFgMap(floorId, ctx, 'fg', onMap);
+ var toDrawCtx = core.getContextByName(config.ctx);
+ if (!toDrawCtx) return;
+
+ var cacheCtx = toDrawCtx;
+ if (config.onMap) {
+ cacheCtx = core.bigmap.cacheCanvas;
+ cacheCtx.canvas.width = toDrawCtx.canvas.width;
+ cacheCtx.canvas.height = toDrawCtx.canvas.height;
+ if (core.bigmap.v2) cacheCtx.translate(32, 32);
+ }
+ this._drawFg_draw(floorId, toDrawCtx, cacheCtx, config);
+ if (config.onMap) cacheCtx.translate(0, 0);
+}
+
+maps.prototype._drawFg_draw = function (floorId, toDrawCtx, cacheCtx, config) {
+ config.ctx = cacheCtx;
+ // ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制前景图块;后绘制的覆盖先绘制的。
+ core.maps._drawFloorImages(floorId, config.ctx, 'fg', null, null, config.onMap);
+ core.maps._drawBgFgMap(floorId, 'fg', config);
+ if (config.onMap) core.drawImage(toDrawCtx, cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
+ config.ctx = toDrawCtx;
}
////// 实际的背景/前景图块的绘制 //////
-maps.prototype._drawBgFgMap = function (floorId, ctx, name, onMap) {
+maps.prototype._drawBgFgMap = function (floorId, name, config) {
floorId = floorId || core.status.floorId;
if (!floorId) return;
var width = core.floors[floorId].width;
@@ -924,14 +1089,20 @@ maps.prototype._drawBgFgMap = function (floorId, ctx, name, onMap) {
if (!core.status[name + "maps"])
core.status[name + "maps"] = {};
- var arr = this._getBgFgMapArray(name, floorId, true);
+ var startX = config.onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posX - 1) : 0;
+ var endX = config.onMap && core.bigmap.v2 ? Math.min(width, core.bigmap.posX + core.__SIZE__ + 1) : width;
+ var startY = config.onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posY - 1) : 0;
+ var endY = config.onMap && core.bigmap.v2 ? Math.min(height, core.bigmap.posY + core.__SIZE__ + 2) : height; // +1 for 48 px
+
+ var arr = this._getBgFgMapArray(name, floorId, !config.redraw);
var eventArr = null;
- if (name == 'fg' && onMap && this._drawBgFgMap_shouldBlurFg()) {
+ if (name == 'fg' && config.onMap && this._drawBgFgMap_shouldBlurFg()) {
eventArr = this.getMapArray(floorId);
}
- for (var x = 0; x < width; x++) {
- for (var y = 0; y < height; y++) {
+ for (var x = startX; x < endX; x++) {
+ for (var y = startY; y < endY; y++) {
+ if (arr[y][x] == 0) continue;
var block = this.initBlock(x, y, arr[y][x], true);
block.name = name;
var blockInfo = this.getBlockInfo(block);
@@ -940,15 +1111,13 @@ maps.prototype._drawBgFgMap = function (floorId, ctx, name, onMap) {
var blur = false, alpha;
if (eventArr != null && eventArr[y][x] != 0) {
blur = true;
- alpha = ctx.globalAlpha;
- ctx.globalAlpha = 0.6;
+ alpha = config.ctx.globalAlpha;
+ config.ctx.globalAlpha = 0.6;
}
- this._drawMap_drawBlockInfo(ctx, block, blockInfo, arr, onMap);
- if (blur) ctx.globalAlpha = alpha;
+ this._drawMap_drawBlockInfo(config.ctx, block, blockInfo, arr, config.onMap);
+ if (blur) config.ctx.globalAlpha = alpha;
}
}
- if (onMap)
- core.status.autotileAnimateObjs[name + "map"] = core.clone(arr);
}
////// 是否应当存在事件时虚化前景层 //////
@@ -957,7 +1126,7 @@ maps.prototype._drawBgFgMap_shouldBlurFg = function () {
}
////// 绘制楼层贴图 //////
-maps.prototype._drawFloorImages = function (floorId, ctx, name, images, currStatus) {
+maps.prototype._drawFloorImages = function (floorId, ctx, name, images, currStatus, onMap) {
floorId = floorId || core.status.floorId;
if (!images) images = this._getFloorImages(floorId);
var redraw = currStatus != null;
@@ -974,7 +1143,7 @@ maps.prototype._drawFloorImages = function (floorId, ctx, name, images, currStat
this._drawFloorImages_gif(image, one.x, one.y);
return;
}
- this._drawFloorImage(ctx, name, one, image, currStatus);
+ this._drawFloorImage(ctx, name, one, image, currStatus, onMap);
}, this);
}
@@ -995,25 +1164,34 @@ maps.prototype._drawFloorImages_gif = function (image, dx, dy) {
return;
}
-maps.prototype._drawFloorImage = function (ctx, name, one, image, currStatus) {
+maps.prototype._drawFloorImage = function (ctx, name, one, image, currStatus, onMap) {
var height = image.height;
var imageName = one.name + (one.reverse||'');
var width = parseInt((one.w == null ? image.width : one.w) / (one.frame || 1));
var height = one.h == null ? image.height : one.h;
var sx = (one.sx || 0) + (currStatus || 0) % (one.frame || 1) * width;
var sy = one.sy || 0;
+ var x = one.x || 0, y = one.y || 0;
+ if (onMap && core.bigmap.v2) {
+ if (x > 32 * core.bigmap.posX + core.__PIXELS__ + 32 || x + width < 32 * core.bigmap.posX - 32
+ || y > 32 * core.bigmap.posX + core.__PIXELS__ + 32 || y + height < 32 * core.bigmap.posY - 32) {
+ return;
+ }
+ x -= 32 * core.bigmap.posX;
+ y -= 32 * core.bigmap.posY;
+ }
if (one.canvas != 'auto' && one.canvas != name) return;
if (one.canvas != 'auto') {
- if (currStatus != null) core.clearMap(ctx, one.x, one.y, width, height);
- core.drawImage(ctx, imageName, sx, sy, width, height, one.x, one.y, width, height);
+ if (currStatus != null) core.clearMap(ctx, x, y, width, height);
+ core.drawImage(ctx, imageName, sx, sy, width, height, x, y, width, height);
} else {
if (name == 'bg') {
- if (currStatus != null) core.clearMap(ctx, one.x, one.y + height - 32, width, 32);
- core.drawImage(ctx, imageName, sx, sy + height - 32, width, 32, one.x, one.y+height - 32, width, 32);
+ if (currStatus != null) core.clearMap(ctx, x, y + height - 32, width, 32);
+ core.drawImage(ctx, imageName, sx, sy + height - 32, width, 32, x, y + height - 32, width, 32);
} else if (name == 'fg') {
- if (currStatus != null) core.clearMap(ctx, one.x, one.y, width, height - 32);
- core.drawImage(ctx, imageName, sx, sy, width, height - 32, one.x, one.y, width, height - 32);
+ if (currStatus != null) core.clearMap(ctx, x, y, width, height - 32);
+ core.drawImage(ctx, imageName, sx, sy, width, height - 32, x, y, width, height - 32);
}
}
}
@@ -1021,7 +1199,7 @@ maps.prototype._drawFloorImage = function (ctx, name, one, image, currStatus) {
////// 绘制Autotile //////
-maps.prototype._drawAutotile = function (ctx, mapArr, block, size, left, top, status) {
+maps.prototype._drawAutotile = function (ctx, mapArr, block, size, left, top, status, onMap) {
var xx = block.x, yy = block.y;
var autotile = core.material.images['autotile'][block.event.id];
status = status || 0;
@@ -1041,27 +1219,32 @@ maps.prototype._drawAutotile = function (ctx, mapArr, block, size, left, top, st
iG[_x][_y] = isGrass(xx + _x, yy + _y);
})});
if(iG[-1][-1] + iG[0][-1] + iG[0][0] + iG[-1][0] == 3 && !iG[-1][-1]){
- this._drawAutotile_render(ctx, xx * size + left, yy * size + top, size, autotile, status, 16);
+ this._drawAutotile_render(ctx, xx * size + left, yy * size + top, size, autotile, status, 16, null, onMap);
done[0] = true;
}
if(iG[0][-1] + iG[1][-1] + iG[1][0] + iG[0][0] == 3 && !iG[1][-1]){
- this._drawAutotile_render(ctx, xx * size + left + size/2, yy * size + top, size, autotile, status, 17);
+ this._drawAutotile_render(ctx, xx * size + left + size/2, yy * size + top, size, autotile, status, 17, null, onMap);
done[1] = true;
}
if(iG[0][0] + iG[1][0] + iG[1][1] + iG[0][1] == 3 && !iG[1][1]){
- this._drawAutotile_render(ctx, xx * size + left+size/2, yy * size + top + size/2, size, autotile, status, 18);
+ this._drawAutotile_render(ctx, xx * size + left+size/2, yy * size + top + size/2, size, autotile, status, 18, null, onMap);
done[3] = true;
}
if(iG[0-1][0] + iG[0][0] + iG[0][1] + iG[-1][1] == 3 && !iG[-1][1]){
- this._drawAutotile_render(ctx, xx * size + left, yy * size + top + size/2, size, autotile, status, 19);
+ this._drawAutotile_render(ctx, xx * size + left, yy * size + top + size/2, size, autotile, status, 19, null, onMap);
done[2] = true;
}
var _id = iG[0][-1] + 2 * iG[-1][0] + 4 * iG[0][1] + 8 * iG[1][0];
- this._drawAutotile_render(ctx, xx * size, yy * size, size, autotile, status, _id, done);
+
+ this._drawAutotile_render(ctx, xx * size, yy * size, size, autotile, status, _id, done, onMap);
}
-maps.prototype._drawAutotile_render = function(canvas, x, y, size, autotile, status, index, done) {
+maps.prototype._drawAutotile_render = function(canvas, x, y, size, autotile, status, index, done, onMap) {
+ if (onMap) {
+ x -= 32 * core.bigmap.posX;
+ y -= 32 * core.bigmap.posY;
+ }
var indexData = [[[96 * status, 0, 32, 32, x, y, size, size],],
[[96 * status, 3 * 32, 16, 32, x, y, size / 2, size],[96 * status + 2 * 32 + 16, 3 * 32, 16, 32, x + size / 2, y, size / 2, size],],
[[96 * status + 2 * 32, 32, 32, 16, x, y, size, size / 2],[96 * status + 2 * 32, 3 * 32 + 16, 32, 16, x, y + size / 2, size, size / 2],],
@@ -1141,7 +1324,7 @@ maps.prototype._drawAutotile_drawBlockByIndex = function (ctx, dx, dy, autotileI
maps.prototype._drawAutotile_getAutotileAroundId = function (currId, x, y, mapArr) {
if (x < 0 || y < 0 || x >= mapArr[0].length || y >= mapArr.length) return 1;
- else return core.material.autotileEdges[currId].indexOf(mapArr[y][x]) >= 0;
+ else return (core.material.autotileEdges[currId] || []).indexOf(mapArr[y][x]) >= 0;
}
maps.prototype._drawAutotile_checkAround = function (x, y, mapArr) {
@@ -1174,20 +1357,27 @@ maps.prototype._drawAutotile_getAutotileIndexs = function (x, y, mapArr, indexAr
maps.prototype._drawAutotileAnimate = function (block, animate) {
var x = block.x, y = block.y;
// ------ 界面外的动画不绘制
- if (32 * x < core.bigmap.offsetX - 64 || 32 * x > core.bigmap.offsetX + core.__PIXELS__ + 32
- || 32 * y < core.bigmap.offsetY - 64 || 32 * y > core.bigmap.offsetY + core.__PIXELS__ + 32 + 16) {
- return;
+ if (core.bigmap.v2) {
+ var posX = core.bigmap.posX, posY = core.bigmap.posY;
+ if (x < posX - 1 || y < posY - 1 || x > posX + core.__SIZE__ || y > posY + core.__SIZE__) {
+ return;
+ }
+ } else {
+ if (32 * x < core.bigmap.offsetX - 64 || 32 * x > core.bigmap.offsetX + core.__PIXELS__ + 32
+ || 32 * y < core.bigmap.offsetY - 64 || 32 * y > core.bigmap.offsetY + core.__PIXELS__ + 32 + 16) {
+ return;
+ }
}
var cv = block.name?core.canvas[block.name]:core.canvas.event;
- cv.clearRect(32 * x, 32 * y, 32, 32);
+ cv.clearRect(32 * x - 32 * core.bigmap.posX, 32 * y - 32 * core.bigmap.posY, 32, 32);
if (block.name) {
if (block.name == 'bg')
- core.drawImage('bg', core.material.groundCanvas.canvas, 32 * x, 32 * y);
- this._drawAutotile(cv, core.status.autotileAnimateObjs[block.name+"map"], block, 32, 0, 0, animate);
+ core.drawImage('bg', core.material.groundCanvas.canvas, 32 * x - 32 * core.bigmap.posX, 32 * y - 32 * core.bigmap.posY);
+ this._drawAutotile(cv, this._getBgFgMapArray(block.name), block, 32, 0, 0, animate, true);
}
else {
- this._drawAutotile(cv, core.status.autotileAnimateObjs.map, block, 32, 0, 0, animate);
+ this._drawAutotile(cv, this.getMapArray(), block, 32, 0, 0, animate, true);
}
}
@@ -1228,31 +1418,54 @@ maps.prototype._makeAutotileEdges = function () {
// 此函数将绘制一个缩略图,floorId为目标floorId,blocks为地图的图块(可为null使用floorId对应默认的)
// options为绘制选项(可为null),包括:
// heroLoc: 勇士位置;heroIcon:勇士图标(默认当前勇士);damage:是否绘制显伤;flags:当前的flags(存读档时使用)
-// toDraw为要绘制到的信息(可为null,或为一个画布名),包括:
// ctx:要绘制到的画布(名);x,y:起点横纵坐标(默认0);size:大小(默认416/480);
// all:是否绘制全图(默认false);centerX,centerY:截取中心(默认为地图正中心)
-maps.prototype.drawThumbnail = function (floorId, blocks, options, toDraw) {
+maps.prototype.drawThumbnail = function (floorId, blocks, options) {
floorId = floorId || core.status.floorId;
if (!floorId) return;
+ options = options || {};
+ if (typeof options == 'string' || options.canvas) options = {ctx: options};
+ var ctx = options.ctx;
// Step1:绘制到tempCanvas上
this._drawThumbnail_drawTempCanvas(floorId, blocks, options);
+ options.ctx = ctx;
// Step2:从tempCanvas绘制到对应的画布上
- this._drawThumbnail_drawToTarget(floorId, toDraw);
+ this._drawThumbnail_drawToTarget(floorId, options);
}
maps.prototype._drawThumbnail_drawTempCanvas = function (floorId, blocks, options) {
- core.extractBlocks(floorId);
- blocks = blocks || core.status.maps[floorId].blocks;
- options = options || {}
-
var width = core.floors[floorId].width;
var height = core.floors[floorId].height;
// 绘制到tempCanvas上面
var tempCanvas = core.bigmap.tempCanvas;
- var tempWidth = width * 32, tempHeight = height * 32;
- tempCanvas.canvas.width = tempWidth;
- tempCanvas.canvas.height = tempHeight;
- tempCanvas.clearRect(0, 0, tempWidth, tempHeight);
+
+ // 如果是大地图模式?
+ if (options.all) {
+ // 计算比例
+ var scale = Math.max(core.__SIZE__ / width, core.__SIZE__ / height);
+ tempCanvas.canvas.width = width * 32 * scale;
+ tempCanvas.canvas.height = height * 32 * scale;
+ tempCanvas.scale(scale, scale);
+ } else if (width * height > core.bigmap.threshold) {
+ options.v2 = true;
+ tempCanvas.canvas.width = core.__PIXELS__;
+ tempCanvas.canvas.height = core.__PIXELS__;
+ var centerX = options.centerX, centerY = options.centerY;
+ if (centerX == null) centerX = Math.floor(width / 2);
+ if (centerY == null) centerY = Math.floor(height / 2);
+ var offsetX = core.clamp(centerX - core.__HALF_SIZE__, 0, width - core.__SIZE__),
+ offsetY = core.clamp(centerY - core.__HALF_SIZE__, 0, height - core.__SIZE__);
+ tempCanvas.translate(-32 * offsetX, -32 * offsetY);
+ } else {
+ options.v2 = false;
+ tempCanvas.canvas.width = width * 32;
+ tempCanvas.canvas.height = height * 32;
+ }
+ options.ctx = tempCanvas;
+
+ // 地图过大的缩略图不绘制显伤
+ if (width * height > (core.__SIZE__ + 2 * core.bigmap.extend) * (core.__SIZE__ + 2 * core.bigmap.extend))
+ options.damage = false;
// --- 暂存 flags
var hasHero = core.status.hero != null, flags = null;
@@ -1262,48 +1475,49 @@ maps.prototype._drawThumbnail_drawTempCanvas = function (floorId, blocks, option
core.status.hero.flags = options.flags;
}
- this._drawThumbnail_realDrawTempCanvas(floorId, blocks, options, tempCanvas);
+ this._drawThumbnail_realDrawTempCanvas(floorId, blocks, options);
// --- 恢复 flags
if (!hasHero) delete core.status.hero;
else if (flags != null) core.status.hero.flags = flags;
+ tempCanvas.setTransform(1, 0, 0, 1, 0, 0);
}
-maps.prototype._drawThumbnail_realDrawTempCanvas = function (floorId, blocks, options, tempCanvas) {
+maps.prototype._drawThumbnail_realDrawTempCanvas = function (floorId, blocks, options) {
// 缩略图:背景
- this.drawBg(floorId, tempCanvas);
+ this.drawBg(floorId, options);
// 缩略图:事件
- this.drawEvents(floorId, blocks, tempCanvas);
+ this.drawEvents(floorId, blocks, options);
// 缩略图:勇士
if (options.heroLoc) {
options.heroIcon = options.heroIcon || core.status.hero.image || 'hero.png';
options.heroIcon = core.getMappedName(options.heroIcon);
var icon = core.material.icons.hero[options.heroLoc.direction];
var height = core.material.images.images[options.heroIcon].height / 4;
- core.drawImage(tempCanvas, core.material.images.images[options.heroIcon], icon.stop * 32, icon.loc * height, 32, height,
+ core.drawImage(options.ctx, core.material.images.images[options.heroIcon], icon.stop * 32, icon.loc * height, 32, height,
32 * options.heroLoc.x, 32 * options.heroLoc.y + 32 - height, 32, height);
}
// 缩略图:前景
- this.drawFg(floorId, tempCanvas);
+ this.drawFg(floorId, options);
// 缩略图:显伤
- if (options.damage)
- core.control.updateDamage(floorId, tempCanvas);
+ if (options.damage && core.hasItem('book')) {
+ core.updateCheckBlock(floorId);
+ core.control.updateDamage(floorId, options.ctx);
+ }
}
-maps.prototype._drawThumbnail_drawToTarget = function (floorId, toDraw) {
- if (toDraw == null) return;
- if (typeof toDraw == 'string' || toDraw.canvas) toDraw = {ctx: toDraw};
- var ctx = core.getContextByName(toDraw.ctx);
+maps.prototype._drawThumbnail_drawToTarget = function (floorId, options) {
+ var ctx = core.getContextByName(options.ctx);
if (ctx == null) return;
- var x = toDraw.x || 0, y = toDraw.y || 0, size = toDraw.size || core.__PIXELS__;
+ var x = options.x || 0, y = options.y || 0, size = options.size || core.__PIXELS__;
var width = core.floors[floorId].width, height = core.floors[floorId].height;
- var centerX = toDraw.centerX, centerY = toDraw.centerY;
+ var centerX = options.centerX, centerY = options.centerY;
if (centerX == null) centerX = Math.floor(width / 2);
if (centerY == null) centerY = Math.floor(height / 2);
- var tempCanvas = core.bigmap.tempCanvas, tempWidth = 32 * width, tempHeight = 32 * height;
+ var tempCanvas = core.bigmap.tempCanvas;
- // core.clearMap(ctx, x, y, size, size);
- if (toDraw.all) {
+ if (options.all) {
+ var tempWidth = tempCanvas.canvas.width, tempHeight = tempCanvas.canvas.height;
// 绘制全景图
if (tempWidth <= tempHeight) {
var realHeight = size, realWidth = realHeight * tempWidth / tempHeight;
@@ -1322,9 +1536,14 @@ maps.prototype._drawThumbnail_drawToTarget = function (floorId, toDraw) {
}
else {
// 只绘制可见窗口
- var offsetX = core.clamp(centerX - core.__HALF_SIZE__, 0, width - core.__SIZE__),
- offsetY = core.clamp(centerY - core.__HALF_SIZE__, 0, height - core.__SIZE__);
- core.drawImage(ctx, tempCanvas.canvas, offsetX * 32, offsetY * 32, core.__PIXELS__, core.__PIXELS__, x, y, size, size);
+ if (options.v2) {
+ core.drawImage(ctx, tempCanvas.canvas, 0, 0, core.__PIXELS__, core.__PIXELS__, x, y, size, size);
+ } else {
+ var offsetX = core.clamp(centerX - core.__HALF_SIZE__, 0, width - core.__SIZE__),
+ offsetY = core.clamp(centerY - core.__HALF_SIZE__, 0, height - core.__SIZE__);
+ core.drawImage(ctx, tempCanvas.canvas, offsetX * 32, offsetY * 32, core.__PIXELS__, core.__PIXELS__, x, y, size, size);
+ }
+
}
}
@@ -1334,21 +1553,21 @@ maps.prototype._drawThumbnail_drawToTarget = function (floorId, toDraw) {
maps.prototype.noPass = function (x, y, floorId) {
var block = core.getBlock(x, y, floorId);
if (block == null) return false;
- return block.block.event.noPass;
+ return block.event.noPass;
}
////// 某个点是否存在NPC //////
maps.prototype.npcExists = function (x, y, floorId) {
var block = this.getBlock(x, y, floorId);
if (block == null) return false;
- return block.block.event.cls.indexOf('npc') == 0;
+ return block.event.cls.indexOf('npc') == 0;
}
////// 某个点是否存在(指定的)地形 //////
maps.prototype.terrainExists = function (x, y, id, floorId) {
var block = this.getBlock(x, y, floorId);
if (block == null) return false;
- return block.block.event.cls == 'terrains' && (id ? block.block.event.id == id : true);
+ return block.event.cls == 'terrains' && (id ? block.event.id == id : true);
}
////// 某个点是否存在楼梯 //////
@@ -1371,7 +1590,7 @@ maps.prototype.nearStair = function () {
maps.prototype.enemyExists = function (x, y, id, floorId) {
var block = this.getBlock(x, y, floorId);
if (block == null) return false;
- return block.block.event.cls.indexOf('enemy') == 0 && (id ? block.block.event.id == id : true);
+ return block.event.cls.indexOf('enemy') == 0 && (id ? block.event.id == id : true);
}
////// 获得某个点的block //////
@@ -1379,26 +1598,28 @@ maps.prototype.getBlock = function (x, y, floorId, showDisable) {
floorId = floorId || core.status.floorId;
if (!floorId) return null;
core.extractBlocks(floorId);
- var blocks = core.status.maps[floorId].blocks;
- for (var n = 0; n < blocks.length; n++) {
- if (blocks[n].x == x && blocks[n].y == y) {
- if (!showDisable && blocks[n].disable) return null;
- return {"index": n, "block": blocks[n]};
- }
- }
+ var blockObjs = this.getMapBlocksObj(floorId);
+ var block = blockObjs[x + "," + y];
+ if (block && (showDisable || !block.disable)) return block;
return null;
}
////// 获得某个点的blockId //////
maps.prototype.getBlockId = function (x, y, floorId, showDisable) {
var block = core.getBlock(x, y, floorId, showDisable);
- return block == null ? null : block.block.event.id;
+ return block == null ? null : block.event.id;
+}
+
+////// 获得某个点的数字 //////
+maps.prototype.getBlockNumber = function (x, y, floorId, showDisable) {
+ var block = core.getBlock(x, y, floorId, showDisable);
+ return block == null ? null : block.id;
}
////// 获得某个点的blockCls //////
maps.prototype.getBlockCls = function (x, y, floorId, showDisable) {
var block = core.getBlock(x, y, floorId, showDisable);
- return block == null ? null : block.block.event.cls;
+ return block == null ? null : block.event.cls;
}
////// 获得某个图块或素材的信息,包括 ID,cls,图片,坐标,faceIds 等等 //////
@@ -1460,7 +1681,7 @@ maps.prototype.searchBlock = function (id, floorId, showDisable) {
for (var i = 0; i < core.status.maps[floorId].blocks.length; ++i) {
var block = core.status.maps[floorId].blocks[i];
if ((showDisable || !block.disable) && (core.matchWildcard(id, block.event.id) || core.matchRegex(id, block.event.id))) {
- result.push({floorId: floorId, index: i, block: block, x: block.x, y: block.y});
+ result.push({floorId: floorId, x: block.x, y: block.y, block: block});
}
}
return result;
@@ -1474,7 +1695,6 @@ maps.prototype.showBlock = function (x, y, floorId) {
if (!floorId) return;
var block = core.getBlock(x, y, floorId, true);
if (block == null) return; // 不存在
- block = block.block;
// 本身是禁用事件,启用之
if (block.disable) {
block.disable = false;
@@ -1500,10 +1720,12 @@ maps.prototype.hideBlock = function (x, y, floorId) {
var block = core.getBlock(x, y, floorId, true);
if (block == null) return; // 不存在
- core.hideBlockByIndex(block.index, floorId);
+ block.disable = true;
+ core.setMapBlockDisabled(floorId, block.x, block.y, true);
+ this._updateMapArray(floorId, block.x, block.y);
// 删除动画,清除地图
- this._removeBlockFromMap(floorId, block.block);
+ this._removeBlockFromMap(floorId, block);
}
////// 根据图块的索引来隐藏图块 //////
@@ -1514,6 +1736,7 @@ maps.prototype.hideBlockByIndex = function (index, floorId) {
var blocks = core.status.maps[floorId].blocks, block = blocks[index];
block.disable = true;
core.setMapBlockDisabled(floorId, block.x, block.y, true);
+ this._updateMapArray(floorId, block.x, block.y);
}
////// 一次性隐藏多个block //////
@@ -1531,11 +1754,13 @@ maps.prototype._removeBlockFromMap = function (floorId, block) {
core.drawMap();
} else {
var x = block.x, y = block.y;
+ var px = 32 * x - core.bigmap.posX * 32;
+ var py = 32 * y - core.bigmap.posY * 32;
core.removeGlobalAnimate(x, y);
- core.clearMap('event', x * 32, y * 32, 32, 32);
+ core.clearMap('event', px, py, 32, 32);
var height = block.event.height || 32;
if (height > 32)
- core.clearMap('event2', x * 32, y * 32 + 32 - height, 32, height - 32);
+ core.clearMap('event2', px, py + 32 - height, 32, height - 32);
core.updateStatusBar();
}
}
@@ -1545,14 +1770,15 @@ maps.prototype.removeBlock = function (x, y, floorId) {
floorId = floorId || core.status.floorId;
if (!floorId) return false;
- var block = core.getBlock(x, y, floorId, true);
- if (block == null) return false; // 不存在
-
- core.removeBlockByIndex(block.index, floorId);
-
- // 删除动画,清除地图
- this._removeBlockFromMap(floorId, block.block);
- return true;
+ for (var i in core.status.maps[floorId].blocks) {
+ var block = core.status.maps[floorId].blocks[i];
+ if (block.x == x && block.y == y) {
+ this.removeBlockByIndex(i, floorId);
+ this._removeBlockFromMap(floorId, block);
+ return true;
+ }
+ }
+ return false;
}
////// 根据block的索引(尽可能)删除该块 //////
@@ -1562,7 +1788,10 @@ maps.prototype.removeBlockByIndex = function (index, floorId) {
core.extractBlocks(floorId);
var blocks = core.status.maps[floorId].blocks, block = blocks[index];
blocks.splice(index, 1);
+ if (core.status.mapBlockObjs[floorId])
+ delete core.status.mapBlockObjs[floorId][block.x+","+block.y];
core.setMapBlockDisabled(floorId, block.x, block.y, true);
+ this._updateMapArray(floorId, block.x, block.y);
}
////// 一次性删除多个block //////
@@ -1587,27 +1816,30 @@ maps.prototype.hideBgFgMap = function (name, loc, floorId, callback) {
////// 设置前景/背景地图的显示状态 //////
maps.prototype._triggerBgFgMap = function (type, name, loc, floorId, callback) {
if (type != 'show') type = 'hide';
- if (name != 'fg') name = 'bg';
+ if (!name || (!name.startsWith('bg') && !name.startsWith('fg'))) return;
if (typeof loc[0] == 'number' && typeof loc[1] == 'number')
loc = [loc];
floorId = floorId || core.status.floorId;
if (!floorId) return;
if (loc.length == 0) return;
+ var disabled = core.getFlag('__'+name+'d__', {});
+ disabled[floorId] = disabled[floorId] || [];
loc.forEach(function (t) {
- var x = t[0], y = t[1];
- var flag = [floorId, x, y, name+"_disable"].join('@');
- if (type == 'hide') core.setFlag(flag, true);
- else core.removeFlag(flag);
+ if (type == 'hide') {
+ disabled[floorId].push([t[0], t[1]]);
+ } else {
+ disabled[floorId] = disabled[floorId].filter(function (one) { return one[0] != t[0] || one[1] != t[1]});
+ }
})
+ core.setFlag('__'+name+'d__', disabled);
+
core.status[name + "maps"][floorId] = null;
if (floorId == core.status.floorId) {
- core.drawMap(floorId, callback);
- }
- else {
- if (callback) callback();
+ core.drawMap(floorId);
}
+ if (callback) callback();
}
////// 显示一个楼层贴图 //////
@@ -1637,11 +1869,9 @@ maps.prototype._triggerFloorImage = function (type, loc, floorId, callback) {
})
if (floorId == core.status.floorId) {
- core.drawMap(floorId, callback);
- }
- else {
- if (callback) callback();
+ core.drawMap(floorId);
}
+ if (callback) callback();
}
////// 改变图块 //////
@@ -1661,17 +1891,20 @@ maps.prototype.setBlock = function (number, x, y, floorId) {
return;
}
var originBlock = core.getBlock(x, y, floorId, true);
- var originEvent = originBlock == null ? null : originBlock.block.event;
+ var originEvent = originBlock == null ? null : originBlock.event;
if (originBlock == null) {
core.status.maps[floorId].blocks.push(block);
+ if (core.status.mapBlockObjs[floorId])
+ core.status.mapBlockObjs[floorId][block.x+","+block.y] = block;
core.setMapBlockDisabled(floorId, block.x, block.y, false);
delete block.disable;
}
else {
- originBlock.block.id = number;
- originBlock.block.event = block.event;
- block = originBlock.block;
+ originBlock.id = number;
+ originBlock.event = block.event;
+ block = originBlock;
}
+ this._updateMapArray(floorId, x, y);
if (floorId == core.status.floorId) {
// 有任何一个是autotile直接重绘地图
if ((originEvent != null && originEvent.cls == 'autotile') || block.event.cls == 'autotile') {
@@ -1706,7 +1939,7 @@ maps.prototype.animateSetBlock = function (number, x, y, floorId, time, callback
var block = this.initBlock(x, y, number, true, core.floors[floorId]);
// 如果原本是启用的
- if (originBlock != null && !originBlock.block.disable) {
+ if (originBlock != null && !originBlock.disable) {
return this._animateSetBlock_originEnabled(block, number, x, y, floorId, time, callback);
}
@@ -1716,7 +1949,7 @@ maps.prototype.animateSetBlock = function (number, x, y, floorId, time, callback
}
// 如果原本存在且禁用;应当直接设置,没有动画
- if (originBlock != null && originBlock.block.disable) {
+ if (originBlock != null && originBlock.disable) {
return this._animateSetBlock_originDisabled(number, x, y, floorId, callback);
}
if (callback) callback();
@@ -1823,8 +2056,10 @@ maps.prototype.replaceBlock = function (fromNumber, toNumber, floorId) {
for (var one in toBlock.event) {
block.event[one] = core.clone(toBlock.event[one]);
}
+ this._updateMapArray(floorId, block.x, block.y);
}
- });
+ }, this);
+ if (floorId == core.status.floorId) core.drawMap();
}
////// 改变前景背景的图块 //////
@@ -1832,19 +2067,23 @@ maps.prototype.setBgFgBlock = function (name, number, x, y, floorId) {
floorId = floorId || core.status.floorId;
if (!floorId || number == null || x == null || y == null) return;
if (x < 0 || x >= core.floors[floorId].width || y < 0 || y >= core.floors[floorId].height) return;
- if (name != 'bg' && name != 'fg') return;
+ if (!name || (!name.startsWith('bg') && !name.startsWith('fg'))) return;
+
if (typeof number == 'string') {
if (/^\d+$/.test(number)) number = parseInt(number);
else number = core.getNumberById(number);
}
- var vFlag = [floorId, x, y, name + "_value"].join('@');
- core.setFlag(vFlag, number);
+ var values = core.getFlag('__'+name+'v__', {});
+ values[floorId] = (values[floorId] || []).filter(function (one) { return one[0] != x || one[1] != y });
+ values[floorId].push([x,y,number]);
+ core.setFlag('__'+name+'v__', values);
+
core.status[name + "maps"][floorId] = null;
if (floorId == core.status.floorId){
core.clearMap(name);
- if (name=='bg') core.drawBg(floorId);
+ if (name.startsWith('bg')) core.drawBg(floorId);
else core.drawFg(floorId);
}
}
@@ -1939,7 +2178,6 @@ maps.prototype._deleteDetachedBlock = function (canvases) {
maps.prototype._getAndRemoveBlock = function (x, y) {
var block = core.getBlock(x, y);
if (block == null) return null;
- block = block.block;
var blockInfo = this.getBlockInfo(block);
if (blockInfo == null) return;
core.removeBlock(x, y);
@@ -2152,7 +2390,6 @@ maps.prototype._animateBlock_getList = function (loc, type) {
loc.forEach(function (t) {
var block = core.getBlock(t[0], t[1], null, true);
if (block == null) return;
- block = block.block;
var blockInfo = core.maps.getBlockInfo(block);
if (blockInfo == null) {
@@ -2190,11 +2427,12 @@ maps.prototype._animateBlock_drawList = function (list, opacity) {
////// 添加一个全局动画 //////
maps.prototype.addGlobalAnimate = function (block) {
- if (!block.event || block.event.animate == null) return;
+ if (!block || !block.event) return;
+ this.removeGlobalAnimate(block.x, block.y, block.name);
if (block.event.cls == 'autotile') {
var id = block.event.id, img = core.material.images.autotile[id];
if (!img || img.width == 96) return;
- core.status.autotileAnimateObjs.blocks.push(block);
+ core.status.autotileAnimateObjs.push(block);
}
else {
if (!block.event.animate || block.event.animate == 1) return;
@@ -2208,7 +2446,7 @@ maps.prototype.removeGlobalAnimate = function (x, y, name) {
if (x == null || y == null) {
core.status.globalAnimateStatus = 0;
core.status.globalAnimateObjs = [];
- core.status.autotileAnimateObjs = {"blocks": [], "map": null, "bgmap": null, "fgmap": null};
+ core.status.autotileAnimateObjs = [];
core.status.floorAnimateObjs = [];
return;
}
@@ -2218,13 +2456,9 @@ maps.prototype.removeGlobalAnimate = function (x, y, name) {
});
// 检查Autotile
- if (core.status.autotileAnimateObjs.blocks) {
- core.status.autotileAnimateObjs.blocks = core.status.autotileAnimateObjs.blocks.filter(function (block) {
- return block.x != x || block.y != y || block.name != name;
- });
- core.status.autotileAnimateObjs.map[y][x] = 0;
- }
-
+ core.status.autotileAnimateObjs = core.status.autotileAnimateObjs.filter(function (block) {
+ return block.x != x || block.y != y || block.name != name;
+ });
}
////// 绘制UI层的box动画 //////
diff --git a/libs/ui.js b/libs/ui.js
index 4bae76a7..e13c6fc9 100644
--- a/libs/ui.js
+++ b/libs/ui.js
@@ -50,14 +50,20 @@ ui.prototype._createUIEvent = function () {
ui.prototype.clearMap = function (name, x, y, width, height) {
if (name == 'all') {
for (var m in core.canvas) {
- core.canvas[m].clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32);
+ core.canvas[m].clearRect(-32, -32, core.canvas[m].width+32, core.canvas[m].height+32);
}
core.dom.gif.innerHTML = "";
core.removeGlobalAnimate();
}
else {
var ctx = this.getContextByName(name);
- if (ctx) ctx.clearRect(x||0, y||0, width||ctx.canvas.width, height||ctx.canvas.height);
+ if (ctx) {
+ if (x != null && y != null && width != null && height != null) {
+ ctx.clearRect(x, y, width, height);
+ } else {
+ ctx.clearRect(-32, -32, ctx.canvas.width + 32, ctx.canvas.height + 32);
+ }
+ }
}
}
@@ -2274,7 +2280,7 @@ ui.prototype.drawFly = function(page) {
}
var size = this.PIXEL - 143;
core.strokeRect('ui', 20, 100, size, size, '#FFFFFF', 2);
- core.drawThumbnail(floorId, null, null, {ctx: 'ui', x: 20, y: 100, size: size});
+ core.drawThumbnail(floorId, null, {ctx: 'ui', x: 20, y: 100, size: size});
}
////// 绘制中心对称飞行器
@@ -2286,8 +2292,7 @@ ui.prototype.drawCenterFly = function () {
var toX = core.bigmap.width - 1 - core.getHeroLoc('x'), toY = core.bigmap.height - 1 - core.getHeroLoc('y');
this.clearUI();
core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, '#000000');
- core.drawThumbnail(null, null, {heroLoc: core.status.hero.loc, heroIcon: core.status.hero.image},
- {ctx: 'ui', centerX: toX, centerY: toY});
+ core.drawThumbnail(null, null, {heroLoc: core.status.hero.loc, heroIcon: core.status.hero.image, ctx: 'ui', centerX: toX, centerY: toY});
var offsetX = core.clamp(toX - core.__HALF_SIZE__, 0, core.bigmap.width - core.__SIZE__),
offsetY = core.clamp(toY - core.__HALF_SIZE__, 0, core.bigmap.height - core.__SIZE__);
core.fillRect('ui', (toX - offsetX) * 32, (toY - offsetY) * 32, 32, 32, fillstyle);
@@ -2306,8 +2311,7 @@ ui.prototype.drawMaps = function (index, x, y) {
core.status.checkBlock.cache = {};
var data = this._drawMaps_buildData(index, x, y);
core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, '#000000');
- core.drawThumbnail(data.floorId, null, {damage: data.damage},
- {ctx: 'ui', centerX: data.x, centerY: data.y, all: data.all});
+ core.drawThumbnail(data.floorId, null, {damage: data.damage, ctx: 'ui', centerX: data.x, centerY: data.y, all: data.all});
core.clearMap('data');
core.setTextAlign('data', 'left');
core.setFont('data', '16px Arial');
@@ -2772,10 +2776,9 @@ ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, hi
if (data && data.floorId) {
core.setTextAlign('ui', "center");
var map = core.maps.loadMap(data.maps, data.floorId);
- core.extractBlocks(map, data.hero.flags);
+ core.extractBlocksForUI(map, data.hero.flags);
core.drawThumbnail(data.floorId, map.blocks, {
- heroLoc: data.hero.loc, heroIcon: data.hero.image, flags: data.hero.flags
- }, {
+ heroLoc: data.hero.loc, heroIcon: data.hero.image, flags: data.hero.flags,
ctx: 'ui', x: x-size/2, y: y+15, size: size, centerX: data.hero.loc.x, centerY: data.hero.loc.y
});
if (core.isPlaying() && core.getFlag("hard") != data.hero.flags.hard) {
diff --git a/libs/utils.js b/libs/utils.js
index f3ad7131..44e1a115 100644
--- a/libs/utils.js
+++ b/libs/utils.js
@@ -58,6 +58,14 @@ utils.prototype._init = function () {
return this.substring(0, search.length) === search;
}
}
+ if (typeof Array.prototype.fill != "function") {
+ Array.prototype.fill = function (value) {
+ for (var i = 0; i < this.length; ++i)
+ if (this[i] == null)
+ this[i] = value;
+ return this;
+ }
+ }
}
@@ -342,6 +350,16 @@ utils.prototype.clone = function (data, filter, recursion) {
return data;
}
+////// 深拷贝1D/2D数组优化 //////
+utils.prototype.cloneArray = function (data) {
+ if (!(data instanceof Array)) return this.clone(data);
+ if (data[0] instanceof Array) {
+ return data.map(function (one) { return one.slice(); });
+ } else {
+ return data.slice();
+ }
+}
+
////// 裁剪图片 //////
utils.prototype.splitImage = function (image, width, height) {
if (typeof image == "string") {
@@ -660,7 +678,7 @@ utils.prototype.isset = function (val) {
utils.prototype.subarray = function (a, b) {
if (!(a instanceof Array) || !(b instanceof Array) || a.length < b.length)
return null;
- var na = core.clone(a), nb = core.clone(b);
+ var na = core.cloneArray(a), nb = core.cloneArray(b);
while (nb.length > 0) {
if (na.shift() != nb.shift()) return null;
}
@@ -697,11 +715,30 @@ utils.prototype.setStatusBarInnerHTML = function (name, value, css) {
var length = this.strlen(value) || 1;
style += 'font-size: ' + Math.min(1, 7 / length) + 'em; ';
if (css) style += css;
+ var _isNumber = core.statusBar[name].getAttribute('_isNumber') == "1";
+ var _style = core.statusBar[name].getAttribute('_style');
+ var _value = core.statusBar[name].getAttribute('_value');
if (isNumber) {
- core.statusBar[name].innerHTML = "" + value + "";
+ if (_isNumber && _style == style) {
+ if (value == _value) return;
+ core.statusBar[name].innerText = value;
+ } else {
+ core.statusBar[name].innerHTML = "" + value + "";
+ core.statusBar[name].setAttribute('_isNumber', '1');
+ core.statusBar[name].setAttribute('_style', style);
+ }
+ core.statusBar[name].setAttribute('_value', value);
} else {
- core.statusBar[name].innerHTML = "";
- core.statusBar[name].children[0].innerText = value;
+ if (!_isNumber && _style == style) {
+ if (value == _value) return;
+ core.statusBar[name].children[0].innerText = value;
+ } else {
+ core.statusBar[name].innerHTML = "";
+ core.statusBar[name].children[0].innerText = value;
+ core.statusBar[name].setAttribute('_isNumber', '0');
+ core.statusBar[name].setAttribute('_style', style);
+ }
+ core.statusBar[name].setAttribute('_value', value);
}
}
diff --git a/migration.html b/migration.html
index 5f0681d8..c50d916b 100644
--- a/migration.html
+++ b/migration.html
@@ -483,8 +483,8 @@ function action_items(callback) {
"cls": "tools",
"name": "破墙镐",
"text": "可以破坏勇士面前的墙",
- "useItemEffect": "(function () {\n\tvar canBreak = function (x, y) {\n\t\tvar block = core.getBlock(x, y);\n\t\tif (block == null || block.block.disable) return false;\n\t\treturn block.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('pickaxe.mp3');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t} else {\n\t\t// 无法使用\n\t\tcore.drawTip(\"当前无法使用\" + core.material.items[itemId].name);\n\t\tcore.addItem(itemId, 1);\n\t\treturn;\n\t}\n})();",
- "canUseItemEffect": "true"
+ "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('pickaxe.mp3');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t} else {\n\t\t// 无法使用\n\t\tcore.drawTip(\"当前无法使用\" + core.material.items[itemId].name);\n\t\tcore.addItem(itemId, 1);\n\t\treturn;\n\t}\n})();",
+ "canUseItemEffect": "true"
},
"icePickaxe": {
"cls": "tools",
@@ -497,8 +497,8 @@ function action_items(callback) {
"cls": "tools",
"name": "炸弹",
"text": "可以炸掉勇士面前的怪物",
- "useItemEffect": "(function () {\n\tvar canBomb = function (x, y) {\n\t\tvar block = core.getBlock(x, y);\n\t\tif (block == null || block.block.disable || block.block.event.cls.indexOf('enemy') != 0) return false;\n\t\tvar enemy = core.material.enemys[block.block.event.id];\n\t\treturn enemy && !enemy.notBomb;\n\t};\n\n\tvar bombList = []; // 炸掉的怪物坐标列表\n\tvar bombFourDirections = false; // 是否四方向可炸;如果是将其改成true。\n\tif (bombFourDirections) {\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 (canBomb(nx, ny)) {\n\t\t\t\tbombList.push([nx, ny]);\n\t\t\t\tcore.removeBlock(nx, ny);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// 仅炸当前\n\t\tif (canBomb(core.nextX(), core.nextY())) {\n\t\t\tbombList.push([core.nextX(), core.nextY()]);\n\t\t\tcore.removeBlock(core.nextX(), core.nextY());\n\t\t}\n\t}\n\n\tif (bombList.length > 0) {\n\t\tcore.playSound('bomb.mp3');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t} else {\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})();",
- "canUseItemEffect": "true"
+ "useItemEffect": "(function () {\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 bombList = []; // 炸掉的怪物坐标列表\n\tvar bombFourDirections = false; // 是否四方向可炸;如果是将其改成true。\n\tif (bombFourDirections) {\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 (canBomb(nx, ny)) {\n\t\t\t\tbombList.push([nx, ny]);\n\t\t\t\tcore.removeBlock(nx, ny);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// 仅炸当前\n\t\tif (canBomb(core.nextX(), core.nextY())) {\n\t\t\tbombList.push([core.nextX(), core.nextY()]);\n\t\t\tcore.removeBlock(core.nextX(), core.nextY());\n\t\t}\n\t}\n\n\tif (bombList.length > 0) {\n\t\tcore.playSound('bomb.mp3');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t} else {\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})();",
+ "canUseItemEffect": "true"
},
"upFly": {
"cls": "tools",
@@ -518,7 +518,7 @@ function action_items(callback) {
"cls": "tools",
"name": "地震卷轴",
"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(core.status.floorId, function () {\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t});\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.drawMap();\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})();"
},
};
diff --git a/project/functions.js b/project/functions.js
index c8172847..c857e7f8 100644
--- a/project/functions.js
+++ b/project/functions.js
@@ -125,6 +125,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
if (block.disable && core.enemys.hasSpecial(block.event.id, 23)) {
block.disable = false;
core.setMapBlockDisabled(floorId, block.x, block.y, false);
+ core.maps._updateMapArray(floorId, block.x, block.y);
}
});
core.control.gatherFollowers();
@@ -284,15 +285,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
return;
}
- // 删除该块
var guards = []; // 支援
if (x != null && y != null) {
- // 检查是否是重生怪物;如果是则仅隐藏不删除
- if (core.hasSpecial(enemy.special, 23)) {
- core.hideBlock(x, y);
- } else {
- core.removeBlock(x, y);
- }
guards = core.getFlag("__guards__" + x + "_" + y, []);
core.removeFlag("__guards__" + x + "_" + y);
}
@@ -389,7 +383,18 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 如果事件不为空,将其插入
if (todo.length > 0) core.insertAction(todo, x, y);
- core.updateStatusBar();
+
+ // 因为removeBlock和hideBlock都会刷新状态栏,因此移动到这里并保证刷新只执行一次,以提升效率
+ if (core.getBlock(x, y) != null) {
+ // 检查是否是重生怪物;如果是则仅隐藏不删除
+ if (core.hasSpecial(enemy.special, 23)) {
+ core.hideBlock(x, y);
+ } else {
+ core.removeBlock(x, y);
+ }
+ } else {
+ core.updateStatusBar();
+ }
// 如果已有事件正在处理中
if (core.status.event.id == null)
@@ -1137,8 +1142,10 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
core.setStatusBarInnerHTML('fly', "飞" + core.itemCount('centerFly'));
// 难度
- core.statusBar.hard.innerText = core.status.hard;
- core.statusBar.hard.style.color = core.getFlag('__hardColor__', 'red');
+ if (core.statusBar.hard.innerText != core.status.hard) {
+ core.statusBar.hard.innerText = core.status.hard;
+ core.statusBar.hard.style.color = core.getFlag('__hardColor__', 'red');
+ }
// 自定义状态栏绘制
core.drawStatusBar();
@@ -1160,6 +1167,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
type = {}, // 每个点的伤害类型
repulse = {}, // 每个点的阻击怪信息
ambush = {}; // 每个点的捕捉信息
+ var betweenAttackLocs = {}; // 所有带夹击的怪物
var needCache = false;
var canGoDeadZone = core.flags.canGoDeadZone;
core.flags.canGoDeadZone = true;
@@ -1171,6 +1179,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
y = block.y,
id = block.event.id,
enemy = core.material.enemys[id];
+ if (block.disable) continue;
type[loc] = type[loc] || {};
@@ -1266,6 +1275,18 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
}
}
+ // 夹击;在这里提前计算所有可能的夹击点,具体计算逻辑在下面
+ // 如果要防止夹击伤害,可以简单的将 flag:no_betweenAttack 设为true
+ if (enemy && core.enemys.hasSpecial(enemy.special, 16) && !core.hasFlag('no_betweenAttack')) {
+ for (var dir in core.utils.scan) {
+ var nx = x + core.utils.scan[dir].x,
+ ny = y + core.utils.scan[dir].y,
+ currloc = nx + "," + ny;
+ if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
+ betweenAttackLocs[currloc] = true;
+ }
+ }
+
// 检查地图范围类技能
var specialFlag = core.getSpecialFlag(enemy);
if (specialFlag & 1) needCache = true;
@@ -1275,48 +1296,46 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 更新夹击伤害
// 如果要防止夹击伤害,可以简单的将 flag:no_betweenAttack 设为true
- if (!core.hasFlag('no_betweenAttack')) {
- for (var x = 0; x < width; x++) {
- for (var y = 0; y < height; y++) {
- var loc = x + "," + y;
- // 夹击怪物的ID
- var enemyId1 = null,
- enemyId2 = null;
- // 检查左右夹击
- var leftBlock = blocks[(x - 1) + "," + y],
- rightBlock = blocks[(x + 1) + "," + y];
- if (leftBlock && rightBlock && leftBlock.id == rightBlock.id) {
- if (core.hasSpecial(leftBlock.event.id, 16))
- enemyId1 = leftBlock.event.id;
- }
- // 检查上下夹击
- var topBlock = blocks[x + "," + (y - 1)],
- bottomBlock = blocks[x + "," + (y + 1)];
- if (topBlock && bottomBlock && topBlock.id == bottomBlock.id) {
- if (core.hasSpecial(topBlock.event.id, 16))
- enemyId2 = topBlock.event.id;
- }
+ for (var loc in betweenAttackLocs) {
+ var xy = loc.split(","),
+ x = parseInt(xy[0]),
+ y = parseInt(xy[1]);
+ // 夹击怪物的ID
+ var enemyId1 = null,
+ enemyId2 = null;
+ // 检查左右夹击
+ var leftBlock = blocks[(x - 1) + "," + y],
+ rightBlock = blocks[(x + 1) + "," + y];
+ if (leftBlock && !leftBlock.disable && rightBlock && !rightBlock.disable && leftBlock.id == rightBlock.id) {
+ if (core.hasSpecial(leftBlock.event.id, 16))
+ enemyId1 = leftBlock.event.id;
+ }
+ // 检查上下夹击
+ var topBlock = blocks[x + "," + (y - 1)],
+ bottomBlock = blocks[x + "," + (y + 1)];
+ if (topBlock && !topBlock.disable && bottomBlock && !bottomBlock.disable && topBlock.id == bottomBlock.id) {
+ if (core.hasSpecial(topBlock.event.id, 16))
+ enemyId2 = topBlock.event.id;
+ }
- if (enemyId1 != null || enemyId2 != null) {
- var leftHp = core.status.hero.hp - (damage[loc] || 0);
- if (leftHp > 1) {
- // 夹击伤害值
- var value = Math.floor(leftHp / 2);
- // 是否不超过怪物伤害值
- if (core.flags.betweenAttackMax) {
- var enemyDamage1 = core.getDamage(enemyId1, x, y, floorId);
- if (enemyDamage1 != null && enemyDamage1 < value)
- value = enemyDamage1;
- var enemyDamage2 = core.getDamage(enemyId2, x, y, floorId);
- if (enemyDamage2 != null && enemyDamage2 < value)
- value = enemyDamage2;
- }
- if (value > 0) {
- damage[loc] = (damage[loc] || 0) + value;
- type[loc] = type[loc] || {};
- type[loc]["夹击伤害"] = true;
- }
- }
+ if (enemyId1 != null || enemyId2 != null) {
+ var leftHp = core.status.hero.hp - (damage[loc] || 0);
+ if (leftHp > 1) {
+ // 夹击伤害值
+ var value = Math.floor(leftHp / 2);
+ // 是否不超过怪物伤害值
+ if (core.flags.betweenAttackMax) {
+ var enemyDamage1 = core.getDamage(enemyId1, x, y, floorId);
+ if (enemyDamage1 != null && enemyDamage1 < value)
+ value = enemyDamage1;
+ var enemyDamage2 = core.getDamage(enemyId2, x, y, floorId);
+ if (enemyDamage2 != null && enemyDamage2 < value)
+ value = enemyDamage2;
+ }
+ if (value > 0) {
+ damage[loc] = (damage[loc] || 0) + value;
+ type[loc] = type[loc] || {};
+ type[loc]["夹击伤害"] = true;
}
}
}
@@ -1372,7 +1391,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
nowy = core.getHeroLoc('y');
var block = core.getBlock(nowx, nowy);
var hasTrigger = false;
- if (block != null && block.block.event.trigger == 'getItem' &&
+ if (block != null && block.event.trigger == 'getItem' &&
!core.floors[core.status.floorId].afterGetItem[nowx + "," + nowy]) {
hasTrigger = true;
core.trigger(nowx, nowy, callback);
diff --git a/project/items.js b/project/items.js
index d019c23e..3227ecef 100644
--- a/project/items.js
+++ b/project/items.js
@@ -374,7 +374,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"cls": "tools",
"name": "破墙镐",
"text": "可以破坏勇士面前的墙",
- "useItemEffect": "(function () {\n\tvar canBreak = function (x, y) {\n\t\tvar block = core.getBlock(x, y);\n\t\tif (block == null || block.block.disable) return false;\n\t\treturn block.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('pickaxe.mp3');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t} else {\n\t\t// 无法使用\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) {\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('pickaxe.mp3');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t} else {\n\t\t// 无法使用\n\t\tcore.drawTip(\"当前无法使用\" + core.material.items[itemId].name);\n\t\tcore.addItem(itemId, 1);\n\t\treturn;\n\t}\n})();",
"canUseItemEffect": "true"
},
"icePickaxe": {
@@ -388,7 +388,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"cls": "tools",
"name": "炸弹",
"text": "可以炸掉勇士面前的怪物",
- "useItemEffect": "(function () {\n\tvar canBomb = function (x, y) {\n\t\tvar block = core.getBlock(x, y);\n\t\tif (block == null || block.block.disable || block.block.event.cls.indexOf('enemy') != 0) return false;\n\t\tvar enemy = core.material.enemys[block.block.event.id];\n\t\treturn enemy && !enemy.notBomb;\n\t};\n\n\tvar bombList = []; // 炸掉的怪物坐标列表\n\tvar bombFourDirections = false; // 是否四方向可炸;如果是将其改成true。\n\tif (bombFourDirections) {\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 (canBomb(nx, ny)) {\n\t\t\t\tbombList.push([nx, ny]);\n\t\t\t\tcore.removeBlock(nx, ny);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// 仅炸当前\n\t\tif (canBomb(core.nextX(), core.nextY())) {\n\t\t\tbombList.push([core.nextX(), core.nextY()]);\n\t\t\tcore.removeBlock(core.nextX(), core.nextY());\n\t\t}\n\t}\n\n\tif (bombList.length > 0) {\n\t\tcore.playSound('bomb.mp3');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t} else {\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 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 bombList = []; // 炸掉的怪物坐标列表\n\tvar bombFourDirections = false; // 是否四方向可炸;如果是将其改成true。\n\tif (bombFourDirections) {\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 (canBomb(nx, ny)) {\n\t\t\t\tbombList.push([nx, ny]);\n\t\t\t\tcore.removeBlock(nx, ny);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// 仅炸当前\n\t\tif (canBomb(core.nextX(), core.nextY())) {\n\t\t\tbombList.push([core.nextX(), core.nextY()]);\n\t\t\tcore.removeBlock(core.nextX(), core.nextY());\n\t\t}\n\t}\n\n\tif (bombList.length > 0) {\n\t\tcore.playSound('bomb.mp3');\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t} else {\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})();",
"canUseItemEffect": "true"
},
"centerFly": {
@@ -416,7 +416,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"cls": "tools",
"name": "地震卷轴",
"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(core.status.floorId, function () {\n\t\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t});\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.drawMap();\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})();"
},
"poisonWine": {
diff --git a/project/plugins.js b/project/plugins.js
index 5f25ac13..95168369 100644
--- a/project/plugins.js
+++ b/project/plugins.js
@@ -321,7 +321,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
// 背景层2将会覆盖背景层 被事件层覆盖 前景层2将会覆盖前景层
// 另外 请注意加入两个新图层 会让大地图的性能降低一些
// 插件作者:ad
- var __enable = false;
+ var __enable = true;
if (!__enable) return;
// 创建新图层
@@ -353,7 +353,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
// 背景层2(bg2) 插入事件层(event)之前(即bg与event之间)
document.getElementById('mapEdit').insertBefore(bg2Canvas, document.getElementById('event'));
// 前景层2(fg2) 插入编辑器前景(efg)之前(即fg之后)
- document.getElementById('mapEdit').insertBefore(fg2Canvas, document.getElementById('efg'));
+ document.getElementById('mapEdit').insertBefore(fg2Canvas, document.getElementById('ebm'));
// 原本有三个图层 从4开始添加
var num = 4;
// 新增图层存入editor.dom中
@@ -364,16 +364,6 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
editor.dom.maps.push('bg2map', 'fg2map');
editor.dom.canvas.push('bg2', 'fg2');
- // 默认全空
- var defaultMap = [];
- for (var i = 0; i < core.__SIZE__; ++i) {
- var row = [];
- for (var j = 0; j < core.__SIZE__; ++j) {
- row.push(0);
- }
- defaultMap.push(row);
- }
-
// 创建编辑器上的按钮
var createCanvasBtn = function (name) {
// 电脑端创建按钮
@@ -390,7 +380,6 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
input.onchange = function () {
editor.uifunctions.setLayerMod(value);
}
- editor[value] = editor[value] || defaultMap;
return input;
};
@@ -402,7 +391,6 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
input.name = 'layerMod';
input.value = value;
editor.dom[id] = input;
- editor[value] = editor[value] || defaultMap;
return input;
};
if (!editor.isMobile) {
@@ -432,157 +420,54 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
parent.appendChild(input2);
}
}
+ core.maps._loadFloor_doNotCopy = function () {
+ return [
+ "firstArrive", "eachArrive", "blocks", "parallelDo", "map", "bgmap", "fgmap", "bg2map", "fg2map",
+ "events", "changeFloor", "afterBattle", "afterGetItem", "afterOpenDoor", "cannotMove"
+ ];
+ }
- ////// 绘制背景层 //////
- core.maps.drawBg = function (floorId, ctx) {
- floorId = floorId || core.status.floorId;
- var onMap = ctx == null;
- if (onMap) {
- ctx = core.canvas.bg;
- core.clearMap(ctx);
- core.status.floorAnimateObjs = this._getFloorImages(floorId);
- }
- core.maps._drawBg_drawBackground(floorId, ctx);
+ ////// 绘制背景和前景层 //////
+ core.maps._drawBg_draw = function (floorId, toDrawCtx, cacheCtx, config) {
+ config.ctx = cacheCtx;
+ core.maps._drawBg_drawBackground(floorId, config);
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
- core.maps._drawFloorImages(floorId, ctx, 'bg');
- core.maps._drawBgFgMap(floorId, ctx, 'bg', onMap);
- // 绘制背景层2
- core.maps._drawBgFgMap(floorId, ctx, 'bg2', onMap);
- };
-
- ////// 绘制前景层 //////
- core.maps.drawFg = function (floorId, ctx) {
- floorId = floorId || core.status.floorId;
- var onMap = ctx == null;
- if (onMap) {
- ctx = core.canvas.fg;
- core.status.floorAnimateObjs = this._getFloorImages(floorId);
+ core.maps._drawFloorImages(floorId, config.ctx, 'bg', null, null, config.onMap);
+ core.maps._drawBgFgMap(floorId, 'bg', config);
+ if (config.onMap) {
+ core.drawImage(toDrawCtx, cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
+ core.clearMap('bg2');
+ core.clearMap(cacheCtx);
}
+ core.maps._drawBgFgMap(floorId, 'bg2', config);
+ if (config.onMap) core.drawImage('bg2', cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
+ config.ctx = toDrawCtx;
+ }
+ core.maps._drawFg_draw = function (floorId, toDrawCtx, cacheCtx, config) {
+ config.ctx = cacheCtx;
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制前景图块;后绘制的覆盖先绘制的。
- this._drawFloorImages(floorId, ctx, 'fg');
- this._drawBgFgMap(floorId, ctx, 'fg', onMap);
- // 绘制前景层2
- this._drawBgFgMap(floorId, ctx, 'fg2', onMap);
- };
+ core.maps._drawFloorImages(floorId, config.ctx, 'fg', null, null, config.onMap);
+ core.maps._drawBgFgMap(floorId, 'fg', config);
+ if (config.onMap) {
+ core.drawImage(toDrawCtx, cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
+ core.clearMap('fg2');
+ core.clearMap(cacheCtx);
+ }
+ core.maps._drawBgFgMap(floorId, 'fg2', config);
+ if (config.onMap) core.drawImage('fg2', cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
+ config.ctx = toDrawCtx;
+ }
+
/* cannotIn/cannotOut适配 start*/
- core.maps.generateMovableArray = function (floorId, x, y, direction) {
- floorId = floorId || core.status.floorId;
- if (!floorId) return null;
- var width = core.floors[floorId].width,
- height = core.floors[floorId].height;
- var bgArray = this.getBgMapArray(floorId),
- bg2Array = this._getBgFgMapArray('bg2', floorId),
- fgArray = this.getFgMapArray(floorId),
- fg2Array = this._getBgFgMapArray('fg2', floorId),
- eventArray = this.getMapArray(floorId);
-
- var generate = function (x, y, direction) {
- if (direction != null) {
- return core.maps._canMoveHero_checkPoint(x, y, direction, floorId, {
- bgArray: bgArray,
- fgArray: fgArray,
- bg2Array: bg2Array,
- fg2Array: fg2Array,
- eventArray: eventArray
- });
- }
- return ["left", "down", "up", "right"].filter(function (direction) {
- return core.maps._canMoveHero_checkPoint(x, y, direction, floorId, {
- bgArray: bgArray,
- fgArray: fgArray,
- bg2Array: bg2Array,
- fg2Array: fg2Array,
- eventArray: eventArray
- });
- });
+ core.maps._generateMovableArray_arrays = function (floorId) {
+ return {
+ bgArray: this.getBgMapArray(floorId),
+ fgArray: this.getFgMapArray(floorId),
+ eventArray: this.getMapArray(floorId),
+ bg2Array: this._getBgFgMapArray('bg2', floorId),
+ fg2Array: this._getBgFgMapArray('fg2', floorId)
};
-
- if (x != null && y != null) return generate(x, y, direction);
- var array = [];
- for (var x = 0; x < width; x++) {
- array[x] = [];
- for (var y = 0; y < height; y++) {
- array[x][y] = generate(x, y);
- }
- }
- return array;
- };
- core.maps._canMoveHero_checkPoint = function (x, y, direction, floorId, extraData) {
- // 1. 检查该点 cannotMove
- if (core.inArray((core.floors[floorId].cannotMove || {})[x + "," + y], direction))
- return false;
-
- var nx = x + core.utils.scan[direction].x,
- ny = y + core.utils.scan[direction].y;
- if (nx < 0 || ny < 0 || nx >= core.floors[floorId].width || ny >= core.floors[floorId].height)
- return false;
-
- // 2. 检查该点素材的 cannotOut 和下一个点的 cannotIn
- if (this._canMoveHero_checkCannotInOut([
- extraData.bgArray[y][x], extraData.bg2Array[y][x], extraData.fgArray[y][x], extraData.fg2Array[y][x], extraData.eventArray[y][x]
- ], "cannotOut", direction))
- return false;
- if (this._canMoveHero_checkCannotInOut([
- extraData.bgArray[ny][nx], extraData.bg2Array[ny][nx], extraData.fgArray[ny][nx], extraData.fg2Array[ny][nx], extraData.eventArray[ny][nx]
- ], "cannotIn", direction))
- return false;
-
- // 3. 检查是否能进将死的领域
- if (floorId == core.status.floorId && !core.flags.canGoDeadZone &&
- core.status.hero.hp <= (core.status.checkBlock.damage[nx + "," + ny] || 0) &&
- extraData.eventArray[ny][nx] == 0)
- return false;
-
- return true;
- };
- /* cannotIn/cannotOut适配 end*/
- // 前景层2与背景层2的隐藏与显示适配
- // 比如:可以用core.hideBgFgMap("bg2",[x, y], floorId)隐藏当前楼层的背景层2图块
- core.maps._triggerBgFgMap = function (type, name, loc, floorId, callback) {
- if (type != 'show') type = 'hide';
- if (!name) name = 'bg';
- if (typeof loc[0] == 'number' && typeof loc[1] == 'number')
- loc = [loc];
- floorId = floorId || core.status.floorId;
- if (!floorId) return;
-
- if (loc.length == 0) return;
- loc.forEach(function (t) {
- var x = t[0],
- y = t[1];
- var flag = [floorId, x, y, name + '_disable'].join('@');
- if (type == 'hide') core.setFlag(flag, true);
- else core.removeFlag(flag);
- });
- core.status[name + "maps"][floorId] = null;
-
- if (floorId == core.status.floorId) {
- core.drawMap(floorId, callback);
- } else {
- if (callback) callback();
- }
- };
- // 改变背景层2与前景层2图块 例:core.setBgFgBlock('fg2',312,core.nextX(),core.nextY())
- core.maps.setBgFgBlock = function (name, number, x, y, floorId) {
- floorId = floorId || core.status.floorId;
- if (!floorId || number == null || x == null || y == null) return;
- if (x < 0 || x >= core.floors[floorId].width || y < 0 || y >= core.floors[floorId].height) return;
- if (name != 'bg' && name != 'fg' && name != 'bg2' && name != 'fg2') return;
- if (typeof number == 'string') {
- if (/^\d+$/.test(number)) number = parseInt(number);
- else number = core.getNumberById(number);
- }
-
- var vFlag = [floorId, x, y, name + "_value"].join('@');
- core.setFlag(vFlag, number);
- core.status[name + "maps"][floorId] = null;
-
- if (floorId == core.status.floorId) {
- core.clearMap(name);
- if (name.startsWith('bg')) core.drawBg(floorId);
- else core.drawFg(floorId);
- }
- };
+ }
},
"itemShop": function () {
// 道具商店相关的插件
@@ -1373,125 +1258,5 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
return true;
}, 100);
-},
- "smoothCamera": function () {
- // 此插件开启后,大地图的瞬间移动将开启平滑镜头移动,避免突兀感
- // 插件作者:老黄鸡
-
- // 是否启用本插件,默认不启用
- var __enable = false;
- if (!__enable) return;
-
- this.Camera = function () {
-
- // 下面这个变量决定本插件的开关
- // 你可以在游戏中使用core.setFlag('smoothCamera',false)来关闭本插件的功能
- // 同时也可以core.setFlag('smoothCamera',true)重新开启
- // 此项默认为true
- //
- this.__switchName = 'smoothCamera';
-
- // 初始化成员变量
- this._cameraNeedRefresh = true;
- this._nowOffsetX = 0;
- this._nowOffsetY = 0;
- this._targetOffsetX = 0;
- this._targetOffsetY = 0;
- this._currentFloorId = null;
-
- // 重置镜头,在楼层变更时使用
- this.resetCamera = function () {
- this._targetOffsetX = core.bigmap.offsetX;
- this._targetOffsetY = core.bigmap.offsetY;
- this._nowOffsetX = this._targetOffsetX;
- this._nowOffsetY = this._targetOffsetY;
- this._cameraNeedRefresh = true;
- };
-
- // 设置焦点坐标,目前没有用
- this.setTarget = function (x, y) {
- this._targetOffsetX = x;
- this._targetOffsetY = y;
- };
-
- // 请求镜头更新
- this.requestCameraUpdate = function () {
- this._cameraNeedRefresh = true;
- };
-
- // 更新焦点坐标,目前仅根据大地图偏移决定
- this.updateTargetPosition = function () {
- this._targetOffsetX = core.bigmap.offsetX;
- this._targetOffsetY = core.bigmap.offsetY;
- };
-
- // 更新额外的刷新条件,即镜头未指向焦点时
- this.updateRefreshFlag = function () {
- if (this._nowOffsetX != this._targetOffsetX || this._nowOffsetY != this._targetOffsetY) {
- this._cameraNeedRefresh = true;
- }
- };
-
- // 判断是否禁止了弹性滚动
- this.canDirectMove = function () {
- return !core.getFlag(this.__switchName, true);
- };
-
- // 更新镜头坐标
- this.updateCameraPosition = function () {
- if (this._cameraNeedRefresh) {
- this._cameraNeedRefresh = false;
- var disX = this._targetOffsetX - this._nowOffsetX;
- var disY = this._targetOffsetY - this._nowOffsetY;
- if (Math.abs(disX) <= 2 && Math.abs(disY) <= 2 || this.canDirectMove()) {
- this._nowOffsetX = this._targetOffsetX;
- this._nowOffsetY = this._targetOffsetY;
- } else {
- this._nowOffsetX += disX / 10;
- this._nowOffsetY += disY / 10;
- }
- var x = -Math.floor(this._nowOffsetX);
- var y = -Math.floor(this._nowOffsetY);
- core.bigmap.canvas.forEach(function (cn) {
- core.control.setGameCanvasTranslate(cn, x, y);
- });
- core.relocateCanvas('route', core.status.automaticRoute.offsetX + x, core.status.automaticRoute.offsetY + y);
- core.setGameCanvasTranslate('hero', x + this._targetOffsetX, y + this._targetOffsetY);
- }
- };
-
- // 更新逻辑主体
- this.update = function () {
- this.updateTargetPosition();
- this.updateRefreshFlag();
- this.updateCameraPosition();
- };
- };
-
- // 创建摄像机对象
- this.camera = new this.Camera();
-
- // 帧事件 更新摄像机
- this.updateCameraEx = function () {
- this.camera.update();
- };
-
- core.control._drawHero_updateViewport = function () {
- core.control.updateViewport();
- }
-
- // 代理原本的镜头事件
- core.control.updateViewport = function () {
- core.plugin.camera.requestCameraUpdate();
- };
-
- // 更变楼层的行为追加,重置镜头
- core.events.changingFloor = function (floorId, heroLoc) {
- this.eventdata.changingFloor(floorId, heroLoc);
- core.plugin.camera.resetCamera();
- };
-
- // 注册帧事件
- core.registerAnimationFrame('smoothCameraFlash', true, this.updateCameraEx.bind(this));
}
}
\ No newline at end of file
diff --git a/runtime.d.ts b/runtime.d.ts
index 6fb09a77..acb2cf43 100644
--- a/runtime.d.ts
+++ b/runtime.d.ts
@@ -149,8 +149,10 @@ type gameStatus = {
thisMap: ResolvedMap
bgmaps: { [key: string]: number[][] }
fgmaps: { [key: string]: number[][] }
+ mapBlockObjs: { [key: string]: any }
/** 显伤伤害 */
checkBlock: {}
+ damage: {}
lockControl: boolean
@@ -230,12 +232,7 @@ type gameStatus = {
globalAnimateObjs: []
floorAnimateObjs: []
boxAnimateObjs: []
- autotileAnimateObjs: {
- blocks: [],
- map: any
- bgmap: any
- fgmap: null
- }
+ autotileAnimateObjs: []
globalAnimateStatus: number
animateObjs: []
}
@@ -393,13 +390,16 @@ declare class control {
nearHero(x: number, y: number, n?: number): boolean
/**
- * 更新地图显伤
+ * 重算并绘制地图显伤
* @example core.updateDamage(); // 更新当前地图的显伤,绘制在显伤层(废话)
* @param floorId 地图id,不填视为当前地图。预览地图时填写
* @param ctx 绘制到的画布,如果填写了就会画在该画布而不是显伤层
*/
updateDamage(floorId?: string, ctx?: CanvasRenderingContext2D): void
+ /** 仅重绘地图显伤 */
+ drawDamage(ctx?: CanvasRenderingContext2D): void
+
/**
* 设置主角的某个属性
* @example core.setStatus('loc', {x : 0, y : 0, direction : 'up'}); // 设置主角位置为地图左上角,脸朝上
@@ -1410,7 +1410,10 @@ declare class maps {
* @param showDisable 可选,true表示隐藏的图块也会被表示出来
* @returns 事件层矩阵,注意对其阵元的访问是[y][x]
*/
- getMapArray(floorId?: string): number[][]
+ getMapArray(floorId?: string, noCache?: boolean): number[][]
+
+ /** 判定图块的事件层数字;不存在为0 */
+ getMapNumber(floorId?: string, noCache?: boolean): number
/**
* 生成背景层矩阵
@@ -1454,12 +1457,9 @@ declare class maps {
* 可通行性判定
* @example core.generateMovableArray(); // 判断当前地图主角从各点能向何方向移动
* @param floorId 地图id,不填视为当前地图
- * @param x 起点横坐标,不填视为挨个判定
- * @param y 起点纵坐标,不填视为挨个判定
- * @param direction 可选,必须和坐标一起使用。填写后将只检查是否可向该方向移动并返回布尔值
- * @returns 不设置坐标时为从各点可移动方向的三维数组,设置坐标但不设置方向时为该点可移动方向的一维数组,都设置时为布尔值
+ * @returns 从各点可移动方向的三维数组
*/
- generateMovableArray(floorId?: string, x?: number, y?: number, direction?: direction): boolean | Array>>
+ generateMovableArray(floorId?: string): Array>>
/**
* 单点单朝向的可通行性判定
@@ -1529,9 +1529,8 @@ declare class maps {
* @param floorId 地图id,不填视为当前地图
* @param blocks 一般不需要
* @param options 额外的绘制项,可选。可以增绘主角位置和朝向、采用不同于游戏中的主角行走图、增绘显伤、提供flags用于存读档
- * @param toDraw 要绘制到的画布名或画布的ctx或还有其他信息,如起绘坐标、绘制大小、是否绘制全图、截取中心
*/
- drawThumbnail(floorId?: string, blocks?: Block[], options?: object, toDraw?: string | CanvasRenderingContext2D | object): void
+ drawThumbnail(floorId?: string, blocks?: Block[], options?: object): void
/**
* 判定某个点是否不可被踏入(不基于主角生命值和图块cannotIn属性)
@@ -1554,6 +1553,9 @@ declare class maps {
*/
getBlockId(x: number, y: number, floorId?: string, showDisable?: boolean): string | null
+ /** 判定某个点的图块数字;空图块为0 */
+ getBlockNumber(x: number, y: number, floorId?: string, showDisable?: boolean): number
+
/**
* 判定某个点的图块类型
* @example if(core.getBlockCls(x1, y1) != 'enemys' && core.getBlockCls(x2, y2) != 'enemy48') core.openDoor(x3, y3); // 另一个简单的机关门事件,打败或炸掉这一对不同身高的敌人就开门
@@ -1709,6 +1711,9 @@ declare class maps {
loadFloor(floorId?: string, map?: any): any
/** 根据需求解析出blocks */
+ extractBlocks(map?: any): void
+
+ /** 根据需求为UI解析出blocks */
extractBlocks(map?: any, flags?: any): void
/** 根据数字获得图块 */
@@ -1721,7 +1726,7 @@ declare class maps {
getIdOfThis(id?: string): string
/** 初始化一个图块 */
- initBlock(x?: number, y?: number, id?: string | number, addInfo?: boolean, eventFloor?: any, flags?: any): any
+ initBlock(x?: number, y?: number, id?: string | number, addInfo?: boolean, eventFloor?: any): any
/** 压缩地图 */
compressMap(mapArr?: any, floorId?: string): any
@@ -1739,7 +1744,7 @@ declare class maps {
resizeMap(floorId?: string): void
/** 以x,y的形式返回每个点的事件 */
- getMapBlocksObj(floorId?: string, showDisable?: any): any
+ getMapBlocksObj(floorId?: string, noCache?: boolean): any
/** 获得某些点可否通行的信息 */
canMoveDirectlyArray(locs?: any): any
@@ -1766,7 +1771,7 @@ declare class maps {
enemyExists(x?: number, y?: number, id?: string, floorId?: string): boolean
/** 获得某个点的block */
- getBlock(x?: number, y?: number, floorId?: string, showDisable?: boolean): any
+ getBlock(x?: number, y?: number, floorId?: string, showDisable?: boolean): Block
/** 获得某个图块或素材的信息,包括ID,cls,图片,坐标,faceIds等等 */
getBlockInfo(block?: any): any
@@ -2372,6 +2377,9 @@ declare class utils {
*/
clone(data?: T, filter?: (name: string, value: any) => boolean, recursion?: boolean): T
+ /** 深拷贝一个1D或2D的数组 */
+ cloneArray(data?: Array|Array>): Array|Array>
+
/**
* 等比例切分一张图片
* @example core.splitImage(core.material.images.images['npc48.png'], 32, 48); // 把npc48.png切分成若干32×48px的小人
@@ -2748,9 +2756,16 @@ type core = {
canvas: string[],
offsetX: number // in pixel
offsetY: number
+ posX: number
+ posY: number
width: number // map width and height
height: number
+ v2: boolean
+ threshold: number
+ extend: number
+ scale: number
tempCanvas: CanvasRenderingContext2D // A temp canvas for drawing
+ cacheCanvas: CanvasRenderingContext2D
}
saves: {
saveIndex: number