kaplayjs / kaplay

🦖 A JavaScript/TypeScript Game Library that feels like a game, fun
https://kaplayjs.com
MIT License
525 stars 35 forks source link

bug: areas stretched with scale, debug outline doesn't line up with real area used for collisions and inspect hover #381

Closed dragoncoder047 closed 2 months ago

dragoncoder047 commented 2 months ago

Now that #338 is "closed", the debug areas are drawn not-stretched, except they don't actually line up with the real area.

Here is a demo that not only shows that they don't line up, but also is what I was doing when I discovered both #338 and this bug.

Paste in kaplayground:

const doMergeAcross = false;
kaplay({ scale: 0.5 });
loadBean();
loadSprite("grass", "/sprites/grass.png");
const SPEED = 480;
setGravity(2400);
const level = addLevel([
    "  @",
    "=============",
], {
    tileWidth: 64,
    tileHeight: 64,
    pos: vec2(100, 200),
    tiles: {
        "@": () => [
            sprite("bean"),
            area(),
            body(),
            anchor("center"),
            "player",
        ],
        "=": () => [
            sprite("grass"),
            area(),
            body({ isStatic: true }),
            anchor("center"),
            "wall",
        ],
    },
});
const player = level.get("player")[0];
onKeyPress("space", () => {
    if (player.isGrounded()) {
        player.jump();
    }
});
onKeyDown("left", () => {
    player.move(-SPEED, 0);
});
onKeyDown("right", () => {
    player.move(SPEED, 0);
});

if (doMergeAcross) mergeAcross();
debug.inspect = true;

// merge across:

function mergeAcross() {
    const tw = level.tileWidth();
    for (var y = 0; y < level.numRows(); y++) {
        var prevTile = null;
        for (var x = 0; x < level.numColumns(); x++) {
            const pos = vec2(x, y);
            const thisTile = level.getAt(pos)[0];
            if (
                prevTile != null
                && prevTile.is("wall")
                && thisTile != null
                && thisTile.is("wall")) {
                prevTile.area.offset.x += tw / 2;
                prevTile.area.scale.x++;
                thisTile.unuse("area");
                thisTile.unuse("wall");
            }
            else {
                if (thisTile != null && thisTile.is("wall"))
                    prevTile = thisTile;
                else
                    prevTile = null;
            }
        }
    }
}

With doMergeAcross set to false, everything is as expected, except there are multiple wall tiles. I don't want this.

Sooooo... with doMergeAcross set to true, some bad things happen:

  1. The blue box, that is supposed to be the area, lines up perfectly with the outline of all the wall tiles. BUT...
  2. The player falls right through the floor.
  3. And hovering over the blue box, no inspector pop up appears, indicating that you're not actually hovering on any area.

why isn't the debug view lining up when the area scale is not (1, 1)?

mflerackers commented 2 months ago

We know, translate and scale transforms were done in the wrong order before drawing for some reason. It's an easy fix, but I'm still busy with the new collision detection code.