你如何考虑放大自上而下的视口?

如果这个问题是坏的,请原谅我。 我有一个通用的自顶向下的RPG结构,我想为它创建一个可缩放的Canvas视口。 我已经阅读了几个教程,我想我一直把它搞乱。

目前的Codepen项目在这里。

项目相关代码:


相机:

function Camera(PARENT, CANVAS, SUBJECT, ZOOM) { this.draw = function() { var refs = []; Rect.call(this, SUBJECT.x, SUBJECT.y, CANVAS.width*ZOOM, CANVAS.height*ZOOM, "cen"); for(o in PARENT.objects) { if(this.overlapping(PARENT.objects[o])) refs.push(o); } while(refs.length>=1) { var obj = PARENT.objects[refs.shift()]; if(obj.draw) obj.draw( this.context, //Drawing ctx this.left, //Offset left this.top, //Offset top ZOOM //Scale factor ); } }; } 

相机调用的绘图function:

 this.draw = function(context, offsetX, offsetY, scale) { context.fillStyle = this.color; context.fillRect((this.left-offsetX)*scale, (this.top-offsetY)*scale, this.width*scale, this.height*scale); }; 

我怎样才能在这里解决这个math问题,这样就可以正确地把缩放到graphics偏移量中?

一般来说,您可以在上下文中使用scalefunction来处理缩放。

 function drawAll(context, cameraX, cameraY, scale) { context.save(); context.translate(cameraX, cameraY); context.scale(scale, scale); // Draw everything else context.restore(); } 

这意味着你可以像这样绘制每个矩形:

 this.draw = function(context) { context.fillStyle = this.color; context.fillRect(this.left, this.top, this.width, this.height); }; 

采取这种方法意味着更less的计算和更简单的操作相机的方式。

那么我已经解决了我的问题。 我没有考虑到CANVAS尺寸和ZOOM的canvas尺寸之间的差异。 我还没有完全优化这个,但我现在发布它,因为我认为这是任何人有类似问题的一个很好的例子。

固定的Codepen叉子。

对代码的相关更改:


相机:

 function Camera(PARENT, CANVAS, SUBJECT, ZOOM) { //... this.getRefs = function() { this.refs = []; for(num in PARENT.objects) { var obj = PARENT.objects[num]; if(this.projectedRect.overlapping(obj)) this.refs.push(num); } return this.refs; }; this.worldToScreen = function(x, y) { if(!y&&typeof x == "object") { if(xx!==undefined&&x.y!==undefined) y = xy, x = xx; else if(x.left!==undefined&&x.top!==undefined) y = x.top, x = x.left; else throw "worldToScreen Error"; } return { x: (x-this.projectedRect.left)*(CANVAS.width/this.projectedRect.width), y: (y-this.projectedRect.top)*(CANVAS.height/this.projectedRect.height) } } this.screenToWorld = function(x, y) { if(!y&&typeof x == "object") { if(xx!==undefined&&x.y!==undefined) y = xy, x = xx; else if(x.left!==undefined&&x.top!==undefined) y = x.top, x = x.left; else throw "screenToWorld Error"; } return { x: (x*(this.projectedRect.width/CANVAS.width))+this.projectedRect.left, y: (y*(this.projectedRect.height/CANVAS.height))+this.projectedRect.top } } this.update = function() { var testRect = new Rect(SUBJECT.x, SUBJECT.y, CANVAS.width*ZOOM, CANVAS.height*ZOOM, "cen"); if(!this.projectedRect|| this.projectedRect.left != testRect.left || this.projectedRect.right != testRect.right || this.projectedRect.top != testRect.top || this.projectedRect.bottom != testRect.bottom) { this.projectedRect = testRect; this.getRefs(); } }; this.update(); this.clear = function() { this.context.clearRect(0,0,CANVAS.width,CANVAS.height); }; this.draw = function() { this.clear(); this.update(); for(num in this.refs) PARENT.objects[this.refs[num]].draw(this); PARENT.mouseLoc.draw(this); }; } 

在对象上调用绘图函数:

 this.draw = function(CAM) { var screenPos = CAM.worldToScreen(this); CAM.context.fillStyle = this.color; CAM.context.fillRect(screenPos.x, screenPos.y, 10, 10); };