我正在尝试创建一个摄像机,以显示包含在平面2d世界中的物品。 忽略碰撞,剔除,世界边界/界限等,我似乎很难为相机的“视口”制定变换,以便将世界中的对象渲染到应有的位置(即,在“世界到相机的坐标”中) “)。
我希望相机:
我在下面的示例中尝试使用println
(基本,不通过requestAnimFramce或类似的东西重绘,只是一个快照)。
很快,这就是它想要做的:
代码:
MyObject obj = new MyObject();
myMethod(obj); // Doesn't work
System.out.print(obj); // Works (why?)
static void myMethod(String str) {
// Do things
}
似乎,我正在使用mat2d(转换->旋转->缩放)使用正确的转换顺序:
glMatrix
<!DOCTYPE html>
<html lang="en-gb">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Camera</title>
<style>
*{
/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */
button,hr,input{overflow:visible}progress,sub,sup{vertical-align:baseline}[type=checkbox],[type=radio],legend{box-sizing:border-box;padding:0}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{padding:.35em .75em .625em}legend{color:inherit;display:table;max-width:100%;white-space:normal}textarea{overflow:auto}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}
}
*{
box-sizing:border-box;
margin:0;
padding:0;
font-family:Arial;
}
body{
background:#e4e4e4;
padding:15px;
font-size:14px;
overflow:hidden;
}
h1{
text-align:center;
font-size:18px;
margin:0 0 15px 0;
position:absolute;
top:20px;
left:50%;
transform:translate(-50%,0);
z-index:99999;
}
#map{
height:100%;
width:100%;
position:absolute;
top:0;
left:0;
overflow:hidden;
z-index:1;
}
#target{
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
z-index:99;
border:1px solid #999;
padding:2px;
}
.block{
background:#ccc;
border:1px solid #333;
position:absolute;
z-index:101;
transform:translate(-50%,-50%);
}
</style>
</head>
<body>
<h1>Camera</h1>
<script src="/js/g.js"></script>
<script src="/js/gl-matrix-min.js"></script>
<script>
(function(w,d){
var Block = function(conf){
this.id = conf.id || Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 20);
this.dimensions = conf.dimensions || [50,50];
this.position = conf.position || [0,0];
this.init();
};
Block.prototype = {
init: function(){
this.shape = this.generateShape();
},
generateShape: function(){
var canvas = d.createElement('canvas');
canvas.width = this.dimensions[0];
canvas.height = this.dimensions[1];
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgba(0,0,0,.4)';
ctx.rect(0, 0, this.dimensions[0], this.dimensions[1]);
ctx.fill();
return canvas;
},
draw: function(ctx){
ctx.save();
ctx.translate(
this.position[0],
this.position[1]
);
ctx.drawImage(
this.shape,
0,
0
);
ctx.restore();
}
};
var World = function(conf){
this.dimensions = conf.dimensions || [10000,10000];
this.blocks = {};
this.init();
};
World.prototype = {
init: function(){
this.grid = this.generateGrid();
this.initBlocks();
},
generateGrid: function(){
var canvas = d.createElement('canvas');
canvas.width = this.dimensions[0];
canvas.height = this.dimensions[1];
var ctx = canvas.getContext('2d');
var grid_spacing = 50;
ctx.lineWidth = 1;
ctx.strokeStyle = 'rgba(200,200,200,0.7)';
ctx.beginPath();
for( var x=0; x<this.dimensions[0]; x = x + grid_spacing ){
ctx.moveTo(0, x);
ctx.lineTo(canvas.width, x);
}
for( var y=0; y<this.dimensions[1]; y = y + grid_spacing ){
ctx.moveTo(y, 0);
ctx.lineTo(y, canvas.height);
}
ctx.closePath();
ctx.stroke();
return canvas;
},
initBlocks: function(){
var nb_blocks_min = 80,
max_blocks_extra = 100;
var nb_blocks = Math.floor(Math.random() * max_blocks_extra) + nb_blocks_min;
var block_min_size_x = 80,
block_extra_size_x = 150,
block_min_size_y = 80,
block_extra_size_y = 150;
var block_id;
for( var i=0; i<nb_blocks; i++ ){
block_id = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 20);
this.blocks[block_id] = new Block({
id: block_id,
dimensions: [
Math.floor(Math.random() * block_extra_size_x) + block_min_size_x,
Math.floor(Math.random() * block_extra_size_y) + block_min_size_y,
],
position: [
Math.floor(Math.random() * this.dimensions[0]) + 0,
Math.floor(Math.random() * this.dimensions[1]) + 0,
]
});
}
},
draw: function(ctx){
// draw grid
ctx.drawImage(this.grid, 0, 0);
// draw blocks
var block,
block_el;
for( var block_id in this.blocks ){
block = this.blocks[block_id];
block.draw(ctx);
}
},
};
var world = new World({});
var Camera = function(conf){
this.position = conf.position;
this.translate = vec2.create();
this.scale = vec2.create();
vec2.set(this.scale, conf.scale, conf.scale);
this.rotation = conf.rotation || 0;
this.matrix = mat2d.create();
this.renderable_minimap = conf.renderable_minimap || false;
this.canvas_id = conf.canvas_id;
this.width = conf.width;
this.height = conf.height;
this.world = conf.world;
this.init();
};
Camera.prototype = {
init: function(){
this.canvas = d.createElement('canvas');
this.canvas.id = this.canvas_id;
this.canvas.width = this.width;
this.canvas.height = this.height;
d.querySelector('body').appendChild(this.canvas);
this.ctx = this.canvas.getContext('2d');
},
setMatrix: function(){
mat2d.identity(this.matrix);
this.translate = vec2.set(this.translate, this.position[0], this.position[1]);
this.matrix = mat2d.translate(this.matrix, this.matrix, this.translate);
this.matrix = mat2d.rotate(this.matrix, this.matrix, this.rotation);
this.matrix = mat2d.scale(this.matrix, this.matrix, this.scale);
this.ctx.setTransform(
this.matrix[0],
this.matrix[1],
this.matrix[2],
this.matrix[3],
this.matrix[4],
this.matrix[5]
);
},
draw: function(){
this.ctx.clearRect(0, 0, this.width, this.height);
this.ctx.save();
this.setMatrix();
this.world.draw(this.ctx);
this.ctx.restore();
},
};
var map = new Camera({
// position: [world.dimensions[0]/2, world.dimensions[1]/2],
position: [0, 0],
rotation: Math.PI/3,
scale: .1,
canvas_id: 'map',
height: w.innerHeight,
width: w.innerWidth,
world: world,
renderable_minimap: true,
});
map.draw();
})(window,document);
</script>
</body>
</html>
this.translate = vec2.set(this.translate, this.position[0], this.position[1]);
this.matrix = mat2d.translate(this.matrix, this.matrix, this.translate);
我怀疑我缺少世界->浏览器转换吗?还是其他?
编辑:经过几次尝试,我想到了:
https://destination.example/accounts/record_activity
转换似乎好得多(即使尚未应用缩放)。我仍然对应用位移的方式不满意。 总体而言,位移->位置处理还能改善什么?