依次检测相邻玩家的有效方法

时间:2019-10-29 05:05:49

标签: javascript arrays canvas

我正在创建一个基于回合的游戏,到目前为止,玩家可以在回合上移动并拿起武器(当前可视化效果不佳,但可以控制玩家的伤害)。我正在使用canvas API进行图形处理。玩家按箭头键移动。

现在,下一步是检查玩家是否在相邻单元格中移动,以便我开始战斗。 我想到两种方法。

  1. 保存当前位于四个单元格上的那些单元格的索引数组 播放器两侧,并在每次移动时对其进行更新。例如,如果 玩家在[1,2]上,则他的筹码为 [[0,1],[0,2],[0,3],[1,1],[1,3],[2,1],[2,3]]。但正如你所见 每一步更新它都将是一团糟。

  2. 在四个面上的每个单元格上方循环以检查另一个是否在其中一个中 他们。那也将需要大量代码。

有没有简单有效的方法来解决此问题?  game link

1 个答案:

答案 0 :(得分:0)

实际上,由于您的游戏是基于图块的,因此这可能非常简单:您可以检查图块中的距离。 假设两个玩家距离足够近,则意味着他们位于相邻的区块上(我包括对角线,但您可以按照自己的意愿做):

+--+---+---+---+--+
|  |   |   |   |  |
+--+---+---+---+--+
|  | x | x | x |  |
+--+---+---+---+--+
|  | x | O | x |  |   All the X are adjacent to O
+--+---+---+---+--+
|  | x | x | x |  |
+--+---+---+---+--+
|  |   |   |   |  |
+--+---+---+---+--+

我们分别呼叫(x1, y1)(x2, y2)的坐标player1player2。您只需检查一下x1x2之间的差异以及y1y2之间的差异就不会超过1(平铺,这就是我写{{ 1}})。 * tileSize表示重叠0的意思是相邻1表示 far

这是一个例子:

2
const KEY_LEFT = 37;
const KEY_RIGHT = 39;
const KEY_UP = 38;
const KEY_DOWN = 40;

let canvas, ctx, closeText;

let playerTurn = 1;
let player1, player2;

let tileSize;

init();

function init() {
	canvas = document.getElementById('canvas');
  ctx = canvas.getContext('2d');
  closeText = document.getElementById('close');
  
  tileSize = canvas.width / 10;
  
  player1 = new Player(10, 20, 'red');
  player2 = new Player(50, 40, 'green');
  
  updateText(areClose(player1, player2));
  
	ctx.strokeStyle = '#888';

	window.addEventListener('keyup', onKeyUp, false);
  
  draw();
}

function onKeyUp(e) {
	let dx = 0, dy = 0;

	// Where does the player move
	switch (e.keyCode) {
  	case KEY_LEFT: dx -= tileSize; break;
  	case KEY_RIGHT: dx += tileSize; break;
  	case KEY_UP: dy -= tileSize; break;
  	case KEY_DOWN: dy += tileSize; break;
  }
  
  // Which player moves
  if (playerTurn === 1) {
  	player1.x += dx;
    player1.y += dy;
  } else if (playerTurn === -1) {
  	player2.x += dx;
    player2.y += dy;
  }
  
  // Change player
  playerTurn *= -1;
  
  // Are they close enough to fight?
  const close = areClose(player1, player2);
  updateText(close);
  
  // Redraw the board and the players
  draw();
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBoard();
  drawPlayer(player1);
  drawPlayer(player2);
}

function drawBoard() {
  // Horizontal lines
	for (let i = tileSize; i < canvas.width; i += tileSize) {
    ctx.beginPath();
    ctx.moveTo(i, 0);
    ctx.lineTo(i, canvas.height);
    ctx.closePath();
  	ctx.stroke();
  }
  // Vertical lines
  for (let j = tileSize; j < canvas.height; j += tileSize) {
    ctx.beginPath();
    ctx.moveTo(0, j);
    ctx.lineTo(canvas.width, j);
    ctx.closePath();
  	ctx.stroke();
  }
}

function drawPlayer(player) {
	ctx.fillStyle = player.color;
  ctx.fillRect(player.x, player.y, player.size, player.size);
}

function Player(x, y, color) {
	this.x = x;
  this.y = y;
  this.color = color;
  this.size = 10;
}

function areClose(a, b) {
	return Math.abs(a.x - b.x) < 2 * tileSize && Math.abs(a.y - b.y) < 2 * tileSize;
}

function updateText(close) {
	closeText.innerText = close ? 'Close' : 'Not close';
}
canvas {
  border: 1px solid black;
}