我正在制作 agar.io 的克隆,但我被困在我的代码中。我不明白为什么我的相机的位置没有正确计算。我希望我的相机的位置是最远 blob 和最近 blob 之间向量的一半。

下面是一张图片和我的代码:

javascript - 为什么没有正确计算相机的位置( Canvas )-LMLPHP

<html>
<head>
	<title>Play Agario Clone</title>

	<style>
	body {
		margin: 0;
		padding: 0;
	}
	</style>
</head>
<body>
	<canvas id="game">
		kindly update your browser.
	</canvas>

	<script>
	var
	canvas,
	ctx,
	width = innerWidth,
	height = innerHeight,
	mouseX = 0,
	mouseY = 0;

	var

	camera = {
		x: 0,
		y: 0,

		// camera
		update: function(obj) {
			var farthestBlobX = Math.max.apply(0, obj.blobs.map(function(cell) { return cell.x }));
			var farthestBlobY = Math.max.apply(0, obj.blobs.map(function(cell) { return cell.y }));
			var closestBlobX = Math.min.apply(0, obj.blobs.map(function(cell) { return cell.x }));
			var closestBlobY = Math.min.apply(0, obj.blobs.map(function(cell) { return cell.y }));
			var x = farthestBlobX - closestBlobX;
			var y = farthestBlobY - closestBlobY;
			var length = Math.sqrt(x * x + y * y);

			this.x = length/2 - width/2;
			this.y = length/2 - height/2;
		}
	},

	player = {
		defaultMass: 54,
		x: 0,
		y: 0,
		blobs: [],

		update: function () {
			for (var i = 0; i < this.blobs.length; i ++) {
				var x = mouseX + camera.x - this.blobs[i].x;
				var y = mouseY + camera.y - this.blobs[i].y;
				var length = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
				var speed = 54/this.blobs[i].mass;

				this.blobs[i].velX = x/length * speed * Math.min(1, Math.pow(x / this.blobs[i].mass, 2));
				this.blobs[i].velY = y/length * speed * Math.min(1, Math.pow(x / this.blobs[i].mass, 2));

				this.blobs[i].x += this.blobs[i].velX;
				this.blobs[i].y += this.blobs[i].velY;

				for (var j = 0; j < this.blobs.length; j ++) {
					if (j != i && this.blobs[i] !== undefined) {
            var blob1 = this.blobs[i];
            var blob2 = this.blobs[j];
            var x = blob2.x - blob1.x;
            var y = blob2.y - blob1.y;
            var dist = Math.sqrt(x * x + y * y);

            if (dist < blob1.mass + blob2.mass) {
              x /= dist;
              y /= dist;
              blob1.x = blob2.x - x * (blob1.mass + blob2.mass);
              blob1.y = blob2.y - y * (blob1.mass + blob2.mass);
            }
          }
				}
			}

			this.x += (mouseX - width/2)/(width/2) * 1;
			this.y += (mouseY - height/2)/(height/2) * 1
		},

		split: function (cell) {
			cell.mass /= 2;

			this.blobs.push({
				x: cell.x,
				y: cell.y,
				mass: cell.mass
			});
		},

		draw: function () {
			for (var i = 0; i < this.blobs.length; i ++) {
				ctx.fillStyle = "red";

				ctx.beginPath();
				ctx.arc(-camera.x + this.blobs[i].x, -camera.y + this.blobs[i].y, this.blobs[i].mass, 0, Math.PI*2);
				ctx.fill();
				ctx.closePath();
			}
		}
	};

	function handleMouseMove (e) {
		mouseX = e.clientX;
		mouseY = e.clientY;
	}

	function setup () {
		canvas = document.getElementById("game");
		ctx = canvas.getContext("2d");
		canvas.width = width;
		canvas.height = height;

		addEventListener("mousemove", handleMouseMove);

		player.blobs.push({
			x: 0,
			y: 0,
			mass: player.defaultMass
		});
		player.blobs.push({
			x: 100,
			y: 100,
			mass: player.defaultMass/2
		});
		player.blobs.push({
			x: 100,
			y: 100,
			mass: player.defaultMass*2
		});

		var loop = function () {
			update();
			draw();
			requestAnimationFrame(loop);
		}
		requestAnimationFrame(loop);
	}

	function update () {
		camera.update(player);
		player.update();
	}

	function draw () {
		ctx.fillStyle = "#fff";
		ctx.fillRect(0, 0, width, height);

		player.draw();
	}

	setup();
	</script>
</body>
</html>

最佳答案

我看到已经有答案了..

var canvas;
var ctx;
var width = innerWidth;
var height = innerHeight;
var mouseX = 0;
var mouseY = 0;

const camera = {
    x : 0,
    y : 0,
    update(obj) { // camera
        this.x = (obj.blobsExtent.minx + obj.blobsExtent.maxx) / 2;
        this.y = (obj.blobsExtent.miny + obj.blobsExtent.maxy) / 2;
        this.x -= width / 2;
        this.y -= height / 2;
    }
};

const player = {
    defaultMass : 54,
    blobs : [],
    blobsExtent : { // get the extent while updating the blobs save you having to iterate all the objects a second time to get extent
        minx :0,
        miny : 0,
        maxx : 0,
        maxy : 0,
    },
    update  () {
        var be = this.blobsExtent; // be for Blob Extent alias to save typing and make code easier to read
        for (var i = 0; i < this.blobs.length; i++) {
            var blob1 = this.blobs[i];
            var x = mouseX - blob1.x;
            var y = mouseY - blob1.y;
            // to stop the divide by zero propigating NaN set length to 1 if less than 1
            var length = Math.max(1,Math.sqrt(x * x + y * y)); // x * x is quicker than Math.pow(x,2)
            var speed = 54 / blob1.mass;

            blob1.velX = x / length * speed * Math.min(1, Math.pow(x / blob1.mass, 2));
            blob1.velY = y / length * speed * Math.min(1, Math.pow(x / blob1.mass, 2));

            blob1.x += blob1.velX;
            blob1.y += blob1.velY;

            for (var j = 0; j < this.blobs.length; j++) {
                if (j != i) {
                    var blob2 = this.blobs[j];
                    var x = blob2.x - blob1.x;
                    var y = blob2.y - blob1.y;
                    var dist = Math.sqrt(x * x + y * y);
                    var radTotal = blob1.mass + blob2.mass;

                    if (dist < radTotal) {
                        x /= dist;
                        y /= dist;
                        blob1.x = blob2.x - x * radTotal;
                        blob1.y = blob2.y - y * radTotal;
                    }
                }
            }

            if(i === 0){ // use first blob to setup min max
                be.maxx = be.minx = blob1.x;
                be.maxy = be.miny = blob1.y;
            }else{
                be.maxx = Math.max(be.maxx, blob1.x);
                be.maxy = Math.max(be.maxy, blob1.y);
                be.minx = Math.min(be.minx, blob1.x);
                be.miny = Math.min(be.miny, blob1.y);
            }
        }
    },
    split (cell) {
        cell.mass /= 2;
        this.blobs.push(createBlob(cell.x, cell.y, cell.mass));
    },
    draw () {
        var b;  // alias for blob
        ctx.fillStyle = "red";  // all the same colour then can render as one path
        ctx.setTransform(1,0,0,1,-camera.x,-camera.y);
        ctx.beginPath();
        for (var i = 0; i < this.blobs.length; i++) {
            b = this.blobs[i];
            ctx.arc( b.x, b.y, b.mass, 0, Math.PI * 2);
            ctx.closePath();
        }
        ctx.fill();
        ctx.setTransform(1,0,0,1,0,0); // restore default transform
    }
};

function handleMouseMove(e) {
    mouseX = e.clientX + camera.x;
    mouseY = e.clientY + camera.y;
}
function createBlob(x,y,mass){ return {x,y,mass} }
function setup() {
    canvas = document.getElementById("game");
    ctx = canvas.getContext("2d");
    canvas.width = width;
    canvas.height = height;
    addEventListener("mousemove", handleMouseMove);
    player.blobs.push(createBlob(0,0,player.defaultMass));
    player.blobs.push(createBlob(100,100,player.defaultMass / 2));
    player.blobs.push(createBlob(100,100,player.defaultMass * 2));
}

function update() {
    camera.update(player);
    player.update();
}

function draw() {
    ctx.fillStyle = "#fff";
    ctx.fillRect(0, 0, width, height);
    player.draw();
}
function loop() {
    update();
    draw();
    requestAnimationFrame(loop);
}


setup();
requestAnimationFrame(loop);
	body {
		margin: 0;
		padding: 0;
	}
<canvas id="game"></canvas>

关于javascript - 为什么没有正确计算相机的位置( Canvas ),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43953941/

10-13 08:14