Rendering solid objects in html canvas?

Viewed 71

I'm making an html5 canvas game, and I need to render some solid objects. It's a sort of sandbox game, and so here's how I was planning on doing it:

  1. Find out which square(s) the player is touching
  2. Check if surrounding squares are solid
  3. If so, do not let the player pass that point
  4. Repeat when the gameloop function does

I'm sorry if you don't understand what I'm saying, but the ground is made up of squares that are the same size as the player's hitbox (meaning that the hitbox can't go inside a solid object). Hope this helps you understand.
Here's what I need:
I can't find out how to detect all the squares around the one that the player is in. Here's my function so far:

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 && player.y < Math.floor(y - 1)) {
  player.y = Math.floor(y);
} else if (pass.left == false && player.x > Math.floor(x + 1)) {
  player.x = Math.floor(x);
} else if (pass.bottom == false && player.y > Math.floor(y + 1)) {
  player.y = Math.floor(y);
} else if (pass.right == false && player.x < Math.floor(x - 1)) {
  player.x = Math.floor(x);
}
}

And I'm also unsure what to do if the player is touching two squares? Sorry if this is a terrible question, and thanks for reading through it. I hope you try to answer, and Thanks in advance!

EDIT: I'm so terribly sorry, but I forgot to mention that my map is an ASCII map, and here's the variable for it

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

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

Take a look (run/play) and ask questions. Note: I've added one wall just to test.

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 && 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] != '#' && x >=0 && y >=0 && x < mapWidth && 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" />

Related