I am using HTML, CSS, and plain JavaScript for a 2D top-down tile-based simulation. I am trying to do collisions in which, for example, if I move up and hit the ceiling collision tile, I cannot proceed to go up and can still move left, right, or down.
Each title is a 64x64 HTML IMG element, including the player. The player's movement uses CSS Transform style for X and Y movements when moving with arrow keys.
For my collision function, I have the following code:
function checkCollision(arrPassableMovements) {
let childrens = cntWorldBaseCollision.children;
let tenantDOM = imgWorldTenant.getBoundingClientRect();
// For number of tiles set in the collision world
for (let i = 0; i < childrens.length; i++) {
// Get the HTML element of that tile
let childrenElement = document.getElementById(childrens[i].id);
// Get the JavaScript DOM object of that tile
let childrenDOM = childrenElement.getBoundingClientRect();
// If that tile's last fixed character ends with C
if (childrens[i].id.substring(9) == 'C') {
if (Math.abs(tenantDOM.x - childrenDOM.x) * 2 < (tenantDOM.width + childrenDOM.width) &&
Math.abs(tenantDOM.y - childrenDOM.y) * 2 < (tenantDOM.height + childrenDOM.height)) {
// Checks for up. Else, down.
if (tenantDOM.bottom - childrenDOM.bottom > 0 &&
tenantDOM.top - childrenDOM.top > 0) {
arrPassableMovements[0] = false;
} else if (tenantDOM.bottom - childrenDOM.bottom < 0 &&
tenantDOM.top - childrenDOM.top < 0) {
arrPassableMovements[1] = false;
}
// Checks for left. Else, right.
if (tenantDOM.left - childrenDOM.left > 0 &&
tenantDOM.right - childrenDOM.right > 0) {
arrPassableMovements[2] = false;
} else if (tenantDOM.left - childrenDOM.left < 0 &&
tenantDOM.right - childrenDOM.right < 0) {
arrPassableMovements[3] = false;
}
}
}
}
}
The issue begins after it is determined that the player is intercepting a collision tile. Let us say that we move up to block a ceiling tile; then, it is impossible to move left or right unless we go back—the same story with left tile, unable to move up or down unless we go right.
I had tried the following:
- Checking if it is not possible to move up or down, allow left and right movement. This, of course, meant that left and right collisions were nullified.
if (!arrPassableMovements[0] || !arrPassableMovements[1]) {
arrPassableMovements[2] = true;
arrPassableMovements[3] = true;
}
- In addition to the above, I have also added that allows up and down movement if it is not possible to move left or right, allow up and down motion. Same story as one above.
if (!arrPassableMovements[2] || !arrPassableMovements[3]) {
arrPassableMovements[0] = true;
arrPassableMovements[1] = true;
}
If I have to speculate, it has to be how I check when to nullify exact movements. In other words, possibly not enough additional conditional statements to correctly conclude that we cannot move in this direction.
NOTES:
- Player is referred to as tenant
- children(s) as the world tile (both plain and collider-bound tiles.)
- Each world tile has a fixed identification. For example, imgWBC000C breaks down the following: three characters for what HTML element it is, followed by the abbreviation for World Based Collision and a number of that, and if it is plain (P) or collision (C) tile.
- arrPassableMovements is an array with four booleans that starts with true. Each element is as follows: up, down, left, and right.
- If you believe that the provided codes are not enough, then refer to the intragarden-dev repository. The ones used are in world.js: https://github.com/Tyu-Uyt/intragarden-dev/blob/menu-redesign/world.js