Рендеринг сплошных объектов в html canvas?

#javascript #html #canvas

#javascript #HTML #холст

Вопрос:

Я создаю игру на html5 canvas, и мне нужно отобразить некоторые твердые объекты. Это своего рода игра в песочнице, и вот как я планировал это сделать:

  1. Узнайте, к какому квадрату (ам) прикасается игрок
  2. Проверьте, являются ли окружающие квадраты сплошными
  3. Если это так, не позволяйте проигрывателю пройти этот момент
  4. Повторите, когда функция gameloop выполнит

Извините, если вы не понимаете, о чем я говорю, но площадка состоит из квадратов того же размера, что и хитбокс игрока (это означает, что хитбокс не может попасть внутрь сплошного объекта). Надеюсь, это поможет вам понять.
Вот что мне нужно:
Я не могу выяснить, как определить все квадраты вокруг того, в котором находится игрок. Вот моя функция на данный момент:

 function rendersolid() {
  var x = player.x;
  var y = player.y;

  var pass = {
  top: true;
  left: true;
  bottom: true;
  right: true;
};
  if (map[x][y] == !undefined) {
  console.log(map[x][y]);
  }
  //check surrounding blocks (and if they're #)
  //change 'pass' variables to false if you CAN'T pass, else true

  //do not let the player pass that point
  //FYI, Math.floor(y - 1) is one square above the player, as the same with x is one left of the player
  if (pass.top == false amp;amp; player.y < Math.floor(y - 1)) {
  player.y = Math.floor(y);
} else if (pass.left == false amp;amp; player.x > Math.floor(x   1)) {
  player.x = Math.floor(x);
} else if (pass.bottom == false amp;amp; player.y > Math.floor(y   1)) {
  player.y = Math.floor(y);
} else if (pass.right == false amp;amp; player.x < Math.floor(x - 1)) {
  player.x = Math.floor(x);
}
}
  

И я также не уверен, что делать, если игрок касается двух квадратов? Извините, если это ужасный вопрос, и спасибо, что прочитали его. Я надеюсь, что вы попытаетесь ответить, и заранее спасибо!

РЕДАКТИРОВАТЬ: Мне так ужасно жаль, но я забыл упомянуть, что моя карта — это карта ASCII, и вот переменная для нее

 var map = 
`##................................................
##........'........................'..............
..'.''....'.....'..........'.''....'.....'........
....'...'....................'...'................
..'..'.....................'..'...................
...''.......................''....................
..'....'...'.....'.........'....'...'.....'.......
.......'...........'............'...........'.....
.......'......'.................'......'..........
....'........................'....................
...'..'...'.................'..'...'..............
.......'......'....'............'......'....'.....
............'....'...'...............'....'...'...
...'....'..'...'............'....'..'...'.........
...'.....'......'...........'.....'......'........
..............'.'.....'................'.'.....'..
......'.....'...'..............'.....'...'........
.......'.......'.......'........'.......'.......'.
....'......'.......'......'..'....................
..........'.'''''.'''..............'.'...'..'.....
...'.....'....'...'.........'...'......'..........
.....'....'...'...'''.........'....'.........'....
.....'.....'..'.....'.........'.....'........'....
...'......'...'...'''.......'......'...'...'......
........'...............'......'....'.............
.......'.....''...........'.......'.........'.....
..........'.......'................'..............
..'.''....'.....'..........'.''....'.....'........
....'...'.......'...''.......'...'................
..'..'....'.......'....'...'..'...................
...''.......................''....................
..'....'...'.....'.........'....'...'.....'.......
.......'...........'............'...........'.....
.......'......'.................'......'..........
....'........................'....................
..........'.'...'.'................'.'.'...'.'....
...'.....'....'.............'.....'...'....'......
.....'....'.........'.........'....'........'.....
.....'.....'..'.....'.........'.....'.............
...'......'...'...'.........'......'...'...'.'....
...'..'...'.................'..'...'..............
.......'......'....'............'......'....'.....
............'....'...'...............'....'...'...
...'....'..'...'............'....'..'...'.........
...'.....'......'...........'.....'......'........
..............'.'.....'................'.'.....'..
......'.....'...'..............'.....'...'........
.......'.......'.......'........'.......'.......'.
....'......'.......'.........'......'.......'.....
..................................................`.split("n");
  

И вот цветовая карта:

 var colorMap = {
'.': "#47CB00", //For grass
'#': "#000000", //Black, solid
' ': "#878787", //Grey
''': "#349500", //Darker green, for grass texture (ignore the '')
'0': "#FFFFFF"  //white
};
  

Комментарии:

1. Я могу дать вам преимущество только для карты ASCII =)

2. Чего вы пытаетесь достичь? Если игрок находится на X, Y и пользователь нажимает на квадрат рядом с ним (так что X или — 1, или Y или — 1), затем проверьте, может ли игрок перемещаться таким образом?

3. Да, сплошной блок должен сделать их неспособными войти в него

Ответ №1:

Посмотрите (запустите / воспроизведите) и задавайте вопросы. Примечание: я добавил одну стену просто для тестирования.

 var map =
  `##................................................
##........'........................'..............
..'.''.#..'.....'..........'.''....'.....'........
....'..#'....................'...'................
..'..'.#...................'..'...................
...''.......................''....................
..'....'...'.....'.........'....'...'.....'.......
.......'...........'............'...........'.....
.......'......'.................'......'..........
....'........................'....................
...'..'...'.................'..'...'..............
.......'......'....'............'......'....'.....
............'....'...'...............'....'...'...
...'....'..'...'............'....'..'...'.........
...'.....'......'...........'.....'......'........
..............'.'.....'................'.'.....'..
......'.....'...'..............'.....'...'........
.......'.......'.......'........'.......'.......'.
....'......'.......'......'..'....................
..........'.'''''.'''..............'.'...'..'.....
...'.....'....'...'.........'...'......'..........
.....'....'...'...'''.........'....'.........'....
.....'.....'..'.....'.........'.....'........'....
...'......'...'...'''.......'......'...'...'......
........'...............'......'....'.............
.......'.....''...........'.......'.........'.....
..........'.......'................'..............
..'.''....'.....'..........'.''....'.....'........
....'...'.......'...''.......'...'................
..'..'....'.......'....'...'..'...................
...''.......................''....................
..'....'...'.....'.........'....'...'.....'.......
.......'...........'............'...........'.....
.......'......'.................'......'..........
....'........................'....................
..........'.'...'.'................'.'.'...'.'....
...'.....'....'.............'.....'...'....'......
.....'....'.........'.........'....'........'.....
.....'.....'..'.....'.........'.....'.............
...'......'...'...'.........'......'...'...'.'....
...'..'...'.................'..'...'..............
.......'......'....'............'......'....'.....
............'....'...'...............'....'...'...
...'....'..'...'............'....'..'...'.........
...'.....'......'...........'.....'......'........
..............'.'.....'................'.'.....'..
......'.....'...'..............'.....'...'........
.......'.......'.......'........'.......'.......'.
....'......'.......'.........'......'.......'.....
..................................................`.split("n");

var colorMap = {
  '.': "#47CB00", //For grass
  '#': "#000000", //Black, solid
  ' ': "#878787", //Grey
  ''': "#349500", //Darker green, for grass texture (ignore the '')
  '0': "#FFFFFF", //white,
  '@': 'red' // Player
};

let mapWidth = map[0].length;
let mapHeight = map.length;
const TILE = 12;
const c = document.getElementById("canvas");
const ctx = c.getContext("2d");
const player = {
  x: 0,
  y: 0
};
const mouse = {
  x: 0,
  y: 0
};

const initCanvas = () => {
  c.width = mapWidth * TILE;
  c.height = mapHeight * TILE;
}

const drawTile = (x, y, type) => {
  ctx.beginPath();
  ctx.rect(x * TILE, y * TILE, TILE, TILE);
  ctx.fillStyle = colorMap[type];
  ctx.fill();
}

const drawMapTile = (x, y) => {
  drawTile(x, y, map[y][x]);
}

const drawMap = () => {
  for (let y = 0; y < mapHeight; y  )
    for (let x = 0; x < mapWidth; x  )
      drawTile(x, y, map[y][x])
}

const initPlayer = () => {
  player.x = 4;
  player.y = 4;
}

const drawPlayer = () => {
  drawTile(player.x, player.y, '@')
}

const drawMouse = () => {
  ctx.beginPath();
  ctx.lineWidth = 1;
  ctx.moveTo(mouse.x * TILE   1, mouse.y * TILE   1);
  ctx.lineTo(mouse.x * TILE   1, mouse.y * TILE   TILE - 1);
  ctx.lineTo(mouse.x * TILE   TILE - 1, mouse.y * TILE   TILE - 1);
  ctx.lineTo(mouse.x * TILE   TILE - 1, mouse.y * TILE   1);
  ctx.lineTo(mouse.x * TILE   1, mouse.y * TILE   1);
  ctx.stroke();
}

const showMouseCursor = (newX, newY) => {
  drawMapTile(mouse.x, mouse.y);
  if (mouse.x == player.x amp;amp; mouse.y == player.y) drawPlayer();
  mouse.x = newX;
  mouse.y = newY;
  drawMouse();
}

const getMousePos = (e) => {
  var rect = e.target.getBoundingClientRect();
  var x = e.clientX - rect.left;
  var y = e.clientY - rect.top;
  let mouseX = x / TILE | 0;
  let mouseY = y / TILE | 0;
  return {
    x: mouseX,
    y: mouseY
  };
}

const teleportPlayerTo = (x, y) => {
  if (map[y][x] != '#' amp;amp; x >=0 amp;amp; y >=0 amp;amp; x < mapWidth amp;amp; y < mapHeight) {
    drawMapTile(player.x, player.y);
    player.x = x;
    player.y = y;
    drawPlayer();
  }
}

c.onmousemove = (e) => {
  const mouse = getMousePos(e);
  showMouseCursor(mouse.x, mouse.y);
  e.preventDefault();
}

c.onclick = (e) => {
  const mouse = getMousePos(e);
  const dx = Math.abs(mouse.x - player.x);
  const dy = Math.abs(mouse.y - player.y);
  if (dx   dy == 1) {
    teleportPlayerTo(mouse.x, mouse.y);
  }
}

initCanvas();
drawMap();
initPlayer();
drawPlayer();  
 <canvas id="canvas" />  

Комментарии:

1. Это было чрезвычайно полезно, и я не могу выразить свою благодарность. Честно говоря, я не мог бы попросить лучшего ответа. Большое вам спасибо!