我正在创建一个基于回合的游戏,到目前为止,玩家可以在回合上移动并拿起武器(当前可视化效果不佳,但可以控制玩家的伤害)。我正在使用canvas API进行图形处理。玩家按箭头键移动。
现在,下一步是检查玩家是否在相邻单元格中移动,以便我开始战斗。 我想到两种方法。
保存当前位于四个单元格上的那些单元格的索引数组 播放器两侧,并在每次移动时对其进行更新。例如,如果 玩家在[1,2]上,则他的筹码为 [[0,1],[0,2],[0,3],[1,1],[1,3],[2,1],[2,3]]。但正如你所见 每一步更新它都将是一团糟。
在四个面上的每个单元格上方循环以检查另一个是否在其中一个中 他们。那也将需要大量代码。
有没有简单有效的方法来解决此问题? game link
答案 0 :(得分:0)
实际上,由于您的游戏是基于图块的,因此这可能非常简单:您可以检查图块中的距离。 假设两个玩家距离足够近,则意味着他们位于相邻的区块上(我包括对角线,但您可以按照自己的意愿做):
+--+---+---+---+--+
| | | | | |
+--+---+---+---+--+
| | x | x | x | |
+--+---+---+---+--+
| | x | O | x | | All the X are adjacent to O
+--+---+---+---+--+
| | x | x | x | |
+--+---+---+---+--+
| | | | | |
+--+---+---+---+--+
我们分别呼叫(x1, y1)
和(x2, y2)
的坐标player1
和player2
。您只需检查一下x1
和x2
之间的差异以及y1
和y2
之间的差异就不会超过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;
}