1
私はAgar.ioクローンを作成しています。私はカメラに基づいて背景を描くことについての質問を見ましたが、それらはすべて画像のためだけでした。以下はキャンバスを使用してカメラに合わせてグリッドを描く
私のコードです:
クリック=スプリット
var canvas = document.querySelector("canvas");
var ctx = canvas.getContext("2d");
var width = innerWidth;
var height = innerHeight;
var evt = "mousemove";
var touchX = 0;
var touchY = 0;
var config = {
gameWidth: width,
gameHeight: height,
playerConfig: {
mass: 10,
hue: Math.round(Math.random() * 360),
border: 6
},
virusConfig: {
mass: 100,
fill: "#33ff33",
stroke: "#19D119",
border: 10
}
}
var maxSplits = 16;
var foods = [];
var viruses = [];
var clients = [];
var player = {
blobs: [],
lastSplit: 0,
extent: {
minX: 0,
minY: 0,
maxX: 0,
maxY: 0
}
};
var camera = {
x: 0,
y: 0
};
function movePlayer() {
for (var i = 0; i < player.blobs.length; i++) {
var b = player.blobs[i];
var e = player.extent;
var x = touchX + camera.x - b.x;
var y = touchY + camera.y - b.y;
var dist = Math.hypot(x, y);
b.velocity = {
x: x/dist * b.speed,
y: y/dist * b.speed
};
b.speed -= b.speed > 4 ? 0.25 : 0;
b.speed -= b.speed > 4 ? 0.25 : 0;
b.x += b.velocity.x * Math.min(1, Math.pow(x/b.r, 2));
b.y += b.velocity.y * Math.min(1, Math.pow(y/b.r, 2));
b.x = Math.min(Math.max(b.x, -config.gameWidth), config.gameWidth);
b.y = Math.min(Math.max(b.y, -config.gameHeight), config.gameHeight);
if (i == 0) {
e.minX = e.maxX = b.x;
e.minY = e.maxY = b.y;
} else {
e.minX = Math.min(b.x, e.minX);
e.minY = Math.min(b.y, e.minY);
e.maxX = Math.max(b.x, e.maxX);
e.maxY = Math.max(b.y, e.maxY);
}
}
}
function handleSelfCollision() {
for (var i = 0; i < player.blobs.length; i++) {
for (var j = 0; j < player.blobs.length; j++) {
if (j !== i && player.blobs[i] !== undefined) {
var b1 = player.blobs[i];
var b2 = player.blobs[j];
var radii = b1.r + b2.r;
var x = b2.x - b1.x;
var y = b2.y - b1.y;
var dist = Math.hypot(x, y);
if (dist < radii) {
if (player.lastSplit + 10000 > new Date().getTime()) {
x /= dist;
y /= dist;
// test
b1.x += ((b2.x - x * radii) - b1.x) * 0.6;
b1.y += ((b2.y - y * radii) - b1.y) * 0.5;
//test
} else if (dist < radii * 0.75) {
b1.mass = b1.mass + b2.mass;
b1.r = massToRadius(b1.mass);
player.blobs.splice(j, 1);
}
}
}
}
}
}
function handleVirusCollision() {
for (var i = 0; i < viruses.length; i++) {
for (var j = 0; j < player.blobs.length; j++) {
var b = player.blobs[j];
var v = viruses[i];
var x = v.x - b.x;
var y = v.y - b.y;
var dist = Math.hypot(x, y);
var radii = v.r + b.r;
if (dist < radii) {
b.r += v.r;
viruses.splice(i, 1);
if (player.blobs.length < maxSplits) {
while (b.r >= defaultPlayerR * 2) {
splitBlob(b);
}
}
}
}
}
}
function splitBlob(blob) {
if (blob.mass >= config.playerConfig.mass * 2 && player.blobs.length < maxSplits) {
blob.mass /= 2;
blob.r = massToRadius(blob.mass)
player.lastSplit = new Date().getTime();
player.blobs.push({
x: blob.x,
y: blob.y,
mass: blob.mass,
r: massToRadius(blob.mass),
speed: 20
});
}
}
function moveCamera() {
var e = player.extent;
camera.x = (e.maxX + e.minX)/2;
camera.y = (e.maxY + e.minY)/2;
camera.x -= width/2;
camera.y -= height/2;
}
function addFood(num) {
var rnd = random(1, 1.5);
while (num--) {
foods.push({
x: random(-config.gameWidth, config.gameWidth),
y: random(-config.gameHeight, config.gameHeight),
mass: rnd,
r: massToRadius(rnd),
hue: Math.round(Math.random() * 360)
});
}
}
function addVirus(num) {
while (num--) {
viruses.push({
x: random(-width, width),
y: random(-height, height),
mass: config.virusConfig.mass,
r: massToRadius(config.virusConfig.mass)
});
}
}
function updateFood() {
for (var i = 0; i < foods.length; i++) {
for (var j = 0; j < player.blobs.length; j++) {
var b = player.blobs[j];
var f = foods[i];
var x = f.x - b.x;
var y = f.y - b.y;
var dist = Math.hypot(x, y);
var radii = f.r + b.r;
if (dist < radii) {
b.mass += f.mass;
b.r = massToRadius(b.mass);
foods.splice(i, 1);
break;
}
}
}
if (foods.length < 100) {
addFood(1);
}
}
function drawPlayer(order) {
var sortedArr = player.blobs.sort(function(b1, b2) {
return b1.mass - b2.mass;
});
for (var i = 0; i < sortedArr.length; i++) {
var b = sortedArr[i];
ctx.fillStyle = "hsl(" + config.playerConfig.hue + ", 100%, 50%)";
ctx.strokeStyle = "hsl(" + config.playerConfig.hue + ", 100%, 45%)";
ctx.lineWidth = config.playerConfig.border;
ctx.beginPath();
ctx.arc(b.x - camera.x, b.y - camera.y, b.r, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
}
}
function drawFood() {
for (var i = 0; i < foods.length; i++) {
var f = foods[i];
ctx.fillStyle = 'hsl(' + f.hue + ', 100%, 50%)';
ctx.beginPath();
ctx.arc(f.x - camera.x, f.y - camera.y, f.r, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
}
function drawVirus() {
for (var i = 0; i < viruses.length; i++) {
var v = viruses[i];
ctx.fillStyle = config.virusConfig.fill;
ctx.strokeStyle = config.virusConfig.stroke;
ctx.lineWidth = config.virusConfig.border;
ctx.beginPath();
ctx.arc(v.x - camera.x, v.y - camera.y, v.r, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
}
}
function drawPlatform(bgcol, borcol, thickness) {
var x = -config.gameWidth - camera.x;
var y = -config.gameHeight - camera.y;
var w = 2 * config.gameWidth;
var h = 2 * config.gameHeight;
ctx.fillStyle = bgcol;
ctx.fillRect(x, y, w, h);
ctx.lineWidth = thickness;
ctx.strokeStyle = borcol;
ctx.strokeRect(x, y, w, h);
}
function drawBackground(col) {
ctx.fillStyle = col;
ctx.fillRect(0, 0, width, height);
}
function drawGrid() {
}
function updateAndDraw() {
movePlayer();
moveCamera();
updateFood();
handleSelfCollision();
//handleVirusCollision();
drawBackground("#f2fbff");
drawPlatform("#fff", "#000", 10);
drawGrid();
drawFood();
drawPlayer();
drawVirus();
requestAnimationFrame(updateAndDraw);
}
function handleEvent(event) {
touchX = event.clientX;
touchY = event.clientY;
}
function random(min, max) {
return (min + (Math.random() * (max - min)));
}
function massToRadius(mass) {
return 4 + Math.sqrt(mass) * 6;
}
function startTheGame() {
evt = width < 600 ? "click" : "mousemove";
canvas.width = width;
canvas.height = height;
addFood(100);
addVirus(5);
player.blobs.push({
x: width/2,
y: height/2,
mass: config.playerConfig.mass,
r: massToRadius(config.playerConfig.mass),
speed: 8
});
//test
canvas.addEventListener("click", function() {
var blobs = player.blobs.length;
for (var i = 0; i < blobs; i++) {
if (blobs < maxSplits) {
splitBlob(player.blobs[i]);
} else {
break;
}
}
});
addEventListener("resize", function() {
width = innerWidth;
height = innerHeight
});
// test
canvas.addEventListener(evt, handleEvent);
updateAndDraw();
}
startTheGame();
body {
padding: 0;
margin: 0;
}
<title>Gaario - A simple Agario clone</title>
<canvas>Awww! Your browser doesn't support canvas.</canvas>
これが尋ねた質問への解決策である理由あなたは十分に説明されていません。あなたは何を変えましたか?どのようにコードが質問された質問と異なるのですか?なぜそれは以前にはうまくいかなかったのですが、これがどのように問題を解決しましたか? – Adam
あなたの例についていくつかの説明をしていただけますか? – mhatch
ループ内のx * gridSizeについて説明できますか –