2017-05-23 29 views
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>

答えて

0

グリッドに水平線を描画した後、垂直なものを追加することによって描画することができます。 ctx.lineTo()ctx.moveTo()の機能をctx.beginPath()ctx.stroke()と組み合わせて使用​​すると、グリッドが描画されます。コンテナの左上隅がどこにある私たちが知っていることを、私たちは事実を使用して線を描画するためのループのために

function drawGrid() { 
    var gridSize = 30; // define the space between each line 
    var x = -config.gameWidth - camera.x; // x start point of the field 
    var y = -config.gameHeight - camera.y // y start point of the field 
    var width = 2 * config.gameWidth; 
    var height = 2 * config.gameHeight; 

    ctx.lineWidth = 1; 
    ctx.beginPath(); 
    for(var i = 0; i * gridSize < height; i++) { // draw the horizontal lines 
     ctx.moveTo(x, i * gridSize + y); 
     ctx.lineTo(x + width, i * gridSize + y); 
    } 
    for(var i = 0; i * gridSize < width; i++) { // draw the vertical lines 
     ctx.moveTo(i * gridSize + x, y); 
     ctx.lineTo(i * gridSize + x, y + height); 
    } 
    ctx.stroke(); 
} 

は私がdrawGrid()関数の本体を満たしました。変数 xおよび y。 したがって、縦線を描画するには、y座標の yから y + heightを指すことがわかります。 forループで i * gridSize + xを実行すると、各行のx座標を計算できます。 最初の行が i = 0の場合は、単にゲームフィールドの左のボーダーである xが返ってきます。 2行目は 1 * gridSize + xで、3行目は 2 * gridSize + xと続きます。

i * gridSize < widthという長さのためにiをインクリメントすると、すべての垂直線がゲームフィールドに描画されます。あなた以下

for(var i = 0; i * gridSize < width; i++) { // draw the vertical lines 
    ctx.moveTo(i * gridSize + x, y); 
    ctx.lineTo(i * gridSize + x, y + height); 
} 

あなたのコード例は、追加された機能で、見つけます。

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() { 
    var gridSize = 30; // define the space between each line 
    var x = -config.gameWidth - camera.x; // x start point 
    var y = -config.gameHeight - camera.y // y start point 
    var width = 2 * config.gameWidth; 
    var height = 2 * config.gameHeight; 
    ctx.lineWidth = 1; 
    ctx.beginPath(); 
    for(var i = 0; i * gridSize < height; i++) { // draw the horizontal lines 
    ctx.moveTo(x, i * gridSize + y); 
    ctx.lineTo(x + width, i * gridSize + y); 
    } 
    for(var i = 0; i * gridSize < width; i++) { // draw the vertical lines 
    ctx.moveTo(i * gridSize + x, y); 
    ctx.lineTo(i * gridSize + x, y + height); 
    } 
    ctx.stroke(); 
} 

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> 
+2

これが尋ねた質問への解決策である理由あなたは十分に説明されていません。あなたは何を変えましたか?どのようにコードが質問された質問と異なるのですか?なぜそれは以前にはうまくいかなかったのですが、これがどのように問題を解決しましたか? – Adam

+0

あなたの例についていくつかの説明をしていただけますか? – mhatch

+0

ループ内のx * gridSizeについて説明できますか –

関連する問題