From c31cd2b30abec479054931e6240a74eec9a1ac97 Mon Sep 17 00:00:00 2001 From: Arne van Iterson Date: Mon, 23 Mar 2020 19:18:30 +0100 Subject: [PATCH] Added some utilites for collision detection --- lib/TileMap.js | 14 ++++++++++ lib/movement/deadInTracks.js | 16 +++++++++++ lib/movement/wallslide.js | 51 ++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 lib/movement/deadInTracks.js create mode 100644 lib/movement/wallslide.js diff --git a/lib/TileMap.js b/lib/TileMap.js index 7900999..5fd50ca 100644 --- a/lib/TileMap.js +++ b/lib/TileMap.js @@ -54,6 +54,20 @@ class TileMap extends Container { setFrameAtPixelPos(pos, frame) { return this.setFrameAtMapPos(this.pixelToMapPos(pos), frame); } + + tilesAtCorners(bounds, xo = 0, yo = 0) { + return [ + [bounds.x, bounds.y], // Top-left + [bounds.x + bounds.w, bounds.y], // Top-right + [bounds.x, bounds.y + bounds.h], // Bottom-left + [bounds.x + bounds.w, bounds.y + bounds.h] // Bottom-right + ].map(([x, y]) => + this.tileAtPixelPos({ + x: x + xo, + y: y + yo + }) + ); + } } module.exports = TileMap; \ No newline at end of file diff --git a/lib/movement/deadInTracks.js b/lib/movement/deadInTracks.js new file mode 100644 index 0000000..cc51fbf --- /dev/null +++ b/lib/movement/deadInTracks.js @@ -0,0 +1,16 @@ +const entity = require("../utilities/entity"); + +function deadInTracks(ent, map, x = 0, y = 0) { + const bounds = entity.bounds(ent); + const tiles = map.tilesAtCorners(bounds, x, y); + const walks = tiles.map(t => t && t.frame.walkable); + const blocked = walks.some(w => !w); + if (blocked) { + x = 0, + y = 0; + } + return { x, y }; +} +module.exports = { + deadInTracks +}; \ No newline at end of file diff --git a/lib/movement/wallslide.js b/lib/movement/wallslide.js new file mode 100644 index 0000000..ad00cab --- /dev/null +++ b/lib/movement/wallslide.js @@ -0,0 +1,51 @@ +const entity = require("../utils/entity.js"); + +function wallslide(ent, map, x = 0, y = 0) { + let tiles; + let tileEdge; + const bounds = entity.bounds(ent); + + // Final amounts of movement to allow + let xo = x; + let yo = y; + + // Check vertical movement + if (y !== 0) { + tiles = map.tilesAtCorners(bounds, 0, yo); + const [tl, tr, bl, br] = tiles.map(t => t && t.frame.walkable); + + // Hit your head + if (y < 0 && !(tl && tr)) { + tileEdge = tiles[0].pos.y + tiles[0].h; + yo = tileEdge - bounds.y; + } + // Hit your feet + if (y > 0 && !(bl && br)) { + tileEdge = tiles[2].pos.y - 1; + yo = tileEdge - (bounds.y + bounds.h); + } + } + + // Check horizontal movement + if (x !== 0) { + tiles = map.tilesAtCorners(bounds, xo, yo); + const [tl, tr, bl, br] = tiles.map(t => t && t.frame.walkable); + + // Hit left edge + if (x < 0 && !(tl && bl)) { + tileEdge = tiles[0].pos.x + tiles[0].w; + xo = tileEdge - bounds.x; + } + // Hit right edge + if (x > 0 && !(tr && br)) { + tileEdge = tiles[1].pos.x - 1; + xo = tileEdge - (bounds.x + bounds.w); + } + } + // xo & yo contain the amount we're allowed to move by. + return { x: xo, y: yo }; +} + +module.exports = { + wallslide +}; \ No newline at end of file