replit / kaboom

💥 JavaScript game library
https://kaboomjs.com
MIT License
2.67k stars 228 forks source link

No collision detection in RPG demo - add an option in the moveleft/right shortcut? #49

Closed triptych closed 3 years ago

triptych commented 3 years ago

In the RPG demo the player can move through walls. This is because of the player.moveLeft etc does not take into consideration solid objects. Can you add some option in the moveLeft /moveRight etc. shortcut to stop if the movement would have if it overlaps with a solid object? Or in some way account for the solid walls.

References:

https://kaboomjs.com/examples#rpg

https://github.com/replit/kaboom/blob/e71c785ce3f1961ab93357d9f612fd564b8962f2/src/kaboom.ts#L1915

triptych commented 3 years ago

Perhaps something like what was implemented here https://replit.com/@AaronJewell/Pathfinding-in-Kaboom ( the collision detection part )


    player.moveLeft()
    // handle tile collision
    const targets = player.resolve()
    if (targets.length
      && targets.find(t => t.obj.gridPos.x === player.gridPos.x && t.obj.gridPos.y === player.gridPos.y)
    ) {
      player.moveRight()
    } else {
      player.findPath(drawSteps);
    }
  })```
triptych commented 3 years ago

I created a local version of the RPG demo and used this:


    K.keyPress("left", () => {
        player.moveLeft();
    const targets = player.resolve()
    if (targets.length
      && targets.find(t => t.obj.gridPos.x === player.gridPos.x && t.obj.gridPos.y === player.gridPos.y)
    ) {
      player.moveRight()
    }
    });

K.keyPress("right", () => {
        player.moveRight();
  // handle tile collision
    const targets = player.resolve()
    if (targets.length
      && targets.find(t => t.obj.gridPos.x === player.gridPos.x && t.obj.gridPos.y === player.gridPos.y)
    ) {
      player.moveLeft()
    }
    });

    K.keyPress("up", () => {
        player.moveUp();
    // handle tile collision
    const targets = player.resolve()
    if (targets.length
      && targets.find(t => t.obj.gridPos.x === player.gridPos.x && t.obj.gridPos.y === player.gridPos.y)
    ) {
      player.moveDown()
    }
    });

    K.keyPress("down", () => {
        player.moveDown();
    const targets = player.resolve()
    if (targets.length
      && targets.find(t => t.obj.gridPos.x === player.gridPos.x && t.obj.gridPos.y === player.gridPos.y)
    ) {
      player.moveUp()
    }
    });

But in order for this to work I had to turn off solid for the door and the characters:

            //K.solid(),
            "door",

Full working example here https://observablehq.com/@triptych/kaboom-rpg-example

triptych commented 3 years ago

I see a related discussion here https://github.com/replit/kaboom/issues/16

slmjkdbtl commented 3 years ago

Yeah, it's an incomplete example. The goal is to develop a system for grid-based games and use cheap grid based collision resolution instead of expensive resolve(). This kinda halted, but will pick up shortly.

rabaut commented 2 years ago

@slmjkdbtl any update on when grid based collision will be supported?

slmjkdbtl commented 2 years ago

Not a priority at the moment. Currently working on a new physics system, I'll give grid-based collision a visit after that's done! It's mainly a matter of API design I think.

triptych commented 2 years ago

Thanks for the update! @slmjkdbtl

wratjs commented 1 year ago

Hello, thanks for this awesome library!

I'm working on a small rogue-like using Kaboom and I see here you planned to finish grid based collision but that work is on pause. My plan was to write my own collision system for this game by simply checking the tile/grid that the player would enter on key press. Since I'm making a rogue-like its turn based and this is fairly easy.

I was curious if level.get ing my various entities and checking them is the best way -- or is there some alternative that I could use and is maybe less obvious?

Perhaps if you elaborated in a short description on how you were going to attempt the grid based collision I might be able to use that to track down a better solution, if one exists.

EDIT: Maybe I should add that perhaps tile/agent components are the solution that arose here. In my case I was intending to create something turn based and as such the various onCollide style hooks only occur once you have a collision. There isn't something like willCollide as a turn based rogue-like might need. Also, agents only work with move style operations as opposed to move{Left,Right,Up,Down} so they didn't seem like the natural fit for something grid based necessarily.