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..2dba66ad 100644 --- a/_server/CodeMirror/defs.js +++ b/_server/CodeMirror/defs.js @@ -1867,6 +1867,14 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [ "!type": "number", "!doc": "大地图视角纵向偏移量" }, + "posX": { + "!type": "number", + "!doc": "大地图视角横向基准格" + }, + "posY": { + "!type": "number", + "!doc": "大地图视角纵向基准格" + }, "tempCanvas": { "!type": "CanvasRenderingContext2D", "!doc": "临时画布" diff --git a/_server/config.json b/_server/config.json index 0414c1bc..bc4f6c27 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":"sample2","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 diff --git a/_server/editor.js b/_server/editor.js index d94e97f6..efca9d6b 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -223,6 +223,18 @@ editor.prototype.init = function (callback) { for (var one in canvases) { canvases[one].width = canvases[one].height = core.__PIXELS__; } + var csize = core.__PIXELS__ + 64; + core.bigmap.canvas.forEach(function (cn) { + core.canvas[cn].canvas.setAttribute("width", csize); + core.canvas[cn].canvas.setAttribute("height", csize); + core.canvas[cn].canvas.style.width = csize * core.domStyle.scale + "px"; + core.canvas[cn].canvas.style.height = csize * core.domStyle.scale + "px"; + core.canvas[cn].translate(32, 32); + if (main.mode === 'editor' && editor.isMobile) { + core.canvas[cn].canvas.style.width = csize / core.__PIXELS__ * 96 + "vw"; + core.canvas[cn].canvas.style.height = csize / core.__PIXELS__ * 96 + "vw"; + } + }); core.resetGame(core.firstData.hero, null, core.firstData.floorId, core.clone(core.initStatus.maps)); var lastFloorId = editor.config.get('editorLastFloorId', core.status.floorId); diff --git a/libs/control.js b/libs/control.js index f6bef443..891342f7 100644 --- a/libs/control.js +++ b/libs/control.js @@ -924,8 +924,19 @@ control.prototype.addGameCanvasTranslate = function (x, y) { ////// 更新视野范围 ////// control.prototype.updateViewport = function() { + // 当前是否应该重绘? + 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); + // redraw + core.redrawMap(); + } + core.bigmap.canvas.forEach(function(cn){ - core.control.setGameCanvasTranslate(cn,-core.bigmap.offsetX,-core.bigmap.offsetY); + core.control.setGameCanvasTranslate(cn, -(core.bigmap.offsetX - 32 * core.bigmap.posX) - 32, -(core.bigmap.offsetY - 32 * core.bigmap.posY) - 32); }); // ------ 路线 core.relocateCanvas('route', core.status.automaticRoute.offsetX - core.bigmap.offsetX, core.status.automaticRoute.offsetY - core.bigmap.offsetY); @@ -2856,9 +2867,17 @@ 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"; + var csize = core.__PIXELS__ + 64; + core.bigmap.canvas.forEach(function (cn) { + core.canvas[cn].canvas.setAttribute("width", csize); + core.canvas[cn].canvas.setAttribute("height", csize); + core.canvas[cn].canvas.style.width = csize * core.domStyle.scale + "px"; + core.canvas[cn].canvas.style.height = csize * core.domStyle.scale + "px"; + core.canvas[cn].translate(32, 32); + if (main.mode === 'editor' && editor.isMobile) { + core.canvas[cn].canvas.style.width = csize / core.__PIXELS__ * 96 + "vw"; + core.canvas[cn].canvas.style.height = csize / core.__PIXELS__ * 96 + "vw"; + } }); // resize dynamic canvas for (var name in core.dymCanvas) { diff --git a/libs/core.js b/libs/core.js index bba8f4fc..1066423b 100644 --- a/libs/core.js +++ b/libs/core.js @@ -93,6 +93,8 @@ 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__, tempCanvas: null, // A temp canvas for drawing diff --git a/libs/maps.js b/libs/maps.js index 52ca529c..e9d2e33d 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -379,18 +379,6 @@ 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.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"; - 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"; - } - }); } ////// 将当前地图重新变成二维数组形式 ////// @@ -758,9 +746,10 @@ maps.prototype.drawBlock = function (block, animate) { 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)) { + + // 判定是否绘制 + 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; } @@ -775,27 +764,31 @@ maps.prototype.drawBlock = function (block, animate) { maps.prototype._drawBlockInfo = function (blockInfo, x, y) { 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; - 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('event', px, py, 32, 32); + core.drawImage('event', 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) { 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; - core.clearMap(name, x * 32, y * 32 + 32 - height, 32, height); + core.clearMap(name, 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('bg', px, py - 32, 32, 32); + core.drawImage('bg', core.material.groundCanvas.canvas, px, py - 32); } - core.drawImage('bg', core.material.groundCanvas.canvas, x * 32, y * 32); + core.drawImage('bg', 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(name, image, posX * 32, posY * height, 32, height, px, py + 32 - height, 32, height); } ////// 生成groundPattern ////// @@ -812,12 +805,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,7 +821,15 @@ maps.prototype.drawMap = function (floorId, callback) { } core.drawHero(); core.updateStatusBar(); - if (callback) callback(); +} + +////// 重绘某张地图 ////// +maps.prototype.redrawMap = function () { + core.bigmap.canvas.forEach(function (one) { + core.clearMap(one); + }); + this._drawMap_drawAll(); + // core.redrawDamage(); } maps.prototype._drawMap_drawAll = function (floorId) { @@ -843,6 +841,14 @@ maps.prototype._drawMap_drawAll = function (floorId) { maps.prototype._drawMap_drawBlockInfo = function (ctx, block, blockInfo, arr, onMap) { if (blockInfo == null) return; + if (onMap) { + // 判定是否绘制 + 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); if (onMap) this.addGlobalAnimate(block); @@ -866,19 +872,18 @@ maps.prototype.drawBg = function (floorId, ctx) { core.clearMap(ctx); core.status.floorAnimateObjs = this._getFloorImages(floorId); } - core.maps._drawBg_drawBackground(floorId, ctx); + core.maps._drawBg_drawBackground(floorId, ctx, onMap); // ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。 - core.maps._drawFloorImages(floorId, ctx, 'bg'); + core.maps._drawFloorImages(floorId, ctx, 'bg', null, null, onMap); core.maps._drawBgFgMap(floorId, ctx, 'bg', onMap); } -maps.prototype._drawBg_drawBackground = function (floorId, ctx) { - var width = core.floors[floorId].width, height = core.floors[floorId].height; +maps.prototype._drawBg_drawBackground = function (floorId, ctx, onMap) { var groundId = (core.status.maps || core.floors)[floorId].defaultGround || "ground"; var groundInfo = core.getBlockInfo(groundId); if (groundInfo != null) { - for (var i = 0; i < width; i++) { - for (var j = 0; j < height; j++) { + for (var i = onMap ? -1 : 0; i < (onMap ? core.__SIZE__ + 1 : core.floors[floorId].width); i++) { + for (var j = onMap ? -1 : 0; j < (onMap ? core.__SIZE__ + 1 : core.floors[floorId].height); j++) { core.drawImage(ctx, groundInfo.image, 32 * groundInfo.posX, groundInfo.height * groundInfo.posY, 32, 32, i * 32, j * 32, 32, 32); } } @@ -910,7 +915,7 @@ maps.prototype.drawFg = function (floorId, ctx) { core.status.floorAnimateObjs = this._getFloorImages(floorId); } // ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。 - this._drawFloorImages(floorId, ctx, 'fg'); + this._drawFloorImages(floorId, ctx, 'fg', null, null, onMap); this._drawBgFgMap(floorId, ctx, 'fg', onMap); } @@ -930,8 +935,13 @@ maps.prototype._drawBgFgMap = function (floorId, ctx, name, onMap) { eventArr = this.getMapArray(floorId); } - for (var x = 0; x < width; x++) { - for (var y = 0; y < height; y++) { + var startX = onMap ? Math.max(0, core.bigmap.posX - 1) : 0; + var endX = onMap ? Math.min(width, core.bigmap.posX + core.__SIZE__ + 1) : width; + var startY = onMap ? Math.max(0, core.bigmap.posY - 1) : 0; + var endY = onMap ? Math.min(height, core.bigmap.posY + core.__SIZE__ + 2) : height; // +1 for 48 px + + for (var x = startX; x < endX; x++) { + for (var y = startY; y < endY; y++) { var block = this.initBlock(x, y, arr[y][x], true); block.name = name; var blockInfo = this.getBlockInfo(block); @@ -957,7 +967,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 +984,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 +1005,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) { + 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); } } } @@ -1531,11 +1550,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(); } } @@ -1603,11 +1624,9 @@ maps.prototype._triggerBgFgMap = function (type, name, loc, floorId, callback) { 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 +1656,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(); } ////// 改变图块 ////// diff --git a/libs/ui.js b/libs/ui.js index 4bae76a7..a1b5f5f3 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); + } + } } } diff --git a/project/data.js b/project/data.js index 352aa95c..107a2762 100644 --- a/project/data.js +++ b/project/data.js @@ -106,7 +106,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "title": "魔塔样板", "name": "template", "version": "Ver 2.7.1", - "floorId": "sample0", + "floorId": "sample2", "hero": { "image": "hero.png", "animate": false, diff --git a/project/items.js b/project/items.js index d019c23e..cc334474 100644 --- a/project/items.js +++ b/project/items.js @@ -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..905f7e9d 100644 --- a/project/plugins.js +++ b/project/plugins.js @@ -557,10 +557,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = 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(); }; // 改变背景层2与前景层2图块 例:core.setBgFgBlock('fg2',312,core.nextX(),core.nextY()) core.maps.setBgFgBlock = function (name, number, x, y, floorId) { diff --git a/runtime.d.ts b/runtime.d.ts index 6fb09a77..3379d22c 100644 --- a/runtime.d.ts +++ b/runtime.d.ts @@ -2748,6 +2748,8 @@ type core = { canvas: string[], offsetX: number // in pixel offsetY: number + posX: number + posY: number width: number // map width and height height: number tempCanvas: CanvasRenderingContext2D // A temp canvas for drawing