Here is the code for allowing a character to move across the screen. It adds the character and keeps track of its position. As the arrow keys are pressed the position of the character is updated as you would expect. To check if the character is contained within a "floor" element the code loops through all the grid items (css grid) and gets the tag of the grid item ("floor" or "brick") and (should) prevent movement if the character is touching the border of a "brick" element.

The code does not work. The character is able to pass freely through the brick "walls" whereas they should only be able to move within the "floor" items (like a maze).

const character = document.createElement("img");
character.id = "character";
character.src = obj.image;
character.style.width = "30px";
document.getElementById(obj.target_id).append(character);

let xPos = Number(window.getComputedStyle(character).left.split("px").join(""));
let yPos = Number(window.getComputedStyle(character).top.split("px").join(""));

const moveAmount = 10;

function updateCharacterPosition() {
    character.style.marginLeft = xPos.toString() + "px";
    character.style.marginTop = yPos.toString() + "px";
}

function contained_inside_block(element1, element2) {
    const character = element1.getBoundingClientRect();
    const block = element2.getBoundingClientRect();
    // Adjust the collision check to prevent the character from moving into the border of "brick" elements
    return (character.top < block.bottom && character.bottom > block.top && character.left < block.right && character.right > block.left);
}
window.addEventListener('keydown', function(event) {
    arrow_directions = {
        up: false,
        down: false,
        left: false,
        right: false
    }
    let newPosX = xPos;
    let newPosY = yPos;
    switch(event.key) {
        case 'ArrowUp':
            newPosY = Math.max(yPos - moveAmount, 0);
            arrow_directions["up"] = true;
            break;
        case 'ArrowDown':
            newPosY = Math.min(yPos + moveAmount, window.innerHeight - character.clientHeight);
            arrow_directions["down"] = true;
            break;
        case 'ArrowLeft':
            newPosX = Math.max(xPos - moveAmount, 0);
            arrow_directions["left"] = true;
            break;
        case 'ArrowRight':
            newPosX = Math.min(xPos + moveAmount, window.innerWidth - character.clientWidth);
            arrow_directions["right"] = true;
            break;
    }
    // Check if the new position is allowed based on the floor and brick elements
    let allowMove = true;
    document.querySelectorAll("[id^=grid_item_]").forEach(function(elem) {
        const containedCheck = contained_inside_block({
            getBoundingClientRect: () => ({
                top: newPosY,
                bottom: newPosY + character.clientHeight,
                left: newPosX,
                right: newPosX + character.clientWidth
            })
        }, elem);
        const tag = elem.getAttribute("store_tag");
        if(containedCheck && tag === "brick") {
            // Prevent movement if the character is touching the border of a "brick" element
            allowMove = false;
        }
    });
    // Update the character position only if movement is allowed
    if(allowMove) {
        xPos = newPosX;
        yPos = newPosY;
        updateCharacterPosition();
    }
});
0

There are 0 answers